Skip to content

Commit 2d8d622

Browse files
committed
[SCEV] Require that addrec operands dominate the loop
SCEVExpander currently has special handling for the case where the start or the step of an addrec do not dominate the loop header, which is not used by any lit test. Initially I thought that this is entirely dead code, because addrec operands are required to be loop invariant. However, SCEV currently allows creating an addrec with operands that are loop invariant but defined *after* the loop. This doesn't seem like a useful case to allow, and we don't appear to be using this outside a single easy to adjust unit test.
1 parent 0c7d0ad commit 2d8d622

File tree

3 files changed

+10
-64
lines changed

3 files changed

+10
-64
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3671,8 +3671,8 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
36713671
assert(!Operands[i]->getType()->isPointerTy() && "Step must be integer");
36723672
}
36733673
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
3674-
assert(isLoopInvariant(Operands[i], L) &&
3675-
"SCEVAddRecExpr operand is not loop-invariant!");
3674+
assert(isAvailableAtLoopEntry(Operands[i], L) &&
3675+
"SCEVAddRecExpr operand is not available at loop entry!");
36763676
#endif
36773677

36783678
if (Operands.back()->isZero()) {

llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

+5-59
Original file line numberDiff line numberDiff line change
@@ -1074,40 +1074,14 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
10741074
normalizeForPostIncUse(S, Loops, SE, /*CheckInvertible=*/false));
10751075
}
10761076

1077-
// Strip off any non-loop-dominating component from the addrec start.
10781077
const SCEV *Start = Normalized->getStart();
1079-
const SCEV *PostLoopOffset = nullptr;
1080-
if (!SE.properlyDominates(Start, L->getHeader())) {
1081-
PostLoopOffset = Start;
1082-
Start = SE.getConstant(Normalized->getType(), 0);
1083-
Normalized = cast<SCEVAddRecExpr>(
1084-
SE.getAddRecExpr(Start, Normalized->getStepRecurrence(SE),
1085-
Normalized->getLoop(),
1086-
Normalized->getNoWrapFlags(SCEV::FlagNW)));
1087-
}
1088-
1089-
// Strip off any non-loop-dominating component from the addrec step.
10901078
const SCEV *Step = Normalized->getStepRecurrence(SE);
1091-
const SCEV *PostLoopScale = nullptr;
1092-
if (!SE.dominates(Step, L->getHeader())) {
1093-
PostLoopScale = Step;
1094-
Step = SE.getConstant(Normalized->getType(), 1);
1095-
if (!Start->isZero()) {
1096-
// The normalization below assumes that Start is constant zero, so if
1097-
// it isn't re-associate Start to PostLoopOffset.
1098-
assert(!PostLoopOffset && "Start not-null but PostLoopOffset set?");
1099-
PostLoopOffset = Start;
1100-
Start = SE.getConstant(Normalized->getType(), 0);
1101-
}
1102-
Normalized =
1103-
cast<SCEVAddRecExpr>(SE.getAddRecExpr(
1104-
Start, Step, Normalized->getLoop(),
1105-
Normalized->getNoWrapFlags(SCEV::FlagNW)));
1106-
}
1079+
assert(SE.properlyDominates(Start, L->getHeader()) &&
1080+
"Start does not properly dominate loop header");
1081+
assert(SE.dominates(Step, L->getHeader()) && "Step not dominate loop header");
11071082

1108-
// Expand the core addrec. If we need post-loop scaling, force it to
1109-
// expand to an integer type to avoid the need for additional casting.
1110-
Type *ExpandTy = PostLoopScale ? IntTy : STy;
1083+
// Expand the core addrec.
1084+
Type *ExpandTy = STy;
11111085
// We can't use a pointer type for the addrec if the pointer type is
11121086
// non-integral.
11131087
Type *AddRecPHIExpandTy =
@@ -1188,28 +1162,6 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
11881162
Result);
11891163
}
11901164

1191-
// Re-apply any non-loop-dominating scale.
1192-
if (PostLoopScale) {
1193-
assert(S->isAffine() && "Can't linearly scale non-affine recurrences.");
1194-
Result = InsertNoopCastOfTo(Result, IntTy);
1195-
Result = Builder.CreateMul(Result, expandCodeFor(PostLoopScale, IntTy));
1196-
}
1197-
1198-
// Re-apply any non-loop-dominating offset.
1199-
if (PostLoopOffset) {
1200-
if (isa<PointerType>(ExpandTy)) {
1201-
if (Result->getType()->isIntegerTy()) {
1202-
Value *Base = expandCodeFor(PostLoopOffset, ExpandTy);
1203-
Result = expandAddToGEP(SE.getUnknown(Result), Base);
1204-
} else {
1205-
Result = expandAddToGEP(PostLoopOffset, Result);
1206-
}
1207-
} else {
1208-
Result = InsertNoopCastOfTo(Result, IntTy);
1209-
Result = Builder.CreateAdd(Result, expandCodeFor(PostLoopOffset, IntTy));
1210-
}
1211-
}
1212-
12131165
return Result;
12141166
}
12151167

@@ -2339,12 +2291,6 @@ struct SCEVFindUnsafe {
23392291
}
23402292
}
23412293
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
2342-
const SCEV *Step = AR->getStepRecurrence(SE);
2343-
if (!AR->isAffine() && !SE.dominates(Step, AR->getLoop()->getHeader())) {
2344-
IsUnsafe = true;
2345-
return false;
2346-
}
2347-
23482294
// For non-affine addrecs or in non-canonical mode we need a preheader
23492295
// to insert into.
23502296
if (!AR->getLoop()->getLoopPreheader() &&

llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVZeroExtendExprNonIntegral) {
129129
* top:
130130
* br label %L.ph
131131
* L.ph:
132+
* %gepbase = getelementptr i64 addrspace(10)* %arg, i64 1
132133
* br label %L
133134
* L:
134135
* %phi = phi i64 [i64 0, %L.ph], [ %add, %L2 ]
135136
* %add = add i64 %phi2, 1
136137
* br i1 undef, label %post, label %L2
137138
* post:
138-
* %gepbase = getelementptr i64 addrspace(10)* %arg, i64 1
139139
* #= %gep = getelementptr i64 addrspace(10)* %gepbase, i64 %add =#
140140
* ret void
141141
*
@@ -170,6 +170,8 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVZeroExtendExprNonIntegral) {
170170
Builder.CreateBr(LPh);
171171

172172
Builder.SetInsertPoint(LPh);
173+
Value *GepBase =
174+
Builder.CreateGEP(T_int64, Arg, ConstantInt::get(T_int64, 1));
173175
Builder.CreateBr(L);
174176

175177
Builder.SetInsertPoint(L);
@@ -180,8 +182,6 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVZeroExtendExprNonIntegral) {
180182
Phi->addIncoming(Add, L);
181183

182184
Builder.SetInsertPoint(Post);
183-
Value *GepBase =
184-
Builder.CreateGEP(T_int64, Arg, ConstantInt::get(T_int64, 1));
185185
Instruction *Ret = Builder.CreateRetVoid();
186186

187187
ScalarEvolution SE = buildSE(*F);

0 commit comments

Comments
 (0)