From 909793fa63414e6928cbd56c7f3b1171d55460a7 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 4 Aug 2016 04:24:02 +0000 Subject: [PATCH] Reinstate "[CloneFunction] Don't remove side effecting calls" This reinstates r277611 + r277614 and reverts r277642. A cast_or_null should have been a dyn_cast_or_null. llvm-svn: 277691 --- llvm/lib/Analysis/InstructionSimplify.cpp | 6 ++-- llvm/lib/Transforms/Utils/CloneFunction.cpp | 35 +++++++++++++++++-- .../Transforms/Inline/inline_constprop.ll | 22 ++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 5b723e597429..ac03fdc86e67 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4356,7 +4356,8 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV, // Gracefully handle edge cases where the instruction is not wired into any // parent block. - if (I->getParent()) + if (I->getParent() && !I->isEHPad() && !isa(I) && + !I->mayHaveSideEffects()) I->eraseFromParent(); } else { Worklist.insert(I); @@ -4384,7 +4385,8 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV, // Gracefully handle edge cases where the instruction is not wired into any // parent block. - if (I->getParent()) + if (I->getParent() && !I->isEHPad() && !isa(I) && + !I->mayHaveSideEffects()) I->eraseFromParent(); } return Simplified; diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index c5ca56360fc8..4f0088246ea9 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -552,9 +553,39 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, // two PHINodes, the iteration over the old PHIs remains valid, and the // mapping will just map us to the new node (which may not even be a PHI // node). + const DataLayout &DL = NewFunc->getParent()->getDataLayout(); + SmallSetVector Worklist; for (unsigned Idx = 0, Size = PHIToResolve.size(); Idx != Size; ++Idx) - if (PHINode *PN = dyn_cast(VMap[PHIToResolve[Idx]])) - recursivelySimplifyInstruction(PN); + if (isa(VMap[PHIToResolve[Idx]])) + Worklist.insert(PHIToResolve[Idx]); + + // Note that we must test the size on each iteration, the worklist can grow. + for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) { + const Value *OrigV = Worklist[Idx]; + auto *I = cast_or_null(VMap.lookup(OrigV)); + if (!I) + continue; + + // See if this instruction simplifies. + Value *SimpleV = SimplifyInstruction(I, DL); + if (!SimpleV) + continue; + + // Stash away all the uses of the old instruction so we can check them for + // recursive simplifications after a RAUW. This is cheaper than checking all + // uses of To on the recursive step in most cases. + for (const User *U : OrigV->users()) + Worklist.insert(cast(U)); + + // Replace the instruction with its simplified value. + I->replaceAllUsesWith(SimpleV); + + // If the original instruction had no side effects, remove it. + if (isInstructionTriviallyDead(I)) + I->eraseFromParent(); + else + VMap[OrigV] = I; + } // Now that the inlined function body has been fully constructed, go through // and zap unconditional fall-through branches. This happens all the time when diff --git a/llvm/test/Transforms/Inline/inline_constprop.ll b/llvm/test/Transforms/Inline/inline_constprop.ll index de23b6157a71..813a71cc24e6 100644 --- a/llvm/test/Transforms/Inline/inline_constprop.ll +++ b/llvm/test/Transforms/Inline/inline_constprop.ll @@ -279,3 +279,25 @@ return: %retval.0 = phi i32* [ %b, %if.end3 ], [ %a, %if.then ] ret i32* %retval.0 } + +declare i32 @PR28802.external(i32 returned %p1) + +define internal i32 @PR28802.callee() { +entry: + br label %cont + +cont: + %0 = phi i32 [ 0, %entry ] + %call = call i32 @PR28802.external(i32 %0) + ret i32 %call +} + +define i32 @PR28802() { +entry: + %call = call i32 @PR28802.callee() + ret i32 %call +} + +; CHECK-LABEL: define i32 @PR28802( +; CHECK: call i32 @PR28802.external(i32 0) +; CHECK: ret i32 0