Skip to content

Commit 1eb04d2

Browse files
author
Serguei Katkov
committed
[LICM] Invalidate SCEV upon instruction hoisting
Since SCEV can cache information about location of an instruction, it should be invalidated when the instruction is moved. There should be similar bug in code sinking part of LICM, it will be fixed in a follow-up change. Patch Author: Daniil Suchkov Reviewers: asbirlea, mkazantsev, reames Reviewed By: asbirlea Subscribers: hiraditya, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D69370
1 parent 193a7bf commit 1eb04d2

File tree

3 files changed

+23
-19
lines changed

3 files changed

+23
-19
lines changed

llvm/include/llvm/Transforms/Utils/LoopUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
133133
/// ORE. It returns changed status.
134134
bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
135135
TargetLibraryInfo *, Loop *, AliasSetTracker *,
136-
MemorySSAUpdater *, ICFLoopSafetyInfo *,
136+
MemorySSAUpdater *, ScalarEvolution *, ICFLoopSafetyInfo *,
137137
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *);
138138

139139
/// This function deletes dead loops. The caller of this function needs to

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop,
137137
TargetTransformInfo *TTI, bool &FreeInLoop);
138138
static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
139139
BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo,
140-
MemorySSAUpdater *MSSAU, OptimizationRemarkEmitter *ORE);
140+
MemorySSAUpdater *MSSAU, ScalarEvolution *SE,
141+
OptimizationRemarkEmitter *ORE);
141142
static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
142143
const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo,
143144
MemorySSAUpdater *MSSAU, OptimizationRemarkEmitter *ORE);
@@ -162,7 +163,7 @@ static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
162163

163164
static void moveInstructionBefore(Instruction &I, Instruction &Dest,
164165
ICFLoopSafetyInfo &SafetyInfo,
165-
MemorySSAUpdater *MSSAU);
166+
MemorySSAUpdater *MSSAU, ScalarEvolution *SE);
166167

167168
namespace {
168169
struct LoopInvariantCodeMotion {
@@ -390,8 +391,9 @@ bool LoopInvariantCodeMotion::runOnLoop(
390391
CurAST.get(), MSSAU.get(), &SafetyInfo, Flags, ORE);
391392
Flags.IsSink = false;
392393
if (Preheader)
393-
Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, TLI, L,
394-
CurAST.get(), MSSAU.get(), &SafetyInfo, Flags, ORE);
394+
Changed |=
395+
hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, TLI, L,
396+
CurAST.get(), MSSAU.get(), SE, &SafetyInfo, Flags, ORE);
395397

396398
// Now that all loop invariants have been removed from the loop, promote any
397399
// memory references to scalars that we can.
@@ -795,7 +797,7 @@ class ControlFlowHoister {
795797
bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
796798
DominatorTree *DT, TargetLibraryInfo *TLI, Loop *CurLoop,
797799
AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU,
798-
ICFLoopSafetyInfo *SafetyInfo,
800+
ScalarEvolution *SE, ICFLoopSafetyInfo *SafetyInfo,
799801
SinkAndHoistLICMFlags &Flags,
800802
OptimizationRemarkEmitter *ORE) {
801803
// Verify inputs.
@@ -855,7 +857,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
855857
I, DT, CurLoop, SafetyInfo, ORE,
856858
CurLoop->getLoopPreheader()->getTerminator())) {
857859
hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
858-
MSSAU, ORE);
860+
MSSAU, SE, ORE);
859861
HoistedInstructions.push_back(&I);
860862
Changed = true;
861863
continue;
@@ -882,7 +884,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
882884
eraseInstruction(I, *SafetyInfo, CurAST, MSSAU);
883885

884886
hoist(*ReciprocalDivisor, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB),
885-
SafetyInfo, MSSAU, ORE);
887+
SafetyInfo, MSSAU, SE, ORE);
886888
HoistedInstructions.push_back(ReciprocalDivisor);
887889
Changed = true;
888890
continue;
@@ -901,7 +903,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
901903
CurLoop->hasLoopInvariantOperands(&I) &&
902904
MustExecuteWithoutWritesBefore(I)) {
903905
hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
904-
MSSAU, ORE);
906+
MSSAU, SE, ORE);
905907
HoistedInstructions.push_back(&I);
906908
Changed = true;
907909
continue;
@@ -915,7 +917,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
915917
PN->setIncomingBlock(
916918
i, CFH.getOrCreateHoistedBlock(PN->getIncomingBlock(i)));
917919
hoist(*PN, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
918-
MSSAU, ORE);
920+
MSSAU, SE, ORE);
919921
assert(DT->dominates(PN, BB) && "Conditional PHIs not expected");
920922
Changed = true;
921923
continue;
@@ -952,7 +954,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
952954
LLVM_DEBUG(dbgs() << "LICM rehoisting to "
953955
<< HoistPoint->getParent()->getName()
954956
<< ": " << *I << "\n");
955-
moveInstructionBefore(*I, *HoistPoint, *SafetyInfo, MSSAU);
957+
moveInstructionBefore(*I, *HoistPoint, *SafetyInfo, MSSAU, SE);
956958
HoistPoint = I;
957959
Changed = true;
958960
}
@@ -1441,14 +1443,17 @@ static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
14411443

14421444
static void moveInstructionBefore(Instruction &I, Instruction &Dest,
14431445
ICFLoopSafetyInfo &SafetyInfo,
1444-
MemorySSAUpdater *MSSAU) {
1446+
MemorySSAUpdater *MSSAU,
1447+
ScalarEvolution *SE) {
14451448
SafetyInfo.removeInstruction(&I);
14461449
SafetyInfo.insertInstructionTo(&I, Dest.getParent());
14471450
I.moveBefore(&Dest);
14481451
if (MSSAU)
14491452
if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
14501453
MSSAU->getMemorySSA()->getMemoryAccess(&I)))
14511454
MSSAU->moveToPlace(OldMemAcc, Dest.getParent(), MemorySSA::End);
1455+
if (SE)
1456+
SE->forgetValue(&I);
14521457
}
14531458

14541459
static Instruction *sinkThroughTriviallyReplaceablePHI(
@@ -1662,7 +1667,8 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
16621667
///
16631668
static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
16641669
BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo,
1665-
MemorySSAUpdater *MSSAU, OptimizationRemarkEmitter *ORE) {
1670+
MemorySSAUpdater *MSSAU, ScalarEvolution *SE,
1671+
OptimizationRemarkEmitter *ORE) {
16661672
LLVM_DEBUG(dbgs() << "LICM hoisting to " << Dest->getName() << ": " << I
16671673
<< "\n");
16681674
ORE->emit([&]() {
@@ -1683,10 +1689,10 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
16831689

16841690
if (isa<PHINode>(I))
16851691
// Move the new node to the end of the phi list in the destination block.
1686-
moveInstructionBefore(I, *Dest->getFirstNonPHI(), *SafetyInfo, MSSAU);
1692+
moveInstructionBefore(I, *Dest->getFirstNonPHI(), *SafetyInfo, MSSAU, SE);
16871693
else
16881694
// Move the new node to the destination block, before its terminator.
1689-
moveInstructionBefore(I, *Dest->getTerminator(), *SafetyInfo, MSSAU);
1695+
moveInstructionBefore(I, *Dest->getTerminator(), *SafetyInfo, MSSAU, SE);
16901696

16911697
// Apply line 0 debug locations when we are moving instructions to different
16921698
// basic blocks because we want to avoid jumpy line tables.

llvm/unittests/Transforms/Scalar/LICMTest.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,8 @@ TEST(LICMTest, TestSCEVInvalidationOnHoisting) {
8686
// If LICM have properly invalidated SCEV,
8787
// 1. SCEV of <load i64, i64* %ptr> should properly dominate the "loop" BB,
8888
// 2. extra invalidation shouldn't change result of the query.
89-
// FIXME: these values should be equal!
90-
EXPECT_NE(DispositionBeforeInvalidation,
89+
EXPECT_EQ(DispositionBeforeInvalidation,
9190
ScalarEvolution::BlockDisposition::ProperlyDominatesBlock);
92-
// FIXME: these values should be equal!
93-
EXPECT_NE(DispositionBeforeInvalidation, DispositionAfterInvalidation);
91+
EXPECT_EQ(DispositionBeforeInvalidation, DispositionAfterInvalidation);
9492
}
9593
}

0 commit comments

Comments
 (0)