[llvm] [RISCV] Fix musttail with indirect arguments by forwarding incoming pointers (PR #185094)
Sam Elliott via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 20 22:14:12 PDT 2026
================
@@ -24665,51 +24686,132 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// Promote the value if needed.
// For now, only handle fully promoted and indirect arguments.
if (VA.getLocInfo() == CCValAssign::Indirect) {
- // Store the argument in a stack slot and pass its address.
- Align StackAlign =
- std::max(getPrefTypeAlign(Outs[OutIdx].ArgVT, DAG),
- getPrefTypeAlign(ArgValue.getValueType(), DAG));
- TypeSize StoredSize = ArgValue.getValueType().getStoreSize();
- // If the original argument was split (e.g. i128), we need
- // to store the required parts of it here (and pass just one address).
- // Vectors may be partly split to registers and partly to the stack, in
- // which case the base address is partly offset and subsequent stores are
- // relative to that.
- unsigned ArgIndex = Outs[OutIdx].OrigArgIndex;
- unsigned ArgPartOffset = Outs[OutIdx].PartOffset;
- assert(VA.getValVT().isVector() || ArgPartOffset == 0);
- // Calculate the total size to store. We don't have access to what we're
- // actually storing other than performing the loop and collecting the
- // info.
- SmallVector<std::pair<SDValue, SDValue>> Parts;
- while (i + 1 != e && Outs[OutIdx + 1].OrigArgIndex == ArgIndex) {
- SDValue PartValue = OutVals[OutIdx + 1];
- unsigned PartOffset = Outs[OutIdx + 1].PartOffset - ArgPartOffset;
- SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
- EVT PartVT = PartValue.getValueType();
- if (PartVT.isScalableVector())
- Offset = DAG.getNode(ISD::VSCALE, DL, XLenVT, Offset);
- StoredSize += PartVT.getStoreSize();
- StackAlign = std::max(StackAlign, getPrefTypeAlign(PartVT, DAG));
- Parts.push_back(std::make_pair(PartValue, Offset));
- ++i;
- ++OutIdx;
- }
- SDValue SpillSlot = DAG.CreateStackTemporary(StoredSize, StackAlign);
- int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
- MemOpChains.push_back(
- DAG.getStore(Chain, DL, ArgValue, SpillSlot,
- MachinePointerInfo::getFixedStack(MF, FI)));
- for (const auto &Part : Parts) {
- SDValue PartValue = Part.first;
- SDValue PartOffset = Part.second;
- SDValue Address =
- DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot, PartOffset);
+ // For musttail calls, reuse incoming indirect pointers instead of
+ // creating new stack temporaries. The incoming pointers point to the
+ // caller's caller's frame, which remains valid after a tail call.
+ if (IsTailCall && CLI.CB && CLI.CB->isMustTailCall()) {
+ RISCVMachineFunctionInfo *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
+ unsigned CallArgIdx = Outs[OutIdx].OrigArgIndex;
+
+ // Resolve which formal parameter is being passed at this call
+ // position. Outs[].OrigArgIndex indexes the filtered arg list
+ // (empty types removed), but IncomingIndirectArgs is keyed by
+ // Argument::getArgNo() (unfiltered position). We need to:
+ // 1. Find the call operand at filtered position CallArgIdx
+ // 2. Check if it's a forwarded formal param (dyn_cast<Argument>)
+ // 3. Resolve the unfiltered formal param index for the map lookup
+ const Argument *FormalArg = nullptr;
+ unsigned FilteredIdx = 0;
+ for (const auto &CallArg : CLI.CB->args()) {
+ if (CallArg->getType()->isEmptyTy())
+ continue;
+ if (FilteredIdx == CallArgIdx) {
+ FormalArg = dyn_cast<Argument>(CallArg);
+ break;
+ }
+ ++FilteredIdx;
+ }
+
+ // For forwarded args, getArgNo() gives the unfiltered index directly.
+ // For computed args, walk the caller's formals to resolve it.
+ unsigned FormalArgIdx = CallArgIdx;
+ if (FormalArg) {
+ FormalArgIdx = FormalArg->getArgNo();
+ } else {
+ const Function *CallerFn = CLI.CB->getFunction();
----------------
lenary wrote:
This `getFunction()` gets the function that contains the `call`, not the function it is calling. I don't think that was intentional.
You probably want `getCalledFunction()`, which can return null if it's not sure - though I'm not sure you would hit that in the musttail case.
https://github.com/llvm/llvm-project/pull/185094
More information about the llvm-commits
mailing list