mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[SCEV] get more accurate range for AddExpr with wrap flag.
Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D64869
This commit is contained in:
parent
f984a8d893
commit
d7d21ed611
@ -66,6 +66,7 @@ public:
|
||||
class OverflowingBinaryOperator : public Operator {
|
||||
public:
|
||||
enum {
|
||||
AnyWrap = 0,
|
||||
NoUnsignedWrap = (1 << 0),
|
||||
NoSignedWrap = (1 << 1)
|
||||
};
|
||||
|
@ -5560,6 +5560,7 @@ ScalarEvolution::getRangeRef(const SCEV *S,
|
||||
|
||||
unsigned BitWidth = getTypeSizeInBits(S->getType());
|
||||
ConstantRange ConservativeResult(BitWidth, /*isFullSet=*/true);
|
||||
using OBO = OverflowingBinaryOperator;
|
||||
|
||||
// If the value has known zeros, the maximum value will have those known zeros
|
||||
// as well.
|
||||
@ -5577,8 +5578,14 @@ ScalarEvolution::getRangeRef(const SCEV *S,
|
||||
|
||||
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
||||
ConstantRange X = getRangeRef(Add->getOperand(0), SignHint);
|
||||
unsigned WrapType = OBO::AnyWrap;
|
||||
if (Add->hasNoSignedWrap())
|
||||
WrapType |= OBO::NoSignedWrap;
|
||||
if (Add->hasNoUnsignedWrap())
|
||||
WrapType |= OBO::NoUnsignedWrap;
|
||||
for (unsigned i = 1, e = Add->getNumOperands(); i != e; ++i)
|
||||
X = X.add(getRangeRef(Add->getOperand(i), SignHint));
|
||||
X = X.addWithNoWrap(getRangeRef(Add->getOperand(i), SignHint),
|
||||
WrapType, RangeType);
|
||||
return setRange(Add, SignHint,
|
||||
ConservativeResult.intersectWith(X, RangeType));
|
||||
}
|
||||
|
@ -84,9 +84,7 @@ define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
|
||||
; CHECK-NEXT: [[SMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[LEN_MINUS_SMAX]], i32 -13
|
||||
; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 %len, [[SMAX1]]
|
||||
; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp slt i32 [[SUB1]], 101
|
||||
; CHECK-NEXT: [[SMAX2:%[^ ]+]] = select i1 [[CMP2]], i32 [[SUB1]], i32 101
|
||||
; CHECK-NEXT: [[CMP3:%[^ ]+]] = icmp sgt i32 [[SMAX2]], 0
|
||||
; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP3]], i32 [[SMAX2]], i32 0
|
||||
; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP2]], i32 [[SUB1]], i32 101
|
||||
; CHECK-NEXT: br i1 true, label %loop.preloop.preheader
|
||||
; CHECK: loop.preloop:
|
||||
; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 0, %loop.preloop.preheader ]
|
||||
@ -291,9 +289,7 @@ define void @test_06(i32* %arr, i32* %a_len_ptr) #0 {
|
||||
; CHECK-NEXT: [[SMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[LEN_MINUS_SMAX]], i32 -13
|
||||
; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 %len, [[SMAX1]]
|
||||
; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp slt i32 [[SUB1]], 101
|
||||
; CHECK-NEXT: [[SMAX2:%[^ ]+]] = select i1 [[CMP2]], i32 [[SUB1]], i32 101
|
||||
; CHECK-NEXT: [[CMP3:%[^ ]+]] = icmp sgt i32 [[SMAX2]], 0
|
||||
; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP3]], i32 [[SMAX2]], i32 0
|
||||
; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP2]], i32 [[SUB1]], i32 101
|
||||
; CHECK-NEXT: br i1 true, label %loop.preloop.preheader
|
||||
; CHECK: in.bounds.preloop:
|
||||
; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop
|
||||
|
Loading…
x
Reference in New Issue
Block a user