summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-06-24 19:34:46 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-06-24 19:34:46 +0000
commit3b3e954ea2a48d0d466dec383f6bfa40a90dd0e1 (patch)
tree1aa8c2d5969c527ac4bafc5c71fe4dfd39fa9ae2
parentf15064871ad933370532f068eca70fb5134ba69f (diff)
downloadbcm5719-llvm-3b3e954ea2a48d0d466dec383f6bfa40a90dd0e1.tar.gz
bcm5719-llvm-3b3e954ea2a48d0d466dec383f6bfa40a90dd0e1.zip
SimplifyInstruction does not imply DCE
We cannot remove an instruction with no uses just because SimplifyInstruction succeeds. It may have side effects. llvm-svn: 273711
-rw-r--r--llvm/lib/Transforms/Scalar/EarlyCSE.cpp17
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp21
-rw-r--r--llvm/lib/Transforms/Scalar/JumpThreading.cpp9
-rw-r--r--llvm/lib/Transforms/Scalar/LoopRotation.cpp9
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp8
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp19
-rw-r--r--llvm/lib/Transforms/Utils/LoopUnroll.cpp11
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp13
-rw-r--r--llvm/test/Transforms/GVN/volatile.ll10
9 files changed, 84 insertions, 33 deletions
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 0e93b0a37b0..9d0ef42e039 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -582,11 +582,18 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// its simpler value.
if (Value *V = SimplifyInstruction(Inst, DL, &TLI, &DT, &AC)) {
DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n');
- Inst->replaceAllUsesWith(V);
- Inst->eraseFromParent();
- Changed = true;
- ++NumSimplify;
- continue;
+ if (!Inst->use_empty()) {
+ Inst->replaceAllUsesWith(V);
+ Changed = true;
+ }
+ if (isInstructionTriviallyDead(Inst, &TLI)) {
+ Inst->eraseFromParent();
+ Changed = true;
+ }
+ if (Changed) {
+ ++NumSimplify;
+ continue;
+ }
}
// If this is a simple instruction that we can value number, process it.
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 944e06d4391..a963b2f50ed 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2056,12 +2056,21 @@ bool GVN::processInstruction(Instruction *I) {
// "%z = and i32 %x, %y" becomes "%z = and i32 %x, %x" which we now simplify.
const DataLayout &DL = I->getModule()->getDataLayout();
if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) {
- I->replaceAllUsesWith(V);
- if (MD && V->getType()->getScalarType()->isPointerTy())
- MD->invalidateCachedPointerInfo(V);
- markInstructionForDeletion(I);
- ++NumGVNSimpl;
- return true;
+ bool Changed = false;
+ if (!I->use_empty()) {
+ I->replaceAllUsesWith(V);
+ Changed = true;
+ }
+ if (isInstructionTriviallyDead(I, TLI)) {
+ markInstructionForDeletion(I);
+ Changed = true;
+ }
+ if (Changed) {
+ if (MD && V->getType()->getScalarType()->isPointerTy())
+ MD->invalidateCachedPointerInfo(V);
+ ++NumGVNSimpl;
+ return true;
+ }
}
if (IntrinsicInst *IntrinsicI = dyn_cast<IntrinsicInst>(I))
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 1d8d2a5e469..e7957f9599a 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1746,13 +1746,18 @@ bool JumpThreadingPass::DuplicateCondBranchOnPHIIntoPred(
// phi translation.
if (Value *IV =
SimplifyInstruction(New, BB->getModule()->getDataLayout())) {
- delete New;
ValueMapping[&*BI] = IV;
+ if (!New->mayHaveSideEffects()) {
+ delete New;
+ New = nullptr;
+ }
} else {
+ ValueMapping[&*BI] = New;
+ }
+ if (New) {
// Otherwise, insert the new instruction into the block.
New->setName(BI->getName());
PredBB->getInstList().insert(OldPredBranch->getIterator(), New);
- ValueMapping[&*BI] = New;
}
}
diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
index c6709d5334a..46db8f1210b 100644
--- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
@@ -312,13 +312,18 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
if (V && LI->replacementPreservesLCSSAForm(C, V)) {
// If so, then delete the temporary instruction and stick the folded value
// in the map.
- delete C;
ValueMap[Inst] = V;
+ if (!C->mayHaveSideEffects()) {
+ delete C;
+ C = nullptr;
+ }
} else {
+ ValueMap[Inst] = C;
+ }
+ if (C) {
// Otherwise, stick the new instruction into the new block!
C->setName(Inst->getName());
C->insertBefore(LoopEntryBranch);
- ValueMap[Inst] = C;
}
}
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 6ff05fe3e59..59b109ead63 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -279,6 +279,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
II != IE; ++II) {
Instruction *NewInst = II->clone();
+ VMap[&*II] = NewInst; // Add instruction map to value.
// Eagerly remap operands to the newly cloned instruction, except for PHI
// nodes for which we defer processing until we update the CFG.
@@ -297,14 +298,15 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
V = MappedV;
VMap[&*II] = V;
- delete NewInst;
- continue;
+ if (!NewInst->mayHaveSideEffects()) {
+ delete NewInst;
+ continue;
+ }
}
}
if (II->hasName())
NewInst->setName(II->getName()+NameSuffix);
- VMap[&*II] = NewInst; // Add instruction map to value.
NewBB->getInstList().push_back(NewInst);
hasCalls |= (isa<CallInst>(II) && !isa<DbgInfoIntrinsic>(II));
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 4f8935dd971..4d76aae2971 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -456,14 +456,23 @@ simplifyAndDCEInstruction(Instruction *I,
if (Value *SimpleV = SimplifyInstruction(I, DL)) {
// Add the users to the worklist. CAREFUL: an instruction can use itself,
// in the case of a phi node.
- for (User *U : I->users())
- if (U != I)
+ for (User *U : I->users()) {
+ if (U != I) {
WorkList.insert(cast<Instruction>(U));
+ }
+ }
// Replace the instruction with its simplified value.
- I->replaceAllUsesWith(SimpleV);
- I->eraseFromParent();
- return true;
+ bool Changed = false;
+ if (!I->use_empty()) {
+ I->replaceAllUsesWith(SimpleV);
+ Changed = true;
+ }
+ if (isInstructionTriviallyDead(I, TLI)) {
+ I->eraseFromParent();
+ Changed = true;
+ }
+ return Changed;
}
return false;
}
diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
index f7e5c0c49f8..9e53b1c2647 100644
--- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -623,18 +623,17 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
// go.
const DataLayout &DL = Header->getModule()->getDataLayout();
const std::vector<BasicBlock*> &NewLoopBlocks = L->getBlocks();
- for (BasicBlock *BB : NewLoopBlocks)
+ for (BasicBlock *BB : NewLoopBlocks) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
Instruction *Inst = &*I++;
+ if (Value *V = SimplifyInstruction(Inst, DL))
+ if (LI->replacementPreservesLCSSAForm(Inst, V))
+ Inst->replaceAllUsesWith(V);
if (isInstructionTriviallyDead(Inst))
BB->getInstList().erase(Inst);
- else if (Value *V = SimplifyInstruction(Inst, DL))
- if (LI->replacementPreservesLCSSAForm(Inst, V)) {
- Inst->replaceAllUsesWith(V);
- BB->getInstList().erase(Inst);
- }
}
+ }
NumCompletelyUnrolled += CompletelyUnroll;
++NumUnrolled;
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 6e1ac2c9a69..d22f5c63dee 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1885,14 +1885,19 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, const DataLayout &DL) {
// Check for trivial simplification.
if (Value *V = SimplifyInstruction(N, DL)) {
- TranslateMap[&*BBI] = V;
- delete N; // Instruction folded away, don't need actual inst
+ if (!BBI->use_empty())
+ TranslateMap[&*BBI] = V;
+ if (!N->mayHaveSideEffects()) {
+ delete N; // Instruction folded away, don't need actual inst
+ N = nullptr;
+ }
} else {
- // Insert the new instruction into its new home.
- EdgeBB->getInstList().insert(InsertPt, N);
if (!BBI->use_empty())
TranslateMap[&*BBI] = N;
}
+ // Insert the new instruction into its new home.
+ if (N)
+ EdgeBB->getInstList().insert(InsertPt, N);
}
// Loop over all of the edges from PredBB to BB, changing them to branch
diff --git a/llvm/test/Transforms/GVN/volatile.ll b/llvm/test/Transforms/GVN/volatile.ll
index b31058db4ea..ccc5bbfa48e 100644
--- a/llvm/test/Transforms/GVN/volatile.ll
+++ b/llvm/test/Transforms/GVN/volatile.ll
@@ -152,6 +152,16 @@ exit:
ret i32 %add
}
+define i32 @test9(i32* %V) {
+entry:
+ %load = load volatile i32, i32* %V, !range !0
+ ret i32 %load
+}
+; CHECK-LABEL: test9
+; CHECK: load volatile
+; CHECK: ret i32 0
+
declare void @use(i32) readonly
declare void @clobber(i32* %p, i32* %q)
+!0 = !{ i32 0, i32 1 }
OpenPOWER on IntegriCloud