mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[ConstantRanges] Use APInt for constant case for urem/srem.
Currently UREM & SREM on constant ranges produces overly pessimistic results for single element constant ranges. Delegate to APInt's implementation if both operands are single element constant ranges. We already do something similar for other binary operators, like binary AND. Fixes PR49731. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D105115
This commit is contained in:
parent
b307f6c209
commit
c934ce7ceb
@ -1221,6 +1221,15 @@ ConstantRange ConstantRange::urem(const ConstantRange &RHS) const {
|
|||||||
if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue())
|
if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue())
|
||||||
return getEmpty();
|
return getEmpty();
|
||||||
|
|
||||||
|
if (const APInt *RHSInt = RHS.getSingleElement()) {
|
||||||
|
// UREM by null is UB.
|
||||||
|
if (RHSInt->isNullValue())
|
||||||
|
return getEmpty();
|
||||||
|
// Use APInt's implementation of UREM for single element ranges.
|
||||||
|
if (const APInt *LHSInt = getSingleElement())
|
||||||
|
return {LHSInt->urem(*RHSInt)};
|
||||||
|
}
|
||||||
|
|
||||||
// L % R for L < R is L.
|
// L % R for L < R is L.
|
||||||
if (getUnsignedMax().ult(RHS.getUnsignedMin()))
|
if (getUnsignedMax().ult(RHS.getUnsignedMin()))
|
||||||
return *this;
|
return *this;
|
||||||
@ -1234,6 +1243,15 @@ ConstantRange ConstantRange::srem(const ConstantRange &RHS) const {
|
|||||||
if (isEmptySet() || RHS.isEmptySet())
|
if (isEmptySet() || RHS.isEmptySet())
|
||||||
return getEmpty();
|
return getEmpty();
|
||||||
|
|
||||||
|
if (const APInt *RHSInt = RHS.getSingleElement()) {
|
||||||
|
// SREM by null is UB.
|
||||||
|
if (RHSInt->isNullValue())
|
||||||
|
return getEmpty();
|
||||||
|
// Use APInt's implementation of SREM for single element ranges.
|
||||||
|
if (const APInt *LHSInt = getSingleElement())
|
||||||
|
return {LHSInt->srem(*RHSInt)};
|
||||||
|
}
|
||||||
|
|
||||||
ConstantRange AbsRHS = RHS.abs();
|
ConstantRange AbsRHS = RHS.abs();
|
||||||
APInt MinAbsRHS = AbsRHS.getUnsignedMin();
|
APInt MinAbsRHS = AbsRHS.getUnsignedMin();
|
||||||
APInt MaxAbsRHS = AbsRHS.getUnsignedMax();
|
APInt MaxAbsRHS = AbsRHS.getUnsignedMax();
|
||||||
|
@ -98,16 +98,10 @@ bb3:
|
|||||||
|
|
||||||
define void @urem_cmp_constants() {
|
define void @urem_cmp_constants() {
|
||||||
; CHECK-LABEL: @urem_cmp_constants(
|
; CHECK-LABEL: @urem_cmp_constants(
|
||||||
; CHECK-NEXT: [[UREM_1:%.*]] = urem i16 12704, 12704
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[UREM_1]], 0
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[UREM_1]], 1
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
|
||||||
; CHECK-NEXT: [[UREM_2:%.*]] = urem i16 12704, 3
|
|
||||||
; CHECK-NEXT: [[C_3:%.*]] = icmp eq i16 [[UREM_2]], 2
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
|
||||||
; CHECK-NEXT: [[C_4:%.*]] = icmp eq i16 [[UREM_2]], 1
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
|
||||||
; CHECK-NEXT: [[UREM_3:%.*]] = urem i16 12704, 0
|
; CHECK-NEXT: [[UREM_3:%.*]] = urem i16 12704, 0
|
||||||
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[UREM_3]], 1
|
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[UREM_3]], 1
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||||
@ -132,16 +126,10 @@ define void @urem_cmp_constants() {
|
|||||||
|
|
||||||
define void @srem_cmp_constants() {
|
define void @srem_cmp_constants() {
|
||||||
; CHECK-LABEL: @srem_cmp_constants(
|
; CHECK-LABEL: @srem_cmp_constants(
|
||||||
; CHECK-NEXT: [[SREM_1:%.*]] = srem i16 12704, 12704
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[SREM_1]], 0
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[SREM_1]], 1
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
|
||||||
; CHECK-NEXT: [[SREM_2:%.*]] = srem i16 12704, 3
|
|
||||||
; CHECK-NEXT: [[C_3:%.*]] = icmp eq i16 [[SREM_2]], 2
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
|
||||||
; CHECK-NEXT: [[C_4:%.*]] = icmp eq i16 [[SREM_2]], 1
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
|
||||||
; CHECK-NEXT: [[SREM_3:%.*]] = srem i16 12704, 0
|
; CHECK-NEXT: [[SREM_3:%.*]] = srem i16 12704, 0
|
||||||
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[SREM_3]], 1
|
; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[SREM_3]], 1
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||||
|
Loading…
Reference in New Issue
Block a user