[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
This commit is contained in:
Sean Fertile 2020-04-15 09:58:22 -04:00
parent b8000c0ce8
commit 2a3cf5e583
4 changed files with 182 additions and 29 deletions

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -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