[llvm] r350270 - [WebAssembly] made assembler parse block_type

Wouter van Oortmerssen via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 2 15:23:52 PST 2019


Author: aardappel
Date: Wed Jan  2 15:23:51 2019
New Revision: 350270

URL: http://llvm.org/viewvc/llvm-project?rev=350270&view=rev
Log:
[WebAssembly] made assembler parse block_type

Summary:
This was previously ignored and an incorrect value generated.

Also fixed Disassembler's handling of block_type.

Reviewers: dschuff, aheejin

Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D56092

Modified:
    llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
    llvm/trunk/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt
    llvm/trunk/test/MC/WebAssembly/basic-assembly.s

Modified: llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp?rev=350270&r1=350269&r2=350270&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp Wed Jan  2 15:23:51 2019
@@ -301,6 +301,18 @@ public:
     return Optional<wasm::ValType>();
   }
 
+  WebAssembly::ExprType parseBlockType(StringRef ID) {
+    return StringSwitch<WebAssembly::ExprType>(ID)
+        .Case("i32", WebAssembly::ExprType::I32)
+        .Case("i64", WebAssembly::ExprType::I64)
+        .Case("f32", WebAssembly::ExprType::F32)
+        .Case("f64", WebAssembly::ExprType::F64)
+        .Case("v128", WebAssembly::ExprType::V128)
+        .Case("except_ref", WebAssembly::ExprType::ExceptRef)
+        .Case("void", WebAssembly::ExprType::Void)
+        .Default(WebAssembly::ExprType::Invalid);
+  }
+
   bool parseRegTypeList(SmallVectorImpl<wasm::ValType> &Types) {
     while (Lexer.is(AsmToken::Identifier)) {
       auto Type = parseType(Lexer.getTok().getString());
@@ -351,6 +363,13 @@ public:
     return false;
   }
 
+  void addBlockTypeOperand(OperandVector &Operands, SMLoc NameLoc,
+                           WebAssembly::ExprType BT) {
+    Operands.push_back(make_unique<WebAssemblyOperand>(
+        WebAssemblyOperand::Integer, NameLoc, NameLoc,
+        WebAssemblyOperand::IntOp{static_cast<int64_t>(BT)}));
+  }
+
   bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
                         SMLoc NameLoc, OperandVector &Operands) override {
     // Note: Name does NOT point into the sourcecode, but to a local, so
@@ -387,14 +406,19 @@ public:
 
     // If this instruction is part of a control flow structure, ensure
     // proper nesting.
+    bool ExpectBlockType = false;
     if (BaseName == "block") {
       push(Block);
+      ExpectBlockType = true;
     } else if (BaseName == "loop") {
       push(Loop);
+      ExpectBlockType = true;
     } else if (BaseName == "try") {
       push(Try);
+      ExpectBlockType = true;
     } else if (BaseName == "if") {
       push(If);
+      ExpectBlockType = true;
     } else if (BaseName == "else") {
       if (pop(BaseName, If))
         return true;
@@ -429,13 +453,23 @@ public:
       switch (Tok.getKind()) {
       case AsmToken::Identifier: {
         auto &Id = Lexer.getTok();
-        const MCExpr *Val;
-        SMLoc End;
-        if (Parser.parsePrimaryExpr(Val, End))
-          return error("Cannot parse symbol: ", Lexer.getTok());
-        Operands.push_back(make_unique<WebAssemblyOperand>(
-            WebAssemblyOperand::Symbol, Id.getLoc(), Id.getEndLoc(),
-            WebAssemblyOperand::SymOp{Val}));
+        if (ExpectBlockType) {
+          // Assume this identifier is a block_type.
+          auto BT = parseBlockType(Id.getString());
+          if (BT == WebAssembly::ExprType::Invalid)
+            return error("Unknown block type: ", Id);
+          addBlockTypeOperand(Operands, NameLoc, BT);
+          Parser.Lex();
+        } else {
+          // Assume this identifier is a label.
+          const MCExpr *Val;
+          SMLoc End;
+          if (Parser.parsePrimaryExpr(Val, End))
+            return error("Cannot parse symbol: ", Lexer.getTok());
+          Operands.push_back(make_unique<WebAssemblyOperand>(
+              WebAssemblyOperand::Symbol, Id.getLoc(), Id.getEndLoc(),
+              WebAssemblyOperand::SymOp{Val}));
+        }
         break;
       }
       case AsmToken::Minus:
@@ -482,18 +516,11 @@ public:
           return true;
       }
     }
-    Parser.Lex();
-
-    // Block instructions require a signature index, but these are missing in
-    // assembly, so we add a dummy one explicitly (since we have no control
-    // over signature tables here, we assume these will be regenerated when
-    // the wasm module is generated).
-    if (BaseName == "block" || BaseName == "loop" || BaseName == "try" ||
-        BaseName == "if") {
-      Operands.push_back(make_unique<WebAssemblyOperand>(
-          WebAssemblyOperand::Integer, NameLoc, NameLoc,
-          WebAssemblyOperand::IntOp{-1}));
+    if (ExpectBlockType && Operands.size() == 1) {
+      // Support blocks with no operands as default to void.
+      addBlockTypeOperand(Operands, NameLoc, WebAssembly::ExprType::Void);
     }
+    Parser.Lex();
     return false;
   }
 

Modified: llvm/trunk/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp?rev=350270&r1=350269&r2=350270&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp Wed Jan  2 15:23:51 2019
@@ -167,12 +167,17 @@ MCDisassembler::DecodeStatus WebAssembly
     }
     // SLEB operands:
     case WebAssembly::OPERAND_I32IMM:
-    case WebAssembly::OPERAND_I64IMM:
-    case WebAssembly::OPERAND_SIGNATURE: {
+    case WebAssembly::OPERAND_I64IMM: {
       if (!parseLEBImmediate(MI, Size, Bytes, true))
         return MCDisassembler::Fail;
       break;
     }
+    // block_type operands (uint8_t).
+    case WebAssembly::OPERAND_SIGNATURE: {
+      if (!parseImmediate<uint8_t>(MI, Size, Bytes))
+        return MCDisassembler::Fail;
+      break;
+    }
     // FP operands.
     case WebAssembly::OPERAND_F32IMM: {
       if (!parseImmediate<float>(MI, Size, Bytes))

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=350270&r1=350269&r2=350270&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Wed Jan  2 15:23:51 2019
@@ -278,6 +278,8 @@ void WebAssemblyInstPrinter::printWebAss
   case WebAssembly::ExprType::ExceptRef:
     O << "except_ref";
     break;
+  default:
+    llvm_unreachable("invalid WebAssembly::ExprType");
   }
 }
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=350270&r1=350269&r2=350270&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Wed Jan  2 15:23:51 2019
@@ -346,7 +346,8 @@ enum class ExprType : unsigned {
   F32 = 0x7D,
   F64 = 0x7C,
   V128 = 0x7B,
-  ExceptRef = 0x68
+  ExceptRef = 0x68,
+  Invalid = 0x00
 };
 
 /// Instruction opcodes emitted via means other than CodeGen.

Modified: llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt?rev=350270&r1=350269&r2=350270&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt Wed Jan  2 15:23:51 2019
@@ -14,10 +14,8 @@
 # CHECK: i64.load32_u 16:p2align=1
 0x35 0x01 0x10
 
-# CHECK: block
-# 3
-# FIXME: WebAssemblyInstPrinter does not currently print block number.
-0x02 0x03
+# CHECK: block f64
+0x02 0x7C
 
 # CHECK: call_indirect
 # $0=, 128, 0

Modified: llvm/trunk/test/MC/WebAssembly/basic-assembly.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/basic-assembly.s?rev=350270&r1=350269&r2=350270&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/basic-assembly.s (original)
+++ llvm/trunk/test/MC/WebAssembly/basic-assembly.s Wed Jan  2 15:23:51 2019
@@ -22,13 +22,13 @@ test0:
     get_local   0
     f64.store   0
     # Loops, conditionals, binary ops, calls etc:
-    block
+    block       i32
     i32.const   1
     get_local   0
     i32.ge_s
     br_if       0        # 0: down to label0
 .LBB0_1:
-    loop             # label1:
+    loop        i32      # label1:
     call        something1 at FUNCTION
     i64.const   1234
     i32.call    something2 at FUNCTION
@@ -42,25 +42,25 @@ test0:
     br_if       0        # 0: up to label1
 .LBB0_2:
     end_loop
-    end_block                       # label0:
+    end_block            # label0:
     get_local   4
     get_local   5
-    block
-    block
-    block
-    block
+    block       void
+    block       i64
+    block       f32
+    block       f64
     br_table {0, 1, 2}   # 2 entries, default
     end_block            # first entry jumps here.
-    i32.const 1
+    i32.const   1
     br 2
     end_block            # second entry jumps here.
-    i32.const 2
+    i32.const   2
     br 1
     end_block            # default jumps here.
-    i32.const 3
+    i32.const   3
     end_block            # "switch" exit.
-    if
-    if
+    if          # void
+    if          i32
     end_if
     else
     end_if
@@ -69,7 +69,7 @@ test0:
     # TODO: enable once instruction has been added.
     #i32x4.trunc_s/f32x4:sat
     i32.trunc_s/f32
-    try
+    try         except_ref
 .LBB0_3:
     i32.catch   0
 .LBB0_4:
@@ -80,7 +80,7 @@ test0:
     get_global  __stack_pointer at GLOBAL
     end_function
 .Lfunc_end0:
-	.size	test0, .Lfunc_end0-test0
+    .size	test0, .Lfunc_end0-test0
     .globaltype	__stack_pointer, i32
 
 # CHECK:           .text
@@ -96,13 +96,13 @@ test0:
 # CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7
 # CHECK-NEXT:      get_local   0
 # CHECK-NEXT:      f64.store   0:p2align=0
-# CHECK-NEXT:      block
+# CHECK-NEXT:      block       i32
 # CHECK-NEXT:      i32.const   1
 # CHECK-NEXT:      get_local   0
 # CHECK-NEXT:      i32.ge_s
 # CHECK-NEXT:      br_if 0            # 0: down to label0
 # CHECK-NEXT:  .LBB0_1:
-# CHECK-NEXT:      loop                    # label1:
+# CHECK-NEXT:      loop        i32         # label1:
 # CHECK-NEXT:      call        something1 at FUNCTION
 # CHECK-NEXT:      i64.const   1234
 # CHECK-NEXT:      i32.call    something2 at FUNCTION
@@ -120,9 +120,9 @@ test0:
 # CHECK-NEXT:      get_local   4
 # CHECK-NEXT:      get_local   5
 # CHECK-NEXT:      block
-# CHECK-NEXT:      block
-# CHECK-NEXT:      block
-# CHECK-NEXT:      block
+# CHECK-NEXT:      block       i64
+# CHECK-NEXT:      block       f32
+# CHECK-NEXT:      block       f64
 # CHECK-NEXT:      br_table {0, 1, 2}  # 1: down to label4
 # CHECK-NEXT:                          # 2: down to label3
 # CHECK-NEXT:      end_block           # label5:
@@ -135,13 +135,13 @@ test0:
 # CHECK-NEXT:      i32.const 3
 # CHECK-NEXT:      end_block           # label2:
 # CHECK-NEXT:      if
-# CHECK-NEXT:      if
+# CHECK-NEXT:      if          i32
 # CHECK-NEXT:      end_if
 # CHECK-NEXT:      else
 # CHECK-NEXT:      end_if
 # CHECK-NEXT:      f32x4.add
 # CHECK-NEXT:      i32.trunc_s/f32
-# CHECK-NEXT:      try
+# CHECK-NEXT:      try         except_ref
 # CHECK-NEXT:  .LBB0_3:
 # CHECK-NEXT:      i32.catch   0
 # CHECK-NEXT:  .LBB0_4:




More information about the llvm-commits mailing list