From: Sean Fertile Date: Wed, 15 Apr 2020 13:58:22 +0000 (-0400) Subject: [PowerPC][AIX] Pass ByVal formal args that span registers and stack. X-Git-Tag: llvmorg-12-init~7559 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2a3cf5e5834302a9525a721627c17902399b8d62;p=platform%2Fupstream%2Fllvm.git [PowerPC][AIX] Pass ByVal formal args that span registers and stack. Implement passing of ByVal formal arguments when the argument is passed partly in the argument registers, with the remainder of the argument passed on the stack. Differential Revision: https://reviews.llvm.org/D78515 --- diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 69dca9b..ac2483c 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7232,20 +7232,24 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX( unsigned Offset = 0; HandleRegLoc(VA.getLocReg(), Offset); Offset += PtrByteSize; - for (; Offset != StackSize; Offset += PtrByteSize) { - assert(I != End && - "Expecting enough RegLocs to copy entire ByVal arg."); - - if (!ArgLocs[I].isRegLoc()) - report_fatal_error("Passing ByVals split between registers and stack " - "not yet implemented."); - + for (; Offset != StackSize && ArgLocs[I].isRegLoc(); + Offset += PtrByteSize) { assert(ArgLocs[I].getValNo() == VA.getValNo() && - "Expecting more RegLocs for ByVal argument."); + "RegLocs should be for ByVal argument."); const CCValAssign RL = ArgLocs[I++]; HandleRegLoc(RL.getLocReg(), Offset); } + + if (Offset != StackSize) { + assert(ArgLocs[I].getValNo() == VA.getValNo() && + "Expected MemLoc for remaining bytes."); + assert(ArgLocs[I].isMemLoc() && "Expected MemLoc for remaining bytes."); + // Consume the MemLoc.The InVal has already been emitted, so nothing + // more needs to be done. + ++I; + } + continue; } diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-byval-limitation1.ll b/llvm/test/CodeGen/PowerPC/aix-cc-byval-limitation1.ll deleted file mode 100644 index eca919b..0000000 --- a/llvm/test/CodeGen/PowerPC/aix-cc-byval-limitation1.ll +++ /dev/null @@ -1,11 +0,0 @@ -; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s -; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s - -%struct.S = type { [65 x i8] } - -define void @foo(%struct.S* byval(%struct.S) align 1 %s) { -entry: - ret void -} - -; CHECK: LLVM ERROR: Passing ByVals split between registers and stack not yet implemented. diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll b/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll index a87a589..3f24a43 100644 --- a/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll @@ -176,8 +176,6 @@ entry: ret void } -declare void @test_byval_mem3(i32, float, %struct_S57* byval(%struct_S57) align 1) - ; CHECK-LABEL: name: call_test_byval_mem3 ; Confirm the expected memcpy call is independent of the call to test_byval_mem3. @@ -236,6 +234,53 @@ declare void @test_byval_mem3(i32, float, %struct_S57* byval(%struct_S57) align ; ASM64BIT: bl .test_byval_mem3 ; ASM64BIT: addi 1, 1, 128 +define void @test_byval_mem3(i32, float, %struct_S57* byval(%struct_S57) align 1 %s) { +entry: + ret void +} + + +;CHECK-LABEL: name: test_byval_mem3 + +; 32BIT: fixedStack: +; 32BIT-NEXT: - { id: 0, type: default, offset: 32, size: 60, alignment: 16, stack-id: default, + +; 32BIT: bb.0.entry: +; 32BIT-NEXT: liveins: $r5, $r6, $r7, $r8, $r9, $r10 + +; 32BIT-DAG: %2:gprc = COPY $r5 +; 32BIT-DAG: %3:gprc = COPY $r6 +; 32BIT-DAG: %4:gprc = COPY $r7 +; 32BIT-DAG: %5:gprc = COPY $r8 +; 32BIT-DAG: %6:gprc = COPY $r9 +; 32BIT-DAG: %7:gprc = COPY $r10 +; 32BIT-NEXT: STW %2, 0, %fixed-stack.0 :: (store 4 into %fixed-stack.0 +; 32BIT-DAG: STW %3, 4, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 4 +; 32BIT-DAG: STW %4, 8, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 8 +; 32BIT-DAG: STW %5, 12, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 12 +; 32BIT-DAG: STW %6, 16, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 16 +; 32BIT-DAG: STW %7, 20, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 20 +; 32BIT-NEXT: BLR implicit $lr, implicit $rm + +; 64BIT: fixedStack: +; 64BIT-NEXT: - { id: 0, type: default, offset: 64, size: 64, alignment: 16, stack-id: default, + +; 64BIT: bb.0.entry +; 64BIT-NEXT: liveins: $x5, $x6, $x7, $x8, $x9, $x10 + +; 64BIT-DAG: %2:g8rc = COPY $x5 +; 64BIT-DAG: %3:g8rc = COPY $x6 +; 64BIT-DAG: %4:g8rc = COPY $x7 +; 64BIT-DAG: %5:g8rc = COPY $x8 +; 64BIT-DAG: %6:g8rc = COPY $x9 +; 64BIT-DAG: %7:g8rc = COPY $x10 +; 64BIT-NEXT: STD %2, 0, %fixed-stack.0 :: (store 8 into %fixed-stack.0, align 16) +; 64BIT-DAG: STD %3, 8, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 8) +; 64BIT-DAG: STD %4, 16, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 16, align 16) +; 64BIT-DAG: STD %5, 24, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 24) +; 64BIT-DAG: STD %6, 32, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 32, align 16) +; 64BIT-DAG: STD %7, 40, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 40) +; 64BIT-NEXT: BLR8 implicit $lr8, implicit $rm %struct_S31 = type { [31 x i8] } @@ -247,7 +292,6 @@ entry: ret void } -declare void @test_byval_mem4(i32, %struct_S31* byval(%struct_S31) align 1, %struct_S256* byval(%struct_S256) align 1) ; CHECK-LABEL: name: call_test_byval_mem4 @@ -340,3 +384,58 @@ declare void @test_byval_mem4(i32, %struct_S31* byval(%struct_S31) align 1, %str ; ASM64BIT-DAG: ld 10, 16([[REG1]]) ; ASM64BIT: bl .test_byval_mem4 ; ASM64BIT: addi 1, 1, 352 + +define void @test_byval_mem4(i32, %struct_S31* byval(%struct_S31) align 1, %struct_S256* byval(%struct_S256) align 1 %s) { +entry: + ret void +} + +; CHECK-LABEL: name: test_byval_mem4 + +; 32BIT: fixedStack: +; 32BIT: - { id: 0, type: default, offset: 60, size: 256, alignment: 4, stack-id: default, +; 32BIT: - { id: 1, type: default, offset: 28, size: 32, alignment: 4, stack-id: default, +; 32BIT: stack: [] + +; 32BIT: bb.0.entry: +; 32BIT-NEXT: liveins: $r4, $r5, $r6, $r7, $r8, $r9, $r10 + +; 32BIT-DAG: %1:gprc = COPY $r4 +; 32BIT-DAG: %2:gprc = COPY $r5 +; 32BIT-DAG: %3:gprc = COPY $r6 +; 32BIT-DAG: %4:gprc = COPY $r7 +; 32BIT-DAG: %5:gprc = COPY $r8 +; 32BIT-DAG: %6:gprc = COPY $r9 +; 32BIT-DAG: %7:gprc = COPY $r10 +; 32BIT-NEXT: STW %1, 0, %fixed-stack.1 :: (store 4 into %fixed-stack.1 +; 32BIT-DAG: STW %2, 4, %fixed-stack.1 :: (store 4 into %fixed-stack.1 + 4 +; 32BIT-DAG: STW %3, 8, %fixed-stack.1 :: (store 4 into %fixed-stack.1 + 8 +; 32BIT-DAG: STW %4, 12, %fixed-stack.1 :: (store 4 into %fixed-stack.1 + 12 +; 32BIT-DAG: STW %5, 16, %fixed-stack.1 :: (store 4 into %fixed-stack.1 + 16 +; 32BIT-DAG: STW %6, 20, %fixed-stack.1 :: (store 4 into %fixed-stack.1 + 20 +; 32BIT-DAG: STW %7, 24, %fixed-stack.1 :: (store 4 into %fixed-stack.1 + 24 +; 32BIT-NEXT: BLR implicit $lr, implicit $rm + +; 64BIT: fixedStack: +; 64BIT: - { id: 0, type: default, offset: 88, size: 256, alignment: 8, stack-id: default, +; 64BIT: - { id: 1, type: default, offset: 56, size: 32, alignment: 8, stack-id: default, +; 64BIT: stack: [] + +; 64BIT: bb.0.entry: +; 64BIT-NEXT: liveins: $x4, $x5, $x6, $x7, $x8, $x9, $x10 + +; 64BIT-DAG: %1:g8rc = COPY $x4 +; 64BIT-DAG: %2:g8rc = COPY $x5 +; 64BIT-DAG: %3:g8rc = COPY $x6 +; 64BIT-DAG: %4:g8rc = COPY $x7 +; 64BIT-DAG: %5:g8rc = COPY $x8 +; 64BIT-DAG: %6:g8rc = COPY $x9 +; 64BIT-DAG: %7:g8rc = COPY $x10 +; 64BIT-NEXT: STD %1, 0, %fixed-stack.1 :: (store 8 into %fixed-stack.1 +; 64BIT-DAG: STD %2, 8, %fixed-stack.1 :: (store 8 into %fixed-stack.1 + 8 +; 64BIT-DAG: STD %3, 16, %fixed-stack.1 :: (store 8 into %fixed-stack.1 + 16 +; 64BIT-DAG: STD %4, 24, %fixed-stack.1 :: (store 8 into %fixed-stack.1 + 24 +; 64BIT-DAG: STD %5, 0, %fixed-stack.0 :: (store 8 into %fixed-stack.0 +; 64BIT-DAG: STD %6, 8, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 8 +; 64BIT-DAG: STD %7, 16, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 16 +; 64BIT-NEXT: BLR8 implicit $lr8, implicit $rm diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-byval-split.ll b/llvm/test/CodeGen/PowerPC/aix-cc-byval-split.ll index 535998a..e9155f2 100644 --- a/llvm/test/CodeGen/PowerPC/aix-cc-byval-split.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-byval-split.ll @@ -1,10 +1,10 @@ -; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -stop-after=machine-cp \ -; RUN: -mcpu=pwr4 -mattr=-altivec -verify-machineinstrs 2>&1 < %s | FileCheck %s +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -stop-after=machine-cp \ +; RUN: -mcpu=pwr4 -mattr=-altivec -verify-machineinstrs 2>&1 < %s | \ +; RUN: FileCheck --check-prefix=CHECK32 %s -; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -stop-after=machine-cp \ -; RUN: -mcpu=pwr4 -mattr=-altivec -verify-machineinstrs 2>&1 < %s | FileCheck %s - -; CHECK: LLVM ERROR: Passing ByVals split between registers and stack not yet implemented. +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -stop-after=machine-cp \ +; RUN: -mcpu=pwr4 -mattr=-altivec -verify-machineinstrs 2>&1 < %s | \ +; RUN: FileCheck --check-prefix=CHECK64 %s %struct.Spill = type { [12 x i64 ] } @GS = external global %struct.Spill, align 4 @@ -18,3 +18,64 @@ entry: %add = add i64 %a, %b ret i64 %add } + +; CHECK32: name: test +; CHECK32: liveins: +; CHECK32: - { reg: '$r3', virtual-reg: '' } +; CHECK32: - { reg: '$r4', virtual-reg: '' } +; CHECK32: - { reg: '$r5', virtual-reg: '' } +; CHECK32: - { reg: '$r6', virtual-reg: '' } +; CHECK32: - { reg: '$r7', virtual-reg: '' } +; CHECK32: - { reg: '$r8', virtual-reg: '' } +; CHECK32: - { reg: '$r9', virtual-reg: '' } +; CHECK32: - { reg: '$r10', virtual-reg: '' } +; CHECK32: fixedStack: +; CHECK32: - { id: 0, type: default, offset: 24, size: 96, alignment: 8, stack-id: default, +; CHECK32: stack: [] + +; CHECK32: bb.0.entry: +; CHECK32-NEXT: liveins: $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10 + +; CHECK32-DAG: STW killed renamable $r3, 0, %fixed-stack.0 :: (store 4 into %fixed-stack.0 +; CHECK32-DAG: STW killed renamable $r4, 4, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 4 +; CHECK32-DAG: STW killed renamable $r5, 8, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 8 +; CHECK32-DAG: STW killed renamable $r6, 12, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 12 +; CHECK32-DAG: STW renamable $r7, 16, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 16 +; CHECK32-DAG: STW renamable $r8, 20, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 20 +; CHECK32-DAG: STW killed renamable $r9, 24, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 24 +; CHECK32-DAG: STW killed renamable $r10, 28, %fixed-stack.0 :: (store 4 into %fixed-stack.0 + 28 +; CHECK32: renamable $r[[REG1:[0-9]+]] = LWZ 84, %fixed-stack.0 +; CHECK32: renamable $r[[REG2:[0-9]+]] = LWZ 80, %fixed-stack.0 +; CHECK32: renamable $r4 = ADDC killed renamable $r8, killed renamable $r[[REG1]], implicit-def $carry +; CHECK32: renamable $r3 = ADDE killed renamable $r7, killed renamable $r[[REG2]], implicit-def dead $carry, implicit killed $carry +; CHECK32: BLR implicit $lr, implicit $rm, implicit $r3, implicit $r4 + + +; CHECK64: name: test +; CHECK64: liveins: +; CHECK64: - { reg: '$x3', virtual-reg: '' } +; CHECK64: - { reg: '$x4', virtual-reg: '' } +; CHECK64: - { reg: '$x5', virtual-reg: '' } +; CHECK64: - { reg: '$x6', virtual-reg: '' } +; CHECK64: - { reg: '$x7', virtual-reg: '' } +; CHECK64: - { reg: '$x8', virtual-reg: '' } +; CHECK64: - { reg: '$x9', virtual-reg: '' } +; CHECK64: - { reg: '$x10', virtual-reg: '' } +; CHECK64: fixedStack: +; CHECK64: - { id: 0, type: default, offset: 48, size: 96, alignment: 16, stack-id: default, +; CHECK64: stack: [] + +; CHECK64: bb.0.entry: +; CHECK64: liveins: $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10 + +; CHECK64: STD killed renamable $x3, 0, %fixed-stack.0 :: (store 8 into %fixed-stack.0 +; CHECK64: STD killed renamable $x4, 8, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 8 +; CHECK64: STD renamable $x5, 16, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 16 +; CHECK64: STD killed renamable $x6, 24, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 24 +; CHECK64: STD killed renamable $x7, 32, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 32 +; CHECK64: STD killed renamable $x8, 40, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 40 +; CHECK64: STD killed renamable $x9, 48, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 48 +; CHECK64: STD killed renamable $x10, 56, %fixed-stack.0 :: (store 8 into %fixed-stack.0 + 56 +; CHECK64: renamable $x[[REG1:[0-9]+]] = LD 80, %fixed-stack.0 +; CHECK64: renamable $x3 = ADD8 killed renamable $x5, killed renamable $x[[REG1]] +; CHECK64: BLR8 implicit $lr8, implicit $rm, implicit $x3