summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-05-20 09:21:39 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-05-20 09:21:39 +0000
commit401049ce33ae8ab52fb304e9646355882e176f37 (patch)
tree60ed5bedd85d61a22bc21e96a0f9a00216680538 /llvm
parent0643f902be09bfd64714dcc3dd4953523b0a8328 (diff)
downloadbcm5719-llvm-401049ce33ae8ab52fb304e9646355882e176f37.tar.gz
bcm5719-llvm-401049ce33ae8ab52fb304e9646355882e176f37.zip
- 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. llvm-svn: 28420
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index ab1c579f1a5..2e744a4af71 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/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
OpenPOWER on IntegriCloud