From b4afb137efbc38462707bab9f5e8bc5c2d07cd2d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Nov 2009 02:51:26 +0000 Subject: [PATCH] Fix fast-isel to avoid selecting the return instruction if a tail call has been encountered. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89444 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGISel.h | 3 ++- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 18 +++++++++++++++--- test/CodeGen/X86/tailcall-fastisel.ll | 13 +++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/X86/tailcall-fastisel.ll diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 5d33224cbe2..adf89b0ce03 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -127,7 +127,8 @@ private: void SelectBasicBlock(BasicBlock *LLVMBB, BasicBlock::iterator Begin, - BasicBlock::iterator End); + BasicBlock::iterator End, + bool &HadTailCall); void CodeGenAndEmitDAG(); void LowerArguments(BasicBlock *BB); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index ab5f21e4337..3a54a9ccd91 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -376,7 +376,8 @@ static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB, void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, BasicBlock::iterator Begin, - BasicBlock::iterator End) { + BasicBlock::iterator End, + bool &HadTailCall) { SDL->setCurrentBasicBlock(BB); MetadataContext &TheMetadata = LLVMBB->getParent()->getContext().getMetadata(); unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); @@ -421,6 +422,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, // Final step, emit the lowered DAG as machine code. CodeGenAndEmitDAG(); + HadTailCall = SDL->HasTailCall; SDL->clear(); } @@ -797,7 +799,16 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, } SDL->setCurDebugLoc(FastIS->getCurDebugLoc()); - SelectBasicBlock(LLVMBB, BI, next(BI)); + + bool HadTailCall = false; + SelectBasicBlock(LLVMBB, BI, next(BI), HadTailCall); + + // If the call was emitted as a tail call, we're done with the block. + if (HadTailCall) { + BI = End; + break; + } + // If the instruction was codegen'd with multiple blocks, // inform the FastISel object where to resume inserting. FastIS->setCurrentBlock(BB); @@ -827,7 +838,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, // If FastISel is run and it has known DebugLoc then use it. if (FastIS && !FastIS->getCurDebugLoc().isUnknown()) SDL->setCurDebugLoc(FastIS->getCurDebugLoc()); - SelectBasicBlock(LLVMBB, BI, End); + bool HadTailCall; + SelectBasicBlock(LLVMBB, BI, End, HadTailCall); } FinishBasicBlock(); diff --git a/test/CodeGen/X86/tailcall-fastisel.ll b/test/CodeGen/X86/tailcall-fastisel.ll new file mode 100644 index 00000000000..d54fb4115b0 --- /dev/null +++ b/test/CodeGen/X86/tailcall-fastisel.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -march=x86-64 -tailcallopt -fast-isel | grep TAILCALL + +; Fast-isel shouldn't attempt to handle this tail call, and it should +; cleanly terminate instruction selection in the block after it's +; done to avoid emitting invalid MachineInstrs. + +%0 = type { i64, i32, i8* } + +define fastcc i8* @"visit_array_aux<`Reference>"(%0 %arg, i32 %arg1) nounwind { +fail: ; preds = %entry + %tmp20 = tail call fastcc i8* @"visit_array_aux<`Reference>"(%0 %arg, i32 undef) ; [#uses=1] + ret i8* %tmp20 +} -- 2.34.1