From 4f7f71de43f2b9981e6e9df97f7b4f296b31a69f Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 20 May 2006 09:21:39 +0000 Subject: [PATCH] - Use of load's chain result should be redirected to load's chain operand. If it reads the chain result of the call, then the use, callseq_start, and call would form a cycle! - Don't forget handle node replacement! - There could also be a TokenFactor between the load and the callseq_start. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28420 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelDAGToDAG.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index ab1c579f1a5..2e744a4af71 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -840,13 +840,18 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) { case X86ISD::TAILCALL: { // Handle indirect call which folds a load here. This never matches by // the TableGen generated code since the load's chain result is read by - // the callseq_start node. + // the callseq_start node or by a TokenFactor which feeds into the + // callseq_start. SDOperand N1 = Node->getOperand(1); if (N1.getOpcode() == ISD::LOAD && N1.hasOneUse() && !CodeGenMap.count(N1.getValue(0))) { SDOperand Chain = Node->getOperand(0); SDNode *CallStart = FindCallStartFromCall(Chain.Val); - if (!CallStart || CallStart->getOperand(0).Val != N1.Val) + if (!CallStart) break; + SDNode *CSOp0 = CallStart->getOperand(0).Val; + if (! (CSOp0 == N1.Val || + (CSOp0->getOpcode() == ISD::TokenFactor && + N1.Val->isOperand(CSOp0)))) break; SDOperand Base, Scale, Index, Disp; if (SelectAddr(N1.getOperand(1), Base, Scale, Index, Disp)) { @@ -872,8 +877,13 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) { SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val, Chain.ResNo); - SelectionDAG::InsertISelMapEntry(CodeGenMap, N1.Val, 1, ResNode, 0); SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, ResNode, 1); + // CALLSEQ_START needs a chain! It can't be ResNode, that would cause + // a cycle. It should be the chain of the load. + Select(Chain, N1.getOperand(0)); + SelectionDAG::InsertISelMapEntry(CodeGenMap, N1.Val, 1, Chain.Val, + Chain.ResNo); + AddHandleReplacement(N1.Val, 1, Chain.Val, Chain.ResNo); Result = SDOperand(ResNode, 0); #ifndef NDEBUG -- 2.34.1