[LoopPassManager + MemorySSA] Only enable use of MemorySSA for LPMs known to preserve it.

Summary:
Add a flag to the FunctionToLoopAdaptor that allows enabling MemorySSA only for the loop pass managers that are known to preserve it.

If an LPM is known to have only loop transforms that *all* preserve MemorySSA, then use MemorySSA if `EnableMSSALoopDependency` is set.
If an LPM has loop passes that do not preserve MemorySSA, then the flag passed is `false`, regardless of the value of `EnableMSSALoopDependency`.

When using a custom loop pass pipeline via `passes=...`, use keyword `loop` vs `loop-mssa` to use MemorySSA in that LPM. If a loop that does not preserve MemorySSA is added while using the `loop-mssa` keyword, that's an error.

Add the new `loop-mssa` keyword to a few tests where a difference occurs when enabling MemorySSA.

Reviewers: chandlerc

Subscribers: mehdi_amini, Prazek, george.burgess.iv, sanjoy.google, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66376

llvm-svn: 369548
This commit is contained in:
Alina Sbirlea 2019-08-21 17:00:57 +00:00
parent 954a012b4c
commit 7425179fee
24 changed files with 122 additions and 54 deletions

View File

@ -86,8 +86,9 @@ typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
template <> class LoopAnalysisManagerFunctionProxy::Result {
public:
explicit Result(LoopAnalysisManager &InnerAM, LoopInfo &LI)
: InnerAM(&InnerAM), LI(&LI) {}
Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)), LI(Arg.LI) {
: InnerAM(&InnerAM), LI(&LI), MSSAUsed(false) {}
Result(Result &&Arg)
: InnerAM(std::move(Arg.InnerAM)), LI(Arg.LI), MSSAUsed(Arg.MSSAUsed) {
// We have to null out the analysis manager in the moved-from state
// because we are taking ownership of the responsibilty to clear the
// analysis state.
@ -96,6 +97,7 @@ public:
Result &operator=(Result &&RHS) {
InnerAM = RHS.InnerAM;
LI = RHS.LI;
MSSAUsed = RHS.MSSAUsed;
// We have to null out the analysis manager in the moved-from state
// because we are taking ownership of the responsibilty to clear the
// analysis state.
@ -112,6 +114,9 @@ public:
InnerAM->clear();
}
/// Mark MemorySSA as used so we can invalidate self if MSSA is invalidated.
void markMSSAUsed() { MSSAUsed = true; }
/// Accessor for the analysis manager.
LoopAnalysisManager &getManager() { return *InnerAM; }
@ -130,6 +135,7 @@ public:
private:
LoopAnalysisManager *InnerAM;
LoopInfo *LI;
bool MSSAUsed;
};
/// Provide a specialized run method for the \c LoopAnalysisManagerFunctionProxy

View File

@ -263,8 +263,10 @@ template <typename LoopPassT>
class FunctionToLoopPassAdaptor
: public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
public:
explicit FunctionToLoopPassAdaptor(LoopPassT Pass, bool DebugLogging = false)
: Pass(std::move(Pass)), LoopCanonicalizationFPM(DebugLogging) {
explicit FunctionToLoopPassAdaptor(LoopPassT Pass, bool UseMemorySSA = false,
bool DebugLogging = false)
: Pass(std::move(Pass)), LoopCanonicalizationFPM(DebugLogging),
UseMemorySSA(UseMemorySSA) {
LoopCanonicalizationFPM.addPass(LoopSimplifyPass());
LoopCanonicalizationFPM.addPass(LCSSAPass());
}
@ -293,7 +295,7 @@ public:
return PA;
// Get the analysis results needed by loop passes.
MemorySSA *MSSA = EnableMSSALoopDependency
MemorySSA *MSSA = UseMemorySSA
? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA())
: nullptr;
LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
@ -310,8 +312,10 @@ public:
// LoopStandardAnalysisResults object. The loop analyses cached in this
// manager have access to those analysis results and so it must invalidate
// itself when they go away.
LoopAnalysisManager &LAM =
AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);
if (UseMemorySSA)
LAMFP.markMSSAUsed();
LoopAnalysisManager &LAM = LAMFP.getManager();
// A postorder worklist of loops to process.
SmallPriorityWorklist<Loop *, 4> Worklist;
@ -382,6 +386,8 @@ public:
PA.preserve<DominatorTreeAnalysis>();
PA.preserve<LoopAnalysis>();
PA.preserve<ScalarEvolutionAnalysis>();
if (UseMemorySSA)
PA.preserve<MemorySSAAnalysis>();
// FIXME: What we really want to do here is preserve an AA category, but
// that concept doesn't exist yet.
PA.preserve<AAManager>();
@ -395,14 +401,18 @@ private:
LoopPassT Pass;
FunctionPassManager LoopCanonicalizationFPM;
bool UseMemorySSA = false;
};
/// A function to deduce a loop pass type and wrap it in the templated
/// adaptor.
template <typename LoopPassT>
FunctionToLoopPassAdaptor<LoopPassT>
createFunctionToLoopPassAdaptor(LoopPassT Pass, bool DebugLogging = false) {
return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass), DebugLogging);
createFunctionToLoopPassAdaptor(LoopPassT Pass, bool UseMemorySSA = false,
bool DebugLogging = false) {
return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass), UseMemorySSA,
DebugLogging);
}
/// Pass for printing a loop's contents as textual IR.

View File

@ -46,7 +46,7 @@ bool LoopAnalysisManagerFunctionProxy::Result::invalidate(
// invalidation logic below to act on that.
auto PAC = PA.getChecker<LoopAnalysisManagerFunctionProxy>();
bool invalidateMemorySSAAnalysis = false;
if (EnableMSSALoopDependency)
if (MSSAUsed)
invalidateMemorySSAAnalysis = Inv.invalidate<MemorySSAAnalysis>(F, PA);
if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
Inv.invalidate<AAManager>(F, PA) ||

View File

@ -477,10 +477,15 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
// We provide the opt remark emitter pass for LICM to use. We only need to do
// this once as it is immutable.
FPM.addPass(RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>());
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM1), DebugLogging));
FPM.addPass(createFunctionToLoopPassAdaptor(
std::move(LPM1), EnableMSSALoopDependency, DebugLogging));
FPM.addPass(SimplifyCFGPass());
FPM.addPass(InstCombinePass());
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM2), DebugLogging));
// The loop passes in LPM2 (IndVarSimplifyPass, LoopIdiomRecognizePass,
// LoopDeletionPass and LoopFullUnrollPass) do not preserve MemorySSA.
// *All* loop passes must preserve it, in order to be able to use it.
FPM.addPass(createFunctionToLoopPassAdaptor(
std::move(LPM2), /*UseMemorySSA=*/false, DebugLogging));
// Eliminate redundancies.
if (Level != O1) {
@ -517,7 +522,7 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
FPM.addPass(DSEPass());
FPM.addPass(createFunctionToLoopPassAdaptor(
LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap),
DebugLogging));
EnableMSSALoopDependency, DebugLogging));
for (auto &C : ScalarOptimizerLateEPCallbacks)
C(FPM, Level);
@ -593,7 +598,8 @@ void PassBuilder::addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging,
MPM.addPass(PGOInstrumentationGen(IsCS));
FunctionPassManager FPM;
FPM.addPass(createFunctionToLoopPassAdaptor(LoopRotatePass(), DebugLogging));
FPM.addPass(createFunctionToLoopPassAdaptor(
LoopRotatePass(), EnableMSSALoopDependency, DebugLogging));
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
// Add the profile lowering pass.
@ -894,8 +900,8 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline(
C(OptimizePM, Level);
// First rotate loops that may have been un-rotated by prior passes.
OptimizePM.addPass(
createFunctionToLoopPassAdaptor(LoopRotatePass(), DebugLogging));
OptimizePM.addPass(createFunctionToLoopPassAdaptor(
LoopRotatePass(), EnableMSSALoopDependency, DebugLogging));
// Distribute loops to allow partial vectorization. I.e. isolate dependences
// into separate loop that would otherwise inhibit vectorization. This is
@ -954,7 +960,7 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline(
OptimizePM.addPass(RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>());
OptimizePM.addPass(createFunctionToLoopPassAdaptor(
LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap),
DebugLogging));
EnableMSSALoopDependency, DebugLogging));
// Now that we've vectorized and unrolled loops, we may have more refined
// alignment information, try to re-derive it here.
@ -1662,7 +1668,7 @@ static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
// Explicitly handle pass manager names.
if (Name == "function")
return true;
if (Name == "loop")
if (Name == "loop" || Name == "loop-mssa")
return true;
// Explicitly handle custom-parsed pass names.
@ -1686,7 +1692,7 @@ static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
template <typename CallbacksT>
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks) {
// Explicitly handle pass manager names.
if (Name == "loop")
if (Name == "loop" || Name == "loop-mssa")
return true;
// Explicitly handle custom-parsed pass names.
@ -1990,14 +1996,15 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
FPM.addPass(std::move(NestedFPM));
return Error::success();
}
if (Name == "loop") {
if (Name == "loop" || Name == "loop-mssa") {
LoopPassManager LPM(DebugLogging);
if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline, VerifyEachPass,
DebugLogging))
return Err;
// Add the nested pass manager with the appropriate adaptor.
FPM.addPass(
createFunctionToLoopPassAdaptor(std::move(LPM), DebugLogging));
bool UseMemorySSA = (Name == "loop-mssa");
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
DebugLogging));
return Error::success();
}
if (auto Count = parseRepeatPassName(Name)) {

View File

@ -1,8 +1,9 @@
; Test that LICM uses basicaa to do alias analysis, which is capable of
; Test that LICM uses basicaa to do alias analysis, which is capable of
; 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 -basicaa -licm -S | FileCheck %s
; RUN: opt < %s -basicaa -licm -enable-mssa-loop-dependency=false -S | FileCheck %s -check-prefixes=CHECK,AST
; RUN: opt < %s -basicaa -licm -enable-mssa-loop-dependency=true -S | FileCheck %s -check-prefixes=CHECK,MSSA
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]
@ -25,10 +26,13 @@ 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: Loop:
; CHECK-NEXT: br i1 %c, label %Out, label %Loop
; CHECK: Out:
; CHECK: store i32 %Atmp, i32* @B
; AST: store i32 %Atmp, i32* @B
; AST: load i32, i32* @A
}
define i32 @test2(i1 %c) {

View File

@ -1,8 +1,10 @@
; RUN: opt -S -basicaa -licm -licm-n2-threshold=0 %s | FileCheck %s
; RUN: opt -licm -basicaa -licm-n2-threshold=200 < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -S -basicaa -licm -licm-n2-threshold=0 -enable-mssa-loop-dependency=false %s | FileCheck %s
; RUN: opt -S -basicaa -licm -licm-n2-threshold=0 -enable-mssa-loop-dependency=true -verify-memoryssa %s | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -licm -basicaa -licm-n2-threshold=200 < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
declare i32 @foo() readonly argmemonly nounwind
declare i32 @foo2() readonly nounwind

View File

@ -1,5 +1,7 @@
; RUN: opt < %s -S -basicaa -licm | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt < %s -S -basicaa -licm -enable-mssa-loop-dependency=false | FileCheck -check-prefixes=CHECK,AST %s
; RUN: opt < %s -S -basicaa -licm -enable-mssa-loop-dependency=true | 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
; Check that we can hoist unordered loads
define i32 @test1(i32* nocapture %y) nounwind uwtable ssp {
@ -173,11 +175,12 @@ loop:
end:
ret i32 %vala
; CHECK-LABEL: define i32 @test7b(
; CHECK-LABEL: entry:
; CHECK: store i32 5, i32* %x
; 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 atomic i32 %{{.+}}, i32* %z unordered, align 4
}

View File

@ -1,7 +1,9 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; REQUIRES: asserts
; RUN: opt -licm -basicaa -ipt-expensive-asserts=true < %s -S | FileCheck %s
; RUN: opt -licm -basicaa -enable-mssa-loop-dependency=false -ipt-expensive-asserts=true < %s -S | FileCheck %s
; RUN: opt -licm -basicaa -enable-mssa-loop-dependency=true -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
; Hoist guard and load.
define void @test1(i1 %cond, i32* %ptr) {
@ -61,13 +63,40 @@ define void @test2b(i1 %cond, i32* %ptr) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
; CHECK-NEXT: store i32 0, i32* [[P2]]
; CHECK-NEXT: store i32 [[X]], i32* [[P2]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[PTR]]
; CHECK-NEXT: [[X_INC]] = add i32 [[X]], [[VAL]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
%x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
%p2 = getelementptr i32, i32* %ptr, i32 1
store i32 %x, i32* %p2
call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
%val = load i32, i32* %ptr
%x.inc = add i32 %x, %val
br label %loop
}
; But can hoist if the side effect is hoisted with MSSA
define void @test2b_prime(i1 %cond, i32* %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]]
entry:
br label %loop

View File

@ -1,7 +1,7 @@
; RUN: opt -S -basicaa -licm < %s | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
; RUN: opt -S -basicaa -licm -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(simplify-cfg,licm)' -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(simplify-cfg,licm)' -verify-memoryssa -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"

View File

@ -5,9 +5,9 @@
; 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(licm)' -licm-control-flow-hoisting=1 -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED
; 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.
; opt -passes='require<opt-remark-emit>,loop(licm)' -licm-control-flow-hoisting=0 -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
; opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -licm-control-flow-hoisting=0 -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
; CHECK-LABEL: @triangle_phi

View File

@ -1,5 +1,7 @@
; RUN: opt -tbaa -basicaa -licm -S < %s | FileCheck %s
; RUN: opt -aa-pipeline=type-based-aa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
; RUN: opt -tbaa -basicaa -licm -enable-mssa-loop-dependency=false -S < %s | FileCheck %s --check-prefixes=CHECK,AST
; RUN: opt -tbaa -basicaa -licm -enable-mssa-loop-dependency=true -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA
; RUN: opt -aa-pipeline=type-based-aa,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=type-based-aa,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
; LICM should keep the stores in their original order when it sinks/promotes them.
; rdar://12045203
@ -12,8 +14,9 @@ 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
; CHECK-LABEL: for.cond.for.end_crit_edge:
; AST-LABEL: for.cond.for.end_crit_edge:
; CHECK: store i32 1, i32* %tmp3
; MSSA-LABEL: for.cond.for.end_crit_edge:
entry:
%cmp1 = icmp slt i32 0, %n

View File

@ -1,6 +1,9 @@
; RUN: opt -S -basicaa -licm -licm-n2-threshold=0 %s | FileCheck %s
; RUN: opt -S -basicaa -licm -licm-n2-threshold=0 -enable-mssa-loop-dependency=false %s | FileCheck %s
; RUN: opt -S -basicaa -licm -licm-n2-threshold=0 -enable-mssa-loop-dependency=true %s | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -licm -basicaa -licm-n2-threshold=200 < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; We should be able to hoist loads in presence of read only calls and stores

View File

@ -1,6 +1,7 @@
; RUN: opt -S -basicaa -licm %s | FileCheck -check-prefixes=CHECK,AST %s
; RUN: opt -S -basicaa -licm -enable-mssa-loop-dependency=false %s | FileCheck -check-prefixes=CHECK,AST %s
; RUN: opt -S -basicaa -licm -enable-mssa-loop-dependency=true %s | 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
define void @test(i32* %loc) {
; CHECK-LABEL: @test

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S %s -passes=loop-instsimplify | FileCheck %s
; RUN: opt -S %s -passes=loop-instsimplify -enable-mssa-loop-dependency=true -verify-memoryssa | FileCheck %s
; RUN: opt -S %s -passes='loop-mssa(loop-instsimplify)' -verify-memoryssa | FileCheck %s
; Test very basic folding and propagation occurs within a loop body. This should
; collapse to the loop iteration structure and the LCSSA PHI node.

View File

@ -1,7 +1,7 @@
; RUN: opt -S -loop-rotate < %s | FileCheck %s
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
; RUN: opt -S -passes='require<targetir>,require<assumptions>,loop(rotate)' < %s | FileCheck %s
; RUN: opt -S -passes='require<targetir>,require<assumptions>,loop(rotate)' -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
; RUN: opt -S -passes='require<targetir>,require<assumptions>,loop-mssa(rotate)' -verify-memoryssa < %s | FileCheck %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"

View File

@ -1,5 +1,5 @@
;RUN: opt %s -passes='adce,loop(rotate),adce' -S -debug-pass-manager -debug-only=loop-rotate 2>&1 | FileCheck %s
;RUN: opt %s -passes='adce,loop(rotate),adce' -S -debug-pass-manager -debug-only=loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa 2>&1 | FileCheck %s --check-prefix=MSSA
;RUN: opt %s -passes='adce,loop-mssa(rotate),adce' -S -debug-pass-manager -debug-only=loop-rotate -verify-memoryssa 2>&1 | FileCheck %s --check-prefix=MSSA
;REQUIRES: asserts
; This test is to make sure we invalidate the post dominator pass after loop rotate simplifies the loop latch.

View File

@ -1,5 +1,5 @@
; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -verify-memoryssa -passes='loop-mssa(unswitch),verify<loops>' -S < %s | FileCheck %s
declare void @incf()
declare void @decf()

View File

@ -1,5 +1,5 @@
; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -verify-memoryssa -passes='loop-mssa(unswitch),verify<loops>' -S < %s | FileCheck %s
define i32 @test(i32* %A, i1 %C) {
entry:

View File

@ -1,6 +1,6 @@
; RUN: opt -passes='loop(unswitch<nontrivial>),verify<loops>' -simple-loop-unswitch-guards -S < %s | FileCheck %s
; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -simple-loop-unswitch-guards -S < %s | FileCheck %s
; RUN: opt -passes='loop(unswitch<nontrivial>),verify<loops>' -simple-loop-unswitch-guards -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
; RUN: opt -passes='loop-mssa(unswitch<nontrivial>),verify<loops>' -simple-loop-unswitch-guards -verify-memoryssa -S < %s | FileCheck %s
declare void @llvm.experimental.guard(i1, ...)

View File

@ -1,5 +1,5 @@
; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -verify-memoryssa -passes='loop-mssa(unswitch),verify<loops>' -S < %s | FileCheck %s
declare void @unknown()
declare void @unknown2()

View File

@ -1,5 +1,5 @@
; RUN: opt -passes='loop(loop-instsimplify,simplify-cfg,unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(loop-instsimplify,simplify-cfg,unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -verify-memoryssa -passes='loop-mssa(loop-instsimplify,simplify-cfg,unswitch),verify<loops>' -S < %s | FileCheck %s
declare void @some_func() noreturn

View File

@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; then metadata checks MDn were added manually.
; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -verify-memoryssa -passes='loop-mssa(unswitch),verify<loops>' -S < %s | FileCheck %s
declare void @some_func()

View File

@ -1,5 +1,5 @@
; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
; RUN: opt -verify-memoryssa -passes='loop-mssa(unswitch),verify<loops>' -S < %s | FileCheck %s
declare void @some_func() noreturn
declare void @sink(i32)

View File

@ -1,5 +1,5 @@
; RUN: opt -passes='print<scalar-evolution>,loop(unswitch<nontrivial>,loop-instsimplify),print<scalar-evolution>' -S < %s 2>%t.scev | FileCheck %s
; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='print<scalar-evolution>,loop(unswitch<nontrivial>,loop-instsimplify),print<scalar-evolution>' -S < %s 2>%t.scev | FileCheck %s
; RUN: opt -verify-memoryssa -passes='print<scalar-evolution>,loop-mssa(unswitch<nontrivial>,loop-instsimplify),print<scalar-evolution>' -S < %s 2>%t.scev | FileCheck %s
; RUN: FileCheck %s --check-prefix=SCEV < %t.scev
target triple = "x86_64-unknown-linux-gnu"