[llvm] r368855 - [AIX] Add call lowering for parameters that could pass onto FPRs

Jason Liu via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 14 07:13:11 PDT 2019


Author: jasonliu
Date: Wed Aug 14 07:13:11 2019
New Revision: 368855

URL: http://llvm.org/viewvc/llvm-project?rev=368855&view=rev
Log:
[AIX] Add call lowering for parameters that could pass onto FPRs

Summary:
This patch adds call lowering functionality to enable passing
parameters onto floating point registers when needed.

Differential Revision: https://reviews.llvm.org/D63654

Added:
    llvm/trunk/test/CodeGen/PowerPC/aix_fpr_param.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=368855&r1=368854&r2=368855&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Aug 14 07:13:11 2019
@@ -3241,8 +3241,8 @@ SDValue PPCTargetLowering::LowerVASTART(
                       MachinePointerInfo(SV, nextOffset));
 }
 
-/// FPR - The set of FP registers that should be allocated for arguments,
-/// on Darwin.
+/// FPR - The set of FP registers that should be allocated for arguments
+/// on Darwin and AIX.
 static const MCPhysReg FPR[] = {PPC::F1,  PPC::F2,  PPC::F3, PPC::F4, PPC::F5,
                                 PPC::F6,  PPC::F7,  PPC::F8, PPC::F9, PPC::F10,
                                 PPC::F11, PPC::F12, PPC::F13};
@@ -6736,8 +6736,12 @@ SDValue PPCTargetLowering::LowerCall_AIX
 
   const unsigned NumGPRs = isPPC64 ? array_lengthof(GPR_64)
                                    : array_lengthof(GPR_32);
+  const unsigned NumFPRs = array_lengthof(FPR);
+  assert(NumFPRs == 13 && "Only FPR 1-13 could be used for parameter passing "
+                          "on AIX");
+
   const MCPhysReg *GPR = isPPC64 ? GPR_64 : GPR_32;
-  unsigned GPR_idx = 0;
+  unsigned GPR_idx = 0, FPR_idx = 0;
 
   SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
 
@@ -6774,6 +6778,20 @@ SDValue PPCTargetLowering::LowerCall_AIX
       break;
     case MVT::f32:
     case MVT::f64:
+      if (FPR_idx != NumFPRs) {
+        RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));
+
+        // If we have any FPRs remaining, we may also have GPRs remaining.
+        // Args passed in FPRs consume 1 or 2 (f64 in 32 bit mode) available
+        // GPRs.
+        if (GPR_idx != NumGPRs)
+          ++GPR_idx;
+        if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64)
+          ++GPR_idx;
+      } else
+        report_fatal_error("Handling of placing parameters on the stack is "
+                           "unimplemented!");
+      break;
     case MVT::v4f32:
     case MVT::v4i32:
     case MVT::v8i16:

Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h?rev=368855&r1=368854&r2=368855&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h Wed Aug 14 07:13:11 2019
@@ -210,7 +210,11 @@ public:
   /// instructions, regardless of whether we are in 32-bit or 64-bit mode.
   bool has64BitSupport() const { return Has64BitSupport; }
   // useSoftFloat - Return true if soft-float option is turned on.
-  bool useSoftFloat() const { return !HasHardFloat; }
+  bool useSoftFloat() const {
+    if (isAIXABI() && !HasHardFloat)
+      report_fatal_error("soft-float is not yet supported on AIX.");
+    return !HasHardFloat;
+  }
 
   /// use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit
   /// registers in 32-bit mode when possible.  This can only true if

Added: llvm/trunk/test/CodeGen/PowerPC/aix_fpr_param.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/aix_fpr_param.ll?rev=368855&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/aix_fpr_param.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/aix_fpr_param.ll Wed Aug 14 07:13:11 2019
@@ -0,0 +1,150 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff -stop-after=machine-cp < %s | \
+; RUN: FileCheck --check-prefix=32BIT %s
+
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -stop-after=machine-cp < %s | \
+; RUN: FileCheck --check-prefix=64BIT %s
+
+ at f1 = global float 0.000000e+00, align 4
+ at d1 = global double 0.000000e+00, align 8
+
+define void @call_test_float() {
+entry:
+; 32BIT: renamable $r3 = LWZtoc @f1, $r2 :: (load 4 from got)
+; 32BIT: renamable $f1 = LFS 0, killed renamable $r3 :: (dereferenceable load 4 from @f1)
+; 32BIT: ADJCALLSTACKDOWN 56, 0, implicit-def dead $r1, implicit $r1
+; 32BIT: BL_NOP <mcsymbol .test_float>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $f1, implicit $r2, implicit-def $r1
+; 32BIT: ADJCALLSTACKUP 56, 0, implicit-def dead $r1, implicit $r1
+
+; 64BIT: renamable $x3 = LDtoc @f1, $x2 :: (load 8 from got)
+; 64BIT: renamable $f1 = LFS 0, killed renamable $x3 :: (dereferenceable load 4 from @f1)
+; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1
+; 64BIT: BL8_NOP <mcsymbol .test_float>, csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit $x2, implicit-def $r1
+; 64BIT: ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1
+
+  %0 = load float, float* @f1, align 4
+  call void @test_float(float %0)
+  ret void
+}
+
+declare void @test_float(float)
+
+define void @call_test_floats() {
+entry:
+; 32BIT: renamable $r3 = LWZtoc @f1, $r2 :: (load 4 from got)
+; 32BIT: renamable $f1 = LFS 0, killed renamable $r3 :: (dereferenceable load 4 from @f1)
+; 32BIT: ADJCALLSTACKDOWN 56, 0, implicit-def dead $r1, implicit $r1
+; 32BIT: $f2 = COPY renamable $f1
+; 32BIT: $f3 = COPY renamable $f1
+; 32BIT: BL_NOP <mcsymbol .test_floats>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $f1, implicit killed $f2, implicit killed $f3, implicit $r2, implicit-def $r1
+; 32BIT: ADJCALLSTACKUP 56, 0, implicit-def dead $r1, implicit $r1
+
+; 64BIT: renamable $x3 = LDtoc @f1, $x2 :: (load 8 from got)
+; 64BIT: renamable $f1 = LFS 0, killed renamable $x3 :: (dereferenceable load 4 from @f1)
+; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1
+; 64BIT: $f2 = COPY renamable $f1
+; 64BIT: $f3 = COPY renamable $f1
+; 64BIT: BL8_NOP <mcsymbol .test_floats>, csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit killed $f2, implicit killed $f3, implicit $x2, implicit-def $r1
+; 64BIT: ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1
+
+  %0 = load float, float* @f1, align 4
+  call void @test_floats(float %0, float %0, float %0)
+  ret void
+}
+
+declare void @test_floats(float, float, float)
+
+define void @call_test_double() {
+entry:
+; 32BIT: renamable $r3 = LWZtoc @d1, $r2 :: (load 4 from got)
+; 32BIT: renamable $f1 = LFD 0, killed renamable $r3 :: (dereferenceable load 8 from @d1)
+; 32BIT: ADJCALLSTACKDOWN 56, 0, implicit-def dead $r1, implicit $r1
+; 32BIT: BL_NOP <mcsymbol .test_double>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $f1, implicit $r2, implicit-def $r1
+; 32BIT: ADJCALLSTACKUP 56, 0, implicit-def dead $r1, implicit $r1
+
+; 64BIT: renamable $x3 = LDtoc @d1, $x2 :: (load 8 from got)
+; 64BIT: renamable $f1 = LFD 0, killed renamable $x3 :: (dereferenceable load 8 from @d1)
+; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1
+; 64BIT: BL8_NOP <mcsymbol .test_double>, csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit $x2, implicit-def $r1
+; 64BIT: ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1
+
+  %0 = load double, double* @d1, align 8
+  call void @test_double(double %0)
+  ret void
+}
+
+declare void @test_double(double)
+
+define void @call_test_fpr_max() {
+entry:
+; 32BIT: renamable $r3 = LWZtoc @d1, $r2 :: (load 4 from got)
+; 32BIT: renamable $f1 = LFD 0, killed renamable $r3 :: (dereferenceable load 8 from @d1)
+; 32BIT: ADJCALLSTACKDOWN 56, 0, implicit-def dead $r1, implicit $r1
+; 32BIT: $f2 = COPY renamable $f1
+; 32BIT: $f3 = COPY renamable $f1
+; 32BIT: $f4 = COPY renamable $f1
+; 32BIT: $f5 = COPY renamable $f1
+; 32BIT: $f6 = COPY renamable $f1
+; 32BIT: $f7 = COPY renamable $f1
+; 32BIT: $f8 = COPY renamable $f1
+; 32BIT: $f9 = COPY renamable $f1
+; 32BIT: $f10 = COPY renamable $f1
+; 32BIT: $f11 = COPY renamable $f1
+; 32BIT: $f12 = COPY renamable $f1
+; 32BIT: $f13 = COPY renamable $f1
+; 32BIT: BL_NOP <mcsymbol .test_fpr_max>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $f1, implicit killed $f2, implicit killed $f3, implicit killed $f4, implicit killed $f5, implicit killed $f6, implicit killed $f7, implicit killed $f8, implicit killed $f9, implicit killed $f10, implicit killed $f11, implicit killed $f12, implicit killed $f13, implicit $r2, implicit-def $r1
+; 32BIT: ADJCALLSTACKUP 56, 0, implicit-def dead $r1, implicit $r1
+
+; 64BIT: renamable $x3 = LDtoc @d1, $x2 :: (load 8 from got)
+; 64BIT: renamable $f1 = LFD 0, killed renamable $x3 :: (dereferenceable load 8 from @d1)
+; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1
+; 64BIT: $f2 = COPY renamable $f1
+; 64BIT: $f3 = COPY renamable $f1
+; 64BIT: $f4 = COPY renamable $f1
+; 64BIT: $f5 = COPY renamable $f1
+; 64BIT: $f6 = COPY renamable $f1
+; 64BIT: $f7 = COPY renamable $f1
+; 64BIT: $f8 = COPY renamable $f1
+; 64BIT: $f9 = COPY renamable $f1
+; 64BIT: $f10 = COPY renamable $f1
+; 64BIT: $f11 = COPY renamable $f1
+; 64BIT: $f12 = COPY renamable $f1
+; 64BIT: $f13 = COPY renamable $f1
+; 64BIT: BL8_NOP <mcsymbol .test_fpr_max>, csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit killed $f2, implicit killed $f3, implicit killed $f4, implicit killed $f5, implicit killed $f6, implicit killed $f7, implicit killed $f8, implicit killed $f9, implicit killed $f10, implicit killed $f11, implicit killed $f12, implicit killed $f13, implicit $x2, implicit-def $r1
+; 64BIT: ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1
+
+  %0 = load double, double* @d1, align 8
+  call void @test_fpr_max(double %0, double %0, double %0, double %0, double %0, double %0, double %0, double %0, double %0, double %0, double %0, double %0, double %0)
+  ret void
+}
+
+declare void @test_fpr_max(double, double, double, double, double, double, double, double, double, double, double, double, double)
+
+define void @call_test_mix() {
+entry:
+; 32BIT: renamable $r3 = LWZtoc @f1, $r2 :: (load 4 from got)
+; 32BIT: renamable $r4 = LWZtoc @d1, $r2 :: (load 4 from got)
+; 32BIT: renamable $f1 = LFS 0, killed renamable $r3 :: (dereferenceable load 4 from @f1)
+; 32BIT: renamable $f2 = LFD 0, killed renamable $r4 :: (dereferenceable load 8 from @d1)
+; 32BIT: ADJCALLSTACKDOWN 56, 0, implicit-def dead $r1, implicit $r1
+; 32BIT: $r4 = LI 1
+; 32BIT: $r7 = LI 97
+; 32BIT: BL_NOP <mcsymbol .test_mix>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $f1, implicit $r4, implicit $f2, implicit killed $r7, implicit $r2, implicit-def $r1
+; 32BIT: ADJCALLSTACKUP 56, 0, implicit-def dead $r1, implicit $r1
+
+; 64BIT: renamable $x3 = LDtoc @f1, $x2 :: (load 8 from got)
+; 64BIT: renamable $x4 = LDtoc @d1, $x2 :: (load 8 from got)
+; 64BIT: renamable $f1 = LFS 0, killed renamable $x3 :: (dereferenceable load 4 from @f1)
+; 64BIT: renamable $f2 = LFD 0, killed renamable $x4 :: (dereferenceable load 8 from @d1)
+; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1
+; 64BIT: $x4 = LI8 1
+; 64BIT: $x6 = LI8 97
+; 64BIT: BL8_NOP <mcsymbol .test_mix>, csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit $x4, implicit $f2, implicit killed $x6, implicit $x2, implicit-def $r1
+; 64BIT: ADJCALLSTACKUP 112, 0, implicit-def dead $r1, implicit $r1
+
+  %0 = load float, float* @f1, align 4
+  %1 = load double, double* @d1, align 8
+  call void @test_mix(float %0, i32 1, double %1, i8 signext 97)
+  ret void
+}
+
+declare void @test_mix(float, i32, double, i8 signext)




More information about the llvm-commits mailing list