1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

Update MemorySSA in LoopRotate.

Summary:
Teach LoopRotate to preserve MemorySSA.
Enable tests for correctness, dependency disabled by default.

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

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

llvm-svn: 345216
This commit is contained in:
Alina Sbirlea 2018-10-24 22:46:45 +00:00
parent 5de5e4f650
commit 91e00bac96
25 changed files with 293 additions and 17 deletions

View File

@ -20,6 +20,7 @@ class AssumptionCache;
class DominatorTree;
class Loop;
class LoopInfo;
class MemorySSAUpdater;
class ScalarEvolution;
struct SimplifyQuery;
class TargetTransformInfo;
@ -32,8 +33,8 @@ class TargetTransformInfo;
/// LoopRotation. If it is true, the profitability heuristic will be ignored.
bool LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI,
AssumptionCache *AC, DominatorTree *DT, ScalarEvolution *SE,
const SimplifyQuery &SQ, bool RotationOnly,
unsigned Threshold, bool IsUtilMode);
MemorySSAUpdater *MSSAU, const SimplifyQuery &SQ,
bool RotationOnly, unsigned Threshold, bool IsUtilMode);
} // namespace llvm

View File

@ -15,6 +15,8 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Support/Debug.h"
@ -40,12 +42,19 @@ PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager &AM,
const DataLayout &DL = L.getHeader()->getModule()->getDataLayout();
const SimplifyQuery SQ = getBestSimplifyQuery(AR, DL);
bool Changed = LoopRotation(&L, &AR.LI, &AR.TTI, &AR.AC, &AR.DT, &AR.SE, SQ,
false, Threshold, false);
Optional<MemorySSAUpdater> MSSAU;
if (AR.MSSA)
MSSAU = MemorySSAUpdater(AR.MSSA);
bool Changed = LoopRotation(&L, &AR.LI, &AR.TTI, &AR.AC, &AR.DT, &AR.SE,
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr,
SQ, false, Threshold, false);
if (!Changed)
return PreservedAnalyses::all();
if (AR.MSSA && VerifyMemorySSA)
AR.MSSA->verifyMemorySSA();
return getLoopPassPreservedAnalyses();
}
@ -68,6 +77,10 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetTransformInfoWrapperPass>();
if (EnableMSSALoopDependency) {
AU.addRequired<MemorySSAWrapperPass>();
AU.addPreserved<MemorySSAWrapperPass>();
}
getLoopAnalysisUsage(AU);
}
@ -84,8 +97,14 @@ public:
auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
auto *SE = SEWP ? &SEWP->getSE() : nullptr;
const SimplifyQuery SQ = getBestSimplifyQuery(*this, F);
return LoopRotation(L, LI, TTI, AC, DT, SE, SQ, false, MaxHeaderSize,
false);
Optional<MemorySSAUpdater> MSSAU;
if (EnableMSSALoopDependency) {
MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
MSSAU = MemorySSAUpdater(MSSA);
}
return LoopRotation(L, LI, TTI, AC, DT, SE,
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr, SQ,
false, MaxHeaderSize, false);
}
};
}
@ -96,6 +115,7 @@ INITIALIZE_PASS_BEGIN(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops",
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops", false,
false)

View File

@ -20,6 +20,8 @@
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/TargetTransformInfo.h"
@ -54,6 +56,7 @@ class LoopRotate {
AssumptionCache *AC;
DominatorTree *DT;
ScalarEvolution *SE;
MemorySSAUpdater *MSSAU;
const SimplifyQuery &SQ;
bool RotationOnly;
bool IsUtilMode;
@ -61,10 +64,11 @@ class LoopRotate {
public:
LoopRotate(unsigned MaxHeaderSize, LoopInfo *LI,
const TargetTransformInfo *TTI, AssumptionCache *AC,
DominatorTree *DT, ScalarEvolution *SE, const SimplifyQuery &SQ,
bool RotationOnly, bool IsUtilMode)
DominatorTree *DT, ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
const SimplifyQuery &SQ, bool RotationOnly, bool IsUtilMode)
: MaxHeaderSize(MaxHeaderSize), LI(LI), TTI(TTI), AC(AC), DT(DT), SE(SE),
SQ(SQ), RotationOnly(RotationOnly), IsUtilMode(IsUtilMode) {}
MSSAU(MSSAU), SQ(SQ), RotationOnly(RotationOnly),
IsUtilMode(IsUtilMode) {}
bool processLoop(Loop *L);
private:
@ -269,6 +273,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
SE->forgetTopmostLoop(L);
LLVM_DEBUG(dbgs() << "LoopRotation: rotating "; L->dump());
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
// Find new Loop header. NewHeader is a Header's one and only successor
// that is inside loop. Header's other successor is outside the
@ -385,6 +391,12 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
// remove the corresponding incoming values from the PHI nodes in OrigHeader.
LoopEntryBranch->eraseFromParent();
// Update MemorySSA before the rewrite call below changes the 1:1
// instruction:cloned_instruction_or_value mapping in ValueMap.
if (MSSAU) {
ValueMap[OrigHeader] = OrigPreheader;
MSSAU->updateForClonedBlockIntoPred(OrigHeader, OrigPreheader, ValueMap);
}
SmallVector<PHINode*, 2> InsertedPHIs;
// If there were any uses of instructions in the duplicated block outside the
@ -411,6 +423,12 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
Updates.push_back({DominatorTree::Insert, OrigPreheader, NewHeader});
Updates.push_back({DominatorTree::Delete, OrigPreheader, OrigHeader});
DT->applyUpdates(Updates);
if (MSSAU) {
MSSAU->applyUpdates(Updates, *DT);
if (VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
}
}
// At this point, we've finished our major CFG changes. As part of cloning
@ -433,7 +451,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
// Split the edge to form a real preheader.
BasicBlock *NewPH = SplitCriticalEdge(
OrigPreheader, NewHeader,
CriticalEdgeSplittingOptions(DT, LI).setPreserveLCSSA());
CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA());
NewPH->setName(NewHeader->getName() + ".lr.ph");
// Preserve canonical loop form, which means that 'Exit' should have only
@ -452,7 +470,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
SplitLatchEdge |= L->getLoopLatch() == ExitPred;
BasicBlock *ExitSplit = SplitCriticalEdge(
ExitPred, Exit,
CriticalEdgeSplittingOptions(DT, LI).setPreserveLCSSA());
CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA());
ExitSplit->moveBefore(Exit);
}
assert(SplitLatchEdge &&
@ -467,17 +485,27 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
// With our CFG finalized, update DomTree if it is available.
if (DT) DT->deleteEdge(OrigPreheader, Exit);
// Update MSSA too, if available.
if (MSSAU)
MSSAU->removeEdge(OrigPreheader, Exit);
}
assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
// Now that the CFG and DomTree are in a consistent state again, try to merge
// the OrigHeader block into OrigLatch. This will succeed if they are
// connected by an unconditional branch. This is just a cleanup so the
// emitted code isn't too gross in this common case.
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
MergeBlockIntoPredecessor(OrigHeader, &DTU, LI);
MergeBlockIntoPredecessor(OrigHeader, &DTU, LI, MSSAU);
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
LLVM_DEBUG(dbgs() << "LoopRotation: into "; L->dump());
@ -586,9 +614,14 @@ bool LoopRotate::simplifyLoopLatch(Loop *L) {
<< LastExit->getName() << "\n");
// Hoist the instructions from Latch into LastExit.
Instruction *FirstLatchInst = &*(Latch->begin());
LastExit->getInstList().splice(BI->getIterator(), Latch->getInstList(),
Latch->begin(), Jmp->getIterator());
// Update MemorySSA
if (MSSAU)
MSSAU->moveAllAfterMergeBlocks(Latch, LastExit, FirstLatchInst);
unsigned FallThruPath = BI->getSuccessor(0) == Latch ? 0 : 1;
BasicBlock *Header = Jmp->getSuccessor(0);
assert(Header == L->getHeader() && "expected a backward branch");
@ -604,6 +637,10 @@ bool LoopRotate::simplifyLoopLatch(Loop *L) {
if (DT)
DT->eraseNode(Latch);
Latch->eraseFromParent();
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
return true;
}
@ -636,11 +673,16 @@ bool LoopRotate::processLoop(Loop *L) {
/// The utility to convert a loop into a loop with bottom test.
bool llvm::LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI,
AssumptionCache *AC, DominatorTree *DT,
ScalarEvolution *SE, const SimplifyQuery &SQ,
bool RotationOnly = true,
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
const SimplifyQuery &SQ, bool RotationOnly = true,
unsigned Threshold = unsigned(-1),
bool IsUtilMode = true) {
LoopRotate LR(Threshold, LI, TTI, AC, DT, SE, SQ, RotationOnly, IsUtilMode);
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
LoopRotate LR(Threshold, LI, TTI, AC, DT, SE, MSSAU, SQ, RotationOnly,
IsUtilMode);
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
return LR.processLoop(L);
}

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -disable-output
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
; PR3408
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"
target triple = "x86_64-unknown-linux-gnu"

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -S | FileCheck %s
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
; CHECK-NOT: [ {{.}}tmp224
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -disable-output
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
; ModuleID = 'PhiSelfReference-1.bc'
define void @snrm2(i32 %incx) {

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -S | FileCheck %s
; RUN: opt < %s -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
; Test alloca in -loop-rotate.

View File

@ -1,5 +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
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,4 +1,5 @@
; RUN: opt < %s -loop-rotate -S | FileCheck %s
; RUN: opt < %s -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
target triple = "x86_64-pc-windows-msvc"

View File

@ -1,4 +1,5 @@
; RUN: opt -S -loop-rotate < %s | FileCheck %s
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
@e = global i32 10

View File

@ -1,4 +1,5 @@
; RUN: opt -loop-rotate -disable-output -verify-dom-info -verify-loop-info < %s
; RUN: opt -loop-rotate -disable-output -verify-dom-info -verify-loop-info -enable-mssa-loop-dependency=true -verify-memoryssa < %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,4 +1,5 @@
; RUN: opt -S -loop-rotate < %s | FileCheck %s
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
source_filename = "/tmp/loop.c"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.13.0"

View File

@ -1,4 +1,5 @@
; RUN: opt -S -loop-rotate < %s | FileCheck %s
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -S -loop-rotate -o - -verify-loop-info -verify-dom-info | FileCheck %s
; RUN: opt < %s -S -loop-rotate -o - -verify-loop-info -verify-dom-info -enable-mssa-loop-dependency=true -verify-memoryssa | FileCheck %s
; PR5502
define void @z80_do_opcodes() nounwind {

View File

@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -loop-rotate < %s -verify-loop-info -verify-dom-info | FileCheck %s
; RUN: opt -S -loop-rotate < %s -verify-loop-info -verify-dom-info -enable-mssa-loop-dependency=true -verify-memoryssa | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv8m.base-arm-none-eabi"

View File

@ -1,4 +1,5 @@
; RUN: opt -S -loop-rotate < %s -verify-loop-info -verify-dom-info | FileCheck %s
; RUN: opt -S -loop-rotate < %s -verify-loop-info -verify-dom-info -enable-mssa-loop-dependency=true -verify-memoryssa | 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-S128"
target triple = "x86_64-apple-macosx10.8.0"

View File

@ -1,4 +1,5 @@
; RUN: opt -S -loop-rotate < %s | FileCheck %s
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
;CHECK-LABEL: func
;CHECK-LABEL: entry

View File

@ -1,4 +1,5 @@
; RUN: opt -S -loop-rotate < %s | FileCheck %s
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -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"

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -S | FileCheck %s
; RUN: opt < %s -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
@a = external global i8, align 4
@tmp = global i8* @a

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -disable-output
; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
define void @func() {
bb0:

View File

@ -1,4 +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
;REQUIRES: asserts
; This test is to make sure we invalidate the post dominator pass after loop rotate simplifies the loop latch.
@ -32,6 +33,36 @@
; CHECK-NEXT: Running analysis: PostDominatorTreeAnalysis on f
; CHECK-NEXT: Finished llvm::Function pass manager run.
; MSSA: Starting llvm::Function pass manager run.
; MSSA-NEXT: Running pass: ADCEPass on f
; MSSA-NEXT: Running analysis: PostDominatorTreeAnalysis on f
; MSSA-NEXT: Running pass: FunctionToLoopPassAdaptor{{.*}} on f
; MSSA-NEXT: Starting llvm::Function pass manager run.
; MSSA-NEXT: Running pass: LoopSimplifyPass on f
; MSSA-NEXT: Running analysis: LoopAnalysis on f
; MSSA-NEXT: Running analysis: DominatorTreeAnalysis on f
; MSSA-NEXT: Running analysis: AssumptionAnalysis on f
; MSSA-NEXT: Running pass: LCSSAPass on f
; MSSA-NEXT: Finished llvm::Function pass manager run.
; MSSA-NEXT: Running analysis: MemorySSAAnalysis on f
; MSSA-NEXT: Running analysis: AAManager on f
; MSSA-NEXT: Running analysis: TargetLibraryAnalysis on f
; MSSA-NEXT: Running analysis: ScalarEvolutionAnalysis on f
; MSSA-NEXT: Running analysis: TargetIRAnalysis on f
; MSSA-NEXT: Running analysis: InnerAnalysisManagerProxy{{.*}} on f
; MSSA-NEXT: Starting Loop pass manager run.
; MSSA-NEXT: Running analysis: PassInstrumentationAnalysis on bb
; MSSA-NEXT: Running pass: LoopRotatePass on Loop at depth 1 containing: %bb<header><exiting>,%bb4<latch>
; MSSA-NEXT: Folding loop latch bb4 into bb
; MSSA-NEXT: Invalidating all non-preserved analyses for: bb
; MSSA-NEXT: Finished Loop pass manager run.
; MSSA-NEXT: Invalidating all non-preserved analyses for: f
; MSSA-NEXT: Invalidating analysis: PostDominatorTreeAnalysis on f
; MSSA-NEXT: Running pass: ADCEPass on f
; MSSA-NEXT: Running analysis: PostDominatorTreeAnalysis on f
; MSSA-NEXT: Finished llvm::Function pass manager run.
; CHECK-LABEL: define i8 @f() {
; CHECK-NEXT : entry:
; CHECK-NEXT : br label %bb
@ -52,6 +83,26 @@
; CHECK-NEXT :
; CHECK-NEXT : attributes #0 = { noreturn }
; MSSA-LABEL: define i8 @f() {
; MSSA-NEXT : entry:
; MSSA-NEXT : br label %bb
; MSSA-NEXT :
; MSSA-NEXT : bb: ; preds = %bb, %entry
; MSSA-NEXT : %mode.0 = phi i8 [ 0, %entry ], [ %indvar.next, %bb ]
; MSSA-NEXT : %tmp5 = icmp eq i8 %mode.0, 1
; MSSA-NEXT : %indvar.next = add i8 %mode.0, 1
; MSSA-NEXT : br i1 %tmp5, label %bb5, label %bb
; MSSA-NEXT :
; MSSA-NEXT : bb5: ; preds = %bb
; MSSA-NEXT : tail call void @raise_exception() #0
; MSSA-NEXT : unreachable
; MSSA-NEXT : }
; MSSA-NEXT :
; MSSA-NEXT : ; Function Attrs: noreturn
; MSSA-NEXT : declare void @raise_exception() #0
; MSSA-NEXT :
; MSSA-NEXT : attributes #0 = { noreturn }
define i8 @f() {
entry:
br label %bb

View File

@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -indvars -verify -loop-rotate -loop-idiom < %s | FileCheck %s
; RUN: opt -S -indvars -verify -loop-rotate -loop-idiom -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
; Verify that we invalidate SCEV properly.

View File

@ -0,0 +1,109 @@
; RUN: opt -S -loop-rotate -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
; CHECK-LABEL: @multiedge(
define void @multiedge() {
entry:
br label %retry
retry: ; preds = %sw.epilog, %entry
br i1 undef, label %cleanup, label %if.end
if.end: ; preds = %retry
switch i32 undef, label %sw.epilog [
i32 -3, label %cleanup
i32 -5, label %cleanup
i32 -16, label %cleanup
i32 -25, label %cleanup
]
sw.epilog: ; preds = %if.end
br label %retry
cleanup: ; preds = %if.end, %if.end, %if.end, %if.end, %retry
ret void
}
; CHECK-LABEL: @read_line(
define internal fastcc i32 @read_line(i8* nocapture %f) unnamed_addr {
entry:
br label %for.cond
for.cond: ; preds = %if.end, %entry
%call = call i8* @prepbuffer(i8* nonnull undef)
%call1 = call i8* @fgets(i8* %call, i32 8192, i8* %f)
br i1 undef, label %if.then, label %if.end
if.then: ; preds = %for.cond
ret i32 undef
if.end: ; preds = %for.cond
%call4 = call i64 @strlen(i8* %call)
br label %for.cond
}
declare dso_local i8* @prepbuffer(i8*) local_unnamed_addr
declare dso_local i8* @fgets(i8*, i32, i8* nocapture) local_unnamed_addr
declare dso_local i64 @strlen(i8* nocapture) local_unnamed_addr
; CHECK-LABEL: @loop3
define dso_local fastcc void @loop3() unnamed_addr {
entry:
br label %for.cond
for.cond: ; preds = %for.body, %entry
br i1 undef, label %for.body, label %for.end81
for.body: ; preds = %for.cond
%.idx122.val = load i32, i32* undef, align 8
call fastcc void @cont()
br label %for.cond
for.end81: ; preds = %for.cond
ret void
}
; CHECK-LABEL: @loop4
define dso_local fastcc void @loop4() unnamed_addr {
entry:
br label %while.cond
while.cond: ; preds = %while.body, %entry
br i1 undef, label %while.end, label %while.body
while.body: ; preds = %while.cond
call fastcc void @cont()
br label %while.cond
while.end: ; preds = %while.cond
call fastcc void @cont()
call fastcc void @cont()
ret void
}
; Function Attrs: inlinehint nounwind uwtable
declare dso_local fastcc void @cont() unnamed_addr
@glob_array = internal unnamed_addr constant [3 x i32] [i32 1, i32 0, i32 2], align 4
; Test against failure in MemorySSAUpdater, when rotate clones instructions as Value.
; CHECK-LABEL: @loop5
define dso_local fastcc void @loop5() unnamed_addr {
entry:
br label %for.body
do.cond: ; preds = %for.body
unreachable
for.body: ; preds = %if.end, %entry
%indvar = phi i64 [ %indvar.next, %if.end ], [ 0, %entry ]
%array = getelementptr inbounds [3 x i32], [3 x i32]* @glob_array, i64 0, i64 %indvar
%0 = load i32, i32* %array, align 4
br i1 undef, label %do.cond, label %if.end
if.end: ; preds = %for.body
store i32 undef, i32* undef, align 4
%indvar.next = add nuw nsw i64 %indvar, 1
br label %for.body
}

View File

@ -1,27 +1,48 @@
; RUN: opt < %s -loop-rotate -loop-reduce -verify-dom-info -verify-loop-info -disable-output
; RUN: opt < %s -loop-rotate -loop-reduce -enable-mssa-loop-dependency=true -verify-memoryssa -verify-dom-info -verify-loop-info -disable-output
define fastcc void @foo() nounwind {
define fastcc void @foo(i32* %A, i64 %i) nounwind {
BB:
br label %BB1
BB1: ; preds = %BB19, %BB
%tttmp1 = getelementptr i32, i32* %A, i64 %i
%tttmp2 = load i32, i32* %tttmp1
%tttmp3 = add i32 %tttmp2, 1
store i32 %tttmp3, i32* %tttmp1
br label %BB4
BB2: ; preds = %BB4
%tmp = bitcast i32 undef to i32 ; <i32> [#uses=1]
%tttmp7 = getelementptr i32, i32* %A, i64 %i
%tttmp8 = load i32, i32* %tttmp7
%tttmp9 = add i32 %tttmp8, 3
store i32 %tttmp9, i32* %tttmp7
br label %BB4
BB4: ; preds = %BB3, %BB1
BB4: ; preds = %BB2, %BB1
%tmp5 = phi i32 [ undef, %BB1 ], [ %tmp, %BB2 ] ; <i32> [#uses=1]
%tttmp4 = getelementptr i32, i32* %A, i64 %i
%tttmp5 = load i32, i32* %tttmp4
%tttmp6 = add i32 %tttmp5, 3
store i32 %tttmp6, i32* %tttmp4
br i1 false, label %BB8, label %BB2
BB8: ; preds = %BB6
%tmp7 = bitcast i32 %tmp5 to i32 ; <i32> [#uses=2]
%tttmp10 = getelementptr i32, i32* %A, i64 %i
%tttmp11 = load i32, i32* %tttmp10
%tttmp12 = add i32 %tttmp11, 3
store i32 %tttmp12, i32* %tttmp10
br i1 false, label %BB9, label %BB13
BB9: ; preds = %BB12, %BB8
%tmp10 = phi i32 [ %tmp11, %BB12 ], [ %tmp7, %BB8 ] ; <i32> [#uses=2]
%tmp11 = add i32 %tmp10, 1 ; <i32> [#uses=1]
%tttmp13 = getelementptr i32, i32* %A, i64 %i
%tttmp14 = load i32, i32* %tttmp13
%tttmp15 = add i32 %tttmp14, 3
store i32 %tttmp15, i32* %tttmp13
br label %BB12
BB12: ; preds = %BB9
@ -29,16 +50,28 @@ BB12: ; preds = %BB9
BB13: ; preds = %BB15, %BB8
%tmp14 = phi i32 [ %tmp16, %BB15 ], [ %tmp7, %BB8 ] ; <i32> [#uses=1]
%tttmp16 = getelementptr i32, i32* %A, i64 %i
%tttmp17 = load i32, i32* %tttmp16
%tttmp18 = add i32 %tttmp17, 3
store i32 %tttmp18, i32* %tttmp16
br label %BB15
BB15: ; preds = %BB13
%tmp16 = add i32 %tmp14, -1 ; <i32> [#uses=1]
%tttmp19 = getelementptr i32, i32* %A, i64 %i
%tttmp20 = load i32, i32* %tttmp19
%tttmp21 = add i32 %tttmp20, 3
store i32 %tttmp21, i32* %tttmp19
br i1 false, label %BB13, label %BB18
BB17: ; preds = %BB12
br label %BB19
BB18: ; preds = %BB15
%tttmp22 = getelementptr i32, i32* %A, i64 %i
%tttmp23 = load i32, i32* %tttmp22
%tttmp24 = add i32 %tttmp23, 3
store i32 %tttmp24, i32* %tttmp22
br label %BB19
BB19: ; preds = %BB18, %BB17

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -loop-rotate -S | FileCheck %s
; RUN: opt < %s -loop-rotate -enable-mssa-loop-dependency=true -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-S128"