From 55aebef654d11a11e24c8d6680f6647b73a715f7 Mon Sep 17 00:00:00 2001 From: Kalle Raiskila Date: Tue, 24 Aug 2010 11:50:48 +0000 Subject: [PATCH] Fix SPU BE to use all the available return registers. llc used to assert on the added testcase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111911 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CellSPU/SPUISelLowering.cpp | 50 +++++++++----------------- test/CodeGen/CellSPU/call.ll | 26 ++++++++++++-- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index a00331c7635..53ec0eed4e9 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -1324,41 +1324,23 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (Ins.empty()) return Chain; + // Now handle the return value(s) + SmallVector RVLocs; + CCState CCRetInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCRetInfo.AnalyzeCallResult(Ins, CCC_SPU); + + // If the call has results, copy the values out of the ret val registers. - switch (Ins[0].VT.getSimpleVT().SimpleTy) { - default: llvm_unreachable("Unexpected ret value!"); - case MVT::Other: break; - case MVT::i32: - if (Ins.size() > 1 && Ins[1].VT == MVT::i32) { - Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4, - MVT::i32, InFlag).getValue(1); - InVals.push_back(Chain.getValue(0)); - Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32, - Chain.getValue(2)).getValue(1); - InVals.push_back(Chain.getValue(0)); - } else { - Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32, - InFlag).getValue(1); - InVals.push_back(Chain.getValue(0)); - } - break; - case MVT::i8: - case MVT::i16: - case MVT::i64: - case MVT::i128: - case MVT::f32: - case MVT::f64: - case MVT::v2f64: - case MVT::v2i64: - case MVT::v4f32: - case MVT::v4i32: - case MVT::v8i16: - case MVT::v16i8: - Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, Ins[0].VT, - InFlag).getValue(1); - InVals.push_back(Chain.getValue(0)); - break; - } + for (unsigned i = 0; i != RVLocs.size(); ++i) { + CCValAssign VA = RVLocs[i]; + + SDValue Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(), + InFlag); + Chain = Val.getValue(1); + InFlag = Val.getValue(2); + InVals.push_back(Val); + } return Chain; } diff --git a/test/CodeGen/CellSPU/call.ll b/test/CodeGen/CellSPU/call.ll index eb7cf2c6467..559b266e59d 100644 --- a/test/CodeGen/CellSPU/call.ll +++ b/test/CodeGen/CellSPU/call.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -march=cellspu -regalloc=linearscan > %t1.s ; RUN: grep brsl %t1.s | count 1 -; RUN: grep brasl %t1.s | count 1 -; RUN: grep stqd %t1.s | count 80 +; RUN: grep brasl %t1.s | count 2 +; RUN: grep stqd %t1.s | count 82 ; RUN: llc < %s -march=cellspu | FileCheck %s target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" @@ -29,3 +29,25 @@ define i32 @stub_2(...) { entry: ret i32 0 } + +; check that struct is passed in r3-> +; assert this by changing the second field in the struct +%0 = type { i32, i32, i32 } +declare %0 @callee() +define %0 @test_structret() +{ +;CHECK: stqd $lr, 16($sp) +;CHECK: stqd $sp, -48($sp) +;CHECK: ai $sp, $sp, -48 +;CHECK: brasl $lr, callee + %rv = call %0 @callee() +;CHECK: ai $4, $4, 1 +;CHECK: lqd $lr, 64($sp) +;CHECK: ai $sp, $sp, 48 +;CHECK: bi $lr + %oldval = extractvalue %0 %rv, 1 + %newval = add i32 %oldval,1 + %newrv = insertvalue %0 %rv, i32 %newval, 1 + ret %0 %newrv +} +