[llvm] r277804 - [PowerPC] fix passing long double arguments to function (soft-float)

Strahinja Petrovic via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 5 01:47:27 PDT 2016


Author: spetrovic
Date: Fri Aug  5 03:47:26 2016
New Revision: 277804

URL: http://llvm.org/viewvc/llvm-project?rev=277804&view=rev
Log:

[PowerPC] fix passing long double arguments to function (soft-float)

This patch fixes passing long double type arguments to function in 
soft float mode. If there is less than 4 argument registers free 
(long double type is mapped in 4 gpr registers in soft float mode) 
long double type argument must be passed through stack.
Differential Revision: https://reviews.llvm.org/D20114.


Added:
    llvm/trunk/test/CodeGen/PowerPC/ppc32-skip-regs.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h

Modified: llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td?rev=277804&r1=277803&r2=277804&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td Fri Aug  5 03:47:26 2016
@@ -26,6 +26,9 @@ class CCIfNotSubtarget<string F, CCActio
 class CCIfOrigArgWasNotPPCF128<CCAction A>
     : CCIf<"!static_cast<PPCCCState *>(&State)->WasOriginalArgPPCF128(ValNo)",
            A>;
+class CCIfOrigArgWasPPCF128<CCAction A>
+    : CCIf<"static_cast<PPCCCState *>(&State)->WasOriginalArgPPCF128(ValNo)",
+           A>;
 
 //===----------------------------------------------------------------------===//
 // Return Value Calling Convention
@@ -142,6 +145,9 @@ def CC_PPC32_SVR4_Common : CallingConv<[
   CCIfType<[i32],
   CCIfSplit<CCIfNotSubtarget<"useSoftFloat()", 
                             CCCustom<"CC_PPC32_SVR4_Custom_AlignArgRegs">>>>,
+  CCIfSplit<CCIfSubtarget<"useSoftFloat()",
+                          CCIfOrigArgWasPPCF128<CCCustom<
+                          "CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128">>>>,
 
   // The 'nest' parameter, if any, is passed in R11.
   CCIfNest<CCAssignToReg<[R11]>>,

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=277804&r1=277803&r2=277804&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Aug  5 03:47:26 2016
@@ -2676,6 +2676,32 @@ bool llvm::CC_PPC32_SVR4_Custom_AlignArg
   return false;
 }
 
+bool 
+llvm::CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT,
+                                                  MVT &LocVT,
+                                                  CCValAssign::LocInfo &LocInfo,
+                                                  ISD::ArgFlagsTy &ArgFlags,
+                                                  CCState &State) {
+  static const MCPhysReg ArgRegs[] = {
+    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
+    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
+  };
+  const unsigned NumArgRegs = array_lengthof(ArgRegs);
+
+  unsigned RegNum = State.getFirstUnallocated(ArgRegs);
+  int RegsLeft = NumArgRegs - RegNum;
+
+  // Skip if there is not enough registers left for long double type (4 gpr regs 
+  // in soft float mode) and put long double argument on the stack.
+  if (RegNum != NumArgRegs && RegsLeft < 4) {
+    for (int i = 0; i < RegsLeft; i++) {
+      State.AllocateReg(ArgRegs[RegNum + i]);
+    }
+  }
+
+  return false;
+}
+
 bool llvm::CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
                                                MVT &LocVT,
                                                CCValAssign::LocInfo &LocInfo,

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=277804&r1=277803&r2=277804&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Fri Aug  5 03:47:26 2016
@@ -953,6 +953,13 @@ namespace llvm {
                                          ISD::ArgFlagsTy &ArgFlags,
                                          CCState &State);
 
+  bool 
+  CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT,
+                                                 MVT &LocVT,
+                                                 CCValAssign::LocInfo &LocInfo,
+                                                 ISD::ArgFlagsTy &ArgFlags,
+                                                 CCState &State);
+
   bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
                                            MVT &LocVT,
                                            CCValAssign::LocInfo &LocInfo,

Added: llvm/trunk/test/CodeGen/PowerPC/ppc32-skip-regs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc32-skip-regs.ll?rev=277804&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/ppc32-skip-regs.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/ppc32-skip-regs.ll Fri Aug  5 03:47:26 2016
@@ -0,0 +1,26 @@
+; RUN: llc -O2 -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s
+
+target datalayout = "E-m:e-p:32:32-i64:64-n32"
+target triple = "powerpc-buildroot-linux-gnu"
+
+ at x = global ppc_fp128 0xM3FF00000000000000000000000000000, align 16
+ at .str = private unnamed_addr constant [9 x i8] c"%Lf %Lf\0A\00", align 1
+
+define void @foo() #0 {
+entry:
+  %0 = load ppc_fp128, ppc_fp128* @x, align 16
+  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), ppc_fp128 %0, ppc_fp128 %0)
+  ret void
+}
+; Do not put second argument of function in r8 register, because there is no enough registers
+; left for long double type (4 registers in soft float mode). Instead in r8 register this
+; argument put on stack.
+; CHECK-NOT: mr 8, 4
+; CHECK: stw 7, 20(1)
+; CHECK: stw 6, 16(1)
+; CHECK: stw 5, 12(1)
+; CHECK: stw 4, 8(1)
+
+declare i32 @printf(i8* nocapture readonly, ...)
+
+attributes #0 = { "use-soft-float"="true" }




More information about the llvm-commits mailing list