Skip to content

Commit

Permalink
[PowerPC][AIX] Pass ByVal formal args that span registers and stack.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mandlebug committed Apr 28, 2020
1 parent b8000c0 commit 2a3cf5e
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 29 deletions.
22 changes: 13 additions & 9 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Expand Up @@ -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;
}

Expand Down
11 changes: 0 additions & 11 deletions llvm/test/CodeGen/PowerPC/aix-cc-byval-limitation1.ll

This file was deleted.

105 changes: 102 additions & 3 deletions llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll
Expand Up @@ -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.
Expand Down Expand Up @@ -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] }

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

Expand Down Expand Up @@ -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
73 changes: 67 additions & 6 deletions 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
Expand All @@ -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

0 comments on commit 2a3cf5e

Please sign in to comment.