Skip to content

Commit 2f17107

Browse files
committed
[SCEV] Try to re-use existing LCSSA phis when expanding SCEVAddRecExpr.
If an AddRec is expanded outside a loop with a single exit block, check if any of the (lcssa) phi nodes in the exit block match the AddRec. If that's the case, simply use the existing lcssa phi. This can reduce the number of instruction created for SCEV expansions, mainly for runtime checks generated by the loop vectorizer. Compile-time impact should be mostly neutral https://llvm-compile-time-tracker.com/compare.php?from=48c7a3187f9831304a38df9bdb3b4d5bf6b6b1a2&to=cf9d039a7b0db5d0d912e0e2c01b19c2a653273a&stat=instructions:u
1 parent 4c27279 commit 2f17107

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
530530

531531
bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
532532

533+
Value *tryToReuseLCSSAPhi(const SCEVAddRecExpr *S);
533534
Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
534535
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
535536
const Loop *L, Type *&TruncTy,

llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,24 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
12231223
return Result;
12241224
}
12251225

1226+
Value *SCEVExpander::tryToReuseLCSSAPhi(const SCEVAddRecExpr *S) {
1227+
const Loop *L = S->getLoop();
1228+
BasicBlock *EB = L->getExitBlock();
1229+
if (!EB || !EB->getSinglePredecessor() ||
1230+
!SE.DT.dominates(EB, Builder.GetInsertBlock()))
1231+
return nullptr;
1232+
1233+
for (auto &PN : EB->phis()) {
1234+
if (!SE.isSCEVable(PN.getType()) || PN.getType() != S->getType())
1235+
continue;
1236+
auto *ExitV = SE.getSCEV(&PN);
1237+
if (S == ExitV)
1238+
return &PN;
1239+
}
1240+
1241+
return nullptr;
1242+
}
1243+
12261244
Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
12271245
// In canonical mode we compute the addrec as an expression of a canonical IV
12281246
// using evaluateAtIteration and expand the resulting SCEV expression. This
@@ -1262,6 +1280,11 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
12621280
return V;
12631281
}
12641282

1283+
// If there S is expanded outside the defining loop, check if there is a
1284+
// matching LCSSA phi node for it.
1285+
if (Value *V = tryToReuseLCSSAPhi(S))
1286+
return V;
1287+
12651288
// {X,+,F} --> X + {0,+,F}
12661289
if (!S->getStart()->isZero()) {
12671290
if (isa<PointerType>(S->getType())) {

llvm/test/Transforms/LoopVectorize/reuse-lcssa-phi-scev-expansion.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ define void @reuse_lcssa_phi_for_add_rec1(ptr %head) {
1818
; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
1919
; CHECK-NEXT: br i1 [[EC_1]], label %[[PH:.*]], label %[[LOOP_1]]
2020
; CHECK: [[PH]]:
21-
; CHECK-NEXT: [[IV_2_LCSSA:%.*]] = phi i32 [ [[IV_2]], %[[LOOP_1]] ]
2221
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP_1]] ]
23-
; CHECK-NEXT: [[IV_2_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_2_NEXT]], %[[LOOP_1]] ]
22+
; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[IV_2_NEXT]], %[[LOOP_1]] ]
2423
; CHECK-NEXT: [[SRC_2:%.*]] = tail call noalias noundef dereferenceable_or_null(8) ptr @calloc(i64 1, i64 8)
25-
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[IV_2_LCSSA]], 1
2624
; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 1)
2725
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[SMIN]]
2826
; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64

0 commit comments

Comments
 (0)