Index: llvm/trunk/include/llvm/CodeGen/FastISel.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/FastISel.h +++ llvm/trunk/include/llvm/CodeGen/FastISel.h @@ -539,6 +539,9 @@ /// 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 &Ops, Index: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -127,6 +127,7 @@ LocalValueMap.clear(); LastLocalValue = EmitStartPt; recomputeInsertPt(); + SavedInsertPt = FuncInfo.InsertPt; } bool FastISel::hasTrivialKill(const Value *V) { @@ -1296,7 +1297,7 @@ DbgLoc = I->getDebugLoc(); - MachineBasicBlock::iterator SavedInsertPt = FuncInfo.InsertPt; + SavedInsertPt = FuncInfo.InsertPt; if (const auto *Call = dyn_cast(I)) { const Function *F = Call->getCalledFunction(); @@ -1322,13 +1323,10 @@ 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(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 @@ 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(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. Index: llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll +++ llvm/trunk/test/CodeGen/X86/fast-isel-x86.ll @@ -60,3 +60,21 @@ ; 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)