From 7d29ffbe5b091fae03afd264d8c8b0090c7a45f4 Mon Sep 17 00:00:00 2001 From: Venkatraman Govindaraju Date: Wed, 12 Jan 2011 03:18:21 +0000 Subject: [PATCH] Fix SPARC backend call instruction so that arguments passed through registers are correctly marked as used instead of passing all possible argument registers as used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123301 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/SparcISelLowering.cpp | 22 +++++++++++++++++----- lib/Target/Sparc/SparcInstrInfo.td | 13 +++++++------ test/CodeGen/SPARC/2011-01-11-Call.ll | 13 +++++++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 test/CodeGen/SPARC/2011-01-11-Call.ll diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 27e78f07da5..ec8c7b48097 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -1,3 +1,4 @@ + //===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===// // // The LLVM Compiler Infrastructure @@ -514,11 +515,22 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee, else if (ExternalSymbolSDNode *E = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); - std::vector NodeTys; - NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use. - SDValue Ops[] = { Chain, Callee, InFlag }; - Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops, InFlag.getNode() ? 3 : 2); + // Returns a chain & a flag for retval copy to use + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); + SmallVector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + unsigned Reg = RegsToPass[i].first; + if (Reg >= SP::I0 && Reg <= SP::I7) + Reg = Reg-SP::I0+SP::O0; + + Ops.push_back(DAG.getRegister(Reg, RegsToPass[i].second.getValueType())); + } + if (InFlag.getNode()) + Ops.push_back(InFlag); + + Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 4877af8c8fb..94e1f7adb1b 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -119,9 +119,10 @@ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; -def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; def call : SDNode<"SPISD::CALL", SDT_SPCall, - [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, + SDNPVariadic]>; def retflag : SDNode<"SPISD::RET_FLAG", SDTNone, [SDNPHasChain, SDNPOptInGlue]>; @@ -517,11 +518,11 @@ let Uses = [FCC] in // Section B.24 - Call and Link Instruction, p. 125 // This is the only Format 1 instruction -let Uses = [O0, O1, O2, O3, O4, O5], +let Uses = [O6], hasDelaySlot = 1, isCall = 1, Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { - def CALL : InstSP<(outs), (ins calltarget:$dst), + def CALL : InstSP<(outs), (ins calltarget:$dst, variable_ops), "call $dst", []> { bits<30> disp; let op = 1; @@ -530,11 +531,11 @@ let Uses = [O0, O1, O2, O3, O4, O5], // indirect calls def JMPLrr : F3_1<2, 0b111000, - (outs), (ins MEMrr:$ptr), + (outs), (ins MEMrr:$ptr, variable_ops), "call $ptr", [(call ADDRrr:$ptr)]>; def JMPLri : F3_2<2, 0b111000, - (outs), (ins MEMri:$ptr), + (outs), (ins MEMri:$ptr, variable_ops), "call $ptr", [(call ADDRri:$ptr)]>; } diff --git a/test/CodeGen/SPARC/2011-01-11-Call.ll b/test/CodeGen/SPARC/2011-01-11-Call.ll new file mode 100644 index 00000000000..7350e923242 --- /dev/null +++ b/test/CodeGen/SPARC/2011-01-11-Call.ll @@ -0,0 +1,13 @@ +; RUN: llc -march=sparc -O0 <%s + +define void @test() nounwind { +entry: + %0 = tail call i32 (...)* @foo() nounwind + tail call void (...)* @bar() nounwind + ret void +} + +declare i32 @foo(...) + +declare void @bar(...) +