mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-22 05:21:13 +00:00
[IndVarSimplify] Fix for MemorySSA preserve.
This commit is contained in:
parent
0b827d4aa9
commit
22d4f4cbf9
@ -79,7 +79,8 @@ void FoldSingleEntryPHINodes(BasicBlock *BB,
|
||||
/// recursively delete any operands that become dead as a result. This includes
|
||||
/// tracing the def-use list from the PHI to see if it is ultimately unused or
|
||||
/// if it reaches an unused cycle. Return true if any PHIs were deleted.
|
||||
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr);
|
||||
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
|
||||
/// Attempts to merge a block into its predecessor, if possible. The return
|
||||
/// value indicates success or failure.
|
||||
|
@ -162,7 +162,8 @@ void RecursivelyDeleteTriviallyDeadInstructions(
|
||||
/// operands trivially dead, delete them too, recursively. Return true if a
|
||||
/// change was made.
|
||||
bool RecursivelyDeleteDeadPHINode(PHINode *PN,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
|
||||
/// Scan the specified basic block and try to simplify any instructions in it
|
||||
/// and recursively delete dead instructions.
|
||||
|
@ -2781,7 +2781,8 @@ bool IndVarSimplify::run(Loop *L) {
|
||||
while (!DeadInsts.empty())
|
||||
if (Instruction *Inst =
|
||||
dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val()))
|
||||
Changed |= RecursivelyDeleteTriviallyDeadInstructions(Inst, TLI);
|
||||
Changed |=
|
||||
RecursivelyDeleteTriviallyDeadInstructions(Inst, TLI, MSSAU.get());
|
||||
|
||||
// The Rewriter may not be used from this point on.
|
||||
|
||||
@ -2795,7 +2796,7 @@ bool IndVarSimplify::run(Loop *L) {
|
||||
Changed |= rewriteFirstIterationLoopExitValues(L);
|
||||
|
||||
// Clean up dead instructions.
|
||||
Changed |= DeleteDeadPHIs(L->getHeader(), TLI);
|
||||
Changed |= DeleteDeadPHIs(L->getHeader(), TLI, MSSAU.get());
|
||||
|
||||
// Check a post-condition.
|
||||
assert(L->isRecursivelyLCSSAForm(*DT, *LI) &&
|
||||
@ -2818,6 +2819,8 @@ bool IndVarSimplify::run(Loop *L) {
|
||||
assert(!SE->isKnownPredicate(ICmpInst::ICMP_ULT, BackedgeTakenCount,
|
||||
NewBECount) && "indvars must preserve SCEV");
|
||||
}
|
||||
if (VerifyMemorySSA && MSSAU)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
#endif
|
||||
|
||||
return Changed;
|
||||
|
@ -153,7 +153,8 @@ void llvm::FoldSingleEntryPHINodes(BasicBlock *BB,
|
||||
}
|
||||
}
|
||||
|
||||
bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) {
|
||||
bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI,
|
||||
MemorySSAUpdater *MSSAU) {
|
||||
// Recursively deleting a PHI may cause multiple PHIs to be deleted
|
||||
// or RAUW'd undef, so use an array of WeakTrackingVH for the PHIs to delete.
|
||||
SmallVector<WeakTrackingVH, 8> PHIs;
|
||||
@ -163,7 +164,7 @@ bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) {
|
||||
bool Changed = false;
|
||||
for (unsigned i = 0, e = PHIs.size(); i != e; ++i)
|
||||
if (PHINode *PN = dyn_cast_or_null<PHINode>(PHIs[i].operator Value*()))
|
||||
Changed |= RecursivelyDeleteDeadPHINode(PN, TLI);
|
||||
Changed |= RecursivelyDeleteDeadPHINode(PN, TLI, MSSAU);
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
@ -521,19 +521,20 @@ static bool areAllUsesEqual(Instruction *I) {
|
||||
/// delete it. If that makes any of its operands trivially dead, delete them
|
||||
/// too, recursively. Return true if a change was made.
|
||||
bool llvm::RecursivelyDeleteDeadPHINode(PHINode *PN,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
const TargetLibraryInfo *TLI,
|
||||
llvm::MemorySSAUpdater *MSSAU) {
|
||||
SmallPtrSet<Instruction*, 4> Visited;
|
||||
for (Instruction *I = PN; areAllUsesEqual(I) && !I->mayHaveSideEffects();
|
||||
I = cast<Instruction>(*I->user_begin())) {
|
||||
if (I->use_empty())
|
||||
return RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
|
||||
return RecursivelyDeleteTriviallyDeadInstructions(I, TLI, MSSAU);
|
||||
|
||||
// If we find an instruction more than once, we're on a cycle that
|
||||
// won't prove fruitful.
|
||||
if (!Visited.insert(I).second) {
|
||||
// Break the cycle and delete the instruction and its operands.
|
||||
I->replaceAllUsesWith(UndefValue::get(I->getType()));
|
||||
(void)RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
|
||||
(void)RecursivelyDeleteTriviallyDeadInstructions(I, TLI, MSSAU);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
21
test/Transforms/IndVarSimplify/preserve-memoryssa.ll
Normal file
21
test/Transforms/IndVarSimplify/preserve-memoryssa.ll
Normal file
@ -0,0 +1,21 @@
|
||||
; RUN: opt -S -licm -indvars -verify-memoryssa < %s | FileCheck %s
|
||||
; REQUIRES: asserts
|
||||
@v_69 = external constant { i16, i16 }, align 1
|
||||
|
||||
; CHECK-LABEL: @f()
|
||||
define void @f() {
|
||||
entry:
|
||||
br label %for.cond26
|
||||
|
||||
for.cond26: ; preds = %for.body28, %entry
|
||||
br i1 true, label %for.body28, label %for.cond.cleanup27
|
||||
|
||||
for.cond.cleanup27: ; preds = %for.cond26
|
||||
unreachable
|
||||
|
||||
for.body28: ; preds = %for.cond26
|
||||
%v_69.imag = load volatile i16, i16* getelementptr inbounds ({ i16, i16 }, { i16, i16 }* @v_69, i32 0, i32 1), align 1
|
||||
%.real42 = load i32, i32* undef, align 1
|
||||
store i32 %.real42, i32* undef, align 1
|
||||
br label %for.cond26
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user