[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