[llvm] c7b6fa8 - [AIX] Extend int arguments to register width when passed in stack memory.

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 5 08:50:06 PST 2020


Author: Chris Bowler
Date: 2020-03-05T11:49:16-05:00
New Revision: c7b6fa8f4b860b251e6fc5956955583b8b2a9c33

URL: https://github.com/llvm/llvm-project/commit/c7b6fa8f4b860b251e6fc5956955583b8b2a9c33
DIFF: https://github.com/llvm/llvm-project/commit/c7b6fa8f4b860b251e6fc5956955583b8b2a9c33.diff

LOG: [AIX] Extend int arguments to register width when passed in stack memory.

This is a follow up to the previous patch: [AIX] Implement caller
arguments passed in stack memory.

This corrects a defect in AIX 64-bit where an i32 is written to the
stack with stw (4 bytes) rather than the expected std (8 bytes.) Integer
arguments pass on the stack as images of their register representation.

I also took the opportunity to tidy up some of the calling convention
AIX tests I added in my last commit. This patch adds the missed assembly
expected output for the stack arg int case, which would have caught this
problem.

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

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/test/CodeGen/PowerPC/aix-cc-abi.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 3615f0cf2b81..9e5f2f118984 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -6796,6 +6796,16 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
                    CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
                    CCState &State) {
 
+  const PPCSubtarget &Subtarget = static_cast<const PPCSubtarget &>(
+      State.getMachineFunction().getSubtarget());
+  const bool IsPPC64 = Subtarget.isPPC64();
+  const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
+  const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
+
+  assert((!ValVT.isInteger() ||
+          (ValVT.getSizeInBits() <= RegVT.getSizeInBits())) &&
+         "Integer argument exceeds register size: should have been legalized");
+
   if (ValVT == MVT::f128)
     report_fatal_error("f128 is unimplemented on AIX.");
 
@@ -6808,11 +6818,6 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
   if (ValVT.isVector() || LocVT.isVector())
     report_fatal_error("Vector arguments are unimplemented on AIX.");
 
-  const PPCSubtarget &Subtarget = static_cast<const PPCSubtarget &>(
-      State.getMachineFunction().getSubtarget());
-  const bool IsPPC64 = Subtarget.isPPC64();
-  const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
-
   static const MCPhysReg GPR_32[] = {// 32-bit registers.
                                      PPC::R3, PPC::R4, PPC::R5, PPC::R6,
                                      PPC::R7, PPC::R8, PPC::R9, PPC::R10};
@@ -6831,14 +6836,12 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
   case MVT::i1:
   case MVT::i32: {
     const unsigned Offset = State.AllocateStack(PtrByteSize, PtrByteSize);
-    const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
-    if (unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
-      // Promote integers if needed.
-      if (ValVT.getSizeInBits() < RegVT.getSizeInBits())
-        LocInfo = ArgFlags.isSExt() ? CCValAssign::LocInfo::SExt
-                                    : CCValAssign::LocInfo::ZExt;
+    // AIX integer arguments are always passed in register width.
+    if (ValVT.getSizeInBits() < RegVT.getSizeInBits())
+      LocInfo = ArgFlags.isSExt() ? CCValAssign::LocInfo::SExt
+                                  : CCValAssign::LocInfo::ZExt;
+    if (unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
       State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, RegVT, LocInfo));
-    }
     else
       State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, RegVT, LocInfo));
 
@@ -6856,7 +6859,6 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
       State.addLoc(CCValAssign::getReg(ValNo, ValVT, FReg, LocVT, LocInfo));
 
     // Reserve and initialize GPRs or initialize the PSA as required.
-    const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
     for (unsigned I = 0; I < StoreSize; I += PtrByteSize) {
       if (unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
         assert(FReg && "An FPR should be available when a GPR is reserved.");
@@ -7080,21 +7082,21 @@ SDValue PPCTargetLowering::LowerCall_AIX(
     if (!VA.isRegLoc() && !VA.isMemLoc())
       report_fatal_error("Unexpected location for function call argument.");
 
+    switch (VA.getLocInfo()) {
+    default:
+      report_fatal_error("Unexpected argument extension type.");
+    case CCValAssign::Full:
+      break;
+    case CCValAssign::ZExt:
+      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
+      break;
+    case CCValAssign::SExt:
+      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
+      break;
+    }
+
     if (VA.isRegLoc() && !VA.needsCustom()) {
-      switch (VA.getLocInfo()) {
-      default:
-        report_fatal_error("Unexpected argument extension type.");
-      case CCValAssign::Full:
-        break;
-      case CCValAssign::ZExt:
-        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
-        break;
-      case CCValAssign::SExt:
-        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
-        break;
-      }
       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
-
       continue;
     }
 

diff  --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
index 2a770cbb6de6..b7c21242c7bd 100644
--- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll
@@ -1039,18 +1039,18 @@ declare void @test_stackarg_int(i32, i32, i32, i32, i32, i32, i32, i32, i8 zeroe
 ; 64BIT-DAG:   $x9 = LI8 7
 ; 64BIT-DAG:   $x10 = LI8 8
 ; 64BIT-DAG:   renamable $x[[REGCADDR:[0-9]+]] = LDtoc @c, $x2 :: (load 8 from got)
-; 64BIT-DAG:   renamable $r[[REGC:[0-9]+]] = LBZ 0, killed renamable $x[[REGCADDR]] :: (dereferenceable load 1 from @c)
-; 64BIT-DAG:   STW killed renamable $r[[REGC]], 112, $x1 :: (store 4)
+; 64BIT-DAG:   renamable $x[[REGC:[0-9]+]] = LBZ8 0, killed renamable $x[[REGCADDR]] :: (dereferenceable load 1 from @c)
+; 64BIT-DAG:   STD killed renamable $x[[REGC]], 112, $x1 :: (store 8)
 ; 64BIT-DAG:   renamable $x[[REGSIADDR:[0-9]+]] = LDtoc @si, $x2 :: (load 8 from got)
-; 64BIT-DAG:   renamable $r[[REGSI:[0-9]+]] = LHA 0, killed renamable $x[[REGSIADDR]] :: (dereferenceable load 2 from @si)
-; 64BIT-DAG:   STW killed renamable $r[[REGSI]], 120, $x1 :: (store 4)
+; 64BIT-DAG:   renamable $x[[REGSI:[0-9]+]] = LHA8 0, killed renamable $x[[REGSIADDR]] :: (dereferenceable load 2 from @si)
+; 64BIT-DAG:   STD killed renamable $x[[REGSI]], 120, $x1 :: (store 8)
 ; 64BIT-DAG:   renamable $x[[REGIADDR:[0-9]+]] = LDtoc @i, $x2 :: (load 8 from got)
-; 64BIT-DAG:   renamable $r[[REGI:[0-9]+]] = LWZ 0, killed renamable $x[[REGIADDR]] :: (dereferenceable load 4 from @i)
-; 64BIT-DAG:   STW killed renamable $r[[REGI]], 128, $x1 :: (store 4)
+; 64BIT-DAG:   renamable $x[[REGI:[0-9]+]] = LWZ8 0, killed renamable $x[[REGIADDR]] :: (dereferenceable load 4 from @i)
+; 64BIT-DAG:   STD killed renamable $x[[REGI]], 128, $x1 :: (store 8)
 ; 64BIT-DAG:   renamable $x[[REGLLIADDR:[0-9]+]] = LDtoc @lli, $x2 :: (load 8 from got)
 ; 64BIT-DAG:   renamable $x[[REGLLI:[0-9]+]] = LD 0, killed renamable $x[[REGLLIADDR]] :: (dereferenceable load 8 from @lli)
 ; 64BIT-DAG:   STD killed renamable $x[[REGLLI]], 136, $x1 :: (store 8)
-; 64BIT-DAG:   STW renamable $r[[REGI]], 144, $x1 :: (store 4)
+; 64BIT-DAG:   STD renamable $x[[REGI]], 144, $x1 :: (store 8)
 ; 64BIT-NEXT:  BL8_NOP <mcsymbol .test_stackarg_int>, csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit $x8, implicit $x9, implicit $x10, implicit $x2, implicit-def $r1
 ; 64BIT-NEXT:  ADJCALLSTACKUP 152, 0, implicit-def dead $r1, implicit $r1
 
@@ -1066,17 +1066,17 @@ declare void @test_stackarg_int(i32, i32, i32, i32, i32, i32, i32, i32, i8 zeroe
 ; ASM64PWR4-DAG:   li 10, 8
 ; ASM64PWR4-DAG:   ld [[REGCADDR:[0-9]+]], LC5(2)
 ; ASM64PWR4-DAG:   lbz [[REGC:[0-9]+]], 0([[REGCADDR]])
-; ASM64PWR4-DAG:   stw [[REGC]], 112(1)
+; ASM64PWR4-DAG:   std [[REGC]], 112(1)
 ; ASM64PWR4-DAG:   ld [[REGSIADDR:[0-9]+]], LC3(2)
 ; ASM64PWR4-DAG:   lha [[REGSI:[0-9]+]], 0([[REGSIADDR]])
-; ASM64PWR4-DAG:   stw [[REGSI]], 120(1)
+; ASM64PWR4-DAG:   std [[REGSI]], 120(1)
 ; ASM64PWR4-DAG:   ld [[REGIADDR:[0-9]+]], LC4(2)
 ; ASM64PWR4-DAG:   lwz [[REGI:[0-9]+]], 0([[REGIADDR]])
-; ASM64PWR4-DAG:   stw [[REGI]], 128(1)
+; ASM64PWR4-DAG:   std [[REGI]], 128(1)
 ; ASM64PWR4-DAG:   ld [[REGLLIADDR:[0-9]+]], LC6(2)
 ; ASM64PWR4-DAG:   ld [[REGLLI:[0-9]+]], 0([[REGLLIADDR]])
 ; ASM64PWR4-DAG:   std [[REGLLI]], 136(1)
-; ASM64PWR4-DAG:   stw [[REGI]], 144(1)
+; ASM64PWR4-DAG:   std [[REGI]], 144(1)
 ; ASM64PWR4-NEXT:  bl .test_stackarg_int
 ; ASM64PWR4-NEXT:  nop
 


        


More information about the llvm-commits mailing list