[llvm] da0ca5d - [WebAssembly] Define local sp if `llvm.stacksave` is used (#68133)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 14:51:38 PDT 2023


Author: Yuta Saito
Date: 2023-10-03T14:51:35-07:00
New Revision: da0ca5dee489aa46ca7f10237aa0dfa01f9b43ea

URL: https://github.com/llvm/llvm-project/commit/da0ca5dee489aa46ca7f10237aa0dfa01f9b43ea
DIFF: https://github.com/llvm/llvm-project/commit/da0ca5dee489aa46ca7f10237aa0dfa01f9b43ea.diff

LOG: [WebAssembly] Define local sp if `llvm.stacksave` is used (#68133)

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 https://github.com/llvm/llvm-project/issues/62235

Added: 
    

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
    llvm/test/CodeGen/WebAssembly/userstack.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
index e60f1397b993355..8f3ad167ae41fcf 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -130,7 +130,15 @@ bool WebAssemblyFrameLowering::hasReservedCallFrame(
 bool WebAssemblyFrameLowering::needsSPForLocalFrame(
     const MachineFunction &MF) const {
   auto &MFI = MF.getFrameInfo();
-  return MFI.getStackSize() || MFI.adjustsStack() || hasFP(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 MFI.getStackSize() || MFI.adjustsStack() || hasFP(MF) ||
+         HasExplicitSPUse;
 }
 
 // In function with EH pads, we need to make a copy of the value of

diff  --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll
index b92946d1a6af7f2..f7bdcdd42ba1315 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.
@@ -617,7 +629,7 @@ define void @copytoreg_fi(i1 %cond, ptr %b) {
 ; CHECK-32-NEXT:    i32.const $push4=, 1
 ; CHECK-32-NEXT:    i32.and $push7=, $pop8, $pop4
 ; CHECK-32-NEXT:    local.set 0, $pop7
-; CHECK-32-NEXT:  .LBB10_1: # %body
+; CHECK-32-NEXT:  # %body
 ; CHECK-32-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-32-NEXT:    loop # label0:
 ; CHECK-32-NEXT:    local.get $push9=, 2
@@ -645,7 +657,7 @@ define void @copytoreg_fi(i1 %cond, ptr %b) {
 ; CHECK-64-NEXT:    i32.const $push4=, 1
 ; CHECK-64-NEXT:    i32.and $push7=, $pop8, $pop4
 ; CHECK-64-NEXT:    local.set 0, $pop7
-; CHECK-64-NEXT:  .LBB10_1: # %body
+; CHECK-64-NEXT:  # %body
 ; CHECK-64-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-64-NEXT:    loop # label0:
 ; CHECK-64-NEXT:    local.get $push9=, 2


        


More information about the llvm-commits mailing list