[llvm] [GISel][RISCV]Implement indirect parameter passing (PR #95429)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 16 14:34:54 PDT 2024


================
@@ -790,6 +810,59 @@ 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 have an
+      // OutgoingValueHandler as our handler (so we are at the call site or the
+      // return value). In this case, start the construction of the following
+      // GMIR, that is responsible for the preparation of indirect parameter
+      // passing:
+      //
+      // %1(indirectly passed type) = The value to pass
+      // %3(pointer) = G_FRAME_INDEX %stack.0
+      // G_STORE %1, %3 :: (store (s128), align 8)
+      //
+      // After this GMIR, the remaining part of the loop body will decide how
+      // to get the value to the caller and we break out of the loop.
+      // NOTE: In the case, when the the pointer pointing to the value is passed
+      // in a register there is an exception to this, that is detailed bellow.
+      if (VA.getLocInfo() == CCValAssign::Indirect && Flags.isSplit() &&
+          !Handler.isIncomingArgumentHandler()) {
+        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);
+
+        MachinePointerInfo DstMPO =
+            MachinePointerInfo::getFixedStack(MF, FrameIdx);
+
+        Align DstAlign =
+            std::max(DL.getStackAlignment(), inferAlignFromPtrInfo(MF, DstMPO));
+
+        MIRBuilder.buildStore(Args[i].OrigRegs[Part], PointerToStackReg, DstMPO,
+                              DstAlign);
+
+        // If the value is not on the stack, then dispatch the process of
+        // moving it to the correct place for the call to the rest of the code.
+        if (!VA.isMemLoc()) {
+          ArgReg = PointerToStackReg;
+        }
+        // This value assign or load are needed here for the case, when the
+        // pointer to stack is passed, since there is no other case later that
+        // would handle this.
+        if (VA.isMemLoc()) {
+          LLT MemTy = Handler.getStackValueStoreType(DL, VA, Flags);
+          MachinePointerInfo MPO;
+          auto PassedStackAddress = Handler.getStackAddress(
+              MemTy.getSizeInBytes(), VA.getLocMemOffset(), MPO, Flags);
+          MIRBuilder.buildStore(PointerToStackReg, PassedStackAddress, DstMPO,
+                                DstAlign);
----------------
s-barannikov wrote:

> So it thinks the stored type is an s32 instead of a pointer. A pointer is 32 bit on rv32, the architecture which I use for testing.
> Is it ok this way? Or it should be pointer type, not the actual type "under" the pointer?

We should try to preserve "pointerness" as long as we can.


https://github.com/llvm/llvm-project/pull/95429


More information about the llvm-commits mailing list