[ConstraintElimination] Support constraints with only const ops.
authorFlorian Hahn <flo@fhahn.com>
Tue, 14 Jun 2022 09:37:12 +0000 (10:37 +0100)
committerFlorian Hahn <flo@fhahn.com>
Tue, 14 Jun 2022 09:37:12 +0000 (10:37 +0100)
Remove the early exit if both constraints contain no variables. This
restriction is unnecessayr for correctness and removing it simplifies
handling of trivial constant conditions in follow-up changes.

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/constants.ll

index a2b62fb..7c6d696 100644 (file)
@@ -282,10 +282,6 @@ getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
   if (ADec.empty() || BDec.empty())
     return {};
 
-  // Skip trivial constraints without any variables.
-  if (ADec.size() == 1 && BDec.size() == 1)
-    return {};
-
   int64_t Offset1 = ADec[0].first;
   int64_t Offset2 = BDec[0].first;
   Offset1 *= -1;
@@ -350,7 +346,7 @@ bool ConstraintTy::isValid(const ConstraintInfo &Info) const {
                Info.getValue2Index(CmpInst::isSigned(C.Pred)), NewIndices);
            // TODO: properly check NewIndices.
            return NewIndices.empty() && R.Preconditions.empty() && !R.IsEq &&
-                  R.size() >= 2 &&
+                  R.size() >= 1 &&
                   Info.getCS(CmpInst::isSigned(C.Pred))
                       .isConditionImplied(R.Coefficients);
          });
@@ -631,7 +627,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
 
         DenseMap<Value *, unsigned> NewIndices;
         auto R = getConstraint(Cmp, Info, NewIndices);
-        if (R.IsEq || R.size() < 2 || R.needsNewIndices(NewIndices) ||
+        if (R.IsEq || R.empty() || R.needsNewIndices(NewIndices) ||
             !R.isValid(Info))
           continue;
 
index eeb8124..896eb07 100644 (file)
@@ -6,11 +6,11 @@ define i1 @test_ult() {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8 10, 11
 ; CHECK-NEXT:    [[F_0:%.*]] = icmp ult i8 10, 10
-; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[T_0]], [[F_0]]
+; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, false
 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ult i8 10, 9
-; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[F_1]]
+; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], false
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 10, -10
-; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[T_1]]
+; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], true
 ; CHECK-NEXT:    ret i1 [[RES_3]]
 ;
 entry:
@@ -75,11 +75,11 @@ define i1 @test_slt() {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8 10, 11
 ; CHECK-NEXT:    [[F_0:%.*]] = icmp ult i8 10, 10
-; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[T_0]], [[F_0]]
+; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, false
 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ult i8 10, 9
-; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[F_1]]
+; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], false
 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ult i8 10, -10
-; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[F_2]]
+; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], true
 ; CHECK-NEXT:    ret i1 [[RES_3]]
 ;
 entry: