[llvm] [GlobalISel][RISCV] SelectionDAG like indirect parameter passing (PR #216724)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 08:10:04 PDT 2026
================
@@ -1011,30 +1027,55 @@ bool CallLowering::handleAssignments(ValueHandler &Handler,
// Finish the handling of indirect parameter passing when receiving
// the value (we are in the called function or the caller when receiving
// the return value).
- if (VA.getLocInfo() == CCValAssign::Indirect &&
- Handler.isIncomingArgumentHandler()) {
- Align Alignment = DL.getABITypeAlign(Args[i].Ty);
+ if (IsIndirect && Handler.isIncomingArgumentHandler()) {
+ if (IsFirstIndirectPart)
+ IncomingIndirectValuePointer = ArgReg;
+
+ uint64_t OffsetBytes = NewLLT.getSizeInBytes()
+ .multiplyCoefficientBy(IndirectIdx)
+ .getKnownMinValue();
+ Align Alignment =
+ commonAlignment(DL.getABITypeAlign(Args[i].Ty), OffsetBytes);
MachinePointerInfo MPO = MachinePointerInfo::getUnknownStack(MF);
-
+ Register PartPtrReg = IncomingIndirectValuePointer;
+ if (IndirectIdx > 0) {
+ LLT OffsetTy = LLT::scalar(PointerTy.getSizeInBits());
+ auto PartOffset = MIRBuilder.buildConstant(OffsetTy, OffsetBytes);
+ PartPtrReg = MIRBuilder
+ .buildPtrAdd(PointerTy, IncomingIndirectValuePointer,
+ PartOffset)
+ .getReg(0);
+ }
// Since we are doing indirect parameter passing, we know that the value
// in the temporary register is not the value passed to the function,
// but rather a pointer to that value. Let's load that value into the
// virtual register where the parameter should go.
- MIRBuilder.buildLoad(Args[i].OrigRegs[0], Args[i].Regs[0], MPO,
- Alignment);
-
- IndirectParameterPassingHandled = true;
+ LLT LoadedPartTy = getLLTForMVT(VA.getValVT());
+ Register LoadedPart;
+ if (NumParts == 1 && LoadedPartTy == OrigTy) {
+ LoadedPart = Args[i].OrigRegs[0];
+ MIRBuilder.buildLoad(LoadedPart, PartPtrReg, MPO, Alignment);
+ } else {
+ LoadedPart =
+ MIRBuilder.buildLoad(LoadedPartTy, PartPtrReg, MPO, Alignment)
+ .getReg(0);
+ }
+ if (Part < Args[i].Regs.size())
+ Args[i].Regs[Part] = LoadedPart;
+ else
+ Args[i].Regs.push_back(LoadedPart);
----------------
spaits wrote:
Yes, it was (In the latest version I removed this push_back). In a previous draft version of mine (pre this PR), `Args[i].Regs` has only one element in our case, the pointer to the memory. And during the receiving of the value we replace that vector with another one that contains the registers in which we already have the loaded values.
Now in the updated version, I resize the this vector to `NumParts`, but in the indirect case I only put in the pointer to memory. Later this loop will replace the pointer with the loaded values.
https://github.com/llvm/llvm-project/pull/216724
More information about the llvm-commits
mailing list