[llvm] afa73e4 - [ConstraintElimination] Handle equality predicates with signed system (#205331)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 03:42:56 PDT 2026
Author: Antonio Frighetto
Date: 2026-07-17T12:42:51+02:00
New Revision: afa73e4ff6db57b0416eb44127105b8092bd01f8
URL: https://github.com/llvm/llvm-project/commit/afa73e4ff6db57b0416eb44127105b8092bd01f8
DIFF: https://github.com/llvm/llvm-project/commit/afa73e4ff6db57b0416eb44127105b8092bd01f8.diff
LOG: [ConstraintElimination] Handle equality predicates with signed system (#205331)
Equality predicate solving has been supported for quite a while, eq/ne
facts were extended to the signed constraint system more recently
(7fb97bee9269f0d4239908ac8def70be696991c6). When solving
eq/ne conditions, query the signed system as well on inconclusive
answers from the unsigned one.
Fixes: https://github.com/llvm/llvm-project/issues/205282.
Fixes: https://github.com/llvm/llvm-project/issues/63505.
Added:
Modified:
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/eq.ll
llvm/test/Transforms/ConstraintElimination/ne.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 35c547bf4f213..cdd15f04730ba 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1513,28 +1513,48 @@ static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
ConstraintInfo &Info) {
LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
- auto R = Info.getConstraintForSolving(Pred, A, B);
- if (R.empty() || !R.isValid(Info)) {
- LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
+ auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
+ if (R.empty() || !R.isValid(Info)) {
+ LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
+ return std::nullopt;
+ }
+
+ auto &CSToUse = Info.getCS(R.IsSigned);
+ if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
+ if (!DebugCounter::shouldExecute(EliminatedCounter))
+ return std::nullopt;
+ LLVM_DEBUG({
+ dbgs() << "Condition ";
+ dumpUnpackedICmp(dbgs(),
+ *ImpliedCondition ? Pred
+ : CmpInst::getInversePredicate(Pred),
+ A, B);
+ dbgs() << " implied by dominating constraints\n";
+ CSToUse.dump();
+ });
+ return ImpliedCondition;
+ }
return std::nullopt;
- }
+ };
+
+ auto R = Info.getConstraintForSolving(Pred, A, B);
+ if (auto ImpliedCondition = TryWithConstraint(R))
+ return ImpliedCondition;
- auto &CSToUse = Info.getCS(R.IsSigned);
- if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
- if (!DebugCounter::shouldExecute(EliminatedCounter))
+ // Additionally, query the signed system for eq/ne predicates if we know about
+ // A or B.
+ if (CmpInst::isEquality(Pred)) {
+ const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
+ if (!Value2Index.contains(A) && !Value2Index.contains(B))
return std::nullopt;
- LLVM_DEBUG({
- dbgs() << "Condition ";
- dumpUnpackedICmp(
- dbgs(), *ImpliedCondition ? Pred : CmpInst::getInversePredicate(Pred),
- A, B);
- dbgs() << " implied by dominating constraints\n";
- CSToUse.dump();
- });
- return ImpliedCondition;
+ SmallVector<Value *> NewVariables;
+ auto SR = Info.getConstraint(Pred, A, B, NewVariables,
+ /*ForceSignedSystem=*/true);
+ if (NewVariables.empty())
+ if (auto ImpliedCondition = TryWithConstraint(SR))
+ return ImpliedCondition;
}
-
return std::nullopt;
}
diff --git a/llvm/test/Transforms/ConstraintElimination/eq.ll b/llvm/test/Transforms/ConstraintElimination/eq.ll
index 511a08f7796a3..e795b9ea58a77 100644
--- a/llvm/test/Transforms/ConstraintElimination/eq.ll
+++ b/llvm/test/Transforms/ConstraintElimination/eq.ll
@@ -472,3 +472,36 @@ entry:
%and3 = and i1 %cmp4, %and2
ret i1 %and3
}
+
+define i1 @assume_a_gt_b_and_b_ge_c_signed(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: @assume_a_gt_b_and_b_ge_c_signed(
+; CHECK-NEXT: [[AB:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[AB]])
+; CHECK-NEXT: [[BC:%.*]] = icmp sge i64 [[B]], [[C:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[BC]])
+; CHECK-NEXT: ret i1 false
+;
+ %ab = icmp sgt i64 %a, %b
+ call void @llvm.assume(i1 %ab)
+ %bc = icmp sge i64 %b, %c
+ call void @llvm.assume(i1 %bc)
+ %eq = icmp eq i64 %a, %c
+ ret i1 %eq
+}
+
+define i1 @assume_a_le_b_and_b_le_c_signed(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: @assume_a_le_b_and_b_le_c_signed(
+; CHECK-NEXT: [[AB:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[AB]])
+; CHECK-NEXT: [[BC:%.*]] = icmp sle i64 [[B]], [[C:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[BC]])
+; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[C]]
+; CHECK-NEXT: ret i1 [[EQ]]
+;
+ %ab = icmp sle i64 %a, %b
+ call void @llvm.assume(i1 %ab)
+ %bc = icmp sle i64 %b, %c
+ call void @llvm.assume(i1 %bc)
+ %eq = icmp eq i64 %a, %c
+ ret i1 %eq
+}
diff --git a/llvm/test/Transforms/ConstraintElimination/ne.ll b/llvm/test/Transforms/ConstraintElimination/ne.ll
index 4753860db2851..f1aa2afe06b6c 100644
--- a/llvm/test/Transforms/ConstraintElimination/ne.ll
+++ b/llvm/test/Transforms/ConstraintElimination/ne.ll
@@ -371,7 +371,6 @@ define i1 @assume_2b(i64 %a, i64 %b) {
ret i1 %ret
}
-; TODO: extend to support signed comparisons
define i1 @assume_3a(i64 %a, i64 %b) {
; CHECK-LABEL: @assume_3a(
; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
@@ -423,3 +422,19 @@ define i1 @assume_4b(i64 %a, i64 %b) {
%ret = icmp sle i64 %a, %b
ret i1 %ret
}
+
+define i1 @assume_a_lt_b_and_b_lt_c_signed(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: @assume_a_lt_b_and_b_lt_c_signed(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i64 [[B]], [[C:%.*]]
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP2]])
+; CHECK-NEXT: ret i1 true
+;
+ %1 = icmp slt i64 %a, %b
+ tail call void @llvm.assume(i1 %1)
+ %2 = icmp slt i64 %b, %c
+ tail call void @llvm.assume(i1 %2)
+ %3 = icmp ne i64 %a, %c
+ ret i1 %3
+}
More information about the llvm-commits
mailing list