[llvm] [GISel][RISCV]Implement indirect parameter passing for large scalars (PR #95429)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 14 05:12:50 PDT 2024
================
@@ -790,6 +804,32 @@ bool CallLowering::handleAssignments(ValueHandler &Handler,
CCValAssign &VA = ArgLocs[j + Idx];
const ISD::ArgFlagsTy Flags = Args[i].Flags[Part];
+ // We found an indirect parameter passing and we are at the first part of
+ // the value being passed. In this case copy the incoming pointer into a
+ // virtual register so later we can load it.
+ if (VA.getLocInfo() == CCValAssign::Indirect && Flags.isSplit()) {
+ IndirectParameterPassingHandled = true;
+ if (Handler.isIncomingArgumentHandler()) {
+ Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
+ Handler.assignValueToAddress(Args[i].OrigRegs[Part],
+ Args[i].Regs[Part], OrigTy,
+ MachinePointerInfo{}, VA);
+ } else {
+ Align StackAlign = DL.getPrefTypeAlign(Args[i].Ty);
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int FrameIdx = MFI.CreateStackObject(OrigTy.getScalarSizeInBits(),
+ StackAlign, false);
+
+ Register PointerToStackReg =
+ MIRBuilder.buildFrameIndex(PointerTy, FrameIdx).getReg(0);
+ Handler.assignValueToAddress(Args[i].OrigRegs[Part],
+ PointerToStackReg, OrigTy,
+ MachinePointerInfo{}, VA);
+ Handler.assignValueToReg(PointerToStackReg, VA.getLocReg(), VA);
----------------
spaits wrote:
I think I solved this. Please could you check it? (I am pretty new to compiler back-ends, so I am not 100% sure.)
Now for this IR:
```llvm
define i64 @fun(i64 %x1, i64 %x2, i64 %x3, i64 %x4, i128 %y ) {
%2 = trunc i128 %y to i64
ret i64 %2
}
define i32 @fun_caller( ) {
%1 = call i64 @fun(i64 1,i64 1, i64 1, i64 1, i128 2)
%2 = trunc i64 %1 to i32
ret i32 %2
}
```
We generate this:
Callee:
```llvm
Frame Objects:
fi#-1: size=4, align=16, fixed, at location [SP]
Function Live Ins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, %14
bb.1 (%ir-block.0):
liveins: $v3, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
%5:_(s32) = COPY $x10
%6:_(s32) = COPY $x11
%0:_(s64) = G_MERGE_VALUES %5:_(s32), %6:_(s32)
%7:_(s32) = COPY $x12
%8:_(s32) = COPY $x13
%1:_(s64) = G_MERGE_VALUES %7:_(s32), %8:_(s32)
%9:_(s32) = COPY $x14
%10:_(s32) = COPY $x15
%2:_(s64) = G_MERGE_VALUES %9:_(s32), %10:_(s32)
%11:_(s32) = COPY $x16
%12:_(s32) = COPY $x17
%3:_(s64) = G_MERGE_VALUES %11:_(s32), %12:_(s32)
%14:_(p0) = G_FRAME_INDEX %fixed-stack.0
%13:_(p0) = COPY %14:_(p0)
%4:_(s128) = G_LOAD %13:_(p0) :: (load (s128), align 8)
%15:_(s64) = G_TRUNC %4:_(s128)
%16:_(s32), %17:_(s32) = G_UNMERGE_VALUES %15:_(s64)
$x10 = COPY %16:_(s32)
$x11 = COPY %17:_(s32)
PseudoRET implicit $x10, implicit $x11
```
>From this the relevant part for us the indirect argument receiving looks like this:
```llvm
%14:_(p0) = G_FRAME_INDEX %fixed-stack.0
%13:_(p0) = COPY %14:_(p0)
%4:_(s128) = G_LOAD %13:_(p0) :: (load (s128), align 8)
%15:_(s64) = G_TRUNC %4:_(s128)
```
Caller:
```llvm
Frame Objects:
fi#0: size=128, align=8, at location [SP]
bb.1 (%ir-block.0):
%1:_(s64) = G_CONSTANT i64 1
%2:_(s128) = G_CONSTANT i128 2
ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %1:_(s64)
%5:_(s32), %6:_(s32) = G_UNMERGE_VALUES %1:_(s64)
%7:_(s32), %8:_(s32) = G_UNMERGE_VALUES %1:_(s64)
%9:_(s32), %10:_(s32) = G_UNMERGE_VALUES %1:_(s64)
%11:_(p0) = COPY $x2
%12:_(s32) = G_CONSTANT i32 0
%13:_(p0) = G_PTR_ADD %11:_, %12:_(s32)
%14:_(p0) = G_FRAME_INDEX %stack.0
G_STORE %2:_(s128), %14:_(p0) :: (store (s128), align 8)
G_STORE %14:_(p0), %13:_(p0) :: (store (p0), align 8)
$x10 = COPY %3:_(s32)
$x11 = COPY %4:_(s32)
$x12 = COPY %5:_(s32)
$x13 = COPY %6:_(s32)
$x14 = COPY %7:_(s32)
$x15 = COPY %8:_(s32)
$x16 = COPY %9:_(s32)
$x17 = COPY %10:_(s32)
PseudoCALL target-flags(riscv-call) @fun, <regmask $vlenb $x0 $x1 $x8 $x9 $x18 $x19 $x20 $x21 $x22 $x23 $x24 $x25 $x26 $x27 $x8_x9 $x18_x19 $x20_x21 $x22_x23 $x24_x25 $x26_x27>, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
%15:_(s32) = COPY $x10
%16:_(s32) = COPY $x11
%0:_(s64) = G_MERGE_VALUES %15:_(s32), %16:_(s32)
%17:_(s32) = G_TRUNC %0:_(s64)
$x10 = COPY %17:_(s32)
PseudoRET implicit $x10
```
The relevant part for argument passing:
```llvm
%11:_(p0) = COPY $x2
%12:_(s32) = G_CONSTANT i32 0
%13:_(p0) = G_PTR_ADD %11:_, %12:_(s32)
%14:_(p0) = G_FRAME_INDEX %stack.0
G_STORE %2:_(s128), %14:_(p0) :: (store (s128), align 8)
G_STORE %14:_(p0), %13:_(p0) :: (store (p0), align 8)
```
https://github.com/llvm/llvm-project/pull/95429
More information about the llvm-commits
mailing list