Skip to content

Commit

Permalink
[CloneFunction] Don't remove side effecting calls
Browse files Browse the repository at this point in the history
We were able to figure out that the result of a call is some constant.
While propagating that fact, we added the constant to the value map.
This is problematic because it results in us losing the call site when
processing the value map.

This fixes PR28802.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277611 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
majnemer committed Aug 3, 2016
1 parent d619aa8 commit 406cfb6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
6 changes: 4 additions & 2 deletions lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TerminatorInst>(I) &&
!I->mayHaveSideEffects())
I->eraseFromParent();
} else {
Worklist.insert(I);
Expand Down Expand Up @@ -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<TerminatorInst>(I) &&
!I->mayHaveSideEffects())
I->eraseFromParent();
}
return Simplified;
Expand Down
35 changes: 33 additions & 2 deletions lib/Transforms/Utils/CloneFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<const Value *, 8> Worklist;
for (unsigned Idx = 0, Size = PHIToResolve.size(); Idx != Size; ++Idx)
if (PHINode *PN = dyn_cast<PHINode>(VMap[PHIToResolve[Idx]]))
recursivelySimplifyInstruction(PN);
if (isa<PHINode>(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<Instruction>(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<Instruction>(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
Expand Down
22 changes: 22 additions & 0 deletions test/Transforms/Inline/inline_constprop.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 406cfb6

Please sign in to comment.