Skip to content

Commit ed1632b

Browse files
authored
[ConstraintElim] Support signed induction variables (llvm#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.
1 parent acbb491 commit ed1632b

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -933,15 +933,20 @@ void State::addInfoForInductions(BasicBlock &BB) {
933933
}
934934

935935
DomTreeNode *DTN = DT.getNode(InLoopSucc);
936-
auto Inc = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_UGT);
937-
bool MonotonicallyIncreasing =
938-
Inc && *Inc == ScalarEvolution::MonotonicallyIncreasing;
939-
if (MonotonicallyIncreasing) {
940-
// SCEV guarantees that AR does not wrap, so PN >= StartValue can be added
941-
// unconditionally.
936+
auto IncUnsigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_UGT);
937+
auto IncSigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_SGT);
938+
bool MonotonicallyIncreasingUnsigned =
939+
IncUnsigned && *IncUnsigned == ScalarEvolution::MonotonicallyIncreasing;
940+
bool MonotonicallyIncreasingSigned =
941+
IncSigned && *IncSigned == ScalarEvolution::MonotonicallyIncreasing;
942+
// If SCEV guarantees that AR does not wrap, PN >= StartValue can be added
943+
// unconditionally.
944+
if (MonotonicallyIncreasingUnsigned)
942945
WorkList.push_back(
943946
FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGE, PN, StartValue));
944-
}
947+
if (MonotonicallyIncreasingSigned)
948+
WorkList.push_back(
949+
FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGE, PN, StartValue));
945950

946951
APInt StepOffset;
947952
if (auto *C = dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE)))
@@ -965,11 +970,17 @@ void State::addInfoForInductions(BasicBlock &BB) {
965970
WorkList.push_back(FactOrCheck::getConditionFact(
966971
DTN, CmpInst::ICMP_UGE, StartValue, PN,
967972
ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
973+
WorkList.push_back(FactOrCheck::getConditionFact(
974+
DTN, CmpInst::ICMP_SGE, StartValue, PN,
975+
ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
968976
// Add PN > B conditional on B <= StartValue which guarantees that the loop
969977
// exits when reaching B with a step of -1.
970978
WorkList.push_back(FactOrCheck::getConditionFact(
971979
DTN, CmpInst::ICMP_UGT, PN, B,
972980
ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
981+
WorkList.push_back(FactOrCheck::getConditionFact(
982+
DTN, CmpInst::ICMP_SGT, PN, B,
983+
ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
973984
return;
974985
}
975986

@@ -990,14 +1001,21 @@ void State::addInfoForInductions(BasicBlock &BB) {
9901001
// AR may wrap. Add PN >= StartValue conditional on StartValue <= B which
9911002
// guarantees that the loop exits before wrapping in combination with the
9921003
// restrictions on B and the step above.
993-
if (!MonotonicallyIncreasing) {
1004+
if (!MonotonicallyIncreasingUnsigned)
9941005
WorkList.push_back(FactOrCheck::getConditionFact(
9951006
DTN, CmpInst::ICMP_UGE, PN, StartValue,
9961007
ConditionTy(CmpInst::ICMP_ULE, StartValue, B)));
997-
}
1008+
if (!MonotonicallyIncreasingSigned)
1009+
WorkList.push_back(FactOrCheck::getConditionFact(
1010+
DTN, CmpInst::ICMP_SGE, PN, StartValue,
1011+
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
1012+
9981013
WorkList.push_back(FactOrCheck::getConditionFact(
9991014
DTN, CmpInst::ICMP_ULT, PN, B,
10001015
ConditionTy(CmpInst::ICMP_ULE, StartValue, B)));
1016+
WorkList.push_back(FactOrCheck::getConditionFact(
1017+
DTN, CmpInst::ICMP_SLT, PN, B,
1018+
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
10011019
}
10021020

10031021
void State::addInfoFor(BasicBlock &BB) {

llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ define void @signed_iv_step_1(i64 %end) {
1515
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
1616
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
1717
; CHECK: loop.latch:
18-
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
19-
; CHECK-NEXT: call void @use(i1 [[CMP2]])
20-
; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], -10
21-
; CHECK-NEXT: call void @use(i1 [[CMP3]])
18+
; CHECK-NEXT: call void @use(i1 true)
19+
; CHECK-NEXT: call void @use(i1 true)
2220
; CHECK-NEXT: br label [[LOOP]]
2321
; CHECK: exit:
2422
; CHECK-NEXT: ret void
@@ -141,10 +139,8 @@ define void @signed_iv_step_4_start_4(i64 %count) {
141139
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
142140
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
143141
; CHECK: loop.latch:
144-
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
145-
; CHECK-NEXT: call void @use(i1 [[CMP2]])
146-
; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 4
147-
; CHECK-NEXT: call void @use(i1 [[CMP3]])
142+
; CHECK-NEXT: call void @use(i1 true)
143+
; CHECK-NEXT: call void @use(i1 true)
148144
; CHECK-NEXT: br label [[LOOP]]
149145
; CHECK: exit:
150146
; CHECK-NEXT: ret void
@@ -226,10 +222,8 @@ define void @signed_iv_step_minus1(i64 %end) {
226222
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
227223
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
228224
; CHECK: loop.latch:
229-
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[IV]], [[END]]
230-
; CHECK-NEXT: call void @use(i1 [[CMP2]])
231-
; CHECK-NEXT: [[CMP3:%.*]] = icmp sle i64 [[IV]], 10
232-
; CHECK-NEXT: call void @use(i1 [[CMP3]])
225+
; CHECK-NEXT: call void @use(i1 true)
226+
; CHECK-NEXT: call void @use(i1 true)
233227
; CHECK-NEXT: br label [[LOOP]]
234228
; CHECK: exit:
235229
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)