[llvm] 2a3cf5e - [PowerPC][AIX] Pass ByVal formal args that span registers and stack.

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 28 12:00:15 PDT 2020


Author: Sean Fertile
Date: 2020-04-28T14:57:14-04:00
New Revision: 2a3cf5e5834302a9525a721627c17902399b8d62

URL: https://github.com/llvm/llvm-project/commit/2a3cf5e5834302a9525a721627c17902399b8d62
DIFF: https://github.com/llvm/llvm-project/commit/2a3cf5e5834302a9525a721627c17902399b8d62.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll
    llvm/test/CodeGen/PowerPC/aix-cc-byval-split.ll

Removed: 
    llvm/test/CodeGen/PowerPC/aix-cc-byval-limitation1.ll


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 69dca9b78caf..ac2483cd1abd 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 eca919bee34b..000000000000
--- 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 a87a5899b293..3f24a43ad6b2 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 535998af9190..e9155f236c9e 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


        


More information about the llvm-commits mailing list