[llvm] [RISCV] Fix musttail with indirect arguments by forwarding incoming pointers (PR #185094)
Xavier Roche via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 04:00:14 PDT 2026
================
@@ -24578,6 +24580,19 @@ bool RISCVTargetLowering::isEligibleForTailCallOptimization(
if (CCInfo.getStackSize() > RVFI->getArgumentStackSize())
return false;
+ // Do not tail call optimize if any argument needs to be passed indirectly.
+ // The caller allocates stack space and passes a pointer to the callee. On a
+ // tail call the caller's stack frame is deallocated before the callee
+ // executes, invalidating the pointer (use-after-free).
+ // musttail is excluded: callers forward incoming indirect pointers that
+ // point to the caller's caller's frame, which remains valid.
+ if (!CLI.CB || !CLI.CB->isMustTailCall()) {
+ for (const auto &VA : ArgLocs) {
+ if (VA.getLocInfo() == CCValAssign::Indirect)
+ return false;
+ }
+ }
+
----------------
xroche wrote:
Darn, you're right
```
define i32 @caller(fp128 %a) nounwind {
%local = fadd fp128 %a, %a
%r = musttail call i32 @callee(fp128 %local)
ret i32 %r
}
```
In this case the fadd result is silently dropped, the fix is definitely wrong
Possible fix: when the call arg is not a forwarded Argument (the dyn_cast<Argument> at line 24799 fails...), we probably want to store the computed value into the incoming indirect pointer, then forward that pointer. The incoming pointer points to the caller's caller's frame, so it should be safe - what do you think ?
https://github.com/llvm/llvm-project/pull/185094
More information about the llvm-commits
mailing list