From: Dan Gohman Date: Thu, 5 May 2016 20:41:15 +0000 (+0000) Subject: [WebAssembly] Don't emit epilogue code in the middle of stackified code. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=928153489945bb00f6e0a1227c66290e6344542c;p=llvm [WebAssembly] Don't emit epilogue code in the middle of stackified code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268679 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp index 549958158eb..2e50c7e6c9f 100644 --- a/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -72,6 +72,7 @@ bool WebAssemblyFrameLowering::needsSP(const MachineFunction &MF, /// false, the stack red zone can be used and only a local SP is needed. bool WebAssemblyFrameLowering::needsSPWriteback( const MachineFunction &MF, const MachineFrameInfo &MFI) const { + assert(needsSP(MF, MFI)); return MFI.getStackSize() > RedZoneSize || MFI.hasCalls() || MF.getFunction()->hasFnAttribute(Attribute::NoRedZone); } @@ -190,6 +191,13 @@ void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF, if (InsertPt != MBB.end()) { DL = InsertPt->getDebugLoc(); + + // If code has been stackified with the return, disconnect it so that we + // don't break the tree when we insert code just before the return. + if (InsertPt->isReturn() && InsertPt->getNumExplicitOperands() != 0) { + WebAssemblyFunctionInfo &MFI = *MF.getInfo(); + MFI.unstackifyVReg(InsertPt->getOperand(0).getReg()); + } } // Restore the stack pointer. If we had fixed-size locals, add the offset diff --git a/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp b/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp index 76ea0d72f6d..d508d448d71 100644 --- a/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp @@ -108,7 +108,8 @@ bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) { } } // Allocate locals for used physical registers - bool HasFP = MF.getSubtarget().getFrameLowering()->hasFP(MF); + bool HasFP = + MF.getSubtarget().getFrameLowering()->hasFP(MF); if (FrameInfo.getStackSize() > 0 || FrameInfo.adjustsStack() || HasFP) { DEBUG(dbgs() << "PReg SP " << CurReg << "\n"); MFI.addPReg(WebAssembly::SP32, CurReg++); diff --git a/test/CodeGen/WebAssembly/reg-stackify.ll b/test/CodeGen/WebAssembly/reg-stackify.ll index c9814cce350..4c667d58eb9 100644 --- a/test/CodeGen/WebAssembly/reg-stackify.ll +++ b/test/CodeGen/WebAssembly/reg-stackify.ll @@ -357,6 +357,18 @@ define void @ignore_dbg_value() { unreachable } +; Don't stackify an expression that might use the stack into a return, since we +; might insert a prologue before the return. + +; CHECK-LABEL: no_stackify_past_epilogue: +; CHECK: return ${{[0-9]+}}{{$}} +declare i32 @use_memory(i32*) +define i32 @no_stackify_past_epilogue() { + %x = alloca i32 + %call = call i32 @use_memory(i32* %x) + ret i32 %call +} + !llvm.module.flags = !{!0} !llvm.dbg.cu = !{!1}