[WebAssembly] Optimize away return instructions using fallthroughs. This saves a small amount of code size, and is a first small step toward passing values on the stack across block boundaries. Differential Review: http://reviews.llvm.org/D20450 llvm-svn: 270294
diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index a450a24b..267d716d 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
@@ -145,9 +145,9 @@ if (int(WAReg) >= 0) printRegName(O, WAReg); else if (OpNo >= MII.get(MI->getOpcode()).getNumDefs()) - O << "$pop" << (WAReg & INT32_MAX); + O << "$pop" << WebAssemblyFunctionInfo::getWARegStackId(WAReg); else if (WAReg != WebAssemblyFunctionInfo::UnusedReg) - O << "$push" << (WAReg & INT32_MAX); + O << "$push" << WebAssemblyFunctionInfo::getWARegStackId(WAReg); else O << "$drop"; // Add a '=' suffix if this is a def.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index d7a753d..64128bf 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -201,6 +201,30 @@ // These represent values which are live into the function entry, so there's // no instruction to emit. break; + case WebAssembly::FALLTHROUGH_RETURN_I32: + case WebAssembly::FALLTHROUGH_RETURN_I64: + case WebAssembly::FALLTHROUGH_RETURN_F32: + case WebAssembly::FALLTHROUGH_RETURN_F64: { + // These instructions represent the implicit return at the end of a + // function body. The operand is always a pop. + assert(MFI->isVRegStackified(MI->getOperand(0).getReg())); + + if (isVerbose()) { + OutStreamer->AddComment("fallthrough-return: $pop" + + utostr(MFI->getWARegStackId( + MFI->getWAReg(MI->getOperand(0).getReg())))); + OutStreamer->AddBlankLine(); + } + break; + } + case WebAssembly::FALLTHROUGH_RETURN_VOID: + // This instruction represents the implicit return at the end of a + // function body with no return value. + if (isVerbose()) { + OutStreamer->AddComment("fallthrough-return"); + OutStreamer->AddBlankLine(); + } + break; default: { WebAssemblyMCInstLower MCInstLowering(OutContext, *this); MCInst TmpInst;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td index ba4e1f9..444e275 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
@@ -71,6 +71,10 @@ multiclass RETURN<WebAssemblyRegClass vt> { def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)], "return \t$val">; + // Equivalent to RETURN_#vt, for use at the end of a function when wasm + // semantics return by falling off the end of the block. + let isCodeGenOnly = 1 in + def FALLTHROUGH_RETURN_#vt : I<(outs), (ins vt:$val), []>; } let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { @@ -80,6 +84,10 @@ defm : RETURN<F32>; defm : RETURN<F64>; def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return">; + + // This is to RETURN_VOID what FALLTHROUGH_RETURN_#vt is to RETURN_#vt. + let isCodeGenOnly = 1 in + def FALLTHROUGH_RETURN_VOID : I<(outs), (ins), []>; } // isReturn = 1 def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable">; } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 79950a6..c2f695d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
@@ -86,6 +86,12 @@ assert(VReg = WARegs.size()); WARegs.push_back(WAReg); } + + // For a given stackified WAReg, return the id number to print with push/pop. + static unsigned getWARegStackId(unsigned Reg) { + assert(Reg & INT32_MIN); + return Reg & INT32_MAX; + } }; } // end namespace llvm
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp index 19c227d..56d44e6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
@@ -12,17 +12,23 @@ /// //===----------------------------------------------------------------------===// -#include "WebAssembly.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" +#include "WebAssembly.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; #define DEBUG_TYPE "wasm-peephole" +static cl::opt<bool> DisableWebAssemblyFallthroughReturnOpt( + "disable-wasm-fallthrough-return-opt", cl::Hidden, + cl::desc("WebAssembly: Disable fallthrough-return optimizations."), + cl::init(false)); + namespace { class WebAssemblyPeephole final : public MachineFunctionPass { const char *getPassName() const override { @@ -50,8 +56,7 @@ /// If desirable, rewrite NewReg to a drop register. static bool MaybeRewriteToDrop(unsigned OldReg, unsigned NewReg, - MachineOperand &MO, - WebAssemblyFunctionInfo &MFI, + MachineOperand &MO, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI) { bool Changed = false; if (OldReg == NewReg) { @@ -60,19 +65,50 @@ MO.setReg(NewReg); MO.setIsDead(); MFI.stackifyVReg(NewReg); - MFI.addWAReg(NewReg, WebAssemblyFunctionInfo::UnusedReg); } return Changed; } +static bool MaybeRewriteToFallthrough(MachineInstr &MI, MachineBasicBlock &MBB, + const MachineFunction &MF, + WebAssemblyFunctionInfo &MFI, + MachineRegisterInfo &MRI, + const WebAssemblyInstrInfo &TII, + unsigned FallthroughOpc, + unsigned CopyLocalOpc) { + if (DisableWebAssemblyFallthroughReturnOpt) + return false; + if (&MBB != &MF.back()) + return false; + if (&MI != &MBB.back()) + return false; + + // If the operand isn't stackified, insert a COPY_LOCAL to read the operand + // and stackify it. + MachineOperand &MO = MI.getOperand(0); + unsigned Reg = MO.getReg(); + if (!MFI.isVRegStackified(Reg)) { + unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg)); + BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(CopyLocalOpc), NewReg) + .addReg(Reg); + MO.setReg(NewReg); + MFI.stackifyVReg(NewReg); + } + + // Rewrite the return. + MI.setDesc(TII.get(FallthroughOpc)); + return true; +} + bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) { DEBUG({ - dbgs() << "********** Store Results **********\n" + dbgs() << "********** Peephole **********\n" << "********** Function: " << MF.getName() << '\n'; }); MachineRegisterInfo &MRI = MF.getRegInfo(); WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); + const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); const WebAssemblyTargetLowering &TLI = *MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering(); auto &LibInfo = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); @@ -127,7 +163,34 @@ } } } + break; } + // Optimize away an explicit void return at the end of the function. + case WebAssembly::RETURN_I32: + Changed |= MaybeRewriteToFallthrough( + MI, MBB, MF, MFI, MRI, TII, WebAssembly::FALLTHROUGH_RETURN_I32, + WebAssembly::COPY_LOCAL_I32); + break; + case WebAssembly::RETURN_I64: + Changed |= MaybeRewriteToFallthrough( + MI, MBB, MF, MFI, MRI, TII, WebAssembly::FALLTHROUGH_RETURN_I64, + WebAssembly::COPY_LOCAL_I64); + break; + case WebAssembly::RETURN_F32: + Changed |= MaybeRewriteToFallthrough( + MI, MBB, MF, MFI, MRI, TII, WebAssembly::FALLTHROUGH_RETURN_F32, + WebAssembly::COPY_LOCAL_F32); + break; + case WebAssembly::RETURN_F64: + Changed |= MaybeRewriteToFallthrough( + MI, MBB, MF, MFI, MRI, TII, WebAssembly::FALLTHROUGH_RETURN_F64, + WebAssembly::COPY_LOCAL_F64); + break; + case WebAssembly::RETURN_VOID: + if (!DisableWebAssemblyFallthroughReturnOpt && + &MBB == &MF.back() && &MI == &MBB.back()) + MI.setDesc(TII.get(WebAssembly::FALLTHROUGH_RETURN_VOID)); + break; } return Changed;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index e4b049d..32154af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -225,10 +225,10 @@ // Lower br_unless into br_if. addPass(createWebAssemblyLowerBrUnless()); - // Create a mapping from LLVM CodeGen virtual registers to wasm registers. - addPass(createWebAssemblyRegNumbering()); - // Perform the very last peephole optimizations on the code. if (getOptLevel() != CodeGenOpt::None) addPass(createWebAssemblyPeephole()); + + // Create a mapping from LLVM CodeGen virtual registers to wasm registers. + addPass(createWebAssemblyRegNumbering()); }
diff --git a/llvm/test/CodeGen/WebAssembly/address-offsets.ll b/llvm/test/CodeGen/WebAssembly/address-offsets.ll index 875e229..6403b37 100644 --- a/llvm/test/CodeGen/WebAssembly/address-offsets.ll +++ b/llvm/test/CodeGen/WebAssembly/address-offsets.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test folding constant offsets and symbols into load and store addresses under ; a variety of circumstances.
diff --git a/llvm/test/CodeGen/WebAssembly/byval.ll b/llvm/test/CodeGen/WebAssembly/byval.ll index ffc3833..bc8f1eb8 100644 --- a/llvm/test/CodeGen/WebAssembly/byval.ll +++ b/llvm/test/CodeGen/WebAssembly/byval.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false -verify-machineinstrs | FileCheck %s -; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -fast-isel | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown"
diff --git a/llvm/test/CodeGen/WebAssembly/call.ll b/llvm/test/CodeGen/WebAssembly/call.ll index 9e05da0..bd5f7b8 100644 --- a/llvm/test/CodeGen/WebAssembly/call.ll +++ b/llvm/test/CodeGen/WebAssembly/call.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that basic call operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll index 8e3529a..d46898b 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false -disable-block-placement -verify-machineinstrs -fast-isel=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -fast-isel=false | FileCheck -check-prefix=OPT %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs -fast-isel=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel=false | FileCheck -check-prefix=OPT %s ; Test the CFG stackifier pass.
diff --git a/llvm/test/CodeGen/WebAssembly/comparisons_f32.ll b/llvm/test/CodeGen/WebAssembly/comparisons_f32.ll index 2d324f7..10e037d 100644 --- a/llvm/test/CodeGen/WebAssembly/comparisons_f32.ll +++ b/llvm/test/CodeGen/WebAssembly/comparisons_f32.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 32-bit floating-point comparison operations assemble as ; expected.
diff --git a/llvm/test/CodeGen/WebAssembly/comparisons_f64.ll b/llvm/test/CodeGen/WebAssembly/comparisons_f64.ll index 22fbc1a..7d038a0 100644 --- a/llvm/test/CodeGen/WebAssembly/comparisons_f64.ll +++ b/llvm/test/CodeGen/WebAssembly/comparisons_f64.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 64-bit floating-point comparison operations assemble as ; expected.
diff --git a/llvm/test/CodeGen/WebAssembly/comparisons_i32.ll b/llvm/test/CodeGen/WebAssembly/comparisons_i32.ll index 84b19bd..d2ba73f 100644 --- a/llvm/test/CodeGen/WebAssembly/comparisons_i32.ll +++ b/llvm/test/CodeGen/WebAssembly/comparisons_i32.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that basic 32-bit integer comparison operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/comparisons_i64.ll b/llvm/test/CodeGen/WebAssembly/comparisons_i64.ll index 7d2b1d9..80950ae 100644 --- a/llvm/test/CodeGen/WebAssembly/comparisons_i64.ll +++ b/llvm/test/CodeGen/WebAssembly/comparisons_i64.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that basic 64-bit integer comparison operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/conv.ll b/llvm/test/CodeGen/WebAssembly/conv.ll index 1a4bd72..27cebb1 100644 --- a/llvm/test/CodeGen/WebAssembly/conv.ll +++ b/llvm/test/CodeGen/WebAssembly/conv.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic conversion operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/f32.ll b/llvm/test/CodeGen/WebAssembly/f32.ll index c32a7c3..1c1d819 100644 --- a/llvm/test/CodeGen/WebAssembly/f32.ll +++ b/llvm/test/CodeGen/WebAssembly/f32.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 32-bit floating-point operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/f64.ll b/llvm/test/CodeGen/WebAssembly/f64.ll index 9228499..670f3f0 100644 --- a/llvm/test/CodeGen/WebAssembly/f64.ll +++ b/llvm/test/CodeGen/WebAssembly/f64.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 64-bit floating-point operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/frem.ll b/llvm/test/CodeGen/WebAssembly/frem.ll index b8c80fbe..b874522 100644 --- a/llvm/test/CodeGen/WebAssembly/frem.ll +++ b/llvm/test/CodeGen/WebAssembly/frem.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that the frem instruction works.
diff --git a/llvm/test/CodeGen/WebAssembly/func.ll b/llvm/test/CodeGen/WebAssembly/func.ll index b7122a3..71c00a4 100644 --- a/llvm/test/CodeGen/WebAssembly/func.ll +++ b/llvm/test/CodeGen/WebAssembly/func.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic functions assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/global.ll b/llvm/test/CodeGen/WebAssembly/global.ll index 704fb3f..1d24035 100644 --- a/llvm/test/CodeGen/WebAssembly/global.ll +++ b/llvm/test/CodeGen/WebAssembly/global.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that globals assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/i128.ll b/llvm/test/CodeGen/WebAssembly/i128.ll index 5c82752..29bf787 100644 --- a/llvm/test/CodeGen/WebAssembly/i128.ll +++ b/llvm/test/CodeGen/WebAssembly/i128.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 128-bit integer operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll b/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll index e7732e7..b254413 100644 --- a/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll +++ b/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test loads and stores with custom alignment values.
diff --git a/llvm/test/CodeGen/WebAssembly/i32.ll b/llvm/test/CodeGen/WebAssembly/i32.ll index 945a447..a07dd02 100644 --- a/llvm/test/CodeGen/WebAssembly/i32.ll +++ b/llvm/test/CodeGen/WebAssembly/i32.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 32-bit integer operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll b/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll index fb38209..b2fb962 100644 --- a/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll +++ b/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test loads and stores with custom alignment values.
diff --git a/llvm/test/CodeGen/WebAssembly/i64.ll b/llvm/test/CodeGen/WebAssembly/i64.ll index 85a8ae3..93e32bfc 100644 --- a/llvm/test/CodeGen/WebAssembly/i64.ll +++ b/llvm/test/CodeGen/WebAssembly/i64.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic 64-bit integer operations assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/immediates.ll b/llvm/test/CodeGen/WebAssembly/immediates.ll index 0ccfe09..3d11f94 100644 --- a/llvm/test/CodeGen/WebAssembly/immediates.ll +++ b/llvm/test/CodeGen/WebAssembly/immediates.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic immediates assemble as expected.
diff --git a/llvm/test/CodeGen/WebAssembly/inline-asm.ll b/llvm/test/CodeGen/WebAssembly/inline-asm.ll index 0d12e03..d36c32b 100644 --- a/llvm/test/CodeGen/WebAssembly/inline-asm.ll +++ b/llvm/test/CodeGen/WebAssembly/inline-asm.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -no-integrated-as | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -no-integrated-as | FileCheck %s ; Test basic inline assembly. Pass -no-integrated-as since these aren't ; actually valid assembly syntax.
diff --git a/llvm/test/CodeGen/WebAssembly/legalize.ll b/llvm/test/CodeGen/WebAssembly/legalize.ll index 5feb2e8..5cbfb8a 100644 --- a/llvm/test/CodeGen/WebAssembly/legalize.ll +++ b/llvm/test/CodeGen/WebAssembly/legalize.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test various types and operators that need to be legalized.
diff --git a/llvm/test/CodeGen/WebAssembly/load-ext.ll b/llvm/test/CodeGen/WebAssembly/load-ext.ll index d52df33..48a7ce7 100644 --- a/llvm/test/CodeGen/WebAssembly/load-ext.ll +++ b/llvm/test/CodeGen/WebAssembly/load-ext.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that extending loads are assembled properly.
diff --git a/llvm/test/CodeGen/WebAssembly/load-store-i1.ll b/llvm/test/CodeGen/WebAssembly/load-store-i1.ll index 2b8ab4a..2a2318f 100644 --- a/llvm/test/CodeGen/WebAssembly/load-store-i1.ll +++ b/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that i1 extending loads and truncating stores are assembled properly.
diff --git a/llvm/test/CodeGen/WebAssembly/load.ll b/llvm/test/CodeGen/WebAssembly/load.ll index 776dba3..a8e174e 100644 --- a/llvm/test/CodeGen/WebAssembly/load.ll +++ b/llvm/test/CodeGen/WebAssembly/load.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that basic loads are assembled properly.
diff --git a/llvm/test/CodeGen/WebAssembly/mem-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/mem-intrinsics.ll index a49ff57..71787fe 100644 --- a/llvm/test/CodeGen/WebAssembly/mem-intrinsics.ll +++ b/llvm/test/CodeGen/WebAssembly/mem-intrinsics.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test memcpy, memmove, and memset intrinsics.
diff --git a/llvm/test/CodeGen/WebAssembly/memory-addr32.ll b/llvm/test/CodeGen/WebAssembly/memory-addr32.ll index 2c2d075..583201b 100644 --- a/llvm/test/CodeGen/WebAssembly/memory-addr32.ll +++ b/llvm/test/CodeGen/WebAssembly/memory-addr32.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic memory operations assemble as expected with 32-bit addresses.
diff --git a/llvm/test/CodeGen/WebAssembly/memory-addr64.ll b/llvm/test/CodeGen/WebAssembly/memory-addr64.ll index 804274d..dc6da61 100644 --- a/llvm/test/CodeGen/WebAssembly/memory-addr64.ll +++ b/llvm/test/CodeGen/WebAssembly/memory-addr64.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that basic memory operations assemble as expected with 64-bit addresses.
diff --git a/llvm/test/CodeGen/WebAssembly/phi.ll b/llvm/test/CodeGen/WebAssembly/phi.ll index 00e5859..747ae5c 100644 --- a/llvm/test/CodeGen/WebAssembly/phi.ll +++ b/llvm/test/CodeGen/WebAssembly/phi.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s ; Test that phis are lowered.
diff --git a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll index f112534..2f70a56 100644 --- a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll +++ b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s ; Test the register stackifier pass.
diff --git a/llvm/test/CodeGen/WebAssembly/return-int32.ll b/llvm/test/CodeGen/WebAssembly/return-int32.ll index cbc9ec9..9e663b9 100644 --- a/llvm/test/CodeGen/WebAssembly/return-int32.ll +++ b/llvm/test/CodeGen/WebAssembly/return-int32.ll
@@ -5,7 +5,30 @@ target triple = "wasm32-unknown-unknown" ; CHECK-LABEL: return_i32: -; CHECK: return $0{{$}} +; CHECK-NEXT: .param i32{{$}} +; CHECK-NEXT: .result i32{{$}} +; CHECK-NEXT: copy_local $push0=, $0 +; CHECK-NEXT: .endfunc{{$}} define i32 @return_i32(i32 %p) { ret i32 %p } + +; CHECK-LABEL: return_i32_twice: +; CHECK: store +; CHECK-NEXT: i32.const $push[[L0:[^,]+]]=, 1{{$}} +; CHECK-NEXT: return $pop[[L0]]{{$}} +; CHECK: store +; CHECK-NEXT: i32.const $push{{[^,]+}}=, 3{{$}} +; CHECK-NEXT: .endfunc{{$}} +define i32 @return_i32_twice(i32 %a) { + %b = icmp ne i32 %a, 0 + br i1 %b, label %true, label %false + +true: + store i32 0, i32* null + ret i32 1 + +false: + store i32 2, i32* null + ret i32 3 +}
diff --git a/llvm/test/CodeGen/WebAssembly/return-void.ll b/llvm/test/CodeGen/WebAssembly/return-void.ll index cf4d168..c3a600f 100644 --- a/llvm/test/CodeGen/WebAssembly/return-void.ll +++ b/llvm/test/CodeGen/WebAssembly/return-void.ll
@@ -5,7 +5,25 @@ target triple = "wasm32-unknown-unknown" ; CHECK-LABEL: return_void: -; CHECK: return{{$}} +; CHECK-NEXT: .endfunc{{$}} define void @return_void() { ret void } + +; CHECK-LABEL: return_void_twice: +; CHECK: store +; CHECK-NEXT: return{{$}} +; CHECK: store +; CHECK-NEXT: .endfunc{{$}} +define void @return_void_twice(i32 %a) { + %b = icmp ne i32 %a, 0 + br i1 %b, label %true, label %false + +true: + store i32 0, i32* null + ret void + +false: + store i32 1, i32* null + ret void +}
diff --git a/llvm/test/CodeGen/WebAssembly/returned.ll b/llvm/test/CodeGen/WebAssembly/returned.ll index 8f590c0..a277928 100644 --- a/llvm/test/CodeGen/WebAssembly/returned.ll +++ b/llvm/test/CodeGen/WebAssembly/returned.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that the "returned" attribute is optimized effectively.
diff --git a/llvm/test/CodeGen/WebAssembly/select.ll b/llvm/test/CodeGen/WebAssembly/select.ll index 6e26da5..06837e4 100644 --- a/llvm/test/CodeGen/WebAssembly/select.ll +++ b/llvm/test/CodeGen/WebAssembly/select.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that wasm select instruction is selected from LLVM select instruction.
diff --git a/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll b/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll index 27e524b..f9561da 100644 --- a/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll +++ b/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test zeroext and signext ABI keywords
diff --git a/llvm/test/CodeGen/WebAssembly/store-results.ll b/llvm/test/CodeGen/WebAssembly/store-results.ll index b2dfc70..121ee91 100644 --- a/llvm/test/CodeGen/WebAssembly/store-results.ll +++ b/llvm/test/CodeGen/WebAssembly/store-results.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Test that the wasm-store-results pass makes users of stored values use the ; result of store expressions to reduce get_local/set_local traffic.
diff --git a/llvm/test/CodeGen/WebAssembly/store.ll b/llvm/test/CodeGen/WebAssembly/store.ll index 03bd28f..3ff8488 100644 --- a/llvm/test/CodeGen/WebAssembly/store.ll +++ b/llvm/test/CodeGen/WebAssembly/store.ll
@@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that basic stores are assembled properly.
diff --git a/llvm/test/CodeGen/WebAssembly/switch.ll b/llvm/test/CodeGen/WebAssembly/switch.ll index 20af644..8355bc8 100644 --- a/llvm/test/CodeGen/WebAssembly/switch.ll +++ b/llvm/test/CodeGen/WebAssembly/switch.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -disable-block-placement -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs | FileCheck %s ; Test switch instructions. Block placement is disabled because it reorders ; the blocks in a way that isn't interesting here.
diff --git a/llvm/test/CodeGen/WebAssembly/unused-argument.ll b/llvm/test/CodeGen/WebAssembly/unused-argument.ll index bfbb7cb..ff943b2 100644 --- a/llvm/test/CodeGen/WebAssembly/unused-argument.ll +++ b/llvm/test/CodeGen/WebAssembly/unused-argument.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s ; Make sure that argument offsets are correct even if some arguments are unused.
diff --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll index 90b3eef..ee2bbfb 100644 --- a/llvm/test/CodeGen/WebAssembly/userstack.ll +++ b/llvm/test/CodeGen/WebAssembly/userstack.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown"
diff --git a/llvm/test/CodeGen/WebAssembly/varargs.ll b/llvm/test/CodeGen/WebAssembly/varargs.ll index 990db2d..483d452 100644 --- a/llvm/test/CodeGen/WebAssembly/varargs.ll +++ b/llvm/test/CodeGen/WebAssembly/varargs.ll
@@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s ; Test varargs constructs.