[llvm] 11a6e64 - [ConstraintElim] Move logic to get constraint for solving to helper.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 9 02:45:15 PDT 2022


Author: Florian Hahn
Date: 2022-10-09T10:44:36+01:00
New Revision: 11a6e64ba7bed04c03ca52e13567ebe4ec7014a5

URL: https://github.com/llvm/llvm-project/commit/11a6e64ba7bed04c03ca52e13567ebe4ec7014a5
DIFF: https://github.com/llvm/llvm-project/commit/11a6e64ba7bed04c03ca52e13567ebe4ec7014a5.diff

LOG: [ConstraintElim] Move logic to get constraint for solving to helper.

Move common logic shared by callers of getConstraint that use the result
to query the constraint system to a new helper getConstraintForSolving.

This includes common legality checks (i.e. not an equality constraint,
no new variables) and the logic to query the unsigned system if possible
for signed predicates.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
    llvm/test/Transforms/ConstraintElimination/gep-sub.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index be7939ac64345..868e1c7c5ef0d 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -111,7 +111,11 @@ class ConstraintInfo {
   ConstraintSystem UnsignedCS;
   ConstraintSystem SignedCS;
 
+  const DataLayout &DL;
+
 public:
+  ConstraintInfo(const DataLayout &DL) : DL(DL) {}
+
   DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
     return Signed ? SignedValue2Index : UnsignedValue2Index;
   }
@@ -143,6 +147,16 @@ class ConstraintInfo {
   ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
                              SmallVectorImpl<Value *> &NewVariables) const;
 
+  /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
+  /// constraints using getConstraint. Returns an empty constraint if the result
+  /// cannot be used to query the existing constraint system, e.g. because it
+  /// would require adding new variables. Also tries to convert signed
+  /// predicates to unsigned ones if possible to allow using the unsigned system
+  /// which increases the effectiveness of the signed <-> unsigned transfer
+  /// logic.
+  ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0,
+                                       Value *Op1) const;
+
   /// Try to add information from \p A \p Pred \p B to the unsigned/signed
   /// system if \p Pred is signed/unsigned.
   void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
@@ -429,6 +443,24 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
   return Res;
 }
 
+ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
+                                                     Value *Op0,
+                                                     Value *Op1) const {
+  // If both operands are known to be non-negative, change signed predicates to
+  // unsigned ones. This increases the reasoning effectiveness in combination
+  // with the signed <-> unsigned transfer logic.
+  if (CmpInst::isSigned(Pred) &&
+      isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) &&
+      isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
+    Pred = CmpInst::getUnsignedPredicate(Pred);
+
+  SmallVector<Value *> NewVariables;
+  ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
+  if (R.IsEq || !NewVariables.empty())
+    return {};
+  return R;
+}
+
 bool ConstraintTy::isValid(const ConstraintInfo &Info) const {
   return Coefficients.size() > 0 &&
          all_of(Preconditions, [&Info](const PreconditionTy &C) {
@@ -438,14 +470,9 @@ bool ConstraintTy::isValid(const ConstraintInfo &Info) const {
 
 bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
                               Value *B) const {
-  SmallVector<Value *> NewVariables;
-  auto R = getConstraint(Pred, A, B, NewVariables);
-
-  if (!NewVariables.empty())
-    return false;
-
-  return NewVariables.empty() && R.Preconditions.empty() && !R.IsEq &&
-         !R.empty() && getCS(R.IsSigned).isConditionImplied(R.Coefficients);
+  auto R = getConstraintForSolving(Pred, A, B);
+  return R.Preconditions.empty() && !R.empty() &&
+         getCS(R.IsSigned).isConditionImplied(R.Coefficients);
 }
 
 void ConstraintInfo::transferToOtherSystem(
@@ -698,9 +725,8 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info,
                           SmallVectorImpl<Instruction *> &ToRemove) {
   auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
                               ConstraintInfo &Info) {
-    SmallVector<Value *> NewVariables;
-    auto R = Info.getConstraint(Pred, A, B, NewVariables);
-    if (R.size() < 2 || !NewVariables.empty() || !R.isValid(Info))
+    auto R = Info.getConstraintForSolving(Pred, A, B);
+    if (R.size() < 2 || !R.isValid(Info))
       return false;
 
     auto &CSToUse = Info.getCS(R.IsSigned);
@@ -752,7 +778,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
   bool Changed = false;
   DT.updateDFSNumbers();
 
-  ConstraintInfo Info;
+  ConstraintInfo Info(F.getParent()->getDataLayout());
   State S(DT);
 
   // First, collect conditions implied by branches and blocks with their
@@ -834,24 +860,9 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
           continue;
 
         LLVM_DEBUG(dbgs() << "Checking " << *Cmp << "\n");
-        SmallVector<Value *> NewVariables;
-        CmpInst::Predicate Pred = Cmp->getPredicate();
-        Value *A = Cmp->getOperand(0);
-        Value *B = Cmp->getOperand(1);
-        const DataLayout &DL = Cmp->getModule()->getDataLayout();
-
-        // If both operands are known to be non-negative, change signed
-        // predicates to unsigned ones. This increases the reasoning
-        // effectiveness in combination with the signed <-> unsigned transfer
-        // logic.
-        if (CmpInst::isSigned(Pred) &&
-            isKnownNonNegative(A, DL,
-                               /*Depth=*/MaxAnalysisRecursionDepth - 1) &&
-            isKnownNonNegative(B, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
-          Pred = CmpInst::getUnsignedPredicate(Pred);
-
-        auto R = Info.getConstraint(Pred, A, B, NewVariables);
-        if (R.IsEq || R.empty() || !NewVariables.empty() || !R.isValid(Info))
+        auto R = Info.getConstraintForSolving(
+            Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1));
+        if (R.empty() || !R.isValid(Info))
           continue;
 
         auto &CSToUse = Info.getCS(R.IsSigned);

diff  --git a/llvm/test/Transforms/ConstraintElimination/gep-sub.ll b/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
index ec317156c3a75..52ba926fd7342 100644
--- a/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
+++ b/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
@@ -156,7 +156,7 @@ define i1 @gep_sub_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {
 ; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER]]
 ; CHECK-NEXT:    [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2
 ; CHECK-NEXT:    [[CMP_SUB_2:%.*]] = icmp ult ptr [[DST_SUB_2]], [[UPPER]]
-; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_2]]
+; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_SUB_2]]
 ; CHECK-NEXT:    [[DST_SUB_1_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_SUB_1]], i64 -1
 ; CHECK-NEXT:    [[CMP_SUB_1_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1_SUB_1]], [[UPPER]]
 ; CHECK-NEXT:    [[CMP_SUB_1_SUB_1_EQ:%.*]] = icmp eq ptr [[DST_SUB_1_SUB_1]], [[DST_SUB_2]]
@@ -232,7 +232,7 @@ define i1 @gep_sub_1_ult_var_idx_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx
 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
 ; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
 ; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
-; CHECK-NEXT:    ret i1 [[CMP_IDX]]
+; CHECK-NEXT:    ret i1 true
 ;
   %not.zero = icmp ne i8 %len, 0
   call void @llvm.assume(i1 %not.zero)


        


More information about the llvm-commits mailing list