Fast-ISel: Remove dead code after falling back from selecting call instructions (PR20863)

Previously, fast-isel would not clean up after failing to select a call
instruction, because it would have called flushLocalValueMap() which moves
the insertion point, making SavedInsertPt in selectInstruction() invalid.

Fixing this by making SavedInsertPt a member variable, and having
flushLocalValueMap() update it.

This removes some redundant code at -O0, and more importantly fixes PR20863.

Differential Revision: http://reviews.llvm.org/D5249

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217401 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hans Wennborg 2014-09-08 20:24:10 +00:00
parent 50a5cda135
commit 4cd53531fd
3 changed files with 31 additions and 15 deletions

View File

@ -539,6 +539,9 @@ private:
/// across heavy instructions like calls.
void flushLocalValueMap();
/// \brief Insertion point before trying to select the current instruction.
MachineBasicBlock::iterator SavedInsertPt;
/// \brief Add a stackmap or patchpoint intrinsic call's live variable
/// operands to a stackmap or patchpoint machine instruction.
bool addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,

View File

@ -127,6 +127,7 @@ void FastISel::flushLocalValueMap() {
LocalValueMap.clear();
LastLocalValue = EmitStartPt;
recomputeInsertPt();
SavedInsertPt = FuncInfo.InsertPt;
}
bool FastISel::hasTrivialKill(const Value *V) {
@ -1296,7 +1297,7 @@ bool FastISel::selectInstruction(const Instruction *I) {
DbgLoc = I->getDebugLoc();
MachineBasicBlock::iterator SavedInsertPt = FuncInfo.InsertPt;
SavedInsertPt = FuncInfo.InsertPt;
if (const auto *Call = dyn_cast<CallInst>(I)) {
const Function *F = Call->getCalledFunction();
@ -1322,13 +1323,10 @@ bool FastISel::selectInstruction(const Instruction *I) {
DbgLoc = DebugLoc();
return true;
}
// Remove dead code. However, ignore call instructions since we've flushed
// the local value map and recomputed the insert point.
if (!isa<CallInst>(I)) {
recomputeInsertPt();
if (SavedInsertPt != FuncInfo.InsertPt)
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
}
// Remove dead code.
recomputeInsertPt();
if (SavedInsertPt != FuncInfo.InsertPt)
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
SavedInsertPt = FuncInfo.InsertPt;
}
// Next, try calling the target to attempt to handle the instruction.
@ -1337,13 +1335,10 @@ bool FastISel::selectInstruction(const Instruction *I) {
DbgLoc = DebugLoc();
return true;
}
// Remove dead code. However, ignore call instructions since we've flushed
// the local value map and recomputed the insert point.
if (!isa<CallInst>(I)) {
recomputeInsertPt();
if (SavedInsertPt != FuncInfo.InsertPt)
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
}
// Remove dead code.
recomputeInsertPt();
if (SavedInsertPt != FuncInfo.InsertPt)
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
DbgLoc = DebugLoc();
// Undo phi node updates, because they will be added again by SelectionDAG.

View File

@ -60,3 +60,21 @@ entry:
; CHECK: addl $28
}
declare fastcc void @test4fastccsret(%struct.a* sret)
; Check that fast-isel cleans up when it fails to lower a call instruction.
define void @test5() {
entry:
%call = call i32 @test5dllimport(i32 42)
ret void
; CHECK-LABEL: test5:
; Local value area is still there:
; CHECK: movl $42, {{%[a-z]+}}
; Fast-ISel's arg push is not here:
; CHECK-NOT: movl $42, (%esp)
; SDag-ISel's arg push:
; CHECK: movl %esp, [[REGISTER:%[a-z]+]]
; CHECK: movl $42, ([[REGISTER]])
; CHECK: movl __imp__test5dllimport
}
declare dllimport i32 @test5dllimport(i32)