[LICM] Remove AST-based implementation
MSSA-based LICM has been enabled by default for a few years now. This drops the old AST-based implementation. Using loop(licm) will result in a fatal error, the use of loop-mssa(licm) is required (or just licm, which defaults to loop-mssa). Note that the core canSinkOrHoistInst() logic has to retain AST support for now, because it is shared with LoopSink. Differential Revision: https://reviews.llvm.org/D108244
This commit is contained in:
parent
4d559837e8
commit
3dd8c9176b
|
@ -151,18 +151,17 @@ protected:
|
|||
/// this function is called by \p sinkRegionForLoopNest.
|
||||
bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
|
||||
BlockFrequencyInfo *, TargetLibraryInfo *,
|
||||
TargetTransformInfo *, Loop *CurLoop, AliasSetTracker *,
|
||||
MemorySSAUpdater *, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *,
|
||||
Loop *OutermostLoop = nullptr);
|
||||
TargetTransformInfo *, Loop *CurLoop, MemorySSAUpdater *,
|
||||
ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
|
||||
OptimizationRemarkEmitter *, Loop *OutermostLoop = nullptr);
|
||||
|
||||
/// Call sinkRegion on loops contained within the specified loop
|
||||
/// in order from innermost to outermost.
|
||||
bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *,
|
||||
DominatorTree *, BlockFrequencyInfo *,
|
||||
TargetLibraryInfo *, TargetTransformInfo *, Loop *,
|
||||
AliasSetTracker *, MemorySSAUpdater *,
|
||||
ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
|
||||
MemorySSAUpdater *, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &,
|
||||
OptimizationRemarkEmitter *);
|
||||
|
||||
/// Walk the specified region of the CFG (defined by all blocks
|
||||
|
@ -175,9 +174,8 @@ bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *,
|
|||
/// Diagnostics is emitted via \p ORE. It returns changed status.
|
||||
bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
|
||||
BlockFrequencyInfo *, TargetLibraryInfo *, Loop *,
|
||||
AliasSetTracker *, MemorySSAUpdater *, ScalarEvolution *,
|
||||
ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
|
||||
OptimizationRemarkEmitter *, bool);
|
||||
MemorySSAUpdater *, ScalarEvolution *, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, bool);
|
||||
|
||||
/// This function deletes dead loops. The caller of this function needs to
|
||||
/// guarantee that the loop is infact dead.
|
||||
|
@ -211,7 +209,7 @@ bool promoteLoopAccessesToScalars(
|
|||
const SmallSetVector<Value *, 8> &, SmallVectorImpl<BasicBlock *> &,
|
||||
SmallVectorImpl<Instruction *> &, SmallVectorImpl<MemoryAccess *> &,
|
||||
PredIteratorCache &, LoopInfo *, DominatorTree *, const TargetLibraryInfo *,
|
||||
Loop *, AliasSetTracker *, MemorySSAUpdater *, ICFLoopSafetyInfo *,
|
||||
Loop *, MemorySSAUpdater *, ICFLoopSafetyInfo *,
|
||||
OptimizationRemarkEmitter *);
|
||||
|
||||
/// Does a BFS from a given node to all of its children inside a given loop.
|
||||
|
|
|
@ -174,7 +174,7 @@ static Instruction *cloneInstructionInExitBlock(
|
|||
const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU);
|
||||
|
||||
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
|
||||
AliasSetTracker *AST, MemorySSAUpdater *MSSAU);
|
||||
MemorySSAUpdater *MSSAU);
|
||||
|
||||
static void moveInstructionBefore(Instruction &I, Instruction &Dest,
|
||||
ICFLoopSafetyInfo &SafetyInfo,
|
||||
|
@ -200,9 +200,6 @@ struct LoopInvariantCodeMotion {
|
|||
private:
|
||||
unsigned LicmMssaOptCap;
|
||||
unsigned LicmMssaNoAccForPromotionCap;
|
||||
|
||||
std::unique_ptr<AliasSetTracker>
|
||||
collectAliasInfoForLoop(Loop *L, LoopInfo *LI, AAResults *AA);
|
||||
};
|
||||
|
||||
struct LegacyLICMPass : public LoopPass {
|
||||
|
@ -265,6 +262,9 @@ private:
|
|||
|
||||
PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &) {
|
||||
if (!AR.MSSA)
|
||||
report_fatal_error("LICM requires MemorySSA (loop-mssa)");
|
||||
|
||||
// For the new PM, we also can't use OptimizationRemarkEmitter as an analysis
|
||||
// pass. Function analyses need to be preserved across loop transformations
|
||||
// but ORE cannot be preserved (see comment before the pass definition).
|
||||
|
@ -279,8 +279,7 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
|
|||
|
||||
PA.preserve<DominatorTreeAnalysis>();
|
||||
PA.preserve<LoopAnalysis>();
|
||||
if (AR.MSSA)
|
||||
PA.preserve<MemorySSAAnalysis>();
|
||||
PA.preserve<MemorySSAAnalysis>();
|
||||
|
||||
return PA;
|
||||
}
|
||||
|
@ -288,6 +287,9 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
|
|||
PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR,
|
||||
LPMUpdater &) {
|
||||
if (!AR.MSSA)
|
||||
report_fatal_error("LNICM requires MemorySSA (loop-mssa)");
|
||||
|
||||
// For the new PM, we also can't use OptimizationRemarkEmitter as an analysis
|
||||
// pass. Function analyses need to be preserved across loop transformations
|
||||
// but ORE cannot be preserved (see comment before the pass definition).
|
||||
|
@ -306,8 +308,7 @@ PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
|
|||
|
||||
PA.preserve<DominatorTreeAnalysis>();
|
||||
PA.preserve<LoopAnalysis>();
|
||||
if (AR.MSSA)
|
||||
PA.preserve<MemorySSAAnalysis>();
|
||||
PA.preserve<MemorySSAAnalysis>();
|
||||
|
||||
return PA;
|
||||
}
|
||||
|
@ -376,10 +377,6 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<AliasSetTracker> CurAST;
|
||||
std::unique_ptr<MemorySSAUpdater> MSSAU;
|
||||
std::unique_ptr<SinkAndHoistLICMFlags> Flags;
|
||||
|
||||
// Don't sink stores from loops with coroutine suspend instructions.
|
||||
// LICM would sink instructions into the default destination of
|
||||
// the coroutine switch. The default destination of the switch is to
|
||||
|
@ -396,17 +393,9 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
});
|
||||
});
|
||||
|
||||
if (!MSSA) {
|
||||
LLVM_DEBUG(dbgs() << "LICM: Using Alias Set Tracker.\n");
|
||||
CurAST = collectAliasInfoForLoop(L, LI, AA);
|
||||
Flags = std::make_unique<SinkAndHoistLICMFlags>(
|
||||
LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true);
|
||||
} else {
|
||||
LLVM_DEBUG(dbgs() << "LICM: Using MemorySSA.\n");
|
||||
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
|
||||
Flags = std::make_unique<SinkAndHoistLICMFlags>(
|
||||
LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true, L, MSSA);
|
||||
}
|
||||
MemorySSAUpdater MSSAU(MSSA);
|
||||
SinkAndHoistLICMFlags Flags(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
|
||||
/*IsSink=*/true, L, MSSA);
|
||||
|
||||
// Get the preheader block to move instructions into...
|
||||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
|
@ -425,19 +414,16 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
// us to sink instructions in one pass, without iteration. After sinking
|
||||
// instructions, we perform another pass to hoist them out of the loop.
|
||||
if (L->hasDedicatedExits())
|
||||
Changed |=
|
||||
LoopNestMode
|
||||
? sinkRegionForLoopNest(DT->getNode(L->getHeader()), AA, LI, DT,
|
||||
BFI, TLI, TTI, L, CurAST.get(), MSSAU.get(),
|
||||
&SafetyInfo, *Flags.get(), ORE)
|
||||
: sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI,
|
||||
L, CurAST.get(), MSSAU.get(), &SafetyInfo,
|
||||
*Flags.get(), ORE);
|
||||
Flags->setIsSink(false);
|
||||
Changed |= LoopNestMode
|
||||
? sinkRegionForLoopNest(DT->getNode(L->getHeader()), AA, LI,
|
||||
DT, BFI, TLI, TTI, L, &MSSAU,
|
||||
&SafetyInfo, Flags, ORE)
|
||||
: sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI,
|
||||
TLI, TTI, L, &MSSAU, &SafetyInfo, Flags, ORE);
|
||||
Flags.setIsSink(false);
|
||||
if (Preheader)
|
||||
Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, L,
|
||||
CurAST.get(), MSSAU.get(), SE, &SafetyInfo,
|
||||
*Flags.get(), ORE, LoopNestMode);
|
||||
&MSSAU, SE, &SafetyInfo, Flags, ORE, LoopNestMode);
|
||||
|
||||
// Now that all loop invariants have been removed from the loop, promote any
|
||||
// memory references to scalars that we can.
|
||||
|
@ -447,7 +433,7 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
// preheader for SSA updater, so also avoid sinking when no preheader
|
||||
// is available.
|
||||
if (!DisablePromotion && Preheader && L->hasDedicatedExits() &&
|
||||
!Flags->tooManyMemoryAccesses() && !HasCoroSuspendInst) {
|
||||
!Flags.tooManyMemoryAccesses() && !HasCoroSuspendInst) {
|
||||
// Figure out the loop exits and their insertion points
|
||||
SmallVector<BasicBlock *, 8> ExitBlocks;
|
||||
L->getUniqueExitBlocks(ExitBlocks);
|
||||
|
@ -461,55 +447,29 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
SmallVector<Instruction *, 8> InsertPts;
|
||||
SmallVector<MemoryAccess *, 8> MSSAInsertPts;
|
||||
InsertPts.reserve(ExitBlocks.size());
|
||||
if (MSSAU)
|
||||
MSSAInsertPts.reserve(ExitBlocks.size());
|
||||
MSSAInsertPts.reserve(ExitBlocks.size());
|
||||
for (BasicBlock *ExitBlock : ExitBlocks) {
|
||||
InsertPts.push_back(&*ExitBlock->getFirstInsertionPt());
|
||||
if (MSSAU)
|
||||
MSSAInsertPts.push_back(nullptr);
|
||||
MSSAInsertPts.push_back(nullptr);
|
||||
}
|
||||
|
||||
PredIteratorCache PIC;
|
||||
|
||||
// Promoting one set of accesses may make the pointers for another set
|
||||
// loop invariant, so run this in a loop (with the MaybePromotable set
|
||||
// decreasing in size over time).
|
||||
bool Promoted = false;
|
||||
if (CurAST.get()) {
|
||||
// Loop over all of the alias sets in the tracker object.
|
||||
for (AliasSet &AS : *CurAST) {
|
||||
// We can promote this alias set if it has a store, if it is a "Must"
|
||||
// alias set, if the pointer is loop invariant, and if we are not
|
||||
// eliminating any volatile loads or stores.
|
||||
if (AS.isForwardingAliasSet() || !AS.isMod() || !AS.isMustAlias() ||
|
||||
!L->isLoopInvariant(AS.begin()->getValue()))
|
||||
continue;
|
||||
|
||||
assert(
|
||||
!AS.empty() &&
|
||||
"Must alias set should have at least one pointer element in it!");
|
||||
|
||||
SmallSetVector<Value *, 8> PointerMustAliases;
|
||||
for (const auto &ASI : AS)
|
||||
PointerMustAliases.insert(ASI.getValue());
|
||||
|
||||
Promoted |= promoteLoopAccessesToScalars(
|
||||
PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, LI,
|
||||
DT, TLI, L, CurAST.get(), MSSAU.get(), &SafetyInfo, ORE);
|
||||
bool LocalPromoted;
|
||||
do {
|
||||
LocalPromoted = false;
|
||||
for (const SmallSetVector<Value *, 8> &PointerMustAliases :
|
||||
collectPromotionCandidates(MSSA, AA, L)) {
|
||||
LocalPromoted |= promoteLoopAccessesToScalars(
|
||||
PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC,
|
||||
LI, DT, TLI, L, &MSSAU, &SafetyInfo, ORE);
|
||||
}
|
||||
} else {
|
||||
// Promoting one set of accesses may make the pointers for another set
|
||||
// loop invariant, so run this in a loop (with the MaybePromotable set
|
||||
// decreasing in size over time).
|
||||
bool LocalPromoted;
|
||||
do {
|
||||
LocalPromoted = false;
|
||||
for (const SmallSetVector<Value *, 8> &PointerMustAliases :
|
||||
collectPromotionCandidates(MSSA, AA, L)) {
|
||||
LocalPromoted |= promoteLoopAccessesToScalars(
|
||||
PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC,
|
||||
LI, DT, TLI, L, /*AST*/nullptr, MSSAU.get(), &SafetyInfo, ORE);
|
||||
}
|
||||
Promoted |= LocalPromoted;
|
||||
} while (LocalPromoted);
|
||||
}
|
||||
Promoted |= LocalPromoted;
|
||||
} while (LocalPromoted);
|
||||
|
||||
// Once we have promoted values across the loop body we have to
|
||||
// recursively reform LCSSA as any nested loop may now have values defined
|
||||
|
@ -531,8 +491,8 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
assert((L->isOutermost() || L->getParentLoop()->isLCSSAForm(*DT)) &&
|
||||
"Parent loop not left in LCSSA form after LICM!");
|
||||
|
||||
if (MSSAU.get() && VerifyMemorySSA)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
if (VerifyMemorySSA)
|
||||
MSSA->verifyMemorySSA();
|
||||
|
||||
if (Changed && SE)
|
||||
SE->forgetLoopDispositions(L);
|
||||
|
@ -547,17 +507,15 @@ bool LoopInvariantCodeMotion::runOnLoop(
|
|||
bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
||||
DominatorTree *DT, BlockFrequencyInfo *BFI,
|
||||
TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
|
||||
Loop *CurLoop, AliasSetTracker *CurAST,
|
||||
MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo,
|
||||
Loop *CurLoop, MemorySSAUpdater *MSSAU,
|
||||
ICFLoopSafetyInfo *SafetyInfo,
|
||||
SinkAndHoistLICMFlags &Flags,
|
||||
OptimizationRemarkEmitter *ORE, Loop *OutermostLoop) {
|
||||
|
||||
// Verify inputs.
|
||||
assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr &&
|
||||
CurLoop != nullptr && SafetyInfo != nullptr &&
|
||||
CurLoop != nullptr && MSSAU != nullptr && SafetyInfo != nullptr &&
|
||||
"Unexpected input to sinkRegion.");
|
||||
assert(((CurAST != nullptr) ^ (MSSAU != nullptr)) &&
|
||||
"Either AliasSetTracker or MemorySSA should be initialized.");
|
||||
|
||||
// We want to visit children before parents. We will enque all the parents
|
||||
// before their children in the worklist and process the worklist in reverse
|
||||
|
@ -582,7 +540,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
salvageKnowledge(&I);
|
||||
salvageDebugInfo(I);
|
||||
++II;
|
||||
eraseInstruction(I, *SafetyInfo, CurAST, MSSAU);
|
||||
eraseInstruction(I, *SafetyInfo, MSSAU);
|
||||
Changed = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -597,20 +555,20 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
if (!I.mayHaveSideEffects() &&
|
||||
isNotUsedOrFreeInLoop(I, LoopNestMode ? OutermostLoop : CurLoop,
|
||||
SafetyInfo, TTI, FreeInLoop, LoopNestMode) &&
|
||||
canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags,
|
||||
ORE)) {
|
||||
canSinkOrHoistInst(I, AA, DT, CurLoop, /*CurAST*/nullptr, MSSAU, true,
|
||||
&Flags, ORE)) {
|
||||
if (sink(I, LI, DT, BFI, CurLoop, SafetyInfo, MSSAU, ORE)) {
|
||||
if (!FreeInLoop) {
|
||||
++II;
|
||||
salvageDebugInfo(I);
|
||||
eraseInstruction(I, *SafetyInfo, CurAST, MSSAU);
|
||||
eraseInstruction(I, *SafetyInfo, MSSAU);
|
||||
}
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (MSSAU && VerifyMemorySSA)
|
||||
if (VerifyMemorySSA)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
return Changed;
|
||||
}
|
||||
|
@ -618,9 +576,8 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
bool llvm::sinkRegionForLoopNest(
|
||||
DomTreeNode *N, AAResults *AA, LoopInfo *LI, DominatorTree *DT,
|
||||
BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
|
||||
Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU,
|
||||
ICFLoopSafetyInfo *SafetyInfo, SinkAndHoistLICMFlags &Flags,
|
||||
OptimizationRemarkEmitter *ORE) {
|
||||
Loop *CurLoop, MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo,
|
||||
SinkAndHoistLICMFlags &Flags, OptimizationRemarkEmitter *ORE) {
|
||||
|
||||
bool Changed = false;
|
||||
SmallPriorityWorklist<Loop *, 4> Worklist;
|
||||
|
@ -628,9 +585,8 @@ bool llvm::sinkRegionForLoopNest(
|
|||
appendLoopsToWorklist(*CurLoop, Worklist);
|
||||
while (!Worklist.empty()) {
|
||||
Loop *L = Worklist.pop_back_val();
|
||||
Changed |=
|
||||
sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI, L,
|
||||
CurAST, MSSAU, SafetyInfo, Flags, ORE, CurLoop);
|
||||
Changed |= sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI,
|
||||
TTI, L, MSSAU, SafetyInfo, Flags, ORE, CurLoop);
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
@ -837,9 +793,8 @@ public:
|
|||
if (HoistTarget == InitialPreheader) {
|
||||
// Phis in the loop header now need to use the new preheader.
|
||||
InitialPreheader->replaceSuccessorsPhiUsesWith(HoistCommonSucc);
|
||||
if (MSSAU)
|
||||
MSSAU->wireOldPredecessorsToNewImmediatePredecessor(
|
||||
HoistTarget->getSingleSuccessor(), HoistCommonSucc, {HoistTarget});
|
||||
MSSAU->wireOldPredecessorsToNewImmediatePredecessor(
|
||||
HoistTarget->getSingleSuccessor(), HoistCommonSucc, {HoistTarget});
|
||||
// The new preheader dominates the loop header.
|
||||
DomTreeNode *PreheaderNode = DT->getNode(HoistCommonSucc);
|
||||
DomTreeNode *HeaderNode = DT->getNode(CurLoop->getHeader());
|
||||
|
@ -901,16 +856,14 @@ static bool worthSinkOrHoistInst(Instruction &I, BasicBlock *DstBlock,
|
|||
bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
||||
DominatorTree *DT, BlockFrequencyInfo *BFI,
|
||||
TargetLibraryInfo *TLI, Loop *CurLoop,
|
||||
AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU,
|
||||
ScalarEvolution *SE, ICFLoopSafetyInfo *SafetyInfo,
|
||||
MemorySSAUpdater *MSSAU, ScalarEvolution *SE,
|
||||
ICFLoopSafetyInfo *SafetyInfo,
|
||||
SinkAndHoistLICMFlags &Flags,
|
||||
OptimizationRemarkEmitter *ORE, bool LoopNestMode) {
|
||||
// Verify inputs.
|
||||
assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr &&
|
||||
CurLoop != nullptr && SafetyInfo != nullptr &&
|
||||
CurLoop != nullptr && MSSAU != nullptr && SafetyInfo != nullptr &&
|
||||
"Unexpected input to hoistRegion.");
|
||||
assert(((CurAST != nullptr) ^ (MSSAU != nullptr)) &&
|
||||
"Either AliasSetTracker or MemorySSA should be initialized.");
|
||||
|
||||
ControlFlowHoister CFH(LI, DT, CurLoop, MSSAU);
|
||||
|
||||
|
@ -939,12 +892,10 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
&I, I.getModule()->getDataLayout(), TLI)) {
|
||||
LLVM_DEBUG(dbgs() << "LICM folding inst: " << I << " --> " << *C
|
||||
<< '\n');
|
||||
if (CurAST)
|
||||
CurAST->copyValue(&I, C);
|
||||
// FIXME MSSA: Such replacements may make accesses unoptimized (D51960).
|
||||
I.replaceAllUsesWith(C);
|
||||
if (isInstructionTriviallyDead(&I, TLI))
|
||||
eraseInstruction(I, *SafetyInfo, CurAST, MSSAU);
|
||||
eraseInstruction(I, *SafetyInfo, MSSAU);
|
||||
Changed = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -957,8 +908,8 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
// and we have accurately duplicated the control flow from the loop header
|
||||
// to that block.
|
||||
if (CurLoop->hasLoopInvariantOperands(&I) &&
|
||||
canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags,
|
||||
ORE) &&
|
||||
canSinkOrHoistInst(I, AA, DT, CurLoop, /*CurAST*/ nullptr, MSSAU,
|
||||
true, &Flags, ORE) &&
|
||||
worthSinkOrHoistInst(I, CurLoop->getLoopPreheader(), ORE, BFI) &&
|
||||
isSafeToExecuteUnconditionally(
|
||||
I, DT, TLI, CurLoop, SafetyInfo, ORE,
|
||||
|
@ -987,7 +938,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
SafetyInfo->insertInstructionTo(Product, I.getParent());
|
||||
Product->insertAfter(&I);
|
||||
I.replaceAllUsesWith(Product);
|
||||
eraseInstruction(I, *SafetyInfo, CurAST, MSSAU);
|
||||
eraseInstruction(I, *SafetyInfo, MSSAU);
|
||||
|
||||
hoist(*ReciprocalDivisor, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB),
|
||||
SafetyInfo, MSSAU, SE, ORE);
|
||||
|
@ -1066,7 +1017,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (MSSAU && VerifyMemorySSA)
|
||||
if (VerifyMemorySSA)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
|
||||
// Now that we've finished hoisting make sure that LI and DT are still
|
||||
|
@ -1573,9 +1524,7 @@ static Instruction *cloneInstructionInExitBlock(
|
|||
}
|
||||
|
||||
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
|
||||
AliasSetTracker *AST, MemorySSAUpdater *MSSAU) {
|
||||
if (AST)
|
||||
AST->deleteValue(&I);
|
||||
MemorySSAUpdater *MSSAU) {
|
||||
if (MSSAU)
|
||||
MSSAU->removeMemoryAccess(&I);
|
||||
SafetyInfo.removeInstruction(&I);
|
||||
|
@ -1813,7 +1762,7 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
|
|||
Instruction *New = sinkThroughTriviallyReplaceablePHI(
|
||||
PN, &I, LI, SunkCopies, SafetyInfo, CurLoop, MSSAU);
|
||||
PN->replaceAllUsesWith(New);
|
||||
eraseInstruction(*PN, *SafetyInfo, nullptr, nullptr);
|
||||
eraseInstruction(*PN, *SafetyInfo, nullptr);
|
||||
Changed = true;
|
||||
}
|
||||
return Changed;
|
||||
|
@ -1902,7 +1851,6 @@ class LoopPromoter : public LoadAndStorePromoter {
|
|||
SmallVectorImpl<Instruction *> &LoopInsertPts;
|
||||
SmallVectorImpl<MemoryAccess *> &MSSAInsertPts;
|
||||
PredIteratorCache &PredCache;
|
||||
AliasSetTracker *AST;
|
||||
MemorySSAUpdater *MSSAU;
|
||||
LoopInfo &LI;
|
||||
DebugLoc DL;
|
||||
|
@ -1934,12 +1882,12 @@ public:
|
|||
SmallVectorImpl<BasicBlock *> &LEB,
|
||||
SmallVectorImpl<Instruction *> &LIP,
|
||||
SmallVectorImpl<MemoryAccess *> &MSSAIP, PredIteratorCache &PIC,
|
||||
AliasSetTracker *ast, MemorySSAUpdater *MSSAU, LoopInfo &li,
|
||||
DebugLoc dl, int alignment, bool UnorderedAtomic,
|
||||
const AAMDNodes &AATags, ICFLoopSafetyInfo &SafetyInfo)
|
||||
MemorySSAUpdater *MSSAU, LoopInfo &li, DebugLoc dl,
|
||||
int alignment, bool UnorderedAtomic, const AAMDNodes &AATags,
|
||||
ICFLoopSafetyInfo &SafetyInfo)
|
||||
: LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA),
|
||||
LoopExitBlocks(LEB), LoopInsertPts(LIP), MSSAInsertPts(MSSAIP),
|
||||
PredCache(PIC), AST(ast), MSSAU(MSSAU), LI(li), DL(std::move(dl)),
|
||||
PredCache(PIC), MSSAU(MSSAU), LI(li), DL(std::move(dl)),
|
||||
Alignment(alignment), UnorderedAtomic(UnorderedAtomic), AATags(AATags),
|
||||
SafetyInfo(SafetyInfo) {}
|
||||
|
||||
|
@ -1972,34 +1920,24 @@ public:
|
|||
if (AATags)
|
||||
NewSI->setAAMetadata(AATags);
|
||||
|
||||
if (MSSAU) {
|
||||
MemoryAccess *MSSAInsertPoint = MSSAInsertPts[i];
|
||||
MemoryAccess *NewMemAcc;
|
||||
if (!MSSAInsertPoint) {
|
||||
NewMemAcc = MSSAU->createMemoryAccessInBB(
|
||||
NewSI, nullptr, NewSI->getParent(), MemorySSA::Beginning);
|
||||
} else {
|
||||
NewMemAcc =
|
||||
MSSAU->createMemoryAccessAfter(NewSI, nullptr, MSSAInsertPoint);
|
||||
}
|
||||
MSSAInsertPts[i] = NewMemAcc;
|
||||
MSSAU->insertDef(cast<MemoryDef>(NewMemAcc), true);
|
||||
// FIXME: true for safety, false may still be correct.
|
||||
MemoryAccess *MSSAInsertPoint = MSSAInsertPts[i];
|
||||
MemoryAccess *NewMemAcc;
|
||||
if (!MSSAInsertPoint) {
|
||||
NewMemAcc = MSSAU->createMemoryAccessInBB(
|
||||
NewSI, nullptr, NewSI->getParent(), MemorySSA::Beginning);
|
||||
} else {
|
||||
NewMemAcc =
|
||||
MSSAU->createMemoryAccessAfter(NewSI, nullptr, MSSAInsertPoint);
|
||||
}
|
||||
MSSAInsertPts[i] = NewMemAcc;
|
||||
MSSAU->insertDef(cast<MemoryDef>(NewMemAcc), true);
|
||||
// FIXME: true for safety, false may still be correct.
|
||||
}
|
||||
}
|
||||
|
||||
void replaceLoadWithValue(LoadInst *LI, Value *V) const override {
|
||||
// Update alias analysis.
|
||||
if (AST)
|
||||
AST->copyValue(LI, V);
|
||||
}
|
||||
void instructionDeleted(Instruction *I) const override {
|
||||
SafetyInfo.removeInstruction(I);
|
||||
if (AST)
|
||||
AST->deleteValue(I);
|
||||
if (MSSAU)
|
||||
MSSAU->removeMemoryAccess(I);
|
||||
MSSAU->removeMemoryAccess(I);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2050,8 +1988,8 @@ bool llvm::promoteLoopAccessesToScalars(
|
|||
SmallVectorImpl<Instruction *> &InsertPts,
|
||||
SmallVectorImpl<MemoryAccess *> &MSSAInsertPts, PredIteratorCache &PIC,
|
||||
LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
|
||||
Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU,
|
||||
ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) {
|
||||
Loop *CurLoop, MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo,
|
||||
OptimizationRemarkEmitter *ORE) {
|
||||
// Verify inputs.
|
||||
assert(LI != nullptr && DT != nullptr && CurLoop != nullptr &&
|
||||
SafetyInfo != nullptr &&
|
||||
|
@ -2283,7 +2221,7 @@ bool llvm::promoteLoopAccessesToScalars(
|
|||
SmallVector<PHINode *, 16> NewPHIs;
|
||||
SSAUpdater SSA(&NewPHIs);
|
||||
LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks,
|
||||
InsertPts, MSSAInsertPts, PIC, CurAST, MSSAU, *LI, DL,
|
||||
InsertPts, MSSAInsertPts, PIC, MSSAU, *LI, DL,
|
||||
Alignment.value(), SawUnorderedAtomic, AATags,
|
||||
*SafetyInfo);
|
||||
|
||||
|
@ -2300,24 +2238,22 @@ bool llvm::promoteLoopAccessesToScalars(
|
|||
PreheaderLoad->setAAMetadata(AATags);
|
||||
SSA.AddAvailableValue(Preheader, PreheaderLoad);
|
||||
|
||||
if (MSSAU) {
|
||||
MemoryAccess *PreheaderLoadMemoryAccess = MSSAU->createMemoryAccessInBB(
|
||||
PreheaderLoad, nullptr, PreheaderLoad->getParent(), MemorySSA::End);
|
||||
MemoryUse *NewMemUse = cast<MemoryUse>(PreheaderLoadMemoryAccess);
|
||||
MSSAU->insertUse(NewMemUse, /*RenameUses=*/true);
|
||||
}
|
||||
MemoryAccess *PreheaderLoadMemoryAccess = MSSAU->createMemoryAccessInBB(
|
||||
PreheaderLoad, nullptr, PreheaderLoad->getParent(), MemorySSA::End);
|
||||
MemoryUse *NewMemUse = cast<MemoryUse>(PreheaderLoadMemoryAccess);
|
||||
MSSAU->insertUse(NewMemUse, /*RenameUses=*/true);
|
||||
|
||||
if (MSSAU && VerifyMemorySSA)
|
||||
if (VerifyMemorySSA)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
// Rewrite all the loads in the loop and remember all the definitions from
|
||||
// stores in the loop.
|
||||
Promoter.run(LoopUses);
|
||||
|
||||
if (MSSAU && VerifyMemorySSA)
|
||||
if (VerifyMemorySSA)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
// If the SSAUpdater didn't use the load in the preheader, just zap it now.
|
||||
if (PreheaderLoad->use_empty())
|
||||
eraseInstruction(*PreheaderLoad, *SafetyInfo, CurAST, MSSAU);
|
||||
eraseInstruction(*PreheaderLoad, *SafetyInfo, MSSAU);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2383,26 +2319,6 @@ collectPromotionCandidates(MemorySSA *MSSA, AliasAnalysis *AA, Loop *L) {
|
|||
return Result;
|
||||
}
|
||||
|
||||
/// Returns an owning pointer to an alias set which incorporates aliasing info
|
||||
/// from L and all subloops of L.
|
||||
std::unique_ptr<AliasSetTracker>
|
||||
LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI,
|
||||
AAResults *AA) {
|
||||
auto CurAST = std::make_unique<AliasSetTracker>(*AA);
|
||||
|
||||
// Add everything from all the sub loops.
|
||||
for (Loop *InnerL : L->getSubLoops())
|
||||
for (BasicBlock *BB : InnerL->blocks())
|
||||
CurAST->add(*BB);
|
||||
|
||||
// And merge in this loop (without anything from inner loops).
|
||||
for (BasicBlock *BB : L->blocks())
|
||||
if (LI->getLoopFor(BB) == L)
|
||||
CurAST->add(*BB);
|
||||
|
||||
return CurAST;
|
||||
}
|
||||
|
||||
static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
|
||||
AliasSetTracker *CurAST, Loop *CurLoop,
|
||||
AAResults *AA) {
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
; disambiguating some obvious cases. If LICM is able to disambiguate the
|
||||
; two pointers, then the load should be hoisted, and the store sunk.
|
||||
|
||||
; RUN: opt < %s -basic-aa -licm -enable-new-pm=0 -S | FileCheck %s -check-prefixes=CHECK,MSSA
|
||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes='loop(licm)' -S | FileCheck %s -check-prefixes=CHECK,AST
|
||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes='loop-mssa(licm)' -S | FileCheck %s -check-prefixes=CHECK,MSSA
|
||||
; RUN: opt < %s -basic-aa -licm -enable-new-pm=0 -S | FileCheck %s
|
||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes='loop-mssa(licm)' -S | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||
|
||||
@A = global i32 7 ; <i32*> [#uses=3]
|
||||
|
@ -27,13 +26,11 @@ Out: ; preds = %Loop
|
|||
; The Loop block should be empty after the load/store are promoted.
|
||||
; CHECK: @test1
|
||||
; CHECK: load i32, i32* @A
|
||||
; MSSA: load i32, i32* @A
|
||||
; MSSA: store i32 %Atmp, i32* @B
|
||||
; CHECK: load i32, i32* @A
|
||||
; CHECK: store i32 %Atmp, i32* @B
|
||||
; CHECK: Loop:
|
||||
; CHECK-NEXT: br i1 %c, label %Out, label %Loop
|
||||
; CHECK: Out:
|
||||
; AST: store i32 %Atmp, i32* @B
|
||||
; AST: load i32, i32* @A
|
||||
}
|
||||
|
||||
define i32 @test2(i1 %c) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -instcombine -globals-aa -licm -enable-new-pm=0 -S | FileCheck %s
|
||||
; RUN: opt < %s -aa-pipeline=basic-aa,globals-aa -passes='function(instcombine),require<globals-aa>,function(invalidate<aa>,loop(licm))' -S | FileCheck %s
|
||||
; RUN: opt < %s -aa-pipeline=basic-aa,globals-aa -passes='function(instcombine),require<globals-aa>,function(invalidate<aa>,loop-mssa(licm))' -S | FileCheck %s
|
||||
|
||||
; Make sure -globals-aa ignores dead uses of globals.
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
; RUN: opt -loop-rotate -licm %s -disable-output -debug-only=licm 2>&1 | FileCheck %s -check-prefix=LICM
|
||||
; RUN: opt -loop-rotate -licm %s -S | FileCheck %s
|
||||
|
||||
; LICM: Using
|
||||
; LICM-NOT: LICM sinking instruction: %.pre = load i8, i8* %arrayidx.phi.trans.insert
|
||||
|
||||
; CHECK-LABEL: @fn1
|
||||
|
|
|
@ -4,26 +4,26 @@
|
|||
;
|
||||
; First make sure we emit remarks on this test case.
|
||||
; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \
|
||||
; RUN: -passes='require<opt-remark-emit>,loop(licm)' \
|
||||
; RUN: -passes='require<opt-remark-emit>,loop-mssa(licm)' \
|
||||
; RUN: -pass-remarks=licm -pass-remarks-with-hotness \
|
||||
; RUN: | FileCheck %s
|
||||
;
|
||||
; Check that passes which preserve BFI don't invalidate the emitter.
|
||||
; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \
|
||||
; RUN: -passes='require<opt-remark-emit>,instcombine,require<opt-remark-emit>,loop(licm)' -debug-pass-manager \
|
||||
; RUN: -passes='require<opt-remark-emit>,instcombine,require<opt-remark-emit>,loop-mssa(licm)' -debug-pass-manager \
|
||||
; RUN: -pass-remarks=licm -pass-remarks-with-hotness \
|
||||
; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PM-PRESERVE
|
||||
;
|
||||
; Check that invalidating BFI computes a fresh emitter.
|
||||
; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \
|
||||
; RUN: -passes='require<opt-remark-emit>,invalidate<block-freq>,require<opt-remark-emit>,loop(licm)' -debug-pass-manager \
|
||||
; RUN: -passes='require<opt-remark-emit>,invalidate<block-freq>,require<opt-remark-emit>,loop-mssa(licm)' -debug-pass-manager \
|
||||
; RUN: -pass-remarks=licm -pass-remarks-with-hotness \
|
||||
; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PM-INVALIDATE
|
||||
;
|
||||
; Check that invalidating BFI desn't compute a fresh emitter when we don't
|
||||
; request hotness remarks.
|
||||
; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \
|
||||
; RUN: -passes='require<opt-remark-emit>,invalidate<block-freq>,require<opt-remark-emit>,loop(licm)' -debug-pass-manager \
|
||||
; RUN: -passes='require<opt-remark-emit>,invalidate<block-freq>,require<opt-remark-emit>,loop-mssa(licm)' -debug-pass-manager \
|
||||
; RUN: -pass-remarks=licm \
|
||||
; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PM-NO-INVALIDATE
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
; RUN: opt < %s -disable-output -passes='default<O2>' -time-passes 2>&1 | FileCheck %s --check-prefix=TIME
|
||||
;
|
||||
; For new pass manager, check that -time-passes-per-run emit one report for each pass run.
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,loop(licm),instcombine,loop(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW -check-prefix=TIME-DOUBLE-LICM-NEW
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop-mssa(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,loop-mssa(licm),instcombine,loop-mssa(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW -check-prefix=TIME-DOUBLE-LICM-NEW
|
||||
;
|
||||
; For new pass manager, check that -time-passes emit one report for each pass.
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,loop(licm),instcombine,loop(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop-mssa(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS
|
||||
; RUN: opt < %s -disable-output -passes='instcombine,loop-mssa(licm),instcombine,loop-mssa(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS
|
||||
;
|
||||
; The following 4 test runs verify -info-output-file interaction (default goes to stderr, '-' goes to stdout).
|
||||
; RUN: opt -enable-new-pm=0 < %s -disable-output -O2 -time-passes -info-output-file='-' 2>/dev/null | FileCheck %s --check-prefix=TIME
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -licm -adce -licm -S < %s | FileCheck %s
|
||||
; RUN: opt -passes='loop(licm),adce,loop(licm)' -S < %s | FileCheck %s
|
||||
; RUN: opt -passes='loop-mssa(licm),adce,loop-mssa(licm)' -S < %s | FileCheck %s
|
||||
;
|
||||
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -licm -basic-aa < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
define void @f_0(i1 %p) nounwind ssp {
|
||||
; CHECK-LABEL: @f_0(
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
; RUN: opt < %s -S -basic-aa -licm -enable-new-pm=0 | FileCheck -check-prefixes=CHECK,MSSA %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck -check-prefixes=CHECK,AST %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck -check-prefixes=CHECK,MSSA %s
|
||||
; RUN: opt < %s -S -basic-aa -licm -enable-new-pm=0 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
; Check that we can hoist unordered loads
|
||||
define i32 @test1(i32* nocapture %y) nounwind uwtable ssp {
|
||||
|
@ -174,12 +173,10 @@ loop:
|
|||
end:
|
||||
ret i32 %vala
|
||||
; CHECK-LABEL: define i32 @test7b(
|
||||
; AST-LABEL: entry:
|
||||
; AST: store i32 5, i32* %x
|
||||
; CHECK-LABEL: loop:
|
||||
; CHECK: load atomic i32, i32* %y monotonic
|
||||
; CHECK-LABEL: end:
|
||||
; MSSA: store i32 5, i32* %x
|
||||
; CHECK: store i32 5, i32* %x
|
||||
; CHECK: store atomic i32 %{{.+}}, i32* %z unordered, align 4
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -licm | llvm-dis
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s | llvm-dis
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s | llvm-dis
|
||||
|
||||
define void @testfunc(i32 %i) {
|
||||
; <label>:0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -S -basic-aa -licm %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
declare i32 @load(i32* %p) argmemonly readonly nounwind
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -S -basic-aa -licm | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
; This fixes PR22460
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -licm -disable-output < %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -disable-output < %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -disable-output < %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -licm -basic-aa < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
define void @dgefa() nounwind ssp {
|
||||
entry:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -make-guards-explicit -basic-aa -licm < %s | FileCheck %s
|
||||
; RUN: opt -S -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,make-guards-explicit,loop(licm)' < %s | FileCheck %s
|
||||
; RUN: opt -S -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,make-guards-explicit,loop-mssa(licm)' < %s | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1,...)
|
||||
declare void @maythrow()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -licm -S | FileCheck %s
|
||||
; RUN: opt -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
; PR19835
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -licm -basic-aa < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
define void @test1(i64 %n) {
|
||||
; CHECK-LABEL: @test1
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -licm -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
target triple = "i386-pc-windows-msvc18.0.0"
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; REQUIRES: asserts
|
||||
; RUN: opt -licm -basic-aa -ipt-expensive-asserts=true < %s -S | FileCheck %s --check-prefixes=CHECK,MSSA
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -ipt-expensive-asserts=true < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -ipt-expensive-asserts=true < %s -S | FileCheck %s --check-prefixes=CHECK,MSSA
|
||||
; RUN: opt -licm -basic-aa -ipt-expensive-asserts=true < %s -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -ipt-expensive-asserts=true < %s -S | FileCheck %s
|
||||
|
||||
; Hoist guard and load.
|
||||
define void @test1(i1 %cond, i32* %ptr) {
|
||||
|
@ -84,17 +83,17 @@ loop:
|
|||
|
||||
; But can hoist if the side effect is hoisted with MSSA
|
||||
define void @test2b_prime(i1 %cond, i32* noalias %ptr) {
|
||||
; MSSA-LABEL: @test2b_prime(
|
||||
; MSSA-NEXT: entry:
|
||||
; MSSA-NEXT: [[P2:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
|
||||
; MSSA-NEXT: store i32 0, i32* [[P2]]
|
||||
; MSSA-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
|
||||
; MSSA-NEXT: [[VAL:%.*]] = load i32, i32* [[PTR]]
|
||||
; MSSA-NEXT: br label [[LOOP:%.*]]
|
||||
; MSSA: loop:
|
||||
; MSSA-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
|
||||
; MSSA-NEXT: [[X_INC]] = add i32 [[X]], [[VAL]]
|
||||
; MSSA-NEXT: br label [[LOOP]]
|
||||
; CHECK-LABEL: @test2b_prime(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
|
||||
; CHECK-NEXT: store i32 0, i32* [[P2]]
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
|
||||
; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[PTR]]
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[X_INC]] = add i32 [[X]], [[VAL]]
|
||||
; CHECK-NEXT: br label [[LOOP]]
|
||||
|
||||
entry:
|
||||
br label %loop
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(loop-simplifycfg,licm)' -S < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(loop-simplifycfg,licm)' -S < %s | FileCheck %s
|
||||
; RUN: opt -S -basic-aa -licm -verify-memoryssa < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(loop-simplifycfg,licm)' -S < %s | FileCheck %s
|
||||
; RUN: opt -S -basic-aa -licm -verify-memoryssa < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(loop-simplifycfg,licm)' -verify-memoryssa -S < %s | FileCheck %s
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; REQUIRES: asserts
|
||||
; RUN: opt -S -basic-aa -licm -ipt-expensive-asserts=true < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -ipt-expensive-asserts=true -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' -ipt-expensive-asserts=true -S %s | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -S -basic-aa -licm -verify-memoryssa < %s | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
; RUN: opt -S -licm < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
|
||||
; RUN: opt -S -licm -licm-control-flow-hoisting=1 < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED
|
||||
; RUN: opt -S -licm -licm-control-flow-hoisting=0 < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
|
||||
; RUN: opt -passes='require<opt-remark-emit>,loop(licm)' -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
|
||||
; RUN: opt -passes='require<opt-remark-emit>,loop(licm)' -licm-control-flow-hoisting=1 -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED
|
||||
; RUN: opt -passes='require<opt-remark-emit>,loop(licm)' -licm-control-flow-hoisting=0 -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
|
||||
; RUN: opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
|
||||
|
||||
; RUN: opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -licm-control-flow-hoisting=1 -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED
|
||||
; Enable run below when adding promotion. e.g. "store i32 %phi, i32* %p" is promoted to phi.lcssa.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -S -licm -verify-memoryssa < %s | FileCheck %s
|
||||
|
||||
target datalayout = "E-m:e-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-v64:32:32-v128:32:32-a0:0:32-n32"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S | FileCheck %s
|
||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' -S | FileCheck %s
|
||||
; RUN: opt < %s -licm -verify-memoryssa -S | FileCheck %s
|
||||
|
||||
@X = global i32 0 ; <i32*> [#uses=1]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -basic-aa -licm < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
; Make sure we don't hoist the unsafe division to some executable block.
|
||||
define void @test_impossible_exit_in_untaken_block(i32 %a, i32 %b, i32* %p) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -S -basic-aa -licm < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s| FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s| FileCheck %s
|
||||
;
|
||||
; Manually validate LCSSA form is preserved even after SSAUpdater is used to
|
||||
; promote things in the loop bodies.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -passes='loop(licm)' -S %s | FileCheck %s --check-prefixes CHECK,LICM
|
||||
; RUN: opt -passes='loop(lnicm)' -S %s | FileCheck %s --check-prefixes CHECK,LNICM
|
||||
; RUN: opt -passes='loop-mssa(licm)' -S %s | FileCheck %s --check-prefixes CHECK,LICM
|
||||
; RUN: opt -passes='loop-mssa(lnicm)' -S %s | FileCheck %s --check-prefixes CHECK,LNICM
|
||||
|
||||
; This test represents the following function:
|
||||
;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; RUN: opt -aa-pipeline=basic-aa -passes='loop(loop-interchange)' -S %s | FileCheck %s --check-prefixes INTC
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='loop(lnicm,loop-interchange)' -S %s | FileCheck %s --check-prefixes LNICM,CHECK
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='loop(licm,loop-interchange)' -S %s | FileCheck %s --check-prefixes LICM,CHECK
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='loop-mssa(lnicm),loop(loop-interchange)' -S %s | FileCheck %s --check-prefixes LNICM,CHECK
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='loop-mssa(licm),loop(loop-interchange)' -S %s | FileCheck %s --check-prefixes LICM,CHECK
|
||||
|
||||
; This test represents the following function:
|
||||
; void test(int x[10][10], int y[10], int *z) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; Test that LICM works when there is not a loop-preheader
|
||||
; RUN: opt < %s -licm | llvm-dis
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s | llvm-dis
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s | llvm-dis
|
||||
|
||||
define void @testfunc(i32 %i.s, i1 %ifcond) {
|
||||
br i1 %ifcond, label %Then, label %Else
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -licm -pass-remarks-missed=licm -o /dev/null 2>&1 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' %s -o /dev/null -pass-remarks-missed=licm 2>&1 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' %s -o /dev/null -pass-remarks-missed=licm 2>&1 | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||
|
||||
; With the load from %p conditional, we can't optmize this and the remark
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -licm -pass-remarks-missed=licm -o /dev/null 2>&1 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' %s -o /dev/null -pass-remarks-missed=licm 2>&1 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' %s -o /dev/null -pass-remarks-missed=licm 2>&1 | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||
|
||||
; Without the noalias on %p, we can't optmize this and the remark should tell
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -licm -pass-remarks=licm -o /dev/null 2>&1 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' %s -o /dev/null -pass-remarks=licm 2>&1 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' %s -o /dev/null -pass-remarks=licm 2>&1 | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||
|
||||
define void @hoist(i32* %array, i32* noalias %p) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;RUN: opt -verify-dom-info -loop-simplify -postdomtree -licm -adce -verify-loop-info -S -o - %s | FileCheck %s
|
||||
;RUN: opt -verify-dom-info -passes='loop-simplify,require<postdomtree>,require<opt-remark-emit>,loop(licm),function(adce)' -S -o - %s | FileCheck %s
|
||||
;RUN: opt -verify-dom-info -passes='loop-simplify,require<postdomtree>,require<opt-remark-emit>,loop-mssa(licm),function(adce)' -S -o - %s | FileCheck %s
|
||||
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -disable-basic-aa -alias-set-saturation-threshold=2 -passes='loop(licm)' -S < %s | FileCheck %s
|
||||
; RUN: opt -disable-basic-aa -alias-set-saturation-threshold=2 -passes='loop-mssa(licm)' -S < %s | FileCheck %s
|
||||
; REQUIRES: asserts
|
||||
|
||||
; CHECK-LABEL: @f1()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -S -licm < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
declare void @use_nothrow(i64 %a) nounwind
|
||||
declare void @use(i64 %a)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
; RUN: opt -tbaa -basic-aa -licm -enable-new-pm=0 -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s --check-prefixes=CHECK,AST
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s --check-prefixes=CHECK,MSSA
|
||||
; RUN: opt -tbaa -basic-aa -licm -enable-new-pm=0 -S < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
; LICM should keep the stores in their original order when it sinks/promotes them.
|
||||
; rdar://12045203
|
||||
|
@ -13,9 +12,8 @@ target triple = "x86_64-apple-macosx10.8.0"
|
|||
define i32* @_Z4doiti(i32 %n, float* %tmp1, i32* %tmp3) nounwind {
|
||||
; CHECK-LABEL: for.body.lr.ph:
|
||||
; CHECK: store float 1.000000e+00, float* %tmp1
|
||||
; AST-LABEL: for.cond.for.end_crit_edge:
|
||||
; CHECK: store i32 1, i32* %tmp3
|
||||
; MSSA-LABEL: for.cond.for.end_crit_edge:
|
||||
; CHECK-LABEL: for.cond.for.end_crit_edge:
|
||||
|
||||
entry:
|
||||
%cmp1 = icmp slt i32 0, %n
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -tbaa -basic-aa -licm -S < %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
; If we can prove a local is thread local, we can insert stores during
|
||||
; promotion which wouldn't be legal otherwise.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -basic-aa -licm -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
; Make sure we don't hoist a conditionally-executed store out of the loop;
|
||||
; it would violate the concurrency memory model
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -basic-aa -licm -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -basic-aa -tbaa -licm -S | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||
|
||||
@X = global i32 7 ; <i32*> [#uses=4]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; RUN: opt -S -licm -licm-coldness-threshold=0 < %s | FileCheck %s --check-prefix=CHECK-LICM
|
||||
; RUN: opt -S -licm < %s | opt -S -loop-sink | FileCheck %s --check-prefix=CHECK-SINK
|
||||
; RUN: opt -S < %s -passes='require<opt-remark-emit>,loop(licm),loop-sink' \
|
||||
; RUN: opt -S < %s -passes='require<opt-remark-emit>,loop-mssa(licm),loop-sink' \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-SINK
|
||||
; RUN: opt -S -licm -licm-coldness-threshold=0 -verify-memoryssa < %s | FileCheck %s --check-prefix=CHECK-LICM
|
||||
; RUN: opt -S -licm -verify-memoryssa < %s | FileCheck %s --check-prefix=CHECK-BFI-LICM
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt -S -licm < %s | FileCheck %s
|
||||
; RUN: opt -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
|
||||
; RUN: opt -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
|
||||
|
||||
; UDiv is safe to speculate if the denominator is known non-zero.
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
; RUN: opt -S -basic-aa -licm %s -enable-new-pm=0 | FileCheck -check-prefixes=CHECK,MSSA %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck -check-prefixes=CHECK,AST %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck -check-prefixes=CHECK,MSSA %s
|
||||
; RUN: opt -S -basic-aa -licm %s -enable-new-pm=0 | FileCheck %s
|
||||
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
|
||||
|
||||
define void @test(i32* %loc) {
|
||||
; CHECK-LABEL: @test
|
||||
|
@ -47,11 +46,9 @@ exit2:
|
|||
|
||||
define i32* @false_negative_2use(i32* %loc) {
|
||||
; CHECK-LABEL: @false_negative_2use
|
||||
; AST-LABEL: exit:
|
||||
; AST: store i32 0, i32* %loc
|
||||
; MSSA-LABEL: entry:
|
||||
; MSSA: store i32 0, i32* %loc
|
||||
; MSSA-LABEL: loop:
|
||||
; CHECK-LABEL: entry:
|
||||
; CHECK: store i32 0, i32* %loc
|
||||
; CHECK-LABEL: loop:
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
|
@ -348,11 +345,9 @@ exit:
|
|||
; the load must observe.
|
||||
define i32 @test_dominated_read(i32* %loc) {
|
||||
; CHECK-LABEL: @test_dominated_read
|
||||
; MSSA-LABEL: entry:
|
||||
; MSSA: store i32 0, i32* %loc
|
||||
; MSSA-LABEL: loop:
|
||||
; AST-LABEL: exit:
|
||||
; AST: store i32 0, i32* %loc
|
||||
; CHECK-LABEL: entry:
|
||||
; CHECK: store i32 0, i32* %loc
|
||||
; CHECK-LABEL: loop:
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
; alias information for inner loops, and in the new PM it is recomputed for each
|
||||
; loop.
|
||||
;
|
||||
; RUN: opt -S -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s | FileCheck %s
|
||||
; RUN: opt -S -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' < %s | FileCheck %s
|
||||
; RUN: opt -S -basic-aa -licm < %s | FileCheck %s
|
||||
|
||||
define i32 @test(i32* %a, i64 %n.0, i64 %n.0.0, i64 %n.0.0.0, i64 %n.0.0.0.0) nounwind uwtable readonly {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; RUN: opt -S -licm < %s | FileCheck %s --check-prefix=IR-AFTER-TRANSFORM
|
||||
; RUN: opt -analyze -scalar-evolution -licm -scalar-evolution -enable-new-pm=0 < %s | FileCheck %s --check-prefix=SCEV-EXPRS
|
||||
; RUN: opt -passes='print<scalar-evolution>,loop(licm),print<scalar-evolution>' -disable-output < %s 2>&1 | FileCheck %s --check-prefix=SCEV-EXPRS
|
||||
; RUN: opt -passes='print<scalar-evolution>,loop-mssa(licm),print<scalar-evolution>' -disable-output < %s 2>&1 | FileCheck %s --check-prefix=SCEV-EXPRS
|
||||
|
||||
declare void @clobber()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -basic-aa -sroa -loop-rotate %s | opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S | FileCheck %s
|
||||
; RUN: opt -basic-aa -sroa -loop-rotate %s | opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S | FileCheck %s
|
||||
; RUN: opt -basic-aa -sroa -loop-rotate -licm -verify-memoryssa -S < %s | FileCheck %s
|
||||
; The objects *p and *q are aliased to each other, but even though *q is
|
||||
; volatile, *p can be considered invariant in the loop. Check if it is moved
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -O1 -S -loop-versioning-licm -licm -debug-only=loop-versioning-licm -enable-new-pm=0 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -S -passes='default<O1>,loop-versioning-licm,licm' -debug-only=loop-versioning-licm 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -S -passes='default<O1>,function(loop-versioning-licm,loop-mssa(licm))' -debug-only=loop-versioning-licm 2>&1 | FileCheck %s
|
||||
; REQUIRES: asserts
|
||||
;
|
||||
; Test to confirm loop is a candidate for LoopVersioningLICM.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -O1 -S -loop-versioning-licm -licm -debug-only=loop-versioning-licm -disable-loop-unrolling -enable-new-pm=0 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -S -passes='default<O1>,loop-versioning-licm,licm' -debug-only=loop-versioning-licm -disable-loop-unrolling 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -S -passes='default<O1>,function(loop-versioning-licm,loop-mssa(licm))' -debug-only=loop-versioning-licm -disable-loop-unrolling 2>&1 | FileCheck %s
|
||||
; REQUIRES: asserts
|
||||
;
|
||||
; Test to confirm loop is a good candidate for LoopVersioningLICM
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -O1 -S -loop-versioning-licm -licm 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -S -passes='loop-versioning-licm,licm' 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -S -passes='function(loop-versioning-licm,loop-mssa(licm))' 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @without_metadata(
|
||||
define i32 @without_metadata(i32* nocapture %var1, i32* nocapture readnone %var2, i32* nocapture %var3, i32 %itr) #0 {
|
||||
|
|
|
@ -32,7 +32,7 @@ TEST(LICMTest, TestSCEVInvalidationOnHoisting) {
|
|||
PB.registerLoopAnalyses(LAM);
|
||||
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
|
||||
|
||||
StringRef PipelineStr = "require<opt-remark-emit>,loop(licm)";
|
||||
StringRef PipelineStr = "require<opt-remark-emit>,loop-mssa(licm)";
|
||||
ASSERT_THAT_ERROR(PB.parsePassPipeline(MPM, PipelineStr), Succeeded());
|
||||
|
||||
SMDiagnostic Error;
|
||||
|
|
Loading…
Reference in New Issue
Block a user