[llvm] r255354 - Revert r255247, r255265, and r255286 due to serious compile-time regressions.
Chad Rosier via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 11 10:39:41 PST 2015
Author: mcrosier
Date: Fri Dec 11 12:39:41 2015
New Revision: 255354
URL: http://llvm.org/viewvc/llvm-project?rev=255354&view=rev
Log:
Revert r255247, r255265, and r255286 due to serious compile-time regressions.
Revert "[DSE] Disable non-local DSE to see if the bots go green."
Revert "[DeadStoreElimination] Use range-based loops. NFC."
Revert "[DeadStoreElimination] Add support for non-local DSE."
Removed:
llvm/trunk/test/Transforms/DeadStoreElimination/cycle.ll
llvm/trunk/test/Transforms/DeadStoreElimination/ifthen.ll
llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse.ll
llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse2.ll
llvm/trunk/test/Transforms/DeadStoreElimination/loop.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=255354&r1=255353&r2=255354&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Dec 11 12:39:41 2015
@@ -7,8 +7,11 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements dead store elimination that considers redundant stores
-// within a basic-block as well as across basic blocks in a reverse CFG order.
+// This file implements a trivial dead store elimination that only considers
+// basic-block local redundant stores.
+//
+// FIXME: This should eventually be extended to be a post-dominator tree
+// traversal. Doing so would be pretty trivial.
//
//===----------------------------------------------------------------------===//
@@ -41,13 +44,6 @@ using namespace llvm;
STATISTIC(NumRedundantStores, "Number of redundant stores deleted");
STATISTIC(NumFastStores, "Number of stores deleted");
STATISTIC(NumFastOther , "Number of other instrs removed");
-STATISTIC(NumNonLocalStores, "Number of non-local stores deleted");
-
-static cl::opt<bool> EnableNonLocalDSE("enable-nonlocal-dse", cl::init(false));
-
-/// MaxNonLocalAttempts is an arbitrary threshold that provides
-/// an early opportunitiy for bail out to control compile time.
-static const unsigned MaxNonLocalAttempts = 100;
namespace {
struct DSE : public FunctionPass {
@@ -84,7 +80,6 @@ namespace {
bool runOnBasicBlock(BasicBlock &BB);
bool MemoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI);
bool HandleFree(CallInst *F);
- bool handleNonLocalDependency(Instruction *Inst);
bool handleEndBlock(BasicBlock &BB);
void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,
SmallSetVector<Value *, 16> &DeadStackObjects,
@@ -490,7 +485,6 @@ static bool isPossibleSelfRead(Instructi
bool DSE::runOnBasicBlock(BasicBlock &BB) {
const DataLayout &DL = BB.getModule()->getDataLayout();
bool MadeChange = false;
- unsigned NumNonLocalAttempts = 0;
// Do a top-down walk on the BB.
for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ) {
@@ -560,250 +554,107 @@ bool DSE::runOnBasicBlock(BasicBlock &BB
MemDepResult InstDep = MD->getDependency(Inst);
- if (InstDep.isDef() || InstDep.isClobber()) {
- // Figure out what location is being stored to.
- MemoryLocation Loc = getLocForWrite(Inst, *AA);
-
- // If we didn't get a useful location, fail.
- if (!Loc.Ptr)
- continue;
-
- while (InstDep.isDef() || InstDep.isClobber()) {
- // Get the memory clobbered by the instruction we depend on. MemDep
- // will skip any instructions that 'Loc' clearly doesn't interact with.
- // If we end up depending on a may- or must-aliased load, then we can't
- // optimize away the store and we bail out. However, if we depend on on
- // something that overwrites the memory location we *can* potentially
- // optimize it.
- //
- // Find out what memory location the dependent instruction stores.
- Instruction *DepWrite = InstDep.getInst();
- MemoryLocation DepLoc = getLocForWrite(DepWrite, *AA);
- // If we didn't get a useful location, or if it isn't a size, bail out.
- if (!DepLoc.Ptr)
- break;
-
- // If we find a write that is a) removable (i.e., non-volatile), b) is
- // completely obliterated by the store to 'Loc', and c) which we know
- // that 'Inst' doesn't load from, then we can remove it.
- if (isRemovable(DepWrite) &&
- !isPossibleSelfRead(Inst, Loc, DepWrite, *TLI, *AA)) {
- int64_t InstWriteOffset, DepWriteOffset;
- OverwriteResult OR = isOverwrite(Loc, DepLoc, DL, *TLI,
- DepWriteOffset, InstWriteOffset);
- if (OR == OverwriteComplete) {
- DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *DepWrite
- << "\n KILLER: " << *Inst << '\n');
-
- // Delete the store and now-dead instructions that feed it.
- DeleteDeadInstruction(DepWrite, *MD, *TLI);
- ++NumFastStores;
- MadeChange = true;
-
- // DeleteDeadInstruction can delete the current instruction in loop
- // cases, reset BBI.
- BBI = Inst->getIterator();
- if (BBI != BB.begin())
- --BBI;
- break;
- } else if (OR == OverwriteEnd && isShortenable(DepWrite)) {
- // TODO: base this on the target vector size so that if the earlier
- // store was too small to get vector writes anyway then its likely a
- // good idea to shorten it.
-
- // Power of 2 vector writes are probably always a bad idea to
- // optimize as any store/memset/memcpy is likely using vector
- // instructions so shortening it to not vector size is likely to be
- // slower.
- MemIntrinsic *DepIntrinsic = cast<MemIntrinsic>(DepWrite);
- unsigned DepWriteAlign = DepIntrinsic->getAlignment();
- if (llvm::isPowerOf2_64(InstWriteOffset) ||
- ((DepWriteAlign != 0) &&
- InstWriteOffset % DepWriteAlign == 0)) {
-
- DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW END: " << *DepWrite
- << "\n KILLER (offset " << InstWriteOffset << ", "
- << DepLoc.Size << ")" << *Inst << '\n');
-
- Value *DepWriteLength = DepIntrinsic->getLength();
- Value *TrimmedLength = ConstantInt::get(
- DepWriteLength->getType(), InstWriteOffset - DepWriteOffset);
- DepIntrinsic->setLength(TrimmedLength);
- MadeChange = true;
- }
- }
- }
-
- // If this is a may-aliased store that is clobbering the store value, we
- // can keep searching past it for another must-aliased pointer that
- // stores to the same location. For example, in
- // store -> P
- // store -> Q
- // store -> P
- // we can remove the first store to P even though we don't know if P and
- // Q alias.
- if (DepWrite == &BB.front())
- break;
-
- // Can't look past this instruction if it might read 'Loc'.
- if (AA->getModRefInfo(DepWrite, Loc) & MRI_Ref)
- break;
-
- InstDep = MD->getPointerDependencyFrom(Loc, false,
- DepWrite->getIterator(), &BB);
- }
- } else if (EnableNonLocalDSE && InstDep.isNonLocal()) { // DSE across BB
- if (++NumNonLocalAttempts < MaxNonLocalAttempts)
- MadeChange |= handleNonLocalDependency(Inst);
- }
- }
-
- // If this block ends in a return, unwind, or unreachable, all allocas are
- // dead at its end, which means stores to them are also dead.
- if (BB.getTerminator()->getNumSuccessors() == 0)
- MadeChange |= handleEndBlock(BB);
+ // Ignore any store where we can't find a local dependence.
+ // FIXME: cross-block DSE would be fun. :)
+ if (!InstDep.isDef() && !InstDep.isClobber())
+ continue;
- return MadeChange;
-}
+ // Figure out what location is being stored to.
+ MemoryLocation Loc = getLocForWrite(Inst, *AA);
-/// A helper for handleNonLocalDependency() function to find all blocks
-/// that lead to the input block BB and append them to the output PredBlocks.
-/// PredBlocks will include not only predecessors of BB that unconditionally
-/// lead to BB but also:
-/// - single-block loops that lead to BB, and
-/// - if-blocks for which one edge goes to BB and the other edge goes to
-/// a block in the input SafeBlocks.
-/// PredBlocks will not include blocks unreachable from the entry block, nor
-/// blocks that form cycles with BB.
-static void findSafePreds(SmallVectorImpl<BasicBlock *> &PredBlocks,
- SmallSetVector<BasicBlock *, 8> &SafeBlocks,
- BasicBlock *BB, DominatorTree *DT) {
- for (auto *Pred : predecessors(BB)) {
- if (Pred == BB)
- continue;
- // The second check below prevents adding blocks that form a cycle with BB
- // in order to avoid potential problems due to MemoryDependenceAnalysis,
- // isOverwrite, etc. being not loop-aware.
- if (!DT->isReachableFromEntry(Pred) || DT->dominates(BB, Pred))
+ // If we didn't get a useful location, fail.
+ if (!Loc.Ptr)
continue;
- bool PredIsSafe = true;
- for (auto *Succ : successors(Pred)) {
- if (Succ == BB || Succ == Pred) // shortcut, BB should be in SafeBlocks
- continue;
- if (!SafeBlocks.count(Succ)) {
- PredIsSafe = false;
+ while (InstDep.isDef() || InstDep.isClobber()) {
+ // Get the memory clobbered by the instruction we depend on. MemDep will
+ // skip any instructions that 'Loc' clearly doesn't interact with. If we
+ // end up depending on a may- or must-aliased load, then we can't optimize
+ // away the store and we bail out. However, if we depend on on something
+ // that overwrites the memory location we *can* potentially optimize it.
+ //
+ // Find out what memory location the dependent instruction stores.
+ Instruction *DepWrite = InstDep.getInst();
+ MemoryLocation DepLoc = getLocForWrite(DepWrite, *AA);
+ // If we didn't get a useful location, or if it isn't a size, bail out.
+ if (!DepLoc.Ptr)
break;
- }
- }
- if (PredIsSafe)
- PredBlocks.push_back(Pred);
- }
-}
-
-static bool underlyingObjectsDoNotAlias(StoreInst *SI, LoadInst *LI,
- const DataLayout &DL,
- AliasAnalysis &AA) {
- Value *AObj = GetUnderlyingObject(SI->getPointerOperand(), DL);
- SmallVector<Value *, 4> Pointers;
- GetUnderlyingObjects(LI->getPointerOperand(), Pointers, DL);
-
- for (auto *BObj : Pointers) {
- if (!AA.isNoAlias(AObj, DL.getTypeStoreSize(AObj->getType()), BObj,
- DL.getTypeStoreSize(BObj->getType())))
- return false;
- }
- return true;
-}
-/// handleNonLocalDependency - Handle a non-local dependency on
-/// the input instruction Inst located in BB in attempt to remove
-/// redundant stores outside BB.
-bool DSE::handleNonLocalDependency(Instruction *Inst) {
- auto *SI = dyn_cast<StoreInst>(Inst);
- if (!SI)
- return false;
- // Get the location being stored to.
- // If we don't get a useful location, bail out.
- MemoryLocation Loc = getLocForWrite(SI, *AA);
- if (!Loc.Ptr)
- return false;
-
- bool MadeChange = false;
- BasicBlock *BB = Inst->getParent();
- const DataLayout &DL = BB->getModule()->getDataLayout();
-
- // Worklist of predecessor blocks of BB
- SmallVector<BasicBlock *, 8> Blocks;
- // Keep track of all predecessor blocks that are safe to search through
- SmallSetVector<BasicBlock *, 8> SafeBlocks;
- SafeBlocks.insert(BB);
- findSafePreds(Blocks, SafeBlocks, BB, DT);
-
- while (!Blocks.empty()) {
- BasicBlock *PB = Blocks.pop_back_val();
- MemDepResult Dep =
- MD->getPointerDependencyFrom(Loc, false, PB->end(), PB, SI);
- while (Dep.isDef() || Dep.isClobber()) {
- Instruction *Dependency = Dep.getInst();
-
- // Filter out false dependency from a load to SI looking through phis.
- if (auto *LI = dyn_cast<LoadInst>(Dependency)) {
- if (underlyingObjectsDoNotAlias(SI, LI, DL, *AA)) {
- Dep = MD->getPointerDependencyFrom(Loc, false,
- Dependency->getIterator(), PB, SI);
- continue;
+ // If we find a write that is a) removable (i.e., non-volatile), b) is
+ // completely obliterated by the store to 'Loc', and c) which we know that
+ // 'Inst' doesn't load from, then we can remove it.
+ if (isRemovable(DepWrite) &&
+ !isPossibleSelfRead(Inst, Loc, DepWrite, *TLI, *AA)) {
+ int64_t InstWriteOffset, DepWriteOffset;
+ OverwriteResult OR =
+ isOverwrite(Loc, DepLoc, DL, *TLI, DepWriteOffset, InstWriteOffset);
+ if (OR == OverwriteComplete) {
+ DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: "
+ << *DepWrite << "\n KILLER: " << *Inst << '\n');
+
+ // Delete the store and now-dead instructions that feed it.
+ DeleteDeadInstruction(DepWrite, *MD, *TLI);
+ ++NumFastStores;
+ MadeChange = true;
+
+ // DeleteDeadInstruction can delete the current instruction in loop
+ // cases, reset BBI.
+ BBI = Inst->getIterator();
+ if (BBI != BB.begin())
+ --BBI;
+ break;
+ } else if (OR == OverwriteEnd && isShortenable(DepWrite)) {
+ // TODO: base this on the target vector size so that if the earlier
+ // store was too small to get vector writes anyway then its likely
+ // a good idea to shorten it
+ // Power of 2 vector writes are probably always a bad idea to optimize
+ // as any store/memset/memcpy is likely using vector instructions so
+ // shortening it to not vector size is likely to be slower
+ MemIntrinsic* DepIntrinsic = cast<MemIntrinsic>(DepWrite);
+ unsigned DepWriteAlign = DepIntrinsic->getAlignment();
+ if (llvm::isPowerOf2_64(InstWriteOffset) ||
+ ((DepWriteAlign != 0) && InstWriteOffset % DepWriteAlign == 0)) {
+
+ DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW END: "
+ << *DepWrite << "\n KILLER (offset "
+ << InstWriteOffset << ", "
+ << DepLoc.Size << ")"
+ << *Inst << '\n');
+
+ Value* DepWriteLength = DepIntrinsic->getLength();
+ Value* TrimmedLength = ConstantInt::get(DepWriteLength->getType(),
+ InstWriteOffset -
+ DepWriteOffset);
+ DepIntrinsic->setLength(TrimmedLength);
+ MadeChange = true;
+ }
}
}
- // If we don't get a useful location for the dependent instruction,
- // it doesn't write memory, it is not removable, or it might read Loc,
- // then bail out.
- MemoryLocation DepLoc = getLocForWrite(Dependency, *AA);
- if (!DepLoc.Ptr || !hasMemoryWrite(Dependency, *TLI) ||
- !isRemovable(Dependency) ||
- (AA->getModRefInfo(Dependency, Loc) & MRI_Ref))
- break;
+ // If this is a may-aliased store that is clobbering the store value, we
+ // can keep searching past it for another must-aliased pointer that stores
+ // to the same location. For example, in:
+ // store -> P
+ // store -> Q
+ // store -> P
+ // we can remove the first store to P even though we don't know if P and Q
+ // alias.
+ if (DepWrite == &BB.front()) break;
- // Don't remove a store within single-block loops;
- // we need more analysis: e.g. looking for an interferring load
- // above the store within the loop, etc.
- bool SingleBlockLoop = false;
- for (auto I = succ_begin(PB), E = succ_end(PB); I != E; ++I) {
- BasicBlock *Succ = *I;
- if (Succ == PB) {
- SingleBlockLoop = true;
- break;
- }
- }
- if (SingleBlockLoop)
+ // Can't look past this instruction if it might read 'Loc'.
+ if (AA->getModRefInfo(DepWrite, Loc) & MRI_Ref)
break;
- int64_t InstWriteOffset, DepWriteOffset;
- OverwriteResult OR =
- isOverwrite(Loc, DepLoc, DL, *TLI, DepWriteOffset, InstWriteOffset);
- if (OR == OverwriteComplete) {
- DEBUG(dbgs() << "DSE: Remove Non-Local Dead Store:\n DEAD: "
- << *Dependency << "\n KILLER: " << *SI << '\n');
-
- // Delete redundant store and now-dead instructions that feed it.
- auto Next = std::next(Dependency->getIterator());
- DeleteDeadInstruction(Dependency, *MD, *TLI);
- ++NumNonLocalStores;
- MadeChange = true;
- Dep = MD->getPointerDependencyFrom(Loc, false, Next, PB, SI);
- continue;
- }
- // TODO: attempt shortening of Dependency inst as in the local case
- break;
- }
-
- if (Dep.isNonLocal()) {
- SafeBlocks.insert(PB);
- findSafePreds(Blocks, SafeBlocks, PB, DT);
+ InstDep = MD->getPointerDependencyFrom(Loc, false,
+ DepWrite->getIterator(), &BB);
}
}
+ // If this block ends in a return, unwind, or unreachable, all allocas are
+ // dead at its end, which means stores to them are also dead.
+ if (BB.getTerminator()->getNumSuccessors() == 0)
+ MadeChange |= handleEndBlock(BB);
+
return MadeChange;
}
@@ -855,10 +706,10 @@ bool DSE::MemoryIsNotModifiedBetween(Ins
if (B != FirstBB) {
assert(B != &FirstBB->getParent()->getEntryBlock() &&
"Should not hit the entry block because SI must be dominated by LI");
- for (auto *PredI : predecessors(B)) {
- if (!Visited.insert(PredI).second)
+ for (auto PredI = pred_begin(B), PE = pred_end(B); PredI != PE; ++PredI) {
+ if (!Visited.insert(*PredI).second)
continue;
- WorkList.push_back(PredI);
+ WorkList.push_back(*PredI);
}
}
}
Removed: llvm/trunk/test/Transforms/DeadStoreElimination/cycle.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/cycle.ll?rev=255353&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/cycle.ll (original)
+++ llvm/trunk/test/Transforms/DeadStoreElimination/cycle.ll (removed)
@@ -1,26 +0,0 @@
-; RUN: opt < %s -basicaa -dse -S | FileCheck %s
-
- at Table = global [535 x i32] zeroinitializer, align 4
-
-; The store in for.inc block should NOT be removed by non-local DSE.
-; CHECK: store i32 64, i32* %arrayidx
-;
-define void @foo() {
-entry:
- br label %for.body
-
-for.body:
- %i = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
- %arrayidx = getelementptr inbounds [535 x i32], [535 x i32]* @Table, i32 0, i32 %i
- store i32 %i, i32* %arrayidx, align 4
- %cmp1 = icmp slt i32 %i, 64
- br i1 %cmp1, label %for.inc, label %for.end
-
-for.inc:
- store i32 64, i32* %arrayidx, align 4
- %inc = add nsw i32 %i, 1
- br label %for.body
-
-for.end:
- ret void
-}
Removed: llvm/trunk/test/Transforms/DeadStoreElimination/ifthen.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/ifthen.ll?rev=255353&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/ifthen.ll (original)
+++ llvm/trunk/test/Transforms/DeadStoreElimination/ifthen.ll (removed)
@@ -1,22 +0,0 @@
-; RUN: opt < %s -basicaa -dse -enable-nonlocal-dse -S | FileCheck %s
-
-; The store and add in if.then block should be removed by non-local DSE.
-; CHECK-NOT: %stval = add
-; CHECK-NOT: store i32 %stval
-;
-define void @foo(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32 %c) {
-entry:
- %cmp = icmp sgt i32 %c, 0
- br i1 %cmp, label %if.then, label %if.end
-
-if.then:
- %0 = load i32, i32* %b, align 4
- %stval = add nsw i32 %0, 1
- store i32 %stval, i32* %a, align 4
- br label %if.end
-
-if.end:
- %m.0 = phi i32 [ 13, %if.then ], [ 10, %entry ]
- store i32 %m.0, i32* %a, align 4
- ret void
-}
Removed: llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse.ll?rev=255353&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse.ll (original)
+++ llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse.ll (removed)
@@ -1,27 +0,0 @@
-; RUN: opt < %s -basicaa -dse -enable-nonlocal-dse -S | FileCheck %s
-
-; The add and store in entry block should be removed by non-local DSE.
-; CHECK-NOT: %stval = add
-; CHECK-NOT: store i32 %stval
-;
-define void @foo(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32 %c) {
-entry:
- %0 = load i32, i32* %b, align 4
- %stval = add nsw i32 %0, 1
- store i32 %stval, i32* %a, align 4
- %cmp = icmp sgt i32 %c, 0
- br i1 %cmp, label %if.then, label %if.else
-
-if.then:
- %1 = add nsw i32 %c, 10
- br label %if.end
-
-if.else:
- %2 = add nsw i32 %c, 13
- br label %if.end
-
-if.end:
- %3 = phi i32 [ %1, %if.then ], [ %2, %if.else ]
- store i32 %3, i32* %a, align 4
- ret void
-}
Removed: llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse2.ll?rev=255353&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse2.ll (original)
+++ llvm/trunk/test/Transforms/DeadStoreElimination/ifthenelse2.ll (removed)
@@ -1,34 +0,0 @@
-; RUN: opt < %s -basicaa -dse -enable-nonlocal-dse -S | FileCheck %s
-
-; The add and store in entry block should be removed by non-local DSE.
-; CHECK-NOT: %stval = add
-; CHECK-NOT: store i32 %stval
-;
-; The stores in if.then and if.else blocks should be removed by non-local DSE.
-; CHECK-NOT: store i32 %1
-; CHECK-NOT: store i32 %2
-;
-define void @foo(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32 %c) {
-entry:
- %0 = load i32, i32* %b, align 4
- %stval = add nsw i32 %0, 1
- store i32 %stval, i32* %a, align 4
- %cmp = icmp sgt i32 %c, 0
- br i1 %cmp, label %if.then, label %if.else
-
-if.then:
- %1 = add nsw i32 %c, 10
- store i32 %1, i32* %a, align 4
- br label %if.end
-
-if.else:
- %2 = add nsw i32 %c, 13
- store i32 %2, i32* %a, align 4
- br label %if.end
-
-if.end:
- %3 = phi i32 [ %1, %if.then ], [ %2, %if.else ]
- %4 = sub nsw i32 %3, 6
- store i32 %4, i32* %a, align 4
- ret void
-}
Removed: llvm/trunk/test/Transforms/DeadStoreElimination/loop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/loop.ll?rev=255353&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/loop.ll (original)
+++ llvm/trunk/test/Transforms/DeadStoreElimination/loop.ll (removed)
@@ -1,42 +0,0 @@
-; RUN: opt < %s -basicaa -dse -enable-nonlocal-dse -S | FileCheck %s
-
-; The store in for.body block should be removed by non-local DSE.
-; CHECK-NOT: store i32 0, i32* %arrayidx
-;
-define void @sum(i32 %N, i32* noalias nocapture %C, i32* noalias nocapture readonly %A, i32* noalias nocapture readonly %B) {
-entry:
- %cmp24 = icmp eq i32 %N, 0
- br i1 %cmp24, label %for.end11, label %for.body
-
-for.body:
- %i.025 = phi i32 [ %inc10, %for.cond1.for.inc9_crit_edge ], [ 0, %entry ]
- %arrayidx = getelementptr inbounds i32, i32* %C, i32 %i.025
- store i32 0, i32* %arrayidx, align 4
- %mul = mul i32 %i.025, %N
- %arrayidx4.gep = getelementptr i32, i32* %A, i32 %mul
- br label %for.body3
-
-for.body3:
- %0 = phi i32 [ 0, %for.body ], [ %add8, %for.body3 ]
- %arrayidx4.phi = phi i32* [ %arrayidx4.gep, %for.body ], [ %arrayidx4.inc, %for.body3 ]
- %arrayidx5.phi = phi i32* [ %B, %for.body ], [ %arrayidx5.inc, %for.body3 ]
- %j.023 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ]
- %1 = load i32, i32* %arrayidx4.phi, align 4
- %2 = load i32, i32* %arrayidx5.phi, align 4
- %add6 = add nsw i32 %2, %1
- %add8 = add nsw i32 %add6, %0
- %inc = add i32 %j.023, 1
- %exitcond = icmp ne i32 %inc, %N
- %arrayidx4.inc = getelementptr i32, i32* %arrayidx4.phi, i32 1
- %arrayidx5.inc = getelementptr i32, i32* %arrayidx5.phi, i32 1
- br i1 %exitcond, label %for.body3, label %for.cond1.for.inc9_crit_edge
-
-for.cond1.for.inc9_crit_edge:
- store i32 %add8, i32* %arrayidx, align 4
- %inc10 = add i32 %i.025, 1
- %exitcond26 = icmp ne i32 %inc10, %N
- br i1 %exitcond26, label %for.body, label %for.end11
-
-for.end11:
- ret void
-}
More information about the llvm-commits
mailing list