Fix SPU BE to use all the available return registers.
authorKalle Raiskila <kalle.raiskila@nokia.com>
Tue, 24 Aug 2010 11:50:48 +0000 (11:50 +0000)
committerKalle Raiskila <kalle.raiskila@nokia.com>
Tue, 24 Aug 2010 11:50:48 +0000 (11:50 +0000)
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
test/CodeGen/CellSPU/call.ll

index a00331c76359894b63199f6607152912688fc71a..53ec0eed4e908688b9241d7464ea33aa711537d6 100644 (file)
@@ -1324,41 +1324,23 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
   if (Ins.empty())
     return Chain;
 
+  // Now handle the return value(s)
+  SmallVector<CCValAssign, 16> 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;
 }
index eb7cf2c6467c82345a688ba47d1c092c0cbe966d..559b266e59df369ed40fca3ef216fe82663c4be7 100644 (file)
@@ -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
+}
+