[llvm] [ConstraintElim] Support signed induction variables (PR #77103)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 5 06:57:11 PST 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/77103
When adding information for induction variables, add both unsigned and signed constraints, with corresponding signed and unsigned preconditions.
I believe the logic here is equally valid for signed/unsigned, we just need to add preconditions of the same type.
>From a9add93e7166e0ffa9db42a55a5a05c2dbc8b2eb Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 4 Jan 2024 14:26:14 +0100
Subject: [PATCH] [ConstraintElim] Support signed induction variables
When adding information for induction variables, add both unsigned
and signed constraints, with corresponding signed and unsigned
preconditions.
I believe the logic here is equally valid for signed/unsigned,
we just need to add preconditions of the same type.
---
.../Scalar/ConstraintElimination.cpp | 36 ++++++++++++++-----
.../monotonic-int-phis-signed.ll | 18 ++++------
2 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 5889dab1626581..6fec54ac792245 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -933,15 +933,20 @@ void State::addInfoForInductions(BasicBlock &BB) {
}
DomTreeNode *DTN = DT.getNode(InLoopSucc);
- auto Inc = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_UGT);
- bool MonotonicallyIncreasing =
- Inc && *Inc == ScalarEvolution::MonotonicallyIncreasing;
- if (MonotonicallyIncreasing) {
- // SCEV guarantees that AR does not wrap, so PN >= StartValue can be added
- // unconditionally.
+ auto IncUnsigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_UGT);
+ auto IncSigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_SGT);
+ bool MonotonicallyIncreasingUnsigned =
+ IncUnsigned && *IncUnsigned == ScalarEvolution::MonotonicallyIncreasing;
+ bool MonotonicallyIncreasingSigned =
+ IncSigned && *IncSigned == ScalarEvolution::MonotonicallyIncreasing;
+ // If SCEV guarantees that AR does not wrap, PN >= StartValue can be added
+ // unconditionally.
+ if (MonotonicallyIncreasingUnsigned)
WorkList.push_back(
FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGE, PN, StartValue));
- }
+ if (MonotonicallyIncreasingSigned)
+ WorkList.push_back(
+ FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGE, PN, StartValue));
APInt StepOffset;
if (auto *C = dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE)))
@@ -965,11 +970,17 @@ void State::addInfoForInductions(BasicBlock &BB) {
WorkList.push_back(FactOrCheck::getConditionFact(
DTN, CmpInst::ICMP_UGE, StartValue, PN,
ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
+ WorkList.push_back(FactOrCheck::getConditionFact(
+ DTN, CmpInst::ICMP_SGE, StartValue, PN,
+ ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
// Add PN > B conditional on B <= StartValue which guarantees that the loop
// exits when reaching B with a step of -1.
WorkList.push_back(FactOrCheck::getConditionFact(
DTN, CmpInst::ICMP_UGT, PN, B,
ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
+ WorkList.push_back(FactOrCheck::getConditionFact(
+ DTN, CmpInst::ICMP_SGT, PN, B,
+ ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
return;
}
@@ -990,14 +1001,21 @@ void State::addInfoForInductions(BasicBlock &BB) {
// AR may wrap. Add PN >= StartValue conditional on StartValue <= B which
// guarantees that the loop exits before wrapping in combination with the
// restrictions on B and the step above.
- if (!MonotonicallyIncreasing) {
+ if (!MonotonicallyIncreasingUnsigned)
WorkList.push_back(FactOrCheck::getConditionFact(
DTN, CmpInst::ICMP_UGE, PN, StartValue,
ConditionTy(CmpInst::ICMP_ULE, StartValue, B)));
- }
+ if (!MonotonicallyIncreasingSigned)
+ WorkList.push_back(FactOrCheck::getConditionFact(
+ DTN, CmpInst::ICMP_SGE, PN, StartValue,
+ ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
+
WorkList.push_back(FactOrCheck::getConditionFact(
DTN, CmpInst::ICMP_ULT, PN, B,
ConditionTy(CmpInst::ICMP_ULE, StartValue, B)));
+ WorkList.push_back(FactOrCheck::getConditionFact(
+ DTN, CmpInst::ICMP_SLT, PN, B,
+ ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
}
void State::addInfoFor(BasicBlock &BB) {
diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
index 1e95fab5c10c81..7273469fc59e80 100644
--- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
+++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
@@ -15,10 +15,8 @@ define void @signed_iv_step_1(i64 %end) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
-; CHECK-NEXT: call void @use(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], -10
-; CHECK-NEXT: call void @use(i1 [[CMP3]])
+; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -141,10 +139,8 @@ define void @signed_iv_step_4_start_4(i64 %count) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
-; CHECK-NEXT: call void @use(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 4
-; CHECK-NEXT: call void @use(i1 [[CMP3]])
+; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -226,10 +222,8 @@ define void @signed_iv_step_minus1(i64 %end) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[IV]], [[END]]
-; CHECK-NEXT: call void @use(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp sle i64 [[IV]], 10
-; CHECK-NEXT: call void @use(i1 [[CMP3]])
+; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
More information about the llvm-commits
mailing list