diff options
author | Sam Clegg <sbc@chromium.org> | 2019-08-19 19:04:54 +0000 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2019-08-19 19:04:54 +0000 |
commit | 19bf637eb12c119cdda9fae818813084a9cf2b2a (patch) | |
tree | d2712c91e9d395e4aa06cee99118e40d4cd0d7a5 | |
parent | 1a3fdaf6a6ee0d4ff0bb5daf80c54a9fa5594467 (diff) | |
download | bcm5719-llvm-19bf637eb12c119cdda9fae818813084a9cf2b2a.tar.gz bcm5719-llvm-19bf637eb12c119cdda9fae818813084a9cf2b2a.zip |
[WebAssembly][MC] Allow empty assembly functions
Differential Revision: https://reviews.llvm.org/D66434
llvm-svn: 369292
-rw-r--r-- | llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 24 | ||||
-rw-r--r-- | llvm/test/MC/WebAssembly/basic-assembly.s | 8 |
2 files changed, 23 insertions, 9 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index da868e59c5f..bfa16a71e11 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -489,6 +489,7 @@ public: if (pop(Name, Block)) return true; } else if (Name == "end_function") { + ensureLocals(getStreamer()); CurrentState = EndFunction; if (pop(Name, Function) || ensureEmptyNestingStack()) return true; @@ -758,6 +759,19 @@ public: return true; // We didn't process this directive. } + // Called either when the first instruction is parsed of the function ends. + void ensureLocals(MCStreamer &Out) { + if (CurrentState == FunctionStart) { + // We haven't seen a .local directive yet. The streamer requires locals to + // be encoded as a prelude to the instructions, so emit an empty list of + // locals here. + auto &TOut = reinterpret_cast<WebAssemblyTargetStreamer &>( + *Out.getTargetStreamer()); + TOut.emitLocal(SmallVector<wasm::ValType, 0>()); + CurrentState = FunctionLocals; + } + } + bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned & /*Opcode*/, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, @@ -768,15 +782,7 @@ public: MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); switch (MatchResult) { case Match_Success: { - if (CurrentState == FunctionStart) { - // This is the first instruction in a function, but we haven't seen - // a .local directive yet. The streamer requires locals to be encoded - // as a prelude to the instructions, so emit an empty list of locals - // here. - auto &TOut = reinterpret_cast<WebAssemblyTargetStreamer &>( - *Out.getTargetStreamer()); - TOut.emitLocal(SmallVector<wasm::ValType, 0>()); - } + ensureLocals(Out); // Fix unknown p2align operands. auto Align = WebAssembly::GetDefaultP2AlignAny(Inst.getOpcode()); if (Align != -1U) { diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s index ac01dca3755..6de4cff8a05 100644 --- a/llvm/test/MC/WebAssembly/basic-assembly.s +++ b/llvm/test/MC/WebAssembly/basic-assembly.s @@ -2,6 +2,11 @@ # Check that it converts to .o without errors, but don't check any output: # RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+atomics,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling -o %t.o < %s + +empty_func: + .functype empty_func () -> () + end_function + test0: # Test all types: .functype test0 (i32, i64) -> (i32) @@ -111,6 +116,9 @@ test0: .globaltype __stack_pointer, i32 # CHECK: .text +# CHECK-LABEL: empty_func: +# CHECK-NEXT: .functype empty_func () -> () +# CHECK-NEXT: end_function # CHECK-LABEL: test0: # CHECK-NEXT: .functype test0 (i32, i64) -> (i32) # CHECK-NEXT: .eventtype __cpp_exception i32 |