From: Hal Finkel Date: Fri, 28 Mar 2014 19:58:11 +0000 (+0000) Subject: [PowerPC] v2[fi]64 need to be explicitly passed in VSX registers X-Git-Tag: android-x86-7.1-r4~63612 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c9de9e60b9053ba65c2710afeef486f9948c3798;p=android-x86%2Fexternal-llvm.git [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205041 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPCCallingConv.td b/lib/Target/PowerPC/PPCCallingConv.td index 5e3074bacce..d48164d6216 100644 --- a/lib/Target/PowerPC/PPCCallingConv.td +++ b/lib/Target/PowerPC/PPCCallingConv.td @@ -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 ]>; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 1c19160c9c6..6a43ecc2500 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2162,9 +2162,11 @@ PPCTargetLowering::LowerFormalArguments_32SVR4( 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_64SVR4( 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_64SVR4( // 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(SDValue Chain, SDValue Callee, 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(SDValue Chain, SDValue Callee, 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(SDValue Chain, SDValue Callee, // 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, diff --git a/test/CodeGen/PowerPC/vsx-args.ll b/test/CodeGen/PowerPC/vsx-args.ll new file mode 100644 index 00000000000..520aeb5fa90 --- /dev/null +++ b/test/CodeGen/PowerPC/vsx-args.ll @@ -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, + 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 } +