[ConstraintElim] Fix integer overflow in ConstraintSystem::negate.
authorFlorian Hahn <flo@fhahn.com>
Fri, 21 Apr 2023 15:09:46 +0000 (16:09 +0100)
committerFlorian Hahn <flo@fhahn.com>
Fri, 21 Apr 2023 15:09:46 +0000 (16:09 +0100)
This fixes another integer overflow that was exposed by a variant of the
test case from #62226.

llvm/include/llvm/Analysis/ConstraintSystem.h
llvm/lib/Analysis/ConstraintSystem.cpp
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/overflows.ll

index 29ba99b0f6d97a530821eeac70c991018b0d3911..00207accd79be777cd9dc8f4c89b53b604d59de0 100644 (file)
@@ -13,6 +13,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MathExtras.h"
 
 #include <string>
 
@@ -122,7 +123,8 @@ public:
     // the constant.
     R[0] += 1;
     for (auto &C : R)
-      C *= -1;
+      if (MulOverflow(C, int64_t(-1), C))
+        return {};
     return R;
   }
 
index 7df5c0d264479e1303b424f633fba9f7209abf17..8a802515b6f4fb9ce18e096aeaf73eaf2692f0a5 100644 (file)
@@ -206,6 +206,8 @@ bool ConstraintSystem::isConditionImplied(SmallVector<int64_t, 8> R) const {
   // If there is no solution with the negation of R added to the system, the
   // condition must hold based on the existing constraints.
   R = ConstraintSystem::negate(R);
+  if (R.empty())
+    return false;
 
   auto NewSystem = *this;
   NewSystem.addVariableRow(R);
index 3ce0114903ee0931108f460cc55aa24b02c591a3..ba7a590ec2b671341efe629f8688eca36c7705e7 100644 (file)
@@ -961,7 +961,8 @@ static bool checkAndReplaceCondition(
     NumCondsRemoved++;
     Changed = true;
   }
-  if (CSToUse.isConditionImplied(ConstraintSystem::negate(R.Coefficients))) {
+  auto Negated = ConstraintSystem::negate(R.Coefficients);
+  if (!Negated.empty() && CSToUse.isConditionImplied(Negated)) {
     if (!DebugCounter::shouldExecute(EliminatedCounter))
       return false;
 
index 9ec05bb7cf03e6748238fcf7bccbeacba492ed83..1fd6bdbf6615bacd9e79cb912a202a6ce36e56e8 100644 (file)
@@ -17,4 +17,11 @@ bb:
   ret i1 %icmp
 }
 
+define i1 @test_overflow_in_negate_constraint(i8 %x, i64 %y) {
+bb:
+  %zext = zext i8 %x to i64
+  %shl = shl nuw nsw i64 %zext, 63
+  %icmp = icmp uge i64 %y, %shl
+  ret i1 %icmp
+}