[ConstraintElimination] Use AddOverflow for offset summation.
authorFlorian Hahn <flo@fhahn.com>
Fri, 25 Mar 2022 18:08:24 +0000 (18:08 +0000)
committerFlorian Hahn <flo@fhahn.com>
Fri, 25 Mar 2022 18:08:24 +0000 (18:08 +0000)
Fixes an incorrect transformation due to values overflowing
https://alive2.llvm.org/ce/z/uizoea

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/sub-nuw.ll

index acf2d4da360dc74c98f2cbbe621ae9d52bce1ef6..dbc7a534467b1def34c5c29b9b34465f209f7379 100644 (file)
@@ -27,6 +27,7 @@
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/DebugCounter.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Transforms/Scalar.h"
 
 #include <string>
@@ -320,8 +321,13 @@ getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
   for (const auto &KV : VariablesB)
     R[GetOrAddIndex(KV.second)] -= KV.first;
 
-  R[0] = Offset1 + Offset2 +
-         (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT) ? -1 : 0);
+  int64_t OffsetSum;
+  if (AddOverflow(Offset1, Offset2, OffsetSum))
+    return {};
+  if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT))
+    if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum))
+      return {};
+  R[0] = OffsetSum;
   Res.Preconditions = std::move(Preconditions);
   return Res;
 }
index f2d4990ef6b2ee5b86a8f3a83f736832f0c991e1..0af257e3cb5cc9e11aa79716f97f4e1c5079e494 100644 (file)
@@ -362,7 +362,7 @@ define i1 @wrapping_offset_sum(i64 %x) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NON_ZERO]])
 ; CHECK-NEXT:    [[ADD:%.*]] = sub nuw i64 [[X]], 9223372036854775802
 ; CHECK-NEXT:    [[ULT:%.*]] = icmp ugt i64 200, [[ADD]]
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    ret i1 [[ULT]]
 ;
   %non.zero = icmp ugt i64 %x, 0
   call void @llvm.assume(i1 %non.zero)