[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