-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[ConstraintElim] Support signed induction variables #77103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) ChangesWhen 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. Full diff: https://github.com/llvm/llvm-project/pull/77103.diff 2 Files Affected:
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
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.
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.