[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