[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
This commit is contained in:
parent
37fcad7be9
commit
da0ca5dee4
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user