[PATCH] D148621: [SCEV] Support negative constant in willNotOverflow
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 18 02:14:43 PDT 2023
mkazantsev created this revision.
mkazantsev added reviewers: nikic, fhahn, reames, lebedev.ri, dmakogon.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
mkazantsev requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Implemented one of TODOs in this code.
https://reviews.llvm.org/D148621
Files:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
Index: llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
+++ llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
@@ -19,7 +19,7 @@
; CHECK-NEXT: [[ZERO_COND:%.*]] = icmp eq i32 [[IV]], 0
; CHECK-NEXT: br i1 [[ZERO_COND]], label [[EXIT:%.*]], label [[RANGE_CHECK_BLOCK:%.*]]
; CHECK: range_check_block:
-; CHECK-NEXT: [[IV_NEXT]] = sub i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = sub nsw i32 [[IV]], 1
; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
; CHECK: backedge:
; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i32 [[IV]]
@@ -68,7 +68,7 @@
; CHECK-NEXT: [[ZERO_COND:%.*]] = icmp eq i32 [[IV]], 0
; CHECK-NEXT: br i1 [[ZERO_COND]], label [[EXIT:%.*]], label [[RANGE_CHECK_BLOCK:%.*]]
; CHECK: range_check_block:
-; CHECK-NEXT: [[IV_NEXT]] = sub i32 [[IV]], 1
+; CHECK-NEXT: [[IV_NEXT]] = sub nsw i32 [[IV]], 1
; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
; CHECK: backedge:
; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i32 [[IV]]
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2345,22 +2345,25 @@
if (!RHSC)
return false;
APInt C = RHSC->getAPInt();
- // We can prove that add(x, constant) doesn't wrap if isKnownPredicateAt can
- // guarantee that x <= max_int - constant at the given context.
// TODO: Support mul.
if (BinOp == Instruction::Sub)
C = -C;
else if (BinOp != Instruction::Add)
return false;
- // TODO: Also lift this limitation.
- if (Signed && C.isNegative())
- return false;
unsigned NumBits = C.getBitWidth();
- APInt Max =
- Signed ? APInt::getSignedMaxValue(NumBits) : APInt::getMaxValue(NumBits);
- APInt Limit = Max - C;
ICmpInst::Predicate Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
- return isKnownPredicateAt(Pred, LHS, getConstant(Limit), CtxI);
+ if (Signed && C.isNegative()) {
+ // No overflow if we can prove that (MIN - C <= LHS).
+ APInt Min = APInt::getSignedMinValue(NumBits);
+ APInt Limit = Min - C;
+ return isKnownPredicateAt(Pred, getConstant(Limit), LHS, CtxI);
+ } else {
+ // No overflow if we can prove that (LHS <= MAX - C).
+ APInt Max =
+ Signed ? APInt::getSignedMaxValue(NumBits) : APInt::getMaxValue(NumBits);
+ APInt Limit = Max - C;
+ return isKnownPredicateAt(Pred, LHS, getConstant(Limit), CtxI);
+ }
}
std::optional<SCEV::NoWrapFlags>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148621.514571.patch
Type: text/x-patch
Size: 2728 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230418/6e132de9/attachment-0001.bin>
More information about the llvm-commits
mailing list