[llvm] r205041 - [PowerPC] v2[fi]64 need to be explicitly passed in VSX registers

Hal Finkel hfinkel at anl.gov
Fri Mar 28 12:58:12 PDT 2014


Author: hfinkel
Date: Fri Mar 28 14:58:11 2014
New Revision: 205041

URL: http://llvm.org/viewvc/llvm-project?rev=205041&view=rev
Log:
[PowerPC] v2[fi]64 need to be explicitly passed in VSX registers

v2[fi]64 values need to be explicitly passed in VSX registers. This is because
the code in TRI that finds the minimal register class given a register and a
value type will assert if given an Altivec register and a non-Altivec type.

Added:
    llvm/trunk/test/CodeGen/PowerPC/vsx-args.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td?rev=205041&r1=205040&r2=205041&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td Fri Mar 28 14:58:11 2014
@@ -36,7 +36,8 @@ def RetCC_PPC : CallingConv<[
   CCIfType<[f64], CCAssignToReg<[F1, F2, F3, F4]>>,
   
   // Vector types are always returned in V2.
-  CCIfType<[v16i8, v8i16, v4i32, v4f32, v2f64, v2i64], CCAssignToReg<[V2]>>
+  CCIfType<[v16i8, v8i16, v4i32, v4f32], CCAssignToReg<[V2]>>,
+  CCIfType<[v2f64, v2i64], CCAssignToReg<[VSH2]>>
 ]>;
 
 
@@ -70,7 +71,8 @@ def RetCC_PPC64_ELF_FIS : CallingConv<[
   CCIfType<[i128], CCAssignToReg<[X3, X4, X5, X6]>>,
   CCIfType<[f32],  CCAssignToReg<[F1, F2]>>,
   CCIfType<[f64],  CCAssignToReg<[F1, F2, F3, F4]>>,
-  CCIfType<[v16i8, v8i16, v4i32, v4f32, v2f64, v2i64], CCAssignToReg<[V2]>>
+  CCIfType<[v16i8, v8i16, v4i32, v4f32], CCAssignToReg<[V2]>>,
+  CCIfType<[v2f64, v2i64], CCAssignToReg<[VSH2]>>
 ]>;
 
 //===----------------------------------------------------------------------===//
@@ -118,8 +120,11 @@ def CC_PPC32_SVR4_VarArg : CallingConv<[
 // put vector arguments in vector registers before putting them on the stack.
 def CC_PPC32_SVR4 : CallingConv<[
   // The first 12 Vector arguments are passed in AltiVec registers.
-  CCIfType<[v16i8, v8i16, v4i32, v4f32, v2f64, v2i64],
+  CCIfType<[v16i8, v8i16, v4i32, v4f32],
            CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13]>>,
+  CCIfType<[v2f64, v2i64],
+           CCAssignToReg<[VSH2, VSH3, VSH4, VSH5, VSH6, VSH7, VSH8, VSH9,
+                          VSH10, VSH11, VSH12, VSH13]>>,
            
   CCDelegateTo<CC_PPC32_SVR4_Common>
 ]>;  

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=205041&r1=205040&r2=205041&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Mar 28 14:58:11 2014
@@ -2162,9 +2162,11 @@ PPCTargetLowering::LowerFormalArguments_
         case MVT::v8i16:
         case MVT::v4i32:
         case MVT::v4f32:
+          RC = &PPC::VRRCRegClass;
+          break;
         case MVT::v2f64:
         case MVT::v2i64:
-          RC = &PPC::VRRCRegClass;
+          RC = &PPC::VSHRCRegClass;
           break;
       }
 
@@ -2381,6 +2383,10 @@ PPCTargetLowering::LowerFormalArguments_
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
+  static const uint16_t VSRH[] = {
+    PPC::VSH2, PPC::VSH3, PPC::VSH4, PPC::VSH5, PPC::VSH6, PPC::VSH7, PPC::VSH8,
+    PPC::VSH9, PPC::VSH10, PPC::VSH11, PPC::VSH12, PPC::VSH13
+  };
 
   const unsigned Num_GPR_Regs = array_lengthof(GPR);
   const unsigned Num_FPR_Regs = 13;
@@ -2573,7 +2579,9 @@ PPCTargetLowering::LowerFormalArguments_
       // Note that vector arguments in registers don't reserve stack space,
       // except in varargs functions.
       if (VR_idx != Num_VR_Regs) {
-        unsigned VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
+        unsigned VReg = (ObjectVT == MVT::v2f64 || ObjectVT == MVT::v2i64) ?
+                        MF.addLiveIn(VSRH[VR_idx], &PPC::VSHRCRegClass) :
+                        MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
         ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT);
         if (isVarArg) {
           while ((ArgOffset % 16) != 0) {
@@ -4011,6 +4019,11 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
+  static const uint16_t VSRH[] = {
+    PPC::VSH2, PPC::VSH3, PPC::VSH4, PPC::VSH5, PPC::VSH6, PPC::VSH7, PPC::VSH8,
+    PPC::VSH9, PPC::VSH10, PPC::VSH11, PPC::VSH12, PPC::VSH13
+  };
+
   const unsigned NumGPRs = array_lengthof(GPR);
   const unsigned NumFPRs = 13;
   const unsigned NumVRs  = array_lengthof(VR);
@@ -4242,7 +4255,13 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
                                      MachinePointerInfo(),
                                      false, false, false, 0);
           MemOpChains.push_back(Load.getValue(1));
-          RegsToPass.push_back(std::make_pair(VR[VR_idx++], Load));
+
+          unsigned VReg = (Arg.getSimpleValueType() == MVT::v2f64 ||
+                           Arg.getSimpleValueType() == MVT::v2i64) ?
+                          VSRH[VR_idx] : VR[VR_idx];
+          ++VR_idx;
+
+          RegsToPass.push_back(std::make_pair(VReg, Load));
         }
         ArgOffset += 16;
         for (unsigned i=0; i<16; i+=PtrByteSize) {
@@ -4262,7 +4281,12 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
       // stack space allocated at the end.
       if (VR_idx != NumVRs) {
         // Doesn't have GPR space allocated.
-        RegsToPass.push_back(std::make_pair(VR[VR_idx++], Arg));
+        unsigned VReg = (Arg.getSimpleValueType() == MVT::v2f64 ||
+                         Arg.getSimpleValueType() == MVT::v2i64) ?
+                        VSRH[VR_idx] : VR[VR_idx];
+        ++VR_idx;
+
+        RegsToPass.push_back(std::make_pair(VReg, Arg));
       } else {
         LowerMemOpCallTo(DAG, MF, Chain, Arg, PtrOff, SPDiff, ArgOffset,
                          true, isTailCall, true, MemOpChains,

Added: llvm/trunk/test/CodeGen/PowerPC/vsx-args.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/vsx-args.ll?rev=205041&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/vsx-args.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/vsx-args.ll Fri Mar 28 14:58:11 2014
@@ -0,0 +1,26 @@
+; RUN: llc < %s -mcpu=pwr7 -mattr=+vsx | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+declare <2 x double> @sv(<2 x double>, <2 x i64>, <4 x float>) #0
+
+define <2 x double> @main(<4 x float> %a, <2 x double> %b, <2 x i64> %c) #1 {
+entry:
+  %ca = tail call <2 x double> @sv(<2 x double> %b, <2 x i64> %c,  <4 x float> %a)
+  %v = fadd <2 x double> %ca, <double 1.0, double 1.0>
+  ret <2 x double> %v
+
+; CHECK-LABEL: @main
+; CHECK-DAG: vor [[V:[0-9]+]], 2, 2
+; CHECK-DAG: xxlor 34, 35, 35
+; CHECK-DAG: xxlor 35, 36, 36
+; CHECK-DAG: vor 4, [[V]], [[V]]
+; CHECK-DAG: bl sv
+; CHECK-DAG: lxvd2x [[VC:[0-9]+]],
+; CHECK: xvadddp 34, 34, [[VC]]
+; CHECK: blr
+}
+
+attributes #0 = { noinline nounwind readnone }
+attributes #1 = { nounwind }
+





More information about the llvm-commits mailing list