[llvm] [wasm] Disallow tail calls when passing structs on the stack (PR #124443)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 25 20:31:14 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly
Author: Timothy Herchen (anematode)
<details>
<summary>Changes</summary>
[The following code is incorrectly compiled with `-mtail-call`](https://godbolt.org/z/vd95cYh1E):
```
struct passed_by_value { int a; int b; };
int f(struct passed_by_value val);
int g(struct passed_by_value in) {
return f(in);
}
```
Output:
```
g:
global.get __stack_pointer
i32.const 16
i32.sub
local.tee 1
global.set __stack_pointer
local.get 1
local.get 0
i64.load 0:p2align=2
i64.store 8
local.get 1
i32.const 16
i32.add
global.set __stack_pointer
local.get 1
i32.const 8
i32.add
return_call f
end_function
```
Stack space is reserved for the struct arguments, but the stack pointer is moved back before the `return_call`. So I added a check to prevent TCO from happening if we're passing things on the stack.
---
Full diff: https://github.com/llvm/llvm-project/pull/124443.diff
1 Files Affected:
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (+9)
``````````diff
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 02db1b142a22b5..ec745ebabb4f63 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1211,6 +1211,15 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
}
}
}
+
+ // If outgoing arguments are passed via the stack, we cannot tail call
+ for (const ISD::OutputArg &Out : CLI.Outs) {
+ if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
+ NoTail(
+ "WebAssembly does not support tail calling with stack arguments");
+ break;
+ }
+ }
}
SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
``````````
</details>
https://github.com/llvm/llvm-project/pull/124443
More information about the llvm-commits
mailing list