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 @@ -7083,6 +7083,52 @@ continue; } + // Vector arguments passed to VarArg functions need custom handling when + // they are passed (at least partially) in GPRs. + if (VA.isMemLoc() && VA.needsCustom() && ValVT.isVector()) { + assert(CFlags.IsVarArg && "Custom MemLocs only used for Vector args."); + // Store value to its stack slot. + SDValue PtrOff = + DAG.getConstant(VA.getLocMemOffset(), dl, StackPtr.getValueType()); + PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff); + SDValue Store = + DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()); + MemOpChains.push_back(Store); + const unsigned OriginalValNo = VA.getValNo(); + // Then load the GPRs from the stack + unsigned LoadOffset = 0; + auto HandleCustomVecRegLoc = [&]() { + assert(I != E && "Unexpected end of CCvalAssigns."); + assert(ArgLocs[I].isRegLoc() && ArgLocs[I].needsCustom() && + "Expected custom RegLoc."); + CCValAssign RegVA = ArgLocs[I++]; + assert(RegVA.getValNo() == OriginalValNo && + "Custom MemLoc ValNo and custom RegLoc ValNo must match."); + SDValue Add = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, + DAG.getConstant(LoadOffset, dl, PtrVT)); + SDValue Load = DAG.getLoad(PtrVT, dl, Store, Add, MachinePointerInfo()); + MemOpChains.push_back(Load.getValue(1)); + RegsToPass.push_back(std::make_pair(RegVA.getLocReg(), Load)); + LoadOffset += PtrByteSize; + }; + + // In 64-bit there will be exactly 2 custom RegLocs that follow, and in + // in 32-bit there will be 2 custom RegLocs if we are passing in R9 and + // R10. + HandleCustomVecRegLoc(); + HandleCustomVecRegLoc(); + + if (I != E && ArgLocs[I].isRegLoc() && ArgLocs[I].needsCustom() && + ArgLocs[I].getValNo() == OriginalValNo) { + assert(!IsPPC64 && + "Only 2 custom RegLocs expected for 64-bit codegen."); + HandleCustomVecRegLoc(); + HandleCustomVecRegLoc(); + } + + continue; + } + if (VA.isMemLoc()) { SDValue PtrOff = DAG.getConstant(VA.getLocMemOffset(), dl, StackPtr.getValueType()); diff --git a/llvm/test/CodeGen/PowerPC/aix-vector-vararg-caller.ll b/llvm/test/CodeGen/PowerPC/aix-vector-vararg-caller.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-vector-vararg-caller.ll @@ -0,0 +1,133 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -verify-machineinstrs -stop-before=ppc-vsx-copy -vec-extabi \ +; RUN: -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff < %s | \ +; RUN: FileCheck --check-prefix=32BIT %s + +; RUN: llc -verify-machineinstrs -stop-before=ppc-vsx-copy -vec-extabi \ +; RUN: -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff < %s | \ +; RUN: FileCheck --check-prefix=64BIT %s + +define <4 x i32> @caller() { + ; 32BIT-LABEL: name: caller + ; 32BIT: bb.0.entry: + ; 32BIT: ADJCALLSTACKDOWN 176, 0, implicit-def dead $r1, implicit $r1 + ; 32BIT: [[LWZtoc:%[0-9]+]]:gprc = LWZtoc %const.0, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc]] :: (load 16 from constant-pool) + ; 32BIT: [[LI:%[0-9]+]]:gprc = LI 48 + ; 32BIT: STXVW4X killed [[LXVW4X]], $r1, killed [[LI]] :: (store 16) + ; 32BIT: [[LWZtoc1:%[0-9]+]]:gprc = LWZtoc %const.1, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X1:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc1]] :: (load 16 from constant-pool) + ; 32BIT: [[LI1:%[0-9]+]]:gprc = LI 32 + ; 32BIT: STXVW4X killed [[LXVW4X1]], $r1, killed [[LI1]] :: (store 16) + ; 32BIT: [[LWZtoc2:%[0-9]+]]:gprc = LWZtoc %const.2, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X2:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc2]] :: (load 16 from constant-pool) + ; 32BIT: [[LI2:%[0-9]+]]:gprc = LI 160 + ; 32BIT: STXVW4X killed [[LXVW4X2]], $r1, killed [[LI2]] :: (store 16) + ; 32BIT: [[LWZtoc3:%[0-9]+]]:gprc = LWZtoc %const.3, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X3:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc3]] :: (load 16 from constant-pool) + ; 32BIT: [[LI3:%[0-9]+]]:gprc = LI 144 + ; 32BIT: STXVW4X killed [[LXVW4X3]], $r1, killed [[LI3]] :: (store 16) + ; 32BIT: [[LWZtoc4:%[0-9]+]]:gprc = LWZtoc %const.4, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X4:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc4]] :: (load 16 from constant-pool) + ; 32BIT: [[LI4:%[0-9]+]]:gprc = LI 128 + ; 32BIT: STXVW4X killed [[LXVW4X4]], $r1, killed [[LI4]] :: (store 16) + ; 32BIT: [[LWZtoc5:%[0-9]+]]:gprc = LWZtoc %const.5, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X5:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc5]] :: (load 16 from constant-pool) + ; 32BIT: [[LI5:%[0-9]+]]:gprc = LI 112 + ; 32BIT: STXVW4X killed [[LXVW4X5]], $r1, killed [[LI5]] :: (store 16) + ; 32BIT: [[LWZtoc6:%[0-9]+]]:gprc = LWZtoc %const.6, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X6:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc6]] :: (load 16 from constant-pool) + ; 32BIT: [[LI6:%[0-9]+]]:gprc = LI 96 + ; 32BIT: STXVW4X killed [[LXVW4X6]], $r1, killed [[LI6]] :: (store 16) + ; 32BIT: [[LWZtoc7:%[0-9]+]]:gprc = LWZtoc %const.7, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X7:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc7]] :: (load 16 from constant-pool) + ; 32BIT: [[LI7:%[0-9]+]]:gprc = LI 80 + ; 32BIT: STXVW4X killed [[LXVW4X7]], $r1, killed [[LI7]] :: (store 16) + ; 32BIT: [[LWZtoc8:%[0-9]+]]:gprc = LWZtoc %const.8, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X8:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc8]] :: (load 16 from constant-pool) + ; 32BIT: [[LI8:%[0-9]+]]:gprc = LI 64 + ; 32BIT: STXVW4X killed [[LXVW4X8]], $r1, killed [[LI8]] :: (store 16) + ; 32BIT: [[LWZ:%[0-9]+]]:gprc = LWZ 52, $r1 :: (load 4) + ; 32BIT: [[LWZ1:%[0-9]+]]:gprc = LWZ 48, $r1 :: (load 4) + ; 32BIT: [[LWZ2:%[0-9]+]]:gprc = LWZ 44, $r1 :: (load 4) + ; 32BIT: [[LWZ3:%[0-9]+]]:gprc = LWZ 40, $r1 :: (load 4) + ; 32BIT: [[LWZ4:%[0-9]+]]:gprc = LWZ 36, $r1 :: (load 4) + ; 32BIT: [[LWZ5:%[0-9]+]]:gprc = LWZ 32, $r1 :: (load 4) + ; 32BIT: [[LI9:%[0-9]+]]:gprc = LI 9 + ; 32BIT: $r3 = COPY [[LI9]] + ; 32BIT: $r5 = COPY [[LWZ5]] + ; 32BIT: $r6 = COPY [[LWZ4]] + ; 32BIT: $r7 = COPY [[LWZ3]] + ; 32BIT: $r8 = COPY [[LWZ2]] + ; 32BIT: $r9 = COPY [[LWZ1]] + ; 32BIT: $r10 = COPY [[LWZ]] + ; 32BIT: BL_NOP , csr_aix32_altivec, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1, implicit-def $v2 + ; 32BIT: ADJCALLSTACKUP 176, 0, implicit-def dead $r1, implicit $r1 + ; 32BIT: [[COPY:%[0-9]+]]:vsrc = COPY $v2 + ; 32BIT: $v2 = COPY [[COPY]] + ; 32BIT: BLR implicit $lr, implicit $rm, implicit $v2 + + ; 64BIT-LABEL: name: caller + ; 64BIT: bb.0.entry: + ; 64BIT: ADJCALLSTACKDOWN 208, 0, implicit-def dead $r1, implicit $r1 + ; 64BIT: [[LDtocCPT:%[0-9]+]]:g8rc = LDtocCPT %const.0, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_:%[0-9]+]]:g8rc = LI8 96 + ; 64BIT: STXVW4X killed [[LXVW4X]], $x1, killed [[LI8_]] :: (store 16) + ; 64BIT: [[LDtocCPT1:%[0-9]+]]:g8rc = LDtocCPT %const.1, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X1:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT1]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_1:%[0-9]+]]:g8rc = LI8 80 + ; 64BIT: STXVW4X killed [[LXVW4X1]], $x1, killed [[LI8_1]] :: (store 16) + ; 64BIT: [[LDtocCPT2:%[0-9]+]]:g8rc = LDtocCPT %const.2, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X2:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT2]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_2:%[0-9]+]]:g8rc = LI8 64 + ; 64BIT: STXVW4X killed [[LXVW4X2]], $x1, killed [[LI8_2]] :: (store 16) + ; 64BIT: [[LDtocCPT3:%[0-9]+]]:g8rc = LDtocCPT %const.3, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X3:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT3]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_3:%[0-9]+]]:g8rc = LI8 192 + ; 64BIT: STXVW4X killed [[LXVW4X3]], $x1, killed [[LI8_3]] :: (store 16) + ; 64BIT: [[LDtocCPT4:%[0-9]+]]:g8rc = LDtocCPT %const.4, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X4:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT4]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_4:%[0-9]+]]:g8rc = LI8 176 + ; 64BIT: STXVW4X killed [[LXVW4X4]], $x1, killed [[LI8_4]] :: (store 16) + ; 64BIT: [[LDtocCPT5:%[0-9]+]]:g8rc = LDtocCPT %const.5, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X5:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT5]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_5:%[0-9]+]]:g8rc = LI8 160 + ; 64BIT: STXVW4X killed [[LXVW4X5]], $x1, killed [[LI8_5]] :: (store 16) + ; 64BIT: [[LDtocCPT6:%[0-9]+]]:g8rc = LDtocCPT %const.6, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X6:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT6]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_6:%[0-9]+]]:g8rc = LI8 144 + ; 64BIT: STXVW4X killed [[LXVW4X6]], $x1, killed [[LI8_6]] :: (store 16) + ; 64BIT: [[LDtocCPT7:%[0-9]+]]:g8rc = LDtocCPT %const.7, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X7:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT7]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_7:%[0-9]+]]:g8rc = LI8 128 + ; 64BIT: STXVW4X killed [[LXVW4X7]], $x1, killed [[LI8_7]] :: (store 16) + ; 64BIT: [[LDtocCPT8:%[0-9]+]]:g8rc = LDtocCPT %const.8, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X8:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT8]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_8:%[0-9]+]]:g8rc = LI8 112 + ; 64BIT: STXVW4X killed [[LXVW4X8]], $x1, killed [[LI8_8]] :: (store 16) + ; 64BIT: [[LD:%[0-9]+]]:g8rc = LD 104, $x1 :: (load 8) + ; 64BIT: [[LD1:%[0-9]+]]:g8rc = LD 96, $x1 :: (load 8) + ; 64BIT: [[LD2:%[0-9]+]]:g8rc = LD 88, $x1 :: (load 8) + ; 64BIT: [[LD3:%[0-9]+]]:g8rc = LD 80, $x1 :: (load 8) + ; 64BIT: [[LD4:%[0-9]+]]:g8rc = LD 72, $x1 :: (load 8) + ; 64BIT: [[LD5:%[0-9]+]]:g8rc = LD 64, $x1 :: (load 8) + ; 64BIT: [[LI8_9:%[0-9]+]]:g8rc = LI8 9 + ; 64BIT: $x3 = COPY [[LI8_9]] + ; 64BIT: $x5 = COPY [[LD5]] + ; 64BIT: $x6 = COPY [[LD4]] + ; 64BIT: $x7 = COPY [[LD3]] + ; 64BIT: $x8 = COPY [[LD2]] + ; 64BIT: $x9 = COPY [[LD1]] + ; 64BIT: $x10 = COPY [[LD]] + ; 64BIT: BL8_NOP , csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x5, implicit $x6, implicit $x7, implicit $x8, implicit $x9, implicit $x10, implicit $x2, implicit-def $r1, implicit-def $v2 + ; 64BIT: ADJCALLSTACKUP 208, 0, implicit-def dead $r1, implicit $r1 + ; 64BIT: [[COPY:%[0-9]+]]:vsrc = COPY $v2 + ; 64BIT: $v2 = COPY [[COPY]] + ; 64BIT: BLR8 implicit $lr8, implicit $rm, implicit $v2 + entry: + %call = tail call <4 x i32> (i32, ...) @callee(i32 9, <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> ) + ret <4 x i32> %call +} + +declare <4 x i32> @callee(i32, ...) diff --git a/llvm/test/CodeGen/PowerPC/aix-vector-vararg-fixed-caller.ll b/llvm/test/CodeGen/PowerPC/aix-vector-vararg-fixed-caller.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-vector-vararg-fixed-caller.ll @@ -0,0 +1,90 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -verify-machineinstrs -stop-before=ppc-vsx-copy -vec-extabi \ +; RUN: -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff < %s | \ +; RUN: FileCheck --check-prefix=32BIT %s + +; RUN: llc -verify-machineinstrs -stop-before=ppc-vsx-copy -vec-extabi \ +; RUN: -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff < %s | \ +; RUN: FileCheck --check-prefix=64BIT %s + +define void @caller() { + ; 32BIT-LABEL: name: caller + ; 32BIT: bb.0.entry: + ; 32BIT: ADJCALLSTACKDOWN 88, 0, implicit-def dead $r1, implicit $r1 + ; 32BIT: [[LWZtoc:%[0-9]+]]:gprc = LWZtoc %const.0, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc]] :: (load 16 from constant-pool) + ; 32BIT: [[LI:%[0-9]+]]:gprc = LI 64 + ; 32BIT: STXVW4X killed [[LXVW4X]], $r1, killed [[LI]] :: (store 16) + ; 32BIT: [[LIS:%[0-9]+]]:gprc = LIS 38314 + ; 32BIT: [[ORI:%[0-9]+]]:gprc = ORI killed [[LIS]], 63376 + ; 32BIT: STW killed [[ORI]], 84, $r1 :: (store 4 + 4, basealign 8) + ; 32BIT: [[LIS1:%[0-9]+]]:gprc = LIS 16389 + ; 32BIT: [[ORI1:%[0-9]+]]:gprc = ORI killed [[LIS1]], 48905 + ; 32BIT: STW killed [[ORI1]], 80, $r1 :: (store 4, align 8) + ; 32BIT: [[LWZtoc1:%[0-9]+]]:gprc = LWZtoc %const.1, $r2 :: (load 4 from got) + ; 32BIT: [[LXVW4X1:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[LWZtoc1]] :: (load 16 from constant-pool) + ; 32BIT: [[LWZtoc2:%[0-9]+]]:gprc = LWZtoc %const.2, $r2 :: (load 4 from got) + ; 32BIT: [[XFLOADf64_:%[0-9]+]]:vsfrc = XFLOADf64 $zero, killed [[LWZtoc2]] :: (load 8 from constant-pool) + ; 32BIT: [[LIS2:%[0-9]+]]:gprc = LIS 16393 + ; 32BIT: [[ORI2:%[0-9]+]]:gprc = ORI killed [[LIS2]], 8697 + ; 32BIT: [[LIS3:%[0-9]+]]:gprc = LIS 61467 + ; 32BIT: [[ORI3:%[0-9]+]]:gprc = ORI killed [[LIS3]], 34414 + ; 32BIT: [[LWZtoc3:%[0-9]+]]:gprc = LWZtoc %const.3, $r2 :: (load 4 from got) + ; 32BIT: [[XFLOADf64_1:%[0-9]+]]:vsfrc = XFLOADf64 $zero, killed [[LWZtoc3]] :: (load 8 from constant-pool) + ; 32BIT: [[LI1:%[0-9]+]]:gprc = LI 55 + ; 32BIT: $r3 = COPY [[LI1]] + ; 32BIT: $v2 = COPY [[LXVW4X1]] + ; 32BIT: $f1 = COPY [[XFLOADf64_]] + ; 32BIT: $r9 = COPY [[ORI2]] + ; 32BIT: $r10 = COPY [[ORI3]] + ; 32BIT: $f2 = COPY [[XFLOADf64_1]] + ; 32BIT: BL_NOP , csr_aix32_altivec, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $v2, implicit $f1, implicit $r9, implicit $r10, implicit $f2, implicit $r2, implicit-def $r1, implicit-def $v2 + ; 32BIT: ADJCALLSTACKUP 88, 0, implicit-def dead $r1, implicit $r1 + ; 32BIT: [[COPY:%[0-9]+]]:vsrc = COPY $v2 + ; 32BIT: BLR implicit $lr, implicit $rm + + ; 64BIT-LABEL: name: caller + ; 64BIT: bb.0.entry: + ; 64BIT: ADJCALLSTACKDOWN 120, 0, implicit-def dead $r1, implicit $r1 + ; 64BIT: [[LDtocCPT:%[0-9]+]]:g8rc = LDtocCPT %const.0, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT]] :: (load 16 from constant-pool) + ; 64BIT: [[LI8_:%[0-9]+]]:g8rc = LI8 96 + ; 64BIT: STXVW4X killed [[LXVW4X]], $x1, killed [[LI8_]] :: (store 16) + ; 64BIT: [[LIS8_:%[0-9]+]]:g8rc = LIS8 16389 + ; 64BIT: [[ORI8_:%[0-9]+]]:g8rc = ORI8 killed [[LIS8_]], 48905 + ; 64BIT: [[RLDIC:%[0-9]+]]:g8rc = RLDIC killed [[ORI8_]], 32, 1 + ; 64BIT: [[ORIS8_:%[0-9]+]]:g8rc = ORIS8 killed [[RLDIC]], 38314 + ; 64BIT: [[ORI8_1:%[0-9]+]]:g8rc = ORI8 killed [[ORIS8_]], 63376 + ; 64BIT: STD killed [[ORI8_1]], 112, $x1 :: (store 8) + ; 64BIT: [[LDtocCPT1:%[0-9]+]]:g8rc = LDtocCPT %const.1, $x2 :: (load 8 from got) + ; 64BIT: [[LXVW4X1:%[0-9]+]]:vsrc = LXVW4X $zero8, killed [[LDtocCPT1]] :: (load 16 from constant-pool) + ; 64BIT: [[LD:%[0-9]+]]:g8rc = LD 104, $x1 :: (load 8) + ; 64BIT: [[LD1:%[0-9]+]]:g8rc = LD 96, $x1 :: (load 8) + ; 64BIT: [[LDtocCPT2:%[0-9]+]]:g8rc = LDtocCPT %const.2, $x2 :: (load 8 from got) + ; 64BIT: [[XFLOADf64_:%[0-9]+]]:vsfrc = XFLOADf64 $zero8, killed [[LDtocCPT2]] :: (load 8 from constant-pool) + ; 64BIT: [[LDtocCPT3:%[0-9]+]]:g8rc = LDtocCPT %const.3, $x2 :: (load 8 from got) + ; 64BIT: [[XFLOADf64_1:%[0-9]+]]:vsfrc = XFLOADf64 $zero8, killed [[LDtocCPT3]] :: (load 8 from constant-pool) + ; 64BIT: [[LIS8_1:%[0-9]+]]:g8rc = LIS8 16393 + ; 64BIT: [[ORI8_2:%[0-9]+]]:g8rc = ORI8 killed [[LIS8_1]], 8697 + ; 64BIT: [[RLDIC1:%[0-9]+]]:g8rc = RLDIC killed [[ORI8_2]], 32, 1 + ; 64BIT: [[ORIS8_1:%[0-9]+]]:g8rc = ORIS8 killed [[RLDIC1]], 61467 + ; 64BIT: [[ORI8_3:%[0-9]+]]:g8rc = ORI8 killed [[ORIS8_1]], 34414 + ; 64BIT: [[LI8_1:%[0-9]+]]:g8rc = LI8 55 + ; 64BIT: $x3 = COPY [[LI8_1]] + ; 64BIT: $v2 = COPY [[LXVW4X1]] + ; 64BIT: $f1 = COPY [[XFLOADf64_]] + ; 64BIT: $x7 = COPY [[ORI8_3]] + ; 64BIT: $x9 = COPY [[LD1]] + ; 64BIT: $x10 = COPY [[LD]] + ; 64BIT: $f2 = COPY [[XFLOADf64_1]] + ; 64BIT: BL8_NOP , csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $v2, implicit $f1, implicit $x7, implicit $x9, implicit $x10, implicit $f2, implicit $x2, implicit-def $r1, implicit-def $v2 + ; 64BIT: ADJCALLSTACKUP 120, 0, implicit-def dead $r1, implicit $r1 + ; 64BIT: [[COPY:%[0-9]+]]:vsrc = COPY $v2 + ; 64BIT: BLR8 implicit $lr8, implicit $rm +entry: + %call = tail call <4 x i32> (i32, <4 x i32>, double, ...) @callee(i32 signext 55, <4 x i32> , double 3.141590e+00, <4 x i32> , double 2.718280e+00) + ret void +} + +declare <4 x i32> @callee(i32 signext, <4 x i32>, double, ...) + diff --git a/llvm/test/CodeGen/PowerPC/aix32-vector-vararg-caller-split.ll b/llvm/test/CodeGen/PowerPC/aix32-vector-vararg-caller-split.ll --- a/llvm/test/CodeGen/PowerPC/aix32-vector-vararg-caller-split.ll +++ b/llvm/test/CodeGen/PowerPC/aix32-vector-vararg-caller-split.ll @@ -1,13 +1,47 @@ -; RUN: not --crash llc -verify-machineinstrs -stop-before=ppc-vsx-copy -vec-extabi \ +; RUN: llc -verify-machineinstrs -stop-before=ppc-vsx-copy -vec-extabi \ ; RUN: -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | \ ; RUN: FileCheck %s define void @caller() { entry: - %call = tail call <4 x i32> (double, double, double, ...) @split_spill(double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, <4 x i32> ) + %call = tail call <4 x i32> (double, double, double, ...) @split_spill(double 0.000000e+00, double 1.000000e+00, double 2.000000e+00, <4 x i32> ) ret void } declare <4 x i32> @split_spill(double, double, double, ...) -; CHECK: ERROR: Unexpected register handling for calling convention. +; CHECK: ADJCALLSTACKDOWN 64, 0, implicit-def dead $r1, implicit $r1 +; CHECK: [[VECCONSTADDR:%[0-9]+]]:gprc = LWZtoc %const.0, $r2 :: (load 4 from got) +; CHECK: [[VECCONST:%[0-9]+]]:vsrc = LXVW4X $zero, killed [[VECCONSTADDR]] :: (load 16 from constant-pool) +; CHECK: [[STACKOFFSET:%[0-9]+]]:gprc = LI 48 +; CHECK: STXVW4X killed [[VECCONST]], $r1, killed [[STACKOFFSET]] :: (store 16) +; CHECK-DAG: [[ELEMENT1:%[0-9]+]]:gprc = LWZ 48, $r1 :: (load 4) +; CHECK-DAG: [[ELEMENT2:%[0-9]+]]:gprc = LWZ 52, $r1 :: (load 4) +; CHECK: [[FLOAT1ADDR:%[0-9]+]]:gprc_and_gprc_nor0 = LWZtoc %const.1, $r2 :: (load 4 from got) +; CHECK: [[FLOAT1:%[0-9]+]]:f4rc = LFS 0, killed [[FLOAT1ADDR]] :: (load 4 from constant-pool) +; CHECK: [[DOUBLE1:%[0-9]+]]:f8rc = COPY [[FLOAT1]] +; CHECK: [[FLOAT2ADDR:%[0-9]+]]:gprc_and_gprc_nor0 = LWZtoc %const.2, $r2 :: (load 4 from got) +; CHECK: [[FLOAT2:%[0-9]+]]:f4rc = LFS 0, killed [[FLOAT2ADDR]] :: (load 4 from constant-pool) +; CHECK: [[DOUBLE2:%[0-9]+]]:f8rc = COPY [[FLOAT2]] + +; CHECK: [[DZERO:%[0-9]+]]:vsfrc = XXLXORdpz +; CHECK: [[DTOI1:%[0-9]+]]:gprc = LIS 16368 +; CHECK: [[DTOI2:%[0-9]+]]:gprc = LIS 16384 +; CHECK: [[IZERO:%[0-9]+]]:gprc = LI 0 + +; CHECK-DAG: $f1 = COPY [[DZERO]] +; CHECK-DAG: $r3 = COPY [[IZERO]] +; CHECK-DAG: $r4 = COPY [[IZERO]] + +; CHECK-DAG: $f2 = COPY [[DOUBLE1]] +; CHECK-DAG: $r5 = COPY [[DTOI1]] +; CHECK-DAG: $r6 = COPY [[IZERO]] + +; CHECK-DAG: $f3 = COPY [[DOUBLE2]] +; CHECK-DAG: $r7 = COPY [[DTOI2]] +; CHECK-DAG: $r8 = COPY [[IZERO]] + +; CHECK-DAG: $r9 = COPY [[ELEMENT1]] +; CHECK-DAG: $r10 = COPY [[ELEMENT2]] + +; CHECK: BL_NOP , csr_aix32_altivec, implicit-def dead $lr, implicit $rm, implicit $f1, implicit $r3, implicit $r4, implicit $f2, implicit $r5, implicit $r6, implicit $f3, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1, implicit-def $v2