[Mlir-commits] [mlir] [MLIR][WASM] Extending the Wasm binary to WasmSSA dialect importer (PR #154053)

Ferdinand Lemaire llvmlistbot at llvm.org
Sun Aug 17 21:10:49 PDT 2025


https://github.com/flemairen6 updated https://github.com/llvm/llvm-project/pull/154053

>From 32188fdafccd1ed044357bdab902c5a48074e2d5 Mon Sep 17 00:00:00 2001
From: Luc Forget <dev at alias.lforget.fr>
Date: Wed, 2 Jul 2025 01:46:07 +0200
Subject: [PATCH 1/6] [mlir][wasm] Adding support for global in Wasm importer

---------

Co-authored-by: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Co-authored-by: Jessica Paquette <jessica.paquette at woven-planet.global>
---
 mlir/lib/Target/Wasm/TranslateFromWasm.cpp | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
index da811ba0954c2..92c1082905853 100644
--- a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
+++ b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
@@ -1036,6 +1036,9 @@ class WasmBinaryParser {
     if (failed(parsingMems))
       return;
 
+    auto parsingGlobals = parseSection<WasmSectionType::GLOBAL>();
+    if (failed(parsingGlobals))
+      return;
     LogicalResult parsingExports = parseSection<WasmSectionType::EXPORT>();
     if (failed(parsingExports))
       return;
@@ -1229,6 +1232,38 @@ WasmBinaryParser::parseSectionItem<WasmSectionType::MEMORY>(ParserHead &ph,
   symbols.memSymbols.push_back({SymbolRefAttr::get(memOp)});
   return success();
 }
+
+template <>
+LogicalResult
+WasmBinaryParser::parseSectionItem<WasmSectionType::GLOBAL>(ParserHead &ph,
+                                                            size_t) {
+  auto globalLocation = ph.getLocation();
+  auto globalTypeParsed = ph.parseGlobalType(ctx);
+  if (failed(globalTypeParsed))
+    return failure();
+
+  auto globalType = *globalTypeParsed;
+  auto symbol = builder.getStringAttr(symbols.getNewGlobalSymbolName());
+  auto globalOp = builder.create<wasmssa::GlobalOp>(
+      globalLocation, symbol, globalType.type, globalType.isMutable);
+  symbols.globalSymbols.push_back(
+      {{FlatSymbolRefAttr::get(globalOp)}, globalOp.getType()});
+  auto ip = builder.saveInsertionPoint();
+  auto *block = builder.createBlock(&globalOp.getInitializer());
+  builder.setInsertionPointToStart(block);
+  auto expr = ph.parseExpression(builder, symbols);
+  if (failed(expr))
+    return failure();
+  if (block->empty())
+    return emitError(globalLocation, "global with empty initializer");
+  if (expr->size() != 1 && (*expr)[0].getType() != globalType.type)
+    return emitError(
+        globalLocation,
+        "initializer result type does not match global declaration type");
+  builder.create<ReturnOp>(globalLocation, *expr);
+  builder.restoreInsertionPoint(ip);
+  return success();
+}
 } // namespace
 
 namespace mlir::wasm {

>From 4441032605642cfe2d077c63dd40a0f4b184fef8 Mon Sep 17 00:00:00 2001
From: Luc Forget <dev at alias.lforget.fr>
Date: Wed, 2 Jul 2025 06:23:41 +0200
Subject: [PATCH 2/6] [mlir][wasm] Add code section parsing in Wasm Binary
 importer

---------

Co-authored-by: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Co-authored-by: Jessica Paquette <jessica.paquette at woven-planet.global>
---
 mlir/lib/Target/Wasm/TranslateFromWasm.cpp    | 74 ++++++++++++++++++-
 mlir/test/Target/Wasm/const.mlir              | 37 ++++++++++
 mlir/test/Target/Wasm/global.mlir             | 44 +++++++++++
 mlir/test/Target/Wasm/inputs/const.yaml.wasm  | 39 ++++++++++
 mlir/test/Target/Wasm/inputs/global.yaml.wasm | 58 +++++++++++++++
 5 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 mlir/test/Target/Wasm/const.mlir
 create mode 100644 mlir/test/Target/Wasm/global.mlir
 create mode 100644 mlir/test/Target/Wasm/inputs/const.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/global.yaml.wasm

diff --git a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
index 92c1082905853..579a13fde6aa1 100644
--- a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
+++ b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
@@ -289,7 +289,7 @@ class ExpressionParser {
 private:
   std::optional<Location> currentOpLoc;
   ParserHead &parser;
-  [[maybe_unused]] WasmModuleSymbolTables const &symbols;
+  WasmModuleSymbolTables const &symbols;
   locals_t locals;
   ValueStack valueStack;
 };
@@ -510,6 +510,60 @@ class ParserHead {
     return eParser.parse(builder);
   }
 
+  llvm::LogicalResult parseCodeFor(FuncOp func,
+                                   WasmModuleSymbolTables const &symbols) {
+    llvm::SmallVector<local_val_t> locals{};
+    // Populating locals with function argument
+    auto &block = func.getBody().front();
+    // Delete temporary return argument which was only created for IR validity
+    assert(func.getBody().getBlocks().size() == 1 &&
+           "Function should only have its default created block at this point");
+    assert(block.getOperations().size() == 1 &&
+           "Only the placeholder return op should be present at this point");
+    auto returnOp = cast<ReturnOp>(&block.back());
+    assert(returnOp);
+
+    auto codeSizeInBytes = parseUI32();
+    if (failed(codeSizeInBytes))
+      return failure();
+    auto codeContent = consumeNBytes(*codeSizeInBytes);
+    if (failed(codeContent))
+      return failure();
+    auto name = StringAttr::get(func->getContext(),
+                                locName.str() + "::" + func.getSymName());
+    auto cParser = ParserHead{*codeContent, name};
+    auto localVecSize = cParser.parseVectorSize();
+    if (failed(localVecSize))
+      return failure();
+    OpBuilder builder{&func.getBody().front().back()};
+    for (auto arg : block.getArguments())
+      locals.push_back(cast<TypedValue<LocalRefType>>(arg));
+    // Declare the local ops
+    auto nVarVec = *localVecSize;
+    for (size_t i = 0; i < nVarVec; ++i) {
+      auto varLoc = cParser.getLocation();
+      auto nSubVar = cParser.parseUI32();
+      if (failed(nSubVar))
+        return failure();
+      auto varT = cParser.parseValueType(func->getContext());
+      if (failed(varT))
+        return failure();
+      for (size_t j = 0; j < *nSubVar; ++j) {
+        auto local = builder.create<LocalOp>(varLoc, *varT);
+        locals.push_back(local.getResult());
+      }
+    }
+    auto res = cParser.parseExpression(builder, symbols, locals);
+    if (failed(res))
+      return failure();
+    if (!cParser.end())
+      return emitError(cParser.getLocation(),
+                       "Unparsed garbage remaining at end of code block");
+    builder.create<ReturnOp>(func->getLoc(), *res);
+    returnOp->erase();
+    return success();
+  }
+
   bool end() const { return curHead().empty(); }
 
   ParserHead copy() const { return *this; }
@@ -1039,6 +1093,11 @@ class WasmBinaryParser {
     auto parsingGlobals = parseSection<WasmSectionType::GLOBAL>();
     if (failed(parsingGlobals))
       return;
+
+    auto parsingCode = parseSection<WasmSectionType::CODE>();
+    if (failed(parsingCode))
+      return;
+
     LogicalResult parsingExports = parseSection<WasmSectionType::EXPORT>();
     if (failed(parsingExports))
       return;
@@ -1264,6 +1323,19 @@ WasmBinaryParser::parseSectionItem<WasmSectionType::GLOBAL>(ParserHead &ph,
   builder.restoreInsertionPoint(ip);
   return success();
 }
+
+template <>
+LogicalResult WasmBinaryParser::parseSectionItem<WasmSectionType::CODE>(
+    ParserHead &ph, size_t innerFunctionId) {
+  auto funcId = innerFunctionId + firstInternalFuncID;
+  auto symRef = symbols.funcSymbols[funcId];
+  auto funcOp =
+      llvm::dyn_cast<FuncOp>(SymbolTable::lookupSymbolIn(mOp, symRef.symbol));
+  assert(funcOp);
+  if (failed(ph.parseCodeFor(funcOp, symbols)))
+    return failure();
+  return success();
+}
 } // namespace
 
 namespace mlir::wasm {
diff --git a/mlir/test/Target/Wasm/const.mlir b/mlir/test/Target/Wasm/const.mlir
new file mode 100644
index 0000000000000..aa9e76f8502b6
--- /dev/null
+++ b/mlir/test/Target/Wasm/const.mlir
@@ -0,0 +1,37 @@
+// RUN: yaml2obj %S/inputs/const.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+/* Source code used to create this test:
+(module
+    (func(result i32)
+        i32.const 1
+    )
+    (func (result i64)
+        i64.const 3
+    )
+    (func (result f32)
+        f32.const 4.0
+    )
+    (func (result f64)
+        f64.const 9.0
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func nested @func_0() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1 : i32
+// CHECK:           wasmssa.return %[[VAL_0]] : i32
+// CHECK:         }
+
+// CHECK-LABEL:   wasmssa.func nested @func_1() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 3 : i64
+// CHECK:           wasmssa.return %[[VAL_0]] : i64
+// CHECK:         }
+
+// CHECK-LABEL:   wasmssa.func nested @func_2() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 4.000000e+00 : f32
+// CHECK:           wasmssa.return %[[VAL_0]] : f32
+// CHECK:         }
+
+// CHECK-LABEL:   wasmssa.func nested @func_3() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 9.000000e+00 : f64
+// CHECK:           wasmssa.return %[[VAL_0]] : f64
+// CHECK:         }
diff --git a/mlir/test/Target/Wasm/global.mlir b/mlir/test/Target/Wasm/global.mlir
new file mode 100644
index 0000000000000..528f3888303d0
--- /dev/null
+++ b/mlir/test/Target/Wasm/global.mlir
@@ -0,0 +1,44 @@
+// RUN: yaml2obj %S/inputs/global.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+/* Source code used to create this test:
+(module
+
+;; import a global variable from js
+(global $imported_glob (import "env" "from_js") i32)
+
+;; create a global variable
+(global $normal_glob i32(i32.const 10))
+(global $glob_mut (mut i32) (i32.const 10))
+(global $glob_mut_ext (mut i32) (i32.const 10))
+
+(global $normal_glob_i64 i64(i64.const 11))
+(global $normal_glob_f32 f32(f32.const 12))
+(global $normal_glob_f64 f64(f64.const 13))
+)
+*/
+
+// CHECK-LABEL:   wasmssa.import_global "from_js" from "env" as @global_0 nested : i32
+
+
+// CHECK-LABEL:   wasmssa.global @global_1 i32 nested : {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           wasmssa.return %[[VAL_0]] : i32
+
+// CHECK-LABEL:   wasmssa.global @global_2 i32 mutable nested : {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           wasmssa.return %[[VAL_0]] : i32
+
+// CHECK-LABEL:   wasmssa.global @global_3 i32 mutable nested : {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           wasmssa.return %[[VAL_0]] : i32
+
+// CHECK-LABEL:   wasmssa.global @global_4 i64 nested : {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 11 : i64
+// CHECK:           wasmssa.return %[[VAL_0]] : i64
+
+// CHECK-LABEL:   wasmssa.global @global_5 f32 nested : {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.200000e+01 : f32
+// CHECK:           wasmssa.return %[[VAL_0]] : f32
+
+// CHECK-LABEL:   wasmssa.global @global_6 f64 nested : {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.300000e+01 : f64
+// CHECK:           wasmssa.return %[[VAL_0]] : f64
diff --git a/mlir/test/Target/Wasm/inputs/const.yaml.wasm b/mlir/test/Target/Wasm/inputs/const.yaml.wasm
new file mode 100644
index 0000000000000..be8f88e2f3be4
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/const.yaml.wasm
@@ -0,0 +1,39 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+      - Index:           2
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           3
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1, 2, 3 ]
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            41010B
+      - Index:           1
+        Locals:          []
+        Body:            42030B
+      - Index:           2
+        Locals:          []
+        Body:            43000080400B
+      - Index:           3
+        Locals:          []
+        Body:            4400000000000022400B
+...
diff --git a/mlir/test/Target/Wasm/inputs/global.yaml.wasm b/mlir/test/Target/Wasm/inputs/global.yaml.wasm
new file mode 100644
index 0000000000000..e8731fe1f7e5b
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/global.yaml.wasm
@@ -0,0 +1,58 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+  - Type:            IMPORT
+    Imports:
+      - Module:          env
+        Field:           from_js
+        Kind:            GLOBAL
+        GlobalType:      I32
+        GlobalMutable:   false
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0 ]
+  - Type:            GLOBAL
+    Globals:
+      - Index:           1
+        Type:            I32
+        Mutable:         false
+        InitExpr:
+          Opcode:          I32_CONST
+          Value:           10
+      - Index:           2
+        Type:            I32
+        Mutable:         true
+        InitExpr:
+          Opcode:          I32_CONST
+          Value:           10
+      - Index:           3
+        Type:            I32
+        Mutable:         true
+        InitExpr:
+          Opcode:          I32_CONST
+          Value:           10
+      - Index:           4
+        Type:            I64
+        Mutable:         false
+        InitExpr:
+          Opcode:          I64_CONST
+          Value:           11
+      - Index:           5
+        Type:            F32
+        Mutable:         false
+        InitExpr:
+          Opcode:          F32_CONST
+          Value:           1094713344
+      - Index:           6
+        Type:            F64
+        Mutable:         false
+        InitExpr:
+          Opcode:          F64_CONST
+          Value:           4623507967449235456
+...

>From 024a7b68bd1a0810ec802bc7d5e6ba9f76a17628 Mon Sep 17 00:00:00 2001
From: Luc Forget <dev at alias.lforget.fr>
Date: Wed, 2 Jul 2025 07:07:04 +0200
Subject: [PATCH 3/6] [mlir][wasm] Support for numeric instruction in Wasm
 importer

---------

Co-authored-by: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Co-authored-by: Jessica Paquette <jessica.paquette at woven-planet.global>
---
 .../mlir/Target/Wasm/WasmBinaryEncoding.h     |  66 +++++++++
 mlir/lib/Target/Wasm/TranslateFromWasm.cpp    | 103 ++++++++++++++
 mlir/test/Target/Wasm/abs.mlir                |  23 ++++
 mlir/test/Target/Wasm/and.mlir                |  27 ++++
 mlir/test/Target/Wasm/clz.mlir                |  25 ++++
 mlir/test/Target/Wasm/copysign.mlir           |  31 +++++
 mlir/test/Target/Wasm/ctz.mlir                |  25 ++++
 mlir/test/Target/Wasm/div.mlir                | 127 ++++++++++++++++++
 mlir/test/Target/Wasm/inputs/abs.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/and.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/clz.yaml.wasm    |  33 +++++
 .../Target/Wasm/inputs/copysign.yaml.wasm     |  33 +++++
 mlir/test/Target/Wasm/inputs/ctz.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/div.yaml.wasm    |  89 ++++++++++++
 mlir/test/Target/Wasm/inputs/max.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/min.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/neg.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/or.yaml.wasm     |  33 +++++
 mlir/test/Target/Wasm/inputs/popcnt.yaml.wasm |  33 +++++
 mlir/test/Target/Wasm/inputs/rem.yaml.wasm    |  45 +++++++
 mlir/test/Target/Wasm/inputs/rotl.yaml.wasm   |  33 +++++
 mlir/test/Target/Wasm/inputs/rotr.yaml.wasm   |  33 +++++
 mlir/test/Target/Wasm/inputs/shl.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/inputs/shr_s.yaml.wasm  |  33 +++++
 mlir/test/Target/Wasm/inputs/shr_u.yaml.wasm  |  33 +++++
 mlir/test/Target/Wasm/inputs/sqrt.yaml.wasm   |  33 +++++
 mlir/test/Target/Wasm/inputs/sub.yaml.wasm    |  39 ++++++
 mlir/test/Target/Wasm/inputs/xor.yaml.wasm    |  33 +++++
 mlir/test/Target/Wasm/max.mlir                |  30 +++++
 mlir/test/Target/Wasm/min.mlir                |  29 ++++
 mlir/test/Target/Wasm/neg.mlir                |  23 ++++
 mlir/test/Target/Wasm/or.mlir                 |  27 ++++
 mlir/test/Target/Wasm/popcnt.mlir             |  25 ++++
 mlir/test/Target/Wasm/rem.mlir                |  53 ++++++++
 mlir/test/Target/Wasm/rotl.mlir               |  27 ++++
 mlir/test/Target/Wasm/rotr.mlir               |  27 ++++
 mlir/test/Target/Wasm/shl.mlir                |  27 ++++
 mlir/test/Target/Wasm/shr_s.mlir              |  27 ++++
 mlir/test/Target/Wasm/shr_u.mlir              |  27 ++++
 mlir/test/Target/Wasm/sqrt.mlir               |  23 ++++
 mlir/test/Target/Wasm/sub.mlir                |  52 +++++++
 mlir/test/Target/Wasm/xor.mlir                |  27 ++++
 42 files changed, 1585 insertions(+)
 create mode 100644 mlir/test/Target/Wasm/abs.mlir
 create mode 100644 mlir/test/Target/Wasm/and.mlir
 create mode 100644 mlir/test/Target/Wasm/clz.mlir
 create mode 100644 mlir/test/Target/Wasm/copysign.mlir
 create mode 100644 mlir/test/Target/Wasm/ctz.mlir
 create mode 100644 mlir/test/Target/Wasm/div.mlir
 create mode 100644 mlir/test/Target/Wasm/inputs/abs.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/and.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/clz.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/copysign.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/ctz.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/div.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/max.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/min.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/neg.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/or.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/popcnt.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/rem.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/rotl.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/rotr.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/shl.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/shr_s.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/shr_u.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/sqrt.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/sub.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/inputs/xor.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/max.mlir
 create mode 100644 mlir/test/Target/Wasm/min.mlir
 create mode 100644 mlir/test/Target/Wasm/neg.mlir
 create mode 100644 mlir/test/Target/Wasm/or.mlir
 create mode 100644 mlir/test/Target/Wasm/popcnt.mlir
 create mode 100644 mlir/test/Target/Wasm/rem.mlir
 create mode 100644 mlir/test/Target/Wasm/rotl.mlir
 create mode 100644 mlir/test/Target/Wasm/rotr.mlir
 create mode 100644 mlir/test/Target/Wasm/shl.mlir
 create mode 100644 mlir/test/Target/Wasm/shr_s.mlir
 create mode 100644 mlir/test/Target/Wasm/shr_u.mlir
 create mode 100644 mlir/test/Target/Wasm/sqrt.mlir
 create mode 100644 mlir/test/Target/Wasm/sub.mlir
 create mode 100644 mlir/test/Target/Wasm/xor.mlir

diff --git a/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h b/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
index 3280432b5f038..94b768c66c5f8 100644
--- a/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
+++ b/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
@@ -24,6 +24,72 @@ struct WasmBinaryEncoding {
     static constexpr std::byte constI64{0x42};
     static constexpr std::byte constFP32{0x43};
     static constexpr std::byte constFP64{0x44};
+
+    // Numeric operations.
+    static constexpr std::byte clzI32{0x67};
+    static constexpr std::byte ctzI32{0x68};
+    static constexpr std::byte popcntI32{0x69};
+    static constexpr std::byte addI32{0x6A};
+    static constexpr std::byte subI32{0x6B};
+    static constexpr std::byte mulI32{0x6C};
+    static constexpr std::byte divSI32{0x6d};
+    static constexpr std::byte divUI32{0x6e};
+    static constexpr std::byte remSI32{0x6f};
+    static constexpr std::byte remUI32{0x70};
+    static constexpr std::byte andI32{0x71};
+    static constexpr std::byte orI32{0x72};
+    static constexpr std::byte xorI32{0x73};
+    static constexpr std::byte shlI32{0x74};
+    static constexpr std::byte shrSI32{0x75};
+    static constexpr std::byte shrUI32{0x76};
+    static constexpr std::byte rotlI32{0x77};
+    static constexpr std::byte rotrI32{0x78};
+    static constexpr std::byte clzI64{0x79};
+    static constexpr std::byte ctzI64{0x7A};
+    static constexpr std::byte popcntI64{0x7B};
+    static constexpr std::byte addI64{0x7C};
+    static constexpr std::byte subI64{0x7D};
+    static constexpr std::byte mulI64{0x7E};
+    static constexpr std::byte divSI64{0x7F};
+    static constexpr std::byte divUI64{0x80};
+    static constexpr std::byte remSI64{0x81};
+    static constexpr std::byte remUI64{0x82};
+    static constexpr std::byte andI64{0x83};
+    static constexpr std::byte orI64{0x84};
+    static constexpr std::byte xorI64{0x85};
+    static constexpr std::byte shlI64{0x86};
+    static constexpr std::byte shrSI64{0x87};
+    static constexpr std::byte shrUI64{0x88};
+    static constexpr std::byte rotlI64{0x89};
+    static constexpr std::byte rotrI64{0x8A};
+    static constexpr std::byte absF32{0x8B};
+    static constexpr std::byte negF32{0x8C};
+    static constexpr std::byte ceilF32{0x8D};
+    static constexpr std::byte floorF32{0x8E};
+    static constexpr std::byte truncF32{0x8F};
+    static constexpr std::byte sqrtF32{0x91};
+    static constexpr std::byte addF32{0x92};
+    static constexpr std::byte subF32{0x93};
+    static constexpr std::byte mulF32{0x94};
+    static constexpr std::byte divF32{0x95};
+    static constexpr std::byte minF32{0x96};
+    static constexpr std::byte maxF32{0x97};
+    static constexpr std::byte copysignF32{0x98};
+    static constexpr std::byte absF64{0x99};
+    static constexpr std::byte negF64{0x9A};
+    static constexpr std::byte ceilF64{0x9B};
+    static constexpr std::byte floorF64{0x9C};
+    static constexpr std::byte truncF64{0x9D};
+    static constexpr std::byte sqrtF64{0x9F};
+    static constexpr std::byte addF64{0xA0};
+    static constexpr std::byte subF64{0xA1};
+    static constexpr std::byte mulF64{0xA2};
+    static constexpr std::byte divF64{0xA3};
+    static constexpr std::byte minF64{0xA4};
+    static constexpr std::byte maxF64{0xA5};
+    static constexpr std::byte copysignF64{0xA6};
+    static constexpr std::byte wrap{0xA7};
+
   };
 
   /// Byte encodings of types in Wasm binaries
diff --git a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
index 579a13fde6aa1..b1a65330768da 100644
--- a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
+++ b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
@@ -232,6 +232,20 @@ class ExpressionParser {
   parseConstInst(OpBuilder &builder,
                  std::enable_if_t<std::is_arithmetic_v<valueT>> * = nullptr);
 
+  /// Construct an operation with \p numOperands operands and a single result.
+  /// Each operand must have the same type. Suitable for e.g. binops, unary
+  /// ops, etc.
+  ///
+  /// \p opcode - The WASM opcode to build.
+  /// \p valueType - The operand and result type for the built instruction.
+  /// \p numOperands - The number of operands for the built operation.
+  ///
+  /// \returns The parsed instruction result, or failure.
+  template <typename opcode, typename valueType, unsigned int numOperands>
+  inline parsed_inst_t
+  buildNumericOp(OpBuilder &builder,
+                 std::enable_if_t<std::is_arithmetic_v<valueType>> * = nullptr);
+
   /// This function generates a dispatch tree to associate an opcode with a
   /// parser. Parsers are registered by specialising the
   /// `parseSpecificInstruction` function for the op code to handle.
@@ -863,6 +877,95 @@ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
   return parseConstInst<double>(builder);
 }
 
+template <typename opcode, typename valueType, unsigned int numOperands>
+inline parsed_inst_t ExpressionParser::buildNumericOp(
+    OpBuilder &builder, std::enable_if_t<std::is_arithmetic_v<valueType>> *) {
+  auto ty = buildLiteralType<valueType>(builder);
+  LLVM_DEBUG(llvm::dbgs() << "*** buildNumericOp: numOperands = " << numOperands
+                          << ", type = " << ty << " ***\n");
+  auto tysToPop = llvm::SmallVector<Type, numOperands>();
+  tysToPop.resize(numOperands);
+  std::fill(tysToPop.begin(), tysToPop.end(), ty);
+  auto operands = popOperands(tysToPop);
+  if (failed(operands))
+    return failure();
+  auto op = builder.create<opcode>(*currentOpLoc, *operands).getResult();
+  LLVM_DEBUG(llvm::dbgs() << "Built: ");
+  LLVM_DEBUG(op.dump());
+  return {{op}};
+}
+
+// Convenience macro for generating numerical operations.
+#define BUILD_NUMERIC_OP(OP_NAME, N_ARGS, PREFIX, SUFFIX, TYPE)                \
+  template <>                                                                  \
+  inline parsed_inst_t ExpressionParser::parseSpecificInstruction<             \
+      WasmBinaryEncoding::OpCode::PREFIX##SUFFIX>(OpBuilder & builder) {       \
+    return buildNumericOp<OP_NAME, TYPE, N_ARGS>(builder);                     \
+  }
+
+// Macro to define binops that only support integer types.
+#define BUILD_NUMERIC_BINOP_INT(OP_NAME, PREFIX)                               \
+  BUILD_NUMERIC_OP(OP_NAME, 2, PREFIX, I32, int32_t)                           \
+  BUILD_NUMERIC_OP(OP_NAME, 2, PREFIX, I64, int64_t)
+
+// Macro to define binops that only support floating point types.
+#define BUILD_NUMERIC_BINOP_FP(OP_NAME, PREFIX)                                \
+  BUILD_NUMERIC_OP(OP_NAME, 2, PREFIX, F32, float)                             \
+  BUILD_NUMERIC_OP(OP_NAME, 2, PREFIX, F64, double)
+
+// Macro to define binops that support both floating point and integer types.
+#define BUILD_NUMERIC_BINOP_INTFP(OP_NAME, PREFIX)                             \
+  BUILD_NUMERIC_BINOP_INT(OP_NAME, PREFIX)                                     \
+  BUILD_NUMERIC_BINOP_FP(OP_NAME, PREFIX)
+
+// Macro to implement unary ops that only support integers.
+#define BUILD_NUMERIC_UNARY_OP_INT(OP_NAME, PREFIX)                            \
+  BUILD_NUMERIC_OP(OP_NAME, 1, PREFIX, I32, int32_t)                           \
+  BUILD_NUMERIC_OP(OP_NAME, 1, PREFIX, I64, int64_t)
+
+// Macro to implement unary ops that support integer and floating point types.
+#define BUILD_NUMERIC_UNARY_OP_FP(OP_NAME, PREFIX)                             \
+  BUILD_NUMERIC_OP(OP_NAME, 1, PREFIX, F32, float)                             \
+  BUILD_NUMERIC_OP(OP_NAME, 1, PREFIX, F64, double)
+
+BUILD_NUMERIC_BINOP_FP(CopySignOp, copysign)
+BUILD_NUMERIC_BINOP_FP(DivOp, div)
+BUILD_NUMERIC_BINOP_FP(MaxOp, max)
+BUILD_NUMERIC_BINOP_FP(MinOp, min)
+BUILD_NUMERIC_BINOP_INT(AndOp, and)
+BUILD_NUMERIC_BINOP_INT(DivSIOp, divS)
+BUILD_NUMERIC_BINOP_INT(DivUIOp, divU)
+BUILD_NUMERIC_BINOP_INT(OrOp, or)
+BUILD_NUMERIC_BINOP_INT(RemSIOp, remS)
+BUILD_NUMERIC_BINOP_INT(RemUIOp, remU)
+BUILD_NUMERIC_BINOP_INT(RotlOp, rotl)
+BUILD_NUMERIC_BINOP_INT(RotrOp, rotr)
+BUILD_NUMERIC_BINOP_INT(ShLOp, shl)
+BUILD_NUMERIC_BINOP_INT(ShRSOp, shrS)
+BUILD_NUMERIC_BINOP_INT(ShRUOp, shrU)
+BUILD_NUMERIC_BINOP_INT(XOrOp, xor)
+BUILD_NUMERIC_BINOP_INTFP(AddOp, add)
+BUILD_NUMERIC_BINOP_INTFP(MulOp, mul)
+BUILD_NUMERIC_BINOP_INTFP(SubOp, sub)
+BUILD_NUMERIC_UNARY_OP_FP(AbsOp, abs)
+BUILD_NUMERIC_UNARY_OP_FP(CeilOp, ceil)
+BUILD_NUMERIC_UNARY_OP_FP(FloorOp, floor)
+BUILD_NUMERIC_UNARY_OP_FP(NegOp, neg)
+BUILD_NUMERIC_UNARY_OP_FP(SqrtOp, sqrt)
+BUILD_NUMERIC_UNARY_OP_FP(TruncOp, trunc)
+BUILD_NUMERIC_UNARY_OP_INT(ClzOp, clz)
+BUILD_NUMERIC_UNARY_OP_INT(CtzOp, ctz)
+BUILD_NUMERIC_UNARY_OP_INT(PopCntOp, popcnt)
+
+// Don't need these anymore so let's undef them.
+#undef BUILD_NUMERIC_BINOP_FP
+#undef BUILD_NUMERIC_BINOP_INT
+#undef BUILD_NUMERIC_BINOP_INTFP
+#undef BUILD_NUMERIC_UNARY_OP_FP
+#undef BUILD_NUMERIC_UNARY_OP_INT
+#undef BUILD_NUMERIC_OP
+#undef BUILD_NUMERIC_CAST_OP
+
 class WasmBinaryParser {
 private:
   struct SectionRegistry {
diff --git a/mlir/test/Target/Wasm/abs.mlir b/mlir/test/Target/Wasm/abs.mlir
new file mode 100644
index 0000000000000..9c45ba78507ad
--- /dev/null
+++ b/mlir/test/Target/Wasm/abs.mlir
@@ -0,0 +1,23 @@
+// RUN: yaml2obj %S/inputs/abs.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "abs_f32") (result f32)
+    f32.const 10
+    f32.abs)
+
+    (func (export "abs_f64") (result f64)
+    f64.const 10
+    f64.abs)
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @abs_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.abs %[[VAL_0]] : f32
+// CHECK:           wasmssa.return %[[VAL_1]] : f32
+
+// CHECK-LABEL:   wasmssa.func @abs_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.abs %[[VAL_0]] : f64
+// CHECK:           wasmssa.return %[[VAL_1]] : f64
diff --git a/mlir/test/Target/Wasm/and.mlir b/mlir/test/Target/Wasm/and.mlir
new file mode 100644
index 0000000000000..4c0fea01b3ae6
--- /dev/null
+++ b/mlir/test/Target/Wasm/and.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/and.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "and_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.and)
+
+    (func (export "and_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.and)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @and_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.and %0 %1 : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @and_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.and %0 %1 : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/clz.mlir b/mlir/test/Target/Wasm/clz.mlir
new file mode 100644
index 0000000000000..3e6641d9a2a96
--- /dev/null
+++ b/mlir/test/Target/Wasm/clz.mlir
@@ -0,0 +1,25 @@
+// RUN: yaml2obj %S/inputs/clz.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "clz_i32") (result i32)
+    i32.const 10
+    i32.clz
+    )
+
+    (func (export "clz_i64") (result i64)
+    i64.const 10
+    i64.clz
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @clz_i32() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.clz %[[VAL_0]] : i32
+// CHECK:           wasmssa.return %[[VAL_1]] : i32
+
+// CHECK-LABEL:   wasmssa.func @clz_i64() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.clz %[[VAL_0]] : i64
+// CHECK:           wasmssa.return %[[VAL_1]] : i64
diff --git a/mlir/test/Target/Wasm/copysign.mlir b/mlir/test/Target/Wasm/copysign.mlir
new file mode 100644
index 0000000000000..33d7a56694c1c
--- /dev/null
+++ b/mlir/test/Target/Wasm/copysign.mlir
@@ -0,0 +1,31 @@
+// RUN: yaml2obj %S/inputs/copysign.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "copysign_f32") (result f32)
+    f32.const 10
+    f32.const 1
+    f32.copysign
+    )
+
+    (func (export "copysign_f64") (result f64)
+    f64.const 10
+    f64.const 1
+    f64.copysign
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @copysign_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.copysign %[[VAL_0]] %[[VAL_1]] : f32
+// CHECK:           wasmssa.return %[[VAL_2]] : f32
+// CHECK:         }
+
+// CHECK-LABEL:   wasmssa.func @copysign_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.copysign %[[VAL_0]] %[[VAL_1]] : f64
+// CHECK:           wasmssa.return %[[VAL_2]] : f64
+// CHECK:         }
diff --git a/mlir/test/Target/Wasm/ctz.mlir b/mlir/test/Target/Wasm/ctz.mlir
new file mode 100644
index 0000000000000..6c0806f62303c
--- /dev/null
+++ b/mlir/test/Target/Wasm/ctz.mlir
@@ -0,0 +1,25 @@
+// RUN: yaml2obj %S/inputs/ctz.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "ctz_i32") (result i32)
+    i32.const 10
+    i32.ctz
+    )
+
+    (func (export "ctz_i64") (result i64)
+    i64.const 10
+    i64.ctz
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @ctz_i32() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.ctz %[[VAL_0]] : i32
+// CHECK:           wasmssa.return %[[VAL_1]] : i32
+
+// CHECK-LABEL:   wasmssa.func @ctz_i64() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.ctz %[[VAL_0]] : i64
+// CHECK:           wasmssa.return %[[VAL_1]] : i64
diff --git a/mlir/test/Target/Wasm/div.mlir b/mlir/test/Target/Wasm/div.mlir
new file mode 100644
index 0000000000000..c91f7809a255d
--- /dev/null
+++ b/mlir/test/Target/Wasm/div.mlir
@@ -0,0 +1,127 @@
+// RUN: yaml2obj %S/inputs/div.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to create this test:
+(module
+    (func (export "div_u_i32") (result i32)
+        i32.const 10
+        i32.const 2
+        i32.div_u
+    )
+
+    (func (export "div_u_i32_zero") (result i32)
+        i32.const 10
+        i32.const 0
+        i32.div_u
+    )
+
+    (func (export "div_s_i32") (result i32)
+        i32.const 10
+        i32.const 2
+        i32.div_s
+    )
+
+    (func (export "div_s_i32_zero") (result i32)
+        i32.const 10
+        i32.const 0
+        i32.div_s
+    )
+
+    (func (export "div_u_i64") (result i64)
+        i64.const 10
+        i64.const 2
+        i64.div_u
+    )
+
+    ;; explode
+    (func (export "div_u_i64_zero") (result i64)
+        i64.const 10
+        i64.const 0
+        i64.div_u
+    )
+
+    (func (export "div_s_i64") (result i64)
+        i64.const 10
+        i64.const 2
+        i64.div_s
+    )
+
+    ;; explode
+    (func (export "div_s_i64_zero") (result i64)
+        i64.const 10
+        i64.const 0
+        i64.div_s
+    )
+
+    (func (export "div_f32") (result f32)
+        f32.const 10
+        f32.const 2
+        f32.div
+    )
+
+    (func (export "div_f64") (result f64)
+        f64.const 10
+        f64.const 2
+        f64.div
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @div_u_i32() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 2 : i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i32
+// CHECK:           wasmssa.return %[[VAL_2]] : i32
+
+// CHECK-LABEL:   wasmssa.func @div_u_i32_zero() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 0 : i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i32
+// CHECK:           wasmssa.return %[[VAL_2]] : i32
+
+// CHECK-LABEL:   wasmssa.func @div_s_i32() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 2 : i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i32
+// CHECK:           wasmssa.return %[[VAL_2]] : i32
+
+// CHECK-LABEL:   wasmssa.func @div_s_i32_zero() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 0 : i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i32
+// CHECK:           wasmssa.return %[[VAL_2]] : i32
+
+// CHECK-LABEL:   wasmssa.func @div_u_i64() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 2 : i64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i64
+// CHECK:           wasmssa.return %[[VAL_2]] : i64
+
+// CHECK-LABEL:   wasmssa.func @div_u_i64_zero() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 0 : i64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i64
+// CHECK:           wasmssa.return %[[VAL_2]] : i64
+
+// CHECK-LABEL:   wasmssa.func @div_s_i64() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 2 : i64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i64
+// CHECK:           wasmssa.return %[[VAL_2]] : i64
+
+// CHECK-LABEL:   wasmssa.func @div_s_i64_zero() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 0 : i64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i64
+// CHECK:           wasmssa.return %[[VAL_2]] : i64
+
+// CHECK-LABEL:   wasmssa.func @div_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 2.000000e+00 : f32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div %[[VAL_0]] %[[VAL_1]] : f32
+// CHECK:           wasmssa.return %[[VAL_2]] : f32
+
+// CHECK-LABEL:   wasmssa.func @div_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 2.000000e+00 : f64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.div %[[VAL_0]] %[[VAL_1]] : f64
+// CHECK:           wasmssa.return %[[VAL_2]] : f64
diff --git a/mlir/test/Target/Wasm/inputs/abs.yaml.wasm b/mlir/test/Target/Wasm/inputs/abs.yaml.wasm
new file mode 100644
index 0000000000000..1cb6d21b2fdd4
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/abs.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            abs_f32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            abs_f64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            43000020418B0B
+      - Index:           1
+        Locals:          []
+        Body:            440000000000002440990B
+...
diff --git a/mlir/test/Target/Wasm/inputs/and.yaml.wasm b/mlir/test/Target/Wasm/inputs/and.yaml.wasm
new file mode 100644
index 0000000000000..926445b761080
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/and.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            and_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            and_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103710B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203830B
+...
diff --git a/mlir/test/Target/Wasm/inputs/clz.yaml.wasm b/mlir/test/Target/Wasm/inputs/clz.yaml.wasm
new file mode 100644
index 0000000000000..f537bdb359241
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/clz.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            clz_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            clz_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A670B
+      - Index:           1
+        Locals:          []
+        Body:            420A790B
+...
diff --git a/mlir/test/Target/Wasm/inputs/copysign.yaml.wasm b/mlir/test/Target/Wasm/inputs/copysign.yaml.wasm
new file mode 100644
index 0000000000000..46c04124ac84a
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/copysign.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            copysign_f32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            copysign_f64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            4300002041430000803F980B
+      - Index:           1
+        Locals:          []
+        Body:            44000000000000244044000000000000F03FA60B
+...
diff --git a/mlir/test/Target/Wasm/inputs/ctz.yaml.wasm b/mlir/test/Target/Wasm/inputs/ctz.yaml.wasm
new file mode 100644
index 0000000000000..51400852d3dce
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/ctz.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            ctz_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            ctz_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A680B
+      - Index:           1
+        Locals:          []
+        Body:            420A7A0B
+...
diff --git a/mlir/test/Target/Wasm/inputs/div.yaml.wasm b/mlir/test/Target/Wasm/inputs/div.yaml.wasm
new file mode 100644
index 0000000000000..648e10c15cbed
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/div.yaml.wasm
@@ -0,0 +1,89 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+      - Index:           2
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           3
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 3 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            div_u_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            div_u_i32_zero
+        Kind:            FUNCTION
+        Index:           1
+      - Name:            div_s_i32
+        Kind:            FUNCTION
+        Index:           2
+      - Name:            div_s_i32_zero
+        Kind:            FUNCTION
+        Index:           3
+      - Name:            div_u_i64
+        Kind:            FUNCTION
+        Index:           4
+      - Name:            div_u_i64_zero
+        Kind:            FUNCTION
+        Index:           5
+      - Name:            div_s_i64
+        Kind:            FUNCTION
+        Index:           6
+      - Name:            div_s_i64_zero
+        Kind:            FUNCTION
+        Index:           7
+      - Name:            div_f32
+        Kind:            FUNCTION
+        Index:           8
+      - Name:            div_f64
+        Kind:            FUNCTION
+        Index:           9
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A41026E0B
+      - Index:           1
+        Locals:          []
+        Body:            410A41006E0B
+      - Index:           2
+        Locals:          []
+        Body:            410A41026D0B
+      - Index:           3
+        Locals:          []
+        Body:            410A41006D0B
+      - Index:           4
+        Locals:          []
+        Body:            420A4202800B
+      - Index:           5
+        Locals:          []
+        Body:            420A4200800B
+      - Index:           6
+        Locals:          []
+        Body:            420A42027F0B
+      - Index:           7
+        Locals:          []
+        Body:            420A42007F0B
+      - Index:           8
+        Locals:          []
+        Body:            43000020414300000040950B
+      - Index:           9
+        Locals:          []
+        Body:            440000000000002440440000000000000040A30B
+...
diff --git a/mlir/test/Target/Wasm/inputs/max.yaml.wasm b/mlir/test/Target/Wasm/inputs/max.yaml.wasm
new file mode 100644
index 0000000000000..fc04b019fe34c
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/max.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            min_f32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            min_f64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            4300002041430000803F970B
+      - Index:           1
+        Locals:          []
+        Body:            44000000000000244044000000000000F03FA50B
+...
diff --git a/mlir/test/Target/Wasm/inputs/min.yaml.wasm b/mlir/test/Target/Wasm/inputs/min.yaml.wasm
new file mode 100644
index 0000000000000..925a5e96b43c9
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/min.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            min_f32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            min_f64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            4300002041430000803F960B
+      - Index:           1
+        Locals:          []
+        Body:            44000000000000244044000000000000F03FA40B
+...
diff --git a/mlir/test/Target/Wasm/inputs/neg.yaml.wasm b/mlir/test/Target/Wasm/inputs/neg.yaml.wasm
new file mode 100644
index 0000000000000..8392a2bf9a5fb
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/neg.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            neg_f32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            neg_f64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            43000020418C0B
+      - Index:           1
+        Locals:          []
+        Body:            4400000000000024409A0B
+...
diff --git a/mlir/test/Target/Wasm/inputs/or.yaml.wasm b/mlir/test/Target/Wasm/inputs/or.yaml.wasm
new file mode 100644
index 0000000000000..9528ce8b3f911
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/or.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            or_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            or_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103720B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203840B
+...
diff --git a/mlir/test/Target/Wasm/inputs/popcnt.yaml.wasm b/mlir/test/Target/Wasm/inputs/popcnt.yaml.wasm
new file mode 100644
index 0000000000000..03c57ad0841b9
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/popcnt.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            popcnt_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            popcnt_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A690B
+      - Index:           1
+        Locals:          []
+        Body:            420A7B0B
+...
diff --git a/mlir/test/Target/Wasm/inputs/rem.yaml.wasm b/mlir/test/Target/Wasm/inputs/rem.yaml.wasm
new file mode 100644
index 0000000000000..468a9db6f05ae
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/rem.yaml.wasm
@@ -0,0 +1,45 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1, 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            rem_u_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            rem_u_i64
+        Kind:            FUNCTION
+        Index:           1
+      - Name:            rem_s_i32
+        Kind:            FUNCTION
+        Index:           2
+      - Name:            rem_s_i64
+        Kind:            FUNCTION
+        Index:           3
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103700B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203820B
+      - Index:           2
+        Locals:          []
+        Body:            410A41036F0B
+      - Index:           3
+        Locals:          []
+        Body:            420A4203810B
+...
diff --git a/mlir/test/Target/Wasm/inputs/rotl.yaml.wasm b/mlir/test/Target/Wasm/inputs/rotl.yaml.wasm
new file mode 100644
index 0000000000000..87466cb16393f
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/rotl.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            rotl_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            rotl_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103770B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203890B
+...
diff --git a/mlir/test/Target/Wasm/inputs/rotr.yaml.wasm b/mlir/test/Target/Wasm/inputs/rotr.yaml.wasm
new file mode 100644
index 0000000000000..805a93fd55a8c
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/rotr.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            rotr_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            rotr_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103780B
+      - Index:           1
+        Locals:          []
+        Body:            420A42038A0B
+...
diff --git a/mlir/test/Target/Wasm/inputs/shl.yaml.wasm b/mlir/test/Target/Wasm/inputs/shl.yaml.wasm
new file mode 100644
index 0000000000000..d07605e599483
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/shl.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            shl_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            shl_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103740B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203860B
+...
diff --git a/mlir/test/Target/Wasm/inputs/shr_s.yaml.wasm b/mlir/test/Target/Wasm/inputs/shr_s.yaml.wasm
new file mode 100644
index 0000000000000..d5d8013a2f743
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/shr_s.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            shr_s_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            shr_s_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103750B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203870B
+...
diff --git a/mlir/test/Target/Wasm/inputs/shr_u.yaml.wasm b/mlir/test/Target/Wasm/inputs/shr_u.yaml.wasm
new file mode 100644
index 0000000000000..cd815144432f7
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/shr_u.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            shr_u_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            shr_u_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103760B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203880B
+...
diff --git a/mlir/test/Target/Wasm/inputs/sqrt.yaml.wasm b/mlir/test/Target/Wasm/inputs/sqrt.yaml.wasm
new file mode 100644
index 0000000000000..f8ab84be9255f
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/sqrt.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            sqrt_f32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            sqrt_f64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            4300002041910B
+      - Index:           1
+        Locals:          []
+        Body:            4400000000000024409F0B
+...
diff --git a/mlir/test/Target/Wasm/inputs/sub.yaml.wasm b/mlir/test/Target/Wasm/inputs/sub.yaml.wasm
new file mode 100644
index 0000000000000..95b6bcc1d9021
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/sub.yaml.wasm
@@ -0,0 +1,39 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+      - Index:           2
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           3
+        ParamTypes:      []
+        ReturnTypes:
+          - F64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1, 2, 3 ]
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410C41326B0B
+      - Index:           1
+        Locals:          []
+        Body:            421442057D0B
+      - Index:           2
+        Locals:          []
+        Body:            430000A0404300006041930B
+      - Index:           3
+        Locals:          []
+        Body:            440000000000003140440000000000000000A10B
+...
diff --git a/mlir/test/Target/Wasm/inputs/xor.yaml.wasm b/mlir/test/Target/Wasm/inputs/xor.yaml.wasm
new file mode 100644
index 0000000000000..45079c3b4fed3
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/xor.yaml.wasm
@@ -0,0 +1,33 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I64
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1 ]
+  - Type:            EXPORT
+    Exports:
+      - Name:            xor_i32
+        Kind:            FUNCTION
+        Index:           0
+      - Name:            xor_i64
+        Kind:            FUNCTION
+        Index:           1
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            410A4103730B
+      - Index:           1
+        Locals:          []
+        Body:            420A4203850B
+...
diff --git a/mlir/test/Target/Wasm/max.mlir b/mlir/test/Target/Wasm/max.mlir
new file mode 100644
index 0000000000000..4ef2042d923b6
--- /dev/null
+++ b/mlir/test/Target/Wasm/max.mlir
@@ -0,0 +1,30 @@
+// RUN: yaml2obj %S/inputs/max.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "max_f32") (result f32)
+    f32.const 10
+    f32.const 1
+    f32.max
+    )
+
+    (func (export "max_f64") (result f64)
+    f64.const 10
+    f64.const 1
+    f64.max
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @min_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.max %[[VAL_0]] %[[VAL_1]] : f32
+// CHECK:           wasmssa.return %[[VAL_2]] : f32
+
+
+// CHECK-LABEL:   wasmssa.func @min_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.max %[[VAL_0]] %[[VAL_1]] : f64
+// CHECK:           wasmssa.return %[[VAL_2]] : f64
diff --git a/mlir/test/Target/Wasm/min.mlir b/mlir/test/Target/Wasm/min.mlir
new file mode 100644
index 0000000000000..1058c7d32be71
--- /dev/null
+++ b/mlir/test/Target/Wasm/min.mlir
@@ -0,0 +1,29 @@
+// RUN: yaml2obj %S/inputs/min.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "min_f32") (result f32)
+    f32.const 10
+    f32.const 1
+    f32.min
+    )
+
+    (func (export "min_f64") (result f64)
+    f64.const 10
+    f64.const 1
+    f64.min
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @min_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.min %[[VAL_0]] %[[VAL_1]] : f32
+// CHECK:           wasmssa.return %[[VAL_2]] : f32
+
+// CHECK-LABEL:   wasmssa.func @min_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.min %[[VAL_0]] %[[VAL_1]] : f64
+// CHECK:           wasmssa.return %[[VAL_2]] : f64
diff --git a/mlir/test/Target/Wasm/neg.mlir b/mlir/test/Target/Wasm/neg.mlir
new file mode 100644
index 0000000000000..5811ab50348bd
--- /dev/null
+++ b/mlir/test/Target/Wasm/neg.mlir
@@ -0,0 +1,23 @@
+// RUN: yaml2obj %S/inputs/neg.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "neg_f32") (result f32)
+    f32.const 10
+    f32.neg)
+
+    (func (export "neg_f64") (result f64)
+    f64.const 10
+    f64.neg)
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @neg_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.neg %[[VAL_0]] : f32
+// CHECK:           wasmssa.return %[[VAL_1]] : f32
+
+// CHECK-LABEL:   wasmssa.func @neg_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.neg %[[VAL_0]] : f64
+// CHECK:           wasmssa.return %[[VAL_1]] : f64
diff --git a/mlir/test/Target/Wasm/or.mlir b/mlir/test/Target/Wasm/or.mlir
new file mode 100644
index 0000000000000..521f2bac9fa6a
--- /dev/null
+++ b/mlir/test/Target/Wasm/or.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/or.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "or_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.or)
+
+    (func (export "or_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.or)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @or_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.or %0 %1 : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @or_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.or %0 %1 : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/popcnt.mlir b/mlir/test/Target/Wasm/popcnt.mlir
new file mode 100644
index 0000000000000..235333a085177
--- /dev/null
+++ b/mlir/test/Target/Wasm/popcnt.mlir
@@ -0,0 +1,25 @@
+// RUN: yaml2obj %S/inputs/popcnt.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "popcnt_i32") (result i32)
+    i32.const 10
+    i32.popcnt
+    )
+
+    (func (export "popcnt_i64") (result i64)
+    i64.const 10
+    i64.popcnt
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @popcnt_i32() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.popcnt %[[VAL_0]] : i32
+// CHECK:           wasmssa.return %[[VAL_1]] : i32
+
+// CHECK-LABEL:   wasmssa.func @popcnt_i64() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.popcnt %[[VAL_0]] : i64
+// CHECK:           wasmssa.return %[[VAL_1]] : i64
diff --git a/mlir/test/Target/Wasm/rem.mlir b/mlir/test/Target/Wasm/rem.mlir
new file mode 100644
index 0000000000000..b19b8d9d45ed7
--- /dev/null
+++ b/mlir/test/Target/Wasm/rem.mlir
@@ -0,0 +1,53 @@
+// RUN: yaml2obj %S/inputs/rem.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "rem_u_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.rem_u)
+
+    (func (export "rem_u_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.rem_u)
+
+    (func (export "rem_s_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.rem_s)
+
+    (func (export "rem_s_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.rem_s)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @rem_u_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.rem_ui %0 %1 : i32
+// CHECK:    wasmssa.return %2 : i32
+// CHECK:  }
+
+// CHECK-LABEL: wasmssa.func @rem_u_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.rem_ui %0 %1 : i64
+// CHECK:    wasmssa.return %2 : i64
+// CHECK:  }
+
+// CHECK-LABEL:  wasmssa.func @rem_s_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.rem_si %0 %1 : i32
+// CHECK:    wasmssa.return %2 : i32
+// CHECK:  }
+
+// CHECK-LABEL:  wasmssa.func @rem_s_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.rem_si %0 %1 : i64
+// CHECK:    wasmssa.return %2 : i64
+// CHECK:  }
diff --git a/mlir/test/Target/Wasm/rotl.mlir b/mlir/test/Target/Wasm/rotl.mlir
new file mode 100644
index 0000000000000..ec573554f0a8c
--- /dev/null
+++ b/mlir/test/Target/Wasm/rotl.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/rotl.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "rotl_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.rotl)
+
+    (func (export "rotl_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.rotl)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @rotl_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.rotl %0 by %1 bits : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @rotl_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.rotl %0 by %1 bits : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/rotr.mlir b/mlir/test/Target/Wasm/rotr.mlir
new file mode 100644
index 0000000000000..5618b432693ad
--- /dev/null
+++ b/mlir/test/Target/Wasm/rotr.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/rotr.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "rotr_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.rotr)
+
+    (func (export "rotr_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.rotr)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @rotr_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.rotr %0 by %1 bits : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @rotr_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.rotr %0 by %1 bits : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/shl.mlir b/mlir/test/Target/Wasm/shl.mlir
new file mode 100644
index 0000000000000..f2bdd573fab81
--- /dev/null
+++ b/mlir/test/Target/Wasm/shl.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/shl.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "shl_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.shl)
+
+    (func (export "shl_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.shl)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @shl_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.shl %0 by %1 bits : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @shl_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.shl %0 by %1 bits : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/shr_s.mlir b/mlir/test/Target/Wasm/shr_s.mlir
new file mode 100644
index 0000000000000..247d9be28403c
--- /dev/null
+++ b/mlir/test/Target/Wasm/shr_s.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/shr_s.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "shr_s_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.shr_s)
+
+    (func (export "shr_s_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.shr_s)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @shr_s_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.shr_s %0 by %1 bits : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @shr_s_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.shr_s %0 by %1 bits : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/shr_u.mlir b/mlir/test/Target/Wasm/shr_u.mlir
new file mode 100644
index 0000000000000..9a79eed9b1d4a
--- /dev/null
+++ b/mlir/test/Target/Wasm/shr_u.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/shr_u.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "shr_u_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.shr_u)
+
+    (func (export "shr_u_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.shr_u)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @shr_u_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.shr_u %0 by %1 bits : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @shr_u_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.shr_u %0 by %1 bits : i64
+// CHECK:    wasmssa.return %2 : i64
diff --git a/mlir/test/Target/Wasm/sqrt.mlir b/mlir/test/Target/Wasm/sqrt.mlir
new file mode 100644
index 0000000000000..77444ad69b16f
--- /dev/null
+++ b/mlir/test/Target/Wasm/sqrt.mlir
@@ -0,0 +1,23 @@
+// RUN: yaml2obj %S/inputs/sqrt.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "sqrt_f32") (result f32)
+    f32.const 10
+    f32.sqrt)
+
+    (func (export "sqrt_f64") (result f64)
+    f64.const 10
+    f64.sqrt)
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func @sqrt_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.sqrt %[[VAL_0]] : f32
+// CHECK:           wasmssa.return %[[VAL_1]] : f32
+
+// CHECK-LABEL:   wasmssa.func @sqrt_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.sqrt %[[VAL_0]] : f64
+// CHECK:           wasmssa.return %[[VAL_1]] : f64
diff --git a/mlir/test/Target/Wasm/sub.mlir b/mlir/test/Target/Wasm/sub.mlir
new file mode 100644
index 0000000000000..b9c6caf006583
--- /dev/null
+++ b/mlir/test/Target/Wasm/sub.mlir
@@ -0,0 +1,52 @@
+// RUN: yaml2obj %S/inputs/sub.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+/* Source code used to create this test:
+(module
+    (func $sub_i32 (result i32)
+        i32.const 12
+        i32.const 50
+        i32.sub
+    )
+
+    (func $sub_i64 (result i64)
+        i64.const 20
+        i64.const 5
+        i64.sub
+    )
+
+    (func $sub_f32 (result f32)
+        f32.const 5
+        f32.const 14
+        f32.sub
+    )
+
+    (func $sub_f64 (result f64)
+        f64.const 17
+        f64.const 0
+        f64.sub
+    )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func nested @func_0() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 12 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 50 : i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : i32
+// CHECK:           wasmssa.return %[[VAL_2]] : i32
+
+// CHECK-LABEL:   wasmssa.func nested @func_1() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 20 : i64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 5 : i64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : i64
+// CHECK:           wasmssa.return %[[VAL_2]] : i64
+
+// CHECK-LABEL:   wasmssa.func nested @func_2() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : f32
+// CHECK:           wasmssa.return %[[VAL_2]] : f32
+
+// CHECK-LABEL:   wasmssa.func nested @func_3() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 1.700000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = wasmssa.const 0.000000e+00 : f64
+// CHECK:           %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : f64
+// CHECK:           wasmssa.return %[[VAL_2]] : f64
diff --git a/mlir/test/Target/Wasm/xor.mlir b/mlir/test/Target/Wasm/xor.mlir
new file mode 100644
index 0000000000000..94691de2b3be4
--- /dev/null
+++ b/mlir/test/Target/Wasm/xor.mlir
@@ -0,0 +1,27 @@
+// RUN: yaml2obj %S/inputs/xor.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+
+/* Source code used to generate this test:
+(module
+    (func (export "xor_i32") (result i32)
+    i32.const 10
+    i32.const 3
+    i32.xor)
+
+    (func (export "xor_i64") (result i64)
+    i64.const 10
+    i64.const 3
+    i64.xor)
+)
+*/
+
+// CHECK-LABEL: wasmssa.func @xor_i32() -> i32 {
+// CHECK:    %0 = wasmssa.const 10 : i32
+// CHECK:    %1 = wasmssa.const 3 : i32
+// CHECK:    %2 = wasmssa.xor %0 %1 : i32
+// CHECK:    wasmssa.return %2 : i32
+
+// CHECK-LABEL: wasmssa.func @xor_i64() -> i64 {
+// CHECK:    %0 = wasmssa.const 10 : i64
+// CHECK:    %1 = wasmssa.const 3 : i64
+// CHECK:    %2 = wasmssa.xor %0 %1 : i64
+// CHECK:    wasmssa.return %2 : i64

>From 453eb5946118cd9b5afb4ee1cfca925ece6a6186 Mon Sep 17 00:00:00 2001
From: Luc Forget <dev at alias.lforget.fr>
Date: Wed, 2 Jul 2025 06:32:58 +0200
Subject: [PATCH 4/6] [mlir][wasm] Support for variable related instructions in
 Wasm Importer

---------

Co-authored-by: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Co-authored-by: Jessica Paquette <jessica.paquette at woven-planet.global>
---
 .../mlir/Target/Wasm/WasmBinaryEncoding.h     |  4 ++
 mlir/lib/Target/Wasm/TranslateFromWasm.cpp    | 70 +++++++++++++++++++
 mlir/test/Target/Wasm/global.mlir             | 22 ++++++
 mlir/test/Target/Wasm/inputs/global.yaml.wasm |  5 ++
 mlir/test/Target/Wasm/inputs/local.yaml.wasm  | 37 ++++++++++
 mlir/test/Target/Wasm/local.mlir              | 59 ++++++++++++++++
 6 files changed, 197 insertions(+)
 create mode 100644 mlir/test/Target/Wasm/inputs/local.yaml.wasm
 create mode 100644 mlir/test/Target/Wasm/local.mlir

diff --git a/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h b/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
index 94b768c66c5f8..c36d0237ff528 100644
--- a/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
+++ b/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
@@ -20,6 +20,10 @@ struct WasmBinaryEncoding {
   /// Byte encodings for Wasm instructions.
   struct OpCode {
     // Locals, globals, constants.
+    static constexpr std::byte localGet{0x20};
+    static constexpr std::byte localSet{0x21};
+    static constexpr std::byte localTee{0x22};
+    static constexpr std::byte globalGet{0x23};
     static constexpr std::byte constI32{0x41};
     static constexpr std::byte constI64{0x42};
     static constexpr std::byte constFP32{0x43};
diff --git a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
index b1a65330768da..d481dbaec08eb 100644
--- a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
+++ b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
@@ -300,6 +300,12 @@ class ExpressionParser {
     return valueStack.pushResults(results, &currentOpLoc.value());
   }
 
+  /// The local.set and local.tee operations behave similarly and only differ
+  /// on their return value. This function factorizes the behavior of the two
+  /// operations in one place.
+  template <typename OpToCreate>
+  parsed_inst_t parseSetOrTee(OpBuilder &);
+
 private:
   std::optional<Location> currentOpLoc;
   ParserHead &parser;
@@ -786,6 +792,70 @@ ExpressionParser::parse(OpBuilder &builder,
   }
 }
 
+template <>
+inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
+    WasmBinaryEncoding::OpCode::localGet>(OpBuilder &builder) {
+  auto id = parser.parseLiteral<uint32_t>();
+  auto instLoc = *currentOpLoc;
+  if (failed(id))
+    return failure();
+  if (*id >= locals.size())
+    return emitError(instLoc, "Invalid local index. Function has ")
+           << locals.size() << " accessible locals, received index " << *id;
+  return {{builder.create<LocalGetOp>(instLoc, locals[*id]).getResult()}};
+}
+
+template <>
+inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
+    WasmBinaryEncoding::OpCode::globalGet>(OpBuilder &builder) {
+  auto id = parser.parseLiteral<uint32_t>();
+  auto instLoc = *currentOpLoc;
+  if (failed(id))
+    return failure();
+  if (*id >= symbols.globalSymbols.size())
+    return emitError(instLoc, "Invalid global index. Function has ")
+           << symbols.globalSymbols.size()
+           << " accessible globals, received index " << *id;
+  auto globalVar = symbols.globalSymbols[*id];
+  auto globalOp = builder.create<GlobalGetOp>(instLoc, globalVar.globalType,
+                                              globalVar.symbol);
+
+  return {{globalOp.getResult()}};
+}
+
+template <typename OpToCreate>
+parsed_inst_t ExpressionParser::parseSetOrTee(OpBuilder &builder) {
+  auto id = parser.parseLiteral<uint32_t>();
+  if (failed(id))
+    return failure();
+  if (*id >= locals.size())
+    return emitError(*currentOpLoc, "Invalid local index. Function has ")
+           << locals.size() << " accessible locals, received index " << *id;
+  if (valueStack.empty())
+    return emitError(
+        *currentOpLoc,
+        "Invalid stack access, trying to access a value on an empty stack.");
+
+  parsed_inst_t poppedOp = popOperands(locals[*id].getType().getElementType());
+  if (failed(poppedOp))
+    return failure();
+  return {
+      builder.create<OpToCreate>(*currentOpLoc, locals[*id], poppedOp->front())
+          ->getResults()};
+}
+
+template <>
+inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
+    WasmBinaryEncoding::OpCode::localSet>(OpBuilder &builder) {
+  return parseSetOrTee<LocalSetOp>(builder);
+}
+
+template <>
+inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
+    WasmBinaryEncoding::OpCode::localTee>(OpBuilder &builder) {
+  return parseSetOrTee<LocalTeeOp>(builder);
+}
+
 template <typename T>
 inline Type buildLiteralType(OpBuilder &);
 
diff --git a/mlir/test/Target/Wasm/global.mlir b/mlir/test/Target/Wasm/global.mlir
index 528f3888303d0..e72fe69666999 100644
--- a/mlir/test/Target/Wasm/global.mlir
+++ b/mlir/test/Target/Wasm/global.mlir
@@ -13,11 +13,33 @@
 (global $normal_glob_i64 i64(i64.const 11))
 (global $normal_glob_f32 f32(f32.const 12))
 (global $normal_glob_f64 f64(f64.const 13))
+
+(func $main (result i32)
+;; load both global variables onto the stack
+global.get $imported_glob
+global.get $normal_glob
+
+i32.add ;; add up both globals
+
+global.get $glob_mut
+global.get $glob_mut_ext
+i32.add
+i32.add
+)
 )
 */
 
 // CHECK-LABEL:   wasmssa.import_global "from_js" from "env" as @global_0 nested : i32
 
+// CHECK-LABEL:   wasmssa.func nested @func_0() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.global_get @global_0 : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.global_get @global_1 : i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.add %[[VAL_0]] %[[VAL_1]] : i32
+// CHECK:           %[[VAL_3:.*]] = wasmssa.global_get @global_2 : i32
+// CHECK:           %[[VAL_4:.*]] = wasmssa.global_get @global_3 : i32
+// CHECK:           %[[VAL_5:.*]] = wasmssa.add %[[VAL_3]] %[[VAL_4]] : i32
+// CHECK:           %[[VAL_6:.*]] = wasmssa.add %[[VAL_2]] %[[VAL_5]] : i32
+// CHECK:           wasmssa.return %[[VAL_6]] : i32
 
 // CHECK-LABEL:   wasmssa.global @global_1 i32 nested : {
 // CHECK:           %[[VAL_0:.*]] = wasmssa.const 10 : i32
diff --git a/mlir/test/Target/Wasm/inputs/global.yaml.wasm b/mlir/test/Target/Wasm/inputs/global.yaml.wasm
index e8731fe1f7e5b..4bbb434c0c51a 100644
--- a/mlir/test/Target/Wasm/inputs/global.yaml.wasm
+++ b/mlir/test/Target/Wasm/inputs/global.yaml.wasm
@@ -55,4 +55,9 @@ Sections:
         InitExpr:
           Opcode:          F64_CONST
           Value:           4623507967449235456
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:          []
+        Body:            230023016A230223036A6A0B
 ...
diff --git a/mlir/test/Target/Wasm/inputs/local.yaml.wasm b/mlir/test/Target/Wasm/inputs/local.yaml.wasm
new file mode 100644
index 0000000000000..3e937f3e7402a
--- /dev/null
+++ b/mlir/test/Target/Wasm/inputs/local.yaml.wasm
@@ -0,0 +1,37 @@
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:
+          - F32
+      - Index:           1
+        ParamTypes:      []
+        ReturnTypes:
+          - I32
+      - Index:           2
+        ParamTypes:
+          - I32
+        ReturnTypes:
+          - I32
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 1, 2 ]
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+          - Type:            F32
+            Count:           2
+        Body:            43000000412100200043000040412201920B
+      - Index:           1
+        Locals:
+          - Type:            I32
+            Count:           2
+        Body:            410821002000410C22016A0B
+      - Index:           2
+        Locals:          []
+        Body:            4103210020000B
+...
diff --git a/mlir/test/Target/Wasm/local.mlir b/mlir/test/Target/Wasm/local.mlir
new file mode 100644
index 0000000000000..32f590021b959
--- /dev/null
+++ b/mlir/test/Target/Wasm/local.mlir
@@ -0,0 +1,59 @@
+// RUN: yaml2obj %S/inputs/local.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
+/* Source code used to create this test:
+(module
+  (func $local_f32 (result f32)
+    (local $var1 f32)
+    (local $var2 f32)
+    f32.const 8.0
+    local.set $var1
+    local.get $var1
+    f32.const 12.0
+    local.tee $var2
+    f32.add
+  )
+  (func $local_i32 (result i32)
+    (local $var1 i32)
+    (local $var2 i32)
+    i32.const 8
+    local.set $var1
+    local.get $var1
+    i32.const 12
+    local.tee $var2
+    i32.add
+  )
+  (func $local_arg (param $var i32) (result i32)
+    i32.const 3
+    local.set $var
+    local.get $var
+  )
+)
+*/
+
+// CHECK-LABEL:   wasmssa.func nested @func_0() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.local of type f32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.local of type f32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.const 8.000000e+00 : f32
+// CHECK:           wasmssa.local_set %[[VAL_0]] :  ref to f32 to %[[VAL_2]] : f32
+// CHECK:           %[[VAL_3:.*]] = wasmssa.local_get %[[VAL_0]] :  ref to f32
+// CHECK:           %[[VAL_4:.*]] = wasmssa.const 1.200000e+01 : f32
+// CHECK:           %[[VAL_5:.*]] = wasmssa.local_tee %[[VAL_1]] :  ref to f32 to %[[VAL_4]] : f32
+// CHECK:           %[[VAL_6:.*]] = wasmssa.add %[[VAL_3]] %[[VAL_5]] : f32
+// CHECK:           wasmssa.return %[[VAL_6]] : f32
+
+// CHECK-LABEL:   wasmssa.func nested @func_1() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.local of type i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.local of type i32
+// CHECK:           %[[VAL_2:.*]] = wasmssa.const 8 : i32
+// CHECK:           wasmssa.local_set %[[VAL_0]] :  ref to i32 to %[[VAL_2]] : i32
+// CHECK:           %[[VAL_3:.*]] = wasmssa.local_get %[[VAL_0]] :  ref to i32
+// CHECK:           %[[VAL_4:.*]] = wasmssa.const 12 : i32
+// CHECK:           %[[VAL_5:.*]] = wasmssa.local_tee %[[VAL_1]] :  ref to i32 to %[[VAL_4]] : i32
+// CHECK:           %[[VAL_6:.*]] = wasmssa.add %[[VAL_3]] %[[VAL_5]] : i32
+// CHECK:           wasmssa.return %[[VAL_6]] : i32
+
+// CHECK-LABEL:   wasmssa.func nested @func_2(
+// CHECK-SAME:      %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = wasmssa.const 3 : i32
+// CHECK:           wasmssa.local_set %[[ARG0]] :  ref to i32 to %[[VAL_0]] : i32
+// CHECK:           %[[VAL_1:.*]] = wasmssa.local_get %[[ARG0]] :  ref to i32
+// CHECK:           wasmssa.return %[[VAL_1]] : i32

>From 5421c853a758ccc35f565f9e70ad5b9e395594dc Mon Sep 17 00:00:00 2001
From: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Date: Thu, 31 Jul 2025 13:10:59 +0900
Subject: [PATCH 5/6] Formatting and other comments from the previous PR

---
 mlir/lib/Target/Wasm/TranslateFromWasm.cpp | 95 +++++++++++-----------
 1 file changed, 48 insertions(+), 47 deletions(-)

diff --git a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
index d481dbaec08eb..e2fddf34e5256 100644
--- a/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
+++ b/mlir/lib/Target/Wasm/TranslateFromWasm.cpp
@@ -16,15 +16,16 @@
 #include "mlir/IR/BuiltinAttributeInterfaces.h"
 #include "mlir/IR/BuiltinTypes.h"
 #include "mlir/IR/Location.h"
+#include "mlir/Support/LLVM.h"
 #include "mlir/Target/Wasm/WasmBinaryEncoding.h"
 #include "mlir/Target/Wasm/WasmImporter.h"
-#include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/DebugLog.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/LEB128.h"
+#include "llvm/Support/LogicalResult.h"
 
-#include <climits>
+#include <cstddef>
 #include <cstdint>
 #include <variant>
 
@@ -148,22 +149,22 @@ struct WasmModuleSymbolTables {
   }
 
   std::string getNewFuncSymbolName() const {
-    auto id = funcSymbols.size();
+    size_t id = funcSymbols.size();
     return getNewSymbolName("func_", id);
   }
 
   std::string getNewGlobalSymbolName() const {
-    auto id = globalSymbols.size();
+    size_t id = globalSymbols.size();
     return getNewSymbolName("global_", id);
   }
 
   std::string getNewMemorySymbolName() const {
-    auto id = memSymbols.size();
+    size_t id = memSymbols.size();
     return getNewSymbolName("mem_", id);
   }
 
   std::string getNewTableSymbolName() const {
-    auto id = tableSymbols.size();
+    size_t id = tableSymbols.size();
     return getNewSymbolName("table_", id);
   }
 };
@@ -342,7 +343,7 @@ class ParserHead {
   }
 
   FailureOr<std::byte> consumeByte() {
-    auto res = consumeNBytes(1);
+    FailureOr<StringRef> res = consumeNBytes(1);
     if (failed(res))
       return failure();
     return std::byte{*res->bytes_begin()};
@@ -502,7 +503,7 @@ class ParserHead {
     FileLineColLoc importLoc = getLocation();
     FailureOr<std::byte> importType = consumeByte();
     auto packager = [](auto parseResult) -> FailureOr<ImportDesc> {
-      if (llvm::failed(parseResult))
+      if (failed(parseResult))
         return failure();
       return {*parseResult};
     };
@@ -530,11 +531,11 @@ class ParserHead {
     return eParser.parse(builder);
   }
 
-  llvm::LogicalResult parseCodeFor(FuncOp func,
-                                   WasmModuleSymbolTables const &symbols) {
-    llvm::SmallVector<local_val_t> locals{};
+  LogicalResult parseCodeFor(FuncOp func,
+                             WasmModuleSymbolTables const &symbols) {
+    SmallVector<local_val_t> locals{};
     // Populating locals with function argument
-    auto &block = func.getBody().front();
+    Block &block = func.getBody().front();
     // Delete temporary return argument which was only created for IR validity
     assert(func.getBody().getBlocks().size() == 1 &&
            "Function should only have its default created block at this point");
@@ -543,29 +544,29 @@ class ParserHead {
     auto returnOp = cast<ReturnOp>(&block.back());
     assert(returnOp);
 
-    auto codeSizeInBytes = parseUI32();
+    FailureOr<uint32_t> codeSizeInBytes = parseUI32();
     if (failed(codeSizeInBytes))
       return failure();
-    auto codeContent = consumeNBytes(*codeSizeInBytes);
+    FailureOr<StringRef> codeContent = consumeNBytes(*codeSizeInBytes);
     if (failed(codeContent))
       return failure();
     auto name = StringAttr::get(func->getContext(),
                                 locName.str() + "::" + func.getSymName());
     auto cParser = ParserHead{*codeContent, name};
-    auto localVecSize = cParser.parseVectorSize();
+    FailureOr<uint32_t> localVecSize = cParser.parseVectorSize();
     if (failed(localVecSize))
       return failure();
     OpBuilder builder{&func.getBody().front().back()};
     for (auto arg : block.getArguments())
       locals.push_back(cast<TypedValue<LocalRefType>>(arg));
     // Declare the local ops
-    auto nVarVec = *localVecSize;
+    uint32_t nVarVec = *localVecSize;
     for (size_t i = 0; i < nVarVec; ++i) {
-      auto varLoc = cParser.getLocation();
-      auto nSubVar = cParser.parseUI32();
+      FileLineColLoc varLoc = cParser.getLocation();
+      FailureOr<uint32_t> nSubVar = cParser.parseUI32();
       if (failed(nSubVar))
         return failure();
-      auto varT = cParser.parseValueType(func->getContext());
+      FailureOr<Type> varT = cParser.parseValueType(func->getContext());
       if (failed(varT))
         return failure();
       for (size_t j = 0; j < *nSubVar; ++j) {
@@ -573,12 +574,12 @@ class ParserHead {
         locals.push_back(local.getResult());
       }
     }
-    auto res = cParser.parseExpression(builder, symbols, locals);
+    parsed_inst_t res = cParser.parseExpression(builder, symbols, locals);
     if (failed(res))
       return failure();
     if (!cParser.end())
       return emitError(cParser.getLocation(),
-                       "Unparsed garbage remaining at end of code block");
+                       "unparsed garbage remaining at end of code block");
     builder.create<ReturnOp>(func->getLoc(), *res);
     returnOp->erase();
     return success();
@@ -609,7 +610,7 @@ class ParserHead {
 
 template <>
 FailureOr<float> ParserHead::parseLiteral<float>() {
-  auto bytes = consumeNBytes(4);
+  FailureOr<StringRef> bytes = consumeNBytes(4);
   if (failed(bytes))
     return failure();
   float result;
@@ -619,7 +620,7 @@ FailureOr<float> ParserHead::parseLiteral<float>() {
 
 template <>
 FailureOr<double> ParserHead::parseLiteral<double>() {
-  auto bytes = consumeNBytes(8);
+  FailureOr<StringRef> bytes = consumeNBytes(8);
   if (failed(bytes))
     return failure();
   double result;
@@ -724,7 +725,7 @@ parsed_inst_t ValueStack::popOperands(TypeRange operandTypes, Location *opLoc) {
          << "  Current stack size: " << values.size();
   if (operandTypes.size() > values.size())
     return emitError(*opLoc,
-                     "stack doesn't contain enough values. Trying to get ")
+                     "stack doesn't contain enough values. trying to get ")
            << operandTypes.size() << " operands on a stack containing only "
            << values.size() << " values.";
   size_t stackIdxOffset = values.size() - operandTypes.size();
@@ -734,7 +735,7 @@ parsed_inst_t ValueStack::popOperands(TypeRange operandTypes, Location *opLoc) {
     Value operand = values[i + stackIdxOffset];
     Type stackType = operand.getType();
     if (stackType != operandTypes[i])
-      return emitError(*opLoc, "invalid operand type on stack. Expecting ")
+      return emitError(*opLoc, "invalid operand type on stack. expecting ")
              << operandTypes[i] << ", value on stack is of type " << stackType
              << ".";
     LDBG() << "    POP: " << operand;
@@ -795,12 +796,12 @@ ExpressionParser::parse(OpBuilder &builder,
 template <>
 inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
     WasmBinaryEncoding::OpCode::localGet>(OpBuilder &builder) {
-  auto id = parser.parseLiteral<uint32_t>();
-  auto instLoc = *currentOpLoc;
+  FailureOr<uint32_t> id = parser.parseLiteral<uint32_t>();
+  Location instLoc = *currentOpLoc;
   if (failed(id))
     return failure();
   if (*id >= locals.size())
-    return emitError(instLoc, "Invalid local index. Function has ")
+    return emitError(instLoc, "invalid local index. function has ")
            << locals.size() << " accessible locals, received index " << *id;
   return {{builder.create<LocalGetOp>(instLoc, locals[*id]).getResult()}};
 }
@@ -808,15 +809,15 @@ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
 template <>
 inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
     WasmBinaryEncoding::OpCode::globalGet>(OpBuilder &builder) {
-  auto id = parser.parseLiteral<uint32_t>();
-  auto instLoc = *currentOpLoc;
+  FailureOr<uint32_t> id = parser.parseLiteral<uint32_t>();
+  Location instLoc = *currentOpLoc;
   if (failed(id))
     return failure();
   if (*id >= symbols.globalSymbols.size())
-    return emitError(instLoc, "Invalid global index. Function has ")
+    return emitError(instLoc, "invalid global index. function has ")
            << symbols.globalSymbols.size()
            << " accessible globals, received index " << *id;
-  auto globalVar = symbols.globalSymbols[*id];
+  GlobalSymbolRefContainer globalVar = symbols.globalSymbols[*id];
   auto globalOp = builder.create<GlobalGetOp>(instLoc, globalVar.globalType,
                                               globalVar.symbol);
 
@@ -825,16 +826,16 @@ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
 
 template <typename OpToCreate>
 parsed_inst_t ExpressionParser::parseSetOrTee(OpBuilder &builder) {
-  auto id = parser.parseLiteral<uint32_t>();
+  FailureOr<uint32_t> id = parser.parseLiteral<uint32_t>();
   if (failed(id))
     return failure();
   if (*id >= locals.size())
-    return emitError(*currentOpLoc, "Invalid local index. Function has ")
+    return emitError(*currentOpLoc, "invalid local index. function has ")
            << locals.size() << " accessible locals, received index " << *id;
   if (valueStack.empty())
     return emitError(
         *currentOpLoc,
-        "Invalid stack access, trying to access a value on an empty stack.");
+        "invalid stack access, trying to access a value on an empty stack.");
 
   parsed_inst_t poppedOp = popOperands(locals[*id].getType().getElementType());
   if (failed(poppedOp))
@@ -953,7 +954,7 @@ inline parsed_inst_t ExpressionParser::buildNumericOp(
   auto ty = buildLiteralType<valueType>(builder);
   LLVM_DEBUG(llvm::dbgs() << "*** buildNumericOp: numOperands = " << numOperands
                           << ", type = " << ty << " ***\n");
-  auto tysToPop = llvm::SmallVector<Type, numOperands>();
+  auto tysToPop = SmallVector<Type, numOperands>();
   tysToPop.resize(numOperands);
   std::fill(tysToPop.begin(), tysToPop.end(), ty);
   auto operands = popOperands(tysToPop);
@@ -1133,7 +1134,7 @@ class WasmBinaryParser {
     if (failed(nElemsParsed))
       return failure();
     uint32_t nElems = *nElemsParsed;
-    LDBG() << "Starting to parse " << nElems << " items for section "
+    LDBG() << "starting to parse " << nElems << " items for section "
            << secName;
     for (size_t i = 0; i < nElems; ++i) {
       if (failed(parseSectionItem<section>(ph, i)))
@@ -1232,7 +1233,7 @@ class WasmBinaryParser {
       return;
     if (version->compare(expectedVersionString)) {
       emitError(versionLoc,
-                "unsupported Wasm version. Only version 1 is supported.");
+                "unsupported Wasm version. only version 1 is supported");
       return;
     }
     LogicalResult fillRegistry = registry.populateFromBody(parser.copy());
@@ -1263,11 +1264,11 @@ class WasmBinaryParser {
     if (failed(parsingMems))
       return;
 
-    auto parsingGlobals = parseSection<WasmSectionType::GLOBAL>();
+    LogicalResult parsingGlobals = parseSection<WasmSectionType::GLOBAL>();
     if (failed(parsingGlobals))
       return;
 
-    auto parsingCode = parseSection<WasmSectionType::CODE>();
+    LogicalResult parsingCode = parseSection<WasmSectionType::CODE>();
     if (failed(parsingCode))
       return;
 
@@ -1469,21 +1470,21 @@ template <>
 LogicalResult
 WasmBinaryParser::parseSectionItem<WasmSectionType::GLOBAL>(ParserHead &ph,
                                                             size_t) {
-  auto globalLocation = ph.getLocation();
+  FileLineColLoc globalLocation = ph.getLocation();
   auto globalTypeParsed = ph.parseGlobalType(ctx);
   if (failed(globalTypeParsed))
     return failure();
 
-  auto globalType = *globalTypeParsed;
+  GlobalTypeRecord globalType = *globalTypeParsed;
   auto symbol = builder.getStringAttr(symbols.getNewGlobalSymbolName());
   auto globalOp = builder.create<wasmssa::GlobalOp>(
       globalLocation, symbol, globalType.type, globalType.isMutable);
   symbols.globalSymbols.push_back(
       {{FlatSymbolRefAttr::get(globalOp)}, globalOp.getType()});
   auto ip = builder.saveInsertionPoint();
-  auto *block = builder.createBlock(&globalOp.getInitializer());
+  Block *block = builder.createBlock(&globalOp.getInitializer());
   builder.setInsertionPointToStart(block);
-  auto expr = ph.parseExpression(builder, symbols);
+  parsed_inst_t expr = ph.parseExpression(builder, symbols);
   if (failed(expr))
     return failure();
   if (block->empty())
@@ -1500,10 +1501,10 @@ WasmBinaryParser::parseSectionItem<WasmSectionType::GLOBAL>(ParserHead &ph,
 template <>
 LogicalResult WasmBinaryParser::parseSectionItem<WasmSectionType::CODE>(
     ParserHead &ph, size_t innerFunctionId) {
-  auto funcId = innerFunctionId + firstInternalFuncID;
-  auto symRef = symbols.funcSymbols[funcId];
+  unsigned long funcId = innerFunctionId + firstInternalFuncID;
+  FunctionSymbolRefContainer symRef = symbols.funcSymbols[funcId];
   auto funcOp =
-      llvm::dyn_cast<FuncOp>(SymbolTable::lookupSymbolIn(mOp, symRef.symbol));
+      dyn_cast<FuncOp>(SymbolTable::lookupSymbolIn(mOp, symRef.symbol));
   assert(funcOp);
   if (failed(ph.parseCodeFor(funcOp, symbols)))
     return failure();

>From 5a262ebedab000e2b5b1aa2ea743ef853e6674fb Mon Sep 17 00:00:00 2001
From: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Date: Mon, 18 Aug 2025 13:10:23 +0900
Subject: [PATCH 6/6] Format

---
 mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h b/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
index c36d0237ff528..21adde878994e 100644
--- a/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
+++ b/mlir/include/mlir/Target/Wasm/WasmBinaryEncoding.h
@@ -93,7 +93,6 @@ struct WasmBinaryEncoding {
     static constexpr std::byte maxF64{0xA5};
     static constexpr std::byte copysignF64{0xA6};
     static constexpr std::byte wrap{0xA7};
-
   };
 
   /// Byte encodings of types in Wasm binaries



More information about the Mlir-commits mailing list