diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -6796,9 +6796,18 @@ CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) { + const PPCSubtarget &Subtarget = static_cast( + State.getMachineFunction().getSubtarget()); + const bool IsPPC64 = Subtarget.isPPC64(); + const unsigned PtrByteSize = IsPPC64 ? 8 : 4; + const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32; + if (ValVT == MVT::f128) report_fatal_error("f128 is unimplemented on AIX."); + if (ValVT.isInteger() && (ValVT.getSizeInBits() > RegVT.getSizeInBits())) + report_fatal_error("Unexpected argument exceeds word size."); + if (ArgFlags.isByVal()) report_fatal_error("Passing structure by value is unimplemented."); @@ -6808,11 +6817,6 @@ if (ValVT.isVector() || LocVT.isVector()) report_fatal_error("Vector arguments are unimplemented on AIX."); - const PPCSubtarget &Subtarget = static_cast( - 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 +6835,12 @@ 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 +6858,6 @@ 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 +7081,21 @@ 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 --- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll @@ -1039,18 +1039,18 @@ ; 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 , 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 @@ ; 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