[llvm] r261579 - [WebAssembly] Fix writeback of stack pointer with dynamic alloca
Derek Schuff via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 22 13:57:19 PST 2016
Author: dschuff
Date: Mon Feb 22 15:57:17 2016
New Revision: 261579
URL: http://llvm.org/viewvc/llvm-project?rev=261579&view=rev
Log:
[WebAssembly] Fix writeback of stack pointer with dynamic alloca
Previously the stack pointer was only written back to memory in the
prolog. But this is wrong for dynamic allocas, for which
target-independent codegen handles SP updates after the prolog (and
possibly even in another BB). Instead update the SP global in
ADJCALLSTACKDOWN which is generated after the SP update sequence.
This will have further refinements when we add red zone support.
Modified:
llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
llvm/trunk/test/CodeGen/WebAssembly/userstack.ll
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp?rev=261579&r1=261578&r2=261579&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp Mon Feb 22 15:57:17 2016
@@ -59,12 +59,39 @@ bool WebAssemblyFrameLowering::hasReserv
return !MF.getFrameInfo()->hasVarSizedObjects();
}
+static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &InsertPt,
+ DebugLoc DL) {
+ auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
+ unsigned SPAddr =
+ MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
+ const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+
+ BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
+ .addExternalSymbol(SPSymbol);
+ auto *MMO = new MachineMemOperand(MachinePointerInfo(),
+ MachineMemOperand::MOStore, 4, 4);
+ BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::STORE_I32),
+ WebAssembly::SP32)
+ .addImm(0)
+ .addReg(SPAddr)
+ .addImm(2) // p2align
+ .addReg(SrcReg)
+ .addMemOperand(MMO);
+ MF.getInfo<WebAssemblyFunctionInfo>()->stackifyVReg(SPAddr);
+}
+
void WebAssemblyFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
- // TODO: can we avoid using call frame pseudos altogether?
- assert(!I->getOperand(0).getImm() &&
- "Stack should not be adjusted around calls");
+ assert(!I->getOperand(0).getImm() && hasFP(MF) &&
+ "Call frame pseudos should only be used for dynamic stack adjustment");
+ const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+ if (I->getOpcode() == TII->getCallFrameDestroyOpcode()) {
+ DebugLoc DL = I->getDebugLoc();
+ writeSPToMemory(WebAssembly::SP32, MF, MBB, I, DL);
+ }
MBB.erase(I);
}
@@ -125,21 +152,8 @@ void WebAssemblyFrameLowering::emitProlo
WebAssembly::FP32)
.addReg(WebAssembly::SP32);
}
- if (StackSize || hasFP(MF)) {
- SPAddr = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
- // The SP32 register now has the new stacktop. Also write it back to memory.
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
- .addExternalSymbol(SPSymbol);
- auto *MMO = new MachineMemOperand(MachinePointerInfo(),
- MachineMemOperand::MOStore, 4, 4);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::STORE_I32),
- WebAssembly::SP32)
- .addImm(0)
- .addReg(SPAddr)
- .addImm(2) // p2align
- .addReg(WebAssembly::SP32)
- .addMemOperand(MMO);
- WFI->stackifyVReg(SPAddr);
+ if (StackSize) {
+ writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, DL);
}
}
@@ -171,18 +185,7 @@ void WebAssemblyFrameLowering::emitEpilo
WFI->stackifyVReg(OffsetReg);
}
- auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
- unsigned SPAddr = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
- .addExternalSymbol(SPSymbol);
- auto *MMO = new MachineMemOperand(MachinePointerInfo(),
- MachineMemOperand::MOStore, 4, 4);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::STORE_I32),
- WebAssembly::SP32)
- .addImm(0)
- .addReg(SPAddr)
- .addImm(2) // p2align
- .addReg((!StackSize && hasFP(MF)) ? WebAssembly::FP32 : WebAssembly::SP32)
- .addMemOperand(MMO);
- WFI->stackifyVReg(SPAddr);
+ writeSPToMemory(
+ (!StackSize && hasFP(MF)) ? WebAssembly::FP32 : WebAssembly::SP32, MF,
+ MBB, InsertPt, DL);
}
Modified: llvm/trunk/test/CodeGen/WebAssembly/userstack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/userstack.ll?rev=261579&r1=261578&r2=261579&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/userstack.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/userstack.ll Mon Feb 22 15:57:17 2016
@@ -134,8 +134,11 @@ define void @dynamic_alloca(i32 %alloc)
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load [[SP:.+]]=, 0($pop[[L1]])
; CHECK-NEXT: copy_local [[FP:.+]]=, [[SP]]
- ; Target independent codegen bumps the stack pointer
- ; CHECK: i32.const $push[[L4:.+]]=, __stack_pointer{{$}}
+ ; Target independent codegen bumps the stack pointer.
+ ; CHECK: i32.sub
+ ; CHECK-NEXT: copy_local [[SP]]=,
+ ; Check that SP is written back to memory after decrement
+ ; CHECK-NEXT: i32.const $push[[L4:.+]]=, __stack_pointer{{$}}
; CHECK-NEXT: i32.store $discard=, 0($pop[[L4]]), [[SP]]
%r = alloca i32, i32 %alloc
; Target-independent codegen also calculates the store addr
@@ -145,9 +148,9 @@ define void @dynamic_alloca(i32 %alloc)
ret void
}
-
; CHECK-LABEL: dynamic_static_alloca:
define void @dynamic_static_alloca(i32 %alloc) {
+ ; Decrement SP in the prolog by the static amount and writeback to memory.
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load $push[[L2:.+]]=, 0($pop[[L1]])
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
@@ -155,6 +158,12 @@ define void @dynamic_static_alloca(i32 %
; CHECK-NEXT: copy_local [[FP:.+]]=, [[SP]]
; CHECK-NEXT: i32.const $push[[L4:.+]]=, __stack_pointer
; CHECK-NEXT: i32.store {{.*}}=, 0($pop[[L4]]), [[SP]]
+ ; Decrement SP in the body by the dynamic amount.
+ ; CHECK: i32.sub
+ ; CHECK: copy_local [[SP]]=,
+ ; Writeback to memory.
+ ; CHECK-NEXT: i32.const $push[[L4:.+]]=, __stack_pointer
+ ; CHECK-NEXT: i32.store {{.*}}=, 0($pop[[L4]]), [[SP]]
%r1 = alloca i32
%r = alloca i32, i32 %alloc
store i32 0, i32* %r
@@ -194,8 +203,6 @@ declare i8* @llvm.frameaddress(i32)
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load [[SP:.+]]=, 0($pop[[L1]])
; CHECK-NEXT: copy_local [[FP:.+]]=, [[SP]]
-; CHECK-NEXT: i32.const $push[[L2:.+]]=, __stack_pointer{{$}}
-; CHECK-NEXT: i32.store $discard=, 0($pop[[L2]]), [[SP]]
; CHECK-NEXT: call use_i8_star at FUNCTION, [[FP]]
; CHECK-NEXT: i32.const $push[[L6:.+]]=, __stack_pointer
; CHECK-NEXT: i32.store [[SP]]=, 0($pop[[L6]]), [[FP]]
More information about the llvm-commits
mailing list