-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebAssembly] Define local sp if llvm.stacksave
is used
#68133
[WebAssembly] Define local sp if llvm.stacksave
is used
#68133
Conversation
@llvm/pr-subscribers-backend-webassembly ChangesUsually Resolves #62235 Full diff: https://github.com/llvm/llvm-project/pull/68133.diff 2 Files Affected:
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
index e60f1397b993355..d26234e7e71d1d4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -147,7 +147,14 @@ bool WebAssemblyFrameLowering::needsPrologForEH(
/// Unlike a machine stack pointer, the wasm user stack pointer is a global
/// variable, so it is loaded into a register in the prolog.
bool WebAssemblyFrameLowering::needsSP(const MachineFunction &MF) const {
- return needsSPForLocalFrame(MF) || needsPrologForEH(MF);
+ auto &MRI = MF.getRegInfo();
+ // llvm.stacksave can explicitly read SP register and it can appear without
+ // dynamic alloca.
+ bool hasExplicitSPUse = any_of(MRI.use_operands(getSPReg(MF)), [](MachineOperand &MO) {
+ return !MO.isImplicit();
+ });
+
+ return needsSPForLocalFrame(MF) || needsPrologForEH(MF) || hasExplicitSPUse;
}
/// Returns true if the local user-space stack pointer needs to be written back
diff --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll
index b92946d1a6af7f2..ea0fd49503380d6 100644
--- a/llvm/test/CodeGen/WebAssembly/userstack.ll
+++ b/llvm/test/CodeGen/WebAssembly/userstack.ll
@@ -550,6 +550,18 @@ define void @llvm_stack_builtins(i32 %alloc) noredzone {
ret void
}
+; Use of stacksave requires local SP definition even without dymamic alloca.
+; CHECK-LABEL: llvm_stacksave_noalloca:
+define void @llvm_stacksave_noalloca() noredzone {
+ ; CHECK: global.get $push[[L11:.+]]=, __stack_pointer{{$}}
+ %stack = call i8* @llvm.stacksave()
+
+ ; CHECK-NEXT: call use_i8_star, $pop[[L11:.+]]
+ call void @use_i8_star(i8* %stack)
+
+ ret void
+}
+
; Not actually using the alloca'd variables exposed an issue with register
; stackification, where copying the stack pointer into the frame pointer was
; moved after the stack pointer was updated for the dynamic alloca.
|
b5043f5
to
a473cee
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
a473cee
to
16b2203
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM
Usually `llvm.stacksave/stackrestore` are used together with `alloca` but they can appear without it (e.g. `alloca` can be optimized away). WebAssembly's function local physical user sp register, which is referenced by `llvm.stacksave` is created while frame lowering and replaced with virtual register. However the sp register was not created when `llvm.stacksave` is used without `alloca`, and it led MIR verification failure about use-before-def of sp virtual register.
16b2203
to
7659037
Compare
Thank you for reviewing quickly! |
Usually `llvm.stacksave/stackrestore` are used together with `alloca` but they can appear without it (e.g. `alloca` can be optimized away). WebAssembly's function local physical user sp register, which is referenced by `llvm.stacksave` is created while frame lowering and replaced with virtual register. However the sp register was not created when `llvm.stacksave` is used without `alloca`, and it led MIR verification failure about use-before-def of sp virtual register. Resolves llvm#62235
Usually
llvm.stacksave/stackrestore
are used together withalloca
but they can appear without it (e.g.alloca
can be optimized away). WebAssembly's function local physical user sp register, which is referenced byllvm.stacksave
is created while frame lowering and replaced with virtual register.However the sp register was not created when
llvm.stacksave
is used withoutalloca
, and it led MIR verification failure about use-before-def of sp virtual register.Resolves #62235