[Mlir-commits] [mlir] a389989 - [MLIR][WASM] Introduce the RaiseWasmMLIRPass to convert WasmSSA MLIR to core dialects (#164562)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sat Jun 20 00:03:34 PDT 2026


Author: Ferdinand Lemaire
Date: 2026-06-20T16:03:28+09:00
New Revision: a38998941b2f57ffce38d6161a48d59d7d481964

URL: https://github.com/llvm/llvm-project/commit/a38998941b2f57ffce38d6161a48d59d7d481964
DIFF: https://github.com/llvm/llvm-project/commit/a38998941b2f57ffce38d6161a48d59d7d481964.diff

LOG: [MLIR][WASM] Introduce the RaiseWasmMLIRPass to convert WasmSSA MLIR to core dialects (#164562)

This is following https://github.com/llvm/llvm-project/pull/154674 and
still related to
https://discourse.llvm.org/t/rfc-mlir-dialect-for-webassembly/86758.

This PR introduces the RaiseWasmMLIRPass. This pass lowers WasmSSA MLIR
to other dialects of the LLVM ecosystem (namely: arith, math, cf and
memref).
This is the first PR of a series of 2 or 3 to introduce the lowering, as
an introduction it brings support for function calls, local and global
variables and handling of arithmetic operations. As explained in the
RFC, most WasmSSA operations have been made to stay close to other
dialects' semantics so that conversion is trivialized.

---------

Signed-off-by: Ferdinand Lemaire <flemairen6 at gmail.com>
Co-authored-by: Ferdinand Lemaire <ferdinand.lemaire at woven-planet.global>
Co-authored-by: Ferdinand Lemaire <flemairen6 at gmail.com>

Added: 
    mlir/include/mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h
    mlir/lib/Conversion/RaiseWasm/CMakeLists.txt
    mlir/lib/Conversion/RaiseWasm/RaiseWasmMLIR.cpp
    mlir/test/Conversion/RaiseWasm/wasm-abs-to-math-abs.mlir
    mlir/test/Conversion/RaiseWasm/wasm-add-to-arith-add.mlir
    mlir/test/Conversion/RaiseWasm/wasm-and-to-arith-and.mlir
    mlir/test/Conversion/RaiseWasm/wasm-ceil-to-math-ceil.mlir
    mlir/test/Conversion/RaiseWasm/wasm-clz-to-math-clz.mlir
    mlir/test/Conversion/RaiseWasm/wasm-const-to-arith-const.mlir
    mlir/test/Conversion/RaiseWasm/wasm-convert-to-arith-tofp.mlir
    mlir/test/Conversion/RaiseWasm/wasm-copysign-to-math-copysign.mlir
    mlir/test/Conversion/RaiseWasm/wasm-ctz-to-math-ctz.mlir
    mlir/test/Conversion/RaiseWasm/wasm-demote-to-arith-trunc.mlir
    mlir/test/Conversion/RaiseWasm/wasm-div-to-arith-div.mlir
    mlir/test/Conversion/RaiseWasm/wasm-floor-to-math-floor.mlir
    mlir/test/Conversion/RaiseWasm/wasm-func-to-func.mlir
    mlir/test/Conversion/RaiseWasm/wasm-global-to-memref-global.mlir
    mlir/test/Conversion/RaiseWasm/wasm-local-to-memref.mlir
    mlir/test/Conversion/RaiseWasm/wasm-max-to-arith-maximumf.mlir
    mlir/test/Conversion/RaiseWasm/wasm-min-to-arith-minimumf.mlir
    mlir/test/Conversion/RaiseWasm/wasm-mul-to-arith-mul.mlir
    mlir/test/Conversion/RaiseWasm/wasm-neg-to-arith-neg.mlir
    mlir/test/Conversion/RaiseWasm/wasm-or-to-arith-or.mlir
    mlir/test/Conversion/RaiseWasm/wasm-popcnt-to-math-ctpop.mlir
    mlir/test/Conversion/RaiseWasm/wasm-promote-to-arith-ext.mlir
    mlir/test/Conversion/RaiseWasm/wasm-reinterpret-to-arith-bitcast.mlir
    mlir/test/Conversion/RaiseWasm/wasm-rem-to-arith-rem.mlir
    mlir/test/Conversion/RaiseWasm/wasm-shl-to-arith-shl.mlir
    mlir/test/Conversion/RaiseWasm/wasm-shr_s-to-arith-shrs.mlir
    mlir/test/Conversion/RaiseWasm/wasm-shr_u-to-arith-shru.mlir
    mlir/test/Conversion/RaiseWasm/wasm-sqrt-to-math-sqrt.mlir
    mlir/test/Conversion/RaiseWasm/wasm-sub-to-arith-sub.mlir
    mlir/test/Conversion/RaiseWasm/wasm-trunc-to-math-trunc.mlir
    mlir/test/Conversion/RaiseWasm/wasm-wrap-to-arith-trunc.mlir
    mlir/test/Conversion/RaiseWasm/wasm-xor-to-arith-xor.mlir

Modified: 
    mlir/include/mlir/Conversion/Passes.h
    mlir/include/mlir/Conversion/Passes.td
    mlir/include/mlir/Dialect/WasmSSA/IR/WasmSSAOps.td
    mlir/lib/Conversion/CMakeLists.txt
    mlir/lib/Dialect/WasmSSA/IR/WasmSSAOps.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Conversion/Passes.h b/mlir/include/mlir/Conversion/Passes.h
index 82c7670296e52..0ea248df3fee4 100644
--- a/mlir/include/mlir/Conversion/Passes.h
+++ b/mlir/include/mlir/Conversion/Passes.h
@@ -61,6 +61,7 @@
 #include "mlir/Conversion/OpenACCToSCF/ConvertOpenACCToSCF.h"
 #include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
 #include "mlir/Conversion/PDLToPDLInterp/PDLToPDLInterp.h"
+#include "mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h"
 #include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
 #include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
 #include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"

diff  --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index ae93769a66762..8ff794671796c 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -1720,6 +1720,19 @@ def ConvertVectorToAMX : Pass<"convert-vector-to-amx"> {
   ];
 }
 
+//===----------------------------------------------------------------------===//
+// RaiseWasmMLIR
+//===----------------------------------------------------------------------===//
+
+def RaiseWasmMLIR : Pass<"raise-wasm-mlir"> {
+  let summary = "Convert Wasm dialect to a group of dialect as a bridge to LLVM MLIR conversion";
+  let dependentDialects = [
+    "func::FuncDialect", "arith::ArithDialect", "cf::ControlFlowDialect",
+    "memref::MemRefDialect", "vector::VectorDialect", "wasmssa::WasmSSADialect",
+    "math::MathDialect"
+  ];
+}
+
 //===----------------------------------------------------------------------===//
 // XeVMToLLVM
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/include/mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h b/mlir/include/mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h
new file mode 100644
index 0000000000000..048eeb3149cf7
--- /dev/null
+++ b/mlir/include/mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h
@@ -0,0 +1,29 @@
+//===- RaiseWasmMLIR.h - Convert wasm to standard dialects ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_RAISEWASM_RAISEWASMMLIR_H
+#define MLIR_CONVERSION_RAISEWASM_RAISEWASMMLIR_H
+
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+namespace mlir {
+class Pass;
+class RewritePatternSet;
+
+#define GEN_PASS_DECL_RAISEWASMMLIR
+#include "mlir/Conversion/Passes.h.inc"
+
+/// Collect a set of patterns to convert from the Wasm dialect to standard
+/// dialects.
+void populateRaiseWasmMLIRConversionPatterns(TypeConverter &,
+                                             RewritePatternSet &);
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_RAISEWASM_RAISEWASMMLIR_H

diff  --git a/mlir/include/mlir/Dialect/WasmSSA/IR/WasmSSAOps.td b/mlir/include/mlir/Dialect/WasmSSA/IR/WasmSSAOps.td
index a18731f4fd285..bfa0953f50ac8 100644
--- a/mlir/include/mlir/Dialect/WasmSSA/IR/WasmSSAOps.td
+++ b/mlir/include/mlir/Dialect/WasmSSA/IR/WasmSSAOps.td
@@ -318,7 +318,7 @@ def WasmSSA_GlobalOp : WasmSSA_Op<"global", [
     }
     ```
   }];
-  let regions = (region AnyRegion: $initializer);
+  let regions = (region SizedRegion<1>: $initializer);
 
   let extraClassDeclaration = [{
     ::mlir::SymbolTable::Visibility getVisibility() {
@@ -326,8 +326,11 @@ def WasmSSA_GlobalOp : WasmSSA_Op<"global", [
         ::mlir::SymbolTable::Visibility::Public :
         ::mlir::SymbolTable::Visibility::Nested;
     };
+
+    wasmssa::ReturnOp getInitTerminator();
   }];
   let hasCustomAssemblyFormat = 1;
+  let hasVerifier = 1;
 }
 
 def WasmSSA_GlobalImportOp : WasmSSA_Op<"import_global", [

diff  --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt
index b43ed905505fa..4fa5b9d582a4e 100644
--- a/mlir/lib/Conversion/CMakeLists.txt
+++ b/mlir/lib/Conversion/CMakeLists.txt
@@ -55,6 +55,7 @@ add_subdirectory(OpenACCToSCF)
 add_subdirectory(OpenMPToLLVM)
 add_subdirectory(PDLToPDLInterp)
 add_subdirectory(PtrToLLVM)
+add_subdirectory(RaiseWasm)
 add_subdirectory(ReconcileUnrealizedCasts)
 add_subdirectory(SCFToControlFlow)
 add_subdirectory(SCFToEmitC)

diff  --git a/mlir/lib/Conversion/RaiseWasm/CMakeLists.txt b/mlir/lib/Conversion/RaiseWasm/CMakeLists.txt
new file mode 100644
index 0000000000000..43b5fd79e49df
--- /dev/null
+++ b/mlir/lib/Conversion/RaiseWasm/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_mlir_conversion_library(MLIRWasmRaise
+  RaiseWasmMLIR.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/RaiseWasm
+
+  DEPENDS
+  MLIRConversionPassIncGen
+
+  LINK_LIBS PUBLIC
+  MLIRArithDialect
+  MLIRControlFlowDialect
+  MLIRFuncDialect
+  MLIRMathDialect
+  MLIRMemRefDialect
+  MLIRTransforms
+  MLIRVectorDialect
+  MLIRWasmSSADialect
+  )

diff  --git a/mlir/lib/Conversion/RaiseWasm/RaiseWasmMLIR.cpp b/mlir/lib/Conversion/RaiseWasm/RaiseWasmMLIR.cpp
new file mode 100644
index 0000000000000..83bfde7032ef8
--- /dev/null
+++ b/mlir/lib/Conversion/RaiseWasm/RaiseWasmMLIR.cpp
@@ -0,0 +1,469 @@
+//===- RaiseWasmMLIR.cpp - Convert Wasm to less abstract dialects ---*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements lowering of wasm operations to standard dialects ops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h"
+
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/Math/IR/Math.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/Vector/IR/VectorOps.h"
+#include "mlir/Dialect/WasmSSA/IR/WasmSSA.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/BuiltinDialect.h"
+#include "mlir/IR/ValueRange.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "mlir/Transforms/Passes.h"
+#include "llvm/Support/LogicalResult.h"
+#include <optional>
+
+#define DEBUG_TYPE "wasm-convert"
+
+namespace mlir {
+#define GEN_PASS_DEF_RAISEWASMMLIR
+#include "mlir/Conversion/Passes.h.inc"
+} // namespace mlir
+
+using namespace mlir;
+using namespace mlir::wasmssa;
+namespace {
+
+template <typename SourceOp, typename TargetIntOp, typename TargetFPOp>
+struct IntFPDispatchMappingConversion : OpConversionPattern<SourceOp> {
+  using OpConversionPattern<SourceOp>::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(SourceOp srcOp, typename SourceOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    Type type = srcOp.getRhs().getType();
+    if (type.isInteger()) {
+      rewriter.replaceOpWithNewOp<TargetIntOp>(srcOp, srcOp->getResultTypes(),
+                                               adaptor.getOperands());
+      return success();
+    }
+    if (!type.isFloat())
+      return failure();
+    rewriter.replaceOpWithNewOp<TargetFPOp>(srcOp, srcOp->getResultTypes(),
+                                            adaptor.getOperands());
+    return success();
+  }
+};
+
+using WasmAddOpConversion =
+    IntFPDispatchMappingConversion<AddOp, arith::AddIOp, arith::AddFOp>;
+using WasmMulOpConversion =
+    IntFPDispatchMappingConversion<MulOp, arith::MulIOp, arith::MulFOp>;
+using WasmSubOpConversion =
+    IntFPDispatchMappingConversion<SubOp, arith::SubIOp, arith::SubFOp>;
+
+/// Convert a k-ary source operation \p SourceOp into an operation \p TargetOp.
+/// Both \p SourceOp and \p TargetOp must have the same number of operands.
+template <typename SourceOp, typename TargetOp>
+struct OpMappingConversion : OpConversionPattern<SourceOp> {
+  using OpConversionPattern<SourceOp>::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(SourceOp srcOp, typename SourceOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<TargetOp>(srcOp, srcOp->getResultTypes(),
+                                          adaptor.getOperands());
+    return success();
+  }
+};
+
+using WasmAndOpConversion = OpMappingConversion<AndOp, arith::AndIOp>;
+using WasmCeilOpConversion = OpMappingConversion<CeilOp, math::CeilOp>;
+/// TODO: SIToFP and UIToFP don't allow specification of the floating point
+/// rounding mode
+using WasmConvertSOpConversion =
+    OpMappingConversion<ConvertSOp, arith::SIToFPOp>;
+using WasmConvertUOpConversion =
+    OpMappingConversion<ConvertUOp, arith::UIToFPOp>;
+using WasmDemoteOpConversion = OpMappingConversion<DemoteOp, arith::TruncFOp>;
+using WasmDivFPOpConversion = OpMappingConversion<DivOp, arith::DivFOp>;
+using WasmDivSIOpConversion = OpMappingConversion<DivSIOp, arith::DivSIOp>;
+using WasmDivUIOpConversion = OpMappingConversion<DivUIOp, arith::DivUIOp>;
+using WasmExtendSOpConversion =
+    OpMappingConversion<ExtendSI32Op, arith::ExtSIOp>;
+using WasmExtendUOpConversion =
+    OpMappingConversion<ExtendUI32Op, arith::ExtUIOp>;
+using WasmFloorOpConversion = OpMappingConversion<FloorOp, math::FloorOp>;
+using WasmMaxOpConversion = OpMappingConversion<MaxOp, arith::MaximumFOp>;
+using WasmMinOpConversion = OpMappingConversion<MinOp, arith::MinimumFOp>;
+using WasmOrOpConversion = OpMappingConversion<OrOp, arith::OrIOp>;
+using WasmPromoteOpConversion = OpMappingConversion<PromoteOp, arith::ExtFOp>;
+using WasmRemSIOpConversion = OpMappingConversion<RemSIOp, arith::RemSIOp>;
+using WasmRemUIOpConversion = OpMappingConversion<RemUIOp, arith::RemUIOp>;
+using WasmReinterpretOpConversion =
+    OpMappingConversion<ReinterpretOp, arith::BitcastOp>;
+using WasmShLOpConversion = OpMappingConversion<ShLOp, arith::ShLIOp>;
+using WasmShRSOpConversion = OpMappingConversion<ShRSOp, arith::ShRSIOp>;
+using WasmShRUOpConversion = OpMappingConversion<ShRUOp, arith::ShRUIOp>;
+using WasmXOrOpConversion = OpMappingConversion<XOrOp, arith::XOrIOp>;
+using WasmNegOpConversion = OpMappingConversion<NegOp, arith::NegFOp>;
+using WasmCopySignOpConversion =
+    OpMappingConversion<CopySignOp, math::CopySignOp>;
+using WasmClzOpConversion =
+    OpMappingConversion<ClzOp, math::CountLeadingZerosOp>;
+using WasmCtzOpConversion =
+    OpMappingConversion<CtzOp, math::CountTrailingZerosOp>;
+using WasmPopCntOpConversion = OpMappingConversion<PopCntOp, math::CtPopOp>;
+using WasmAbsOpConversion = OpMappingConversion<AbsOp, math::AbsFOp>;
+using WasmTruncOpConversion = OpMappingConversion<TruncOp, math::TruncOp>;
+using WasmSqrtOpConversion = OpMappingConversion<SqrtOp, math::SqrtOp>;
+using WasmWrapOpConversion = OpMappingConversion<WrapOp, arith::TruncIOp>;
+
+struct WasmCallOpConversion : OpConversionPattern<FuncCallOp> {
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(FuncCallOp funcCallOp, FuncCallOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<func::CallOp>(
+        funcCallOp, funcCallOp.getCallee(), funcCallOp.getResults().getTypes(),
+        funcCallOp.getOperands());
+    return success();
+  }
+};
+
+struct WasmConstOpConversion : OpConversionPattern<ConstOp> {
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(ConstOp constOp, ConstOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<arith::ConstantOp>(constOp, constOp.getValue());
+    return success();
+  }
+};
+
+struct WasmFuncImportOpConversion : OpConversionPattern<FuncImportOp> {
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(FuncImportOp funcImportOp, FuncImportOp::Adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    auto nFunc = rewriter.replaceOpWithNewOp<func::FuncOp>(
+        funcImportOp, funcImportOp.getSymName(), funcImportOp.getType());
+    nFunc.setVisibility(SymbolTable::Visibility::Private);
+    return success();
+  }
+};
+
+struct WasmFuncOpConversion : OpConversionPattern<FuncOp> {
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(FuncOp funcOp, FuncOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    auto newFunc =
+        func::FuncOp::create(rewriter, funcOp->getLoc(), funcOp.getSymName(),
+                             funcOp.getFunctionType());
+    rewriter.cloneRegionBefore(funcOp.getBody(), newFunc.getBody(),
+                               newFunc.getBody().end());
+    Block *oldEntryBlock = &newFunc.getBody().front();
+    auto blockArgTypes = oldEntryBlock->getArgumentTypes();
+    TypeConverter::SignatureConversion sC{oldEntryBlock->getNumArguments()};
+    auto numArgs = blockArgTypes.size();
+    for (size_t i = 0; i < numArgs; ++i) {
+      auto argType = dyn_cast<LocalRefType>(blockArgTypes[i]);
+      if (!argType)
+        return failure();
+      sC.addInputs(i, argType.getElementType());
+    }
+
+    rewriter.applySignatureConversion(oldEntryBlock, sC, getTypeConverter());
+    rewriter.replaceOp(funcOp, newFunc);
+    return success();
+  }
+};
+
+struct WasmGlobalImportOpConverter : OpConversionPattern<GlobalImportOp> {
+  using OpConversionPattern::OpConversionPattern;
+  LogicalResult
+  matchAndRewrite(GlobalImportOp gIOp, GlobalImportOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    auto memrefGOp = rewriter.replaceOpWithNewOp<memref::GlobalOp>(
+        gIOp, gIOp.getSymNameAttr(), rewriter.getStringAttr("nested"),
+        TypeAttr::get(MemRefType::get({1}, gIOp.getType())), Attribute{},
+        /*constant*/ UnitAttr{},
+        /*alignment*/ IntegerAttr{});
+    memrefGOp.setConstant(!gIOp.getIsMutable());
+    return success();
+  }
+};
+
+template <typename CRTP, typename OriginOpType>
+struct GlobalOpConverter : OpConversionPattern<GlobalOp> {
+  using OpConversionPattern::OpConversionPattern;
+  LogicalResult
+  matchAndRewrite(GlobalOp globalOp, GlobalOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    ReturnOp rop = globalOp.getInitTerminator();
+
+    if (rop->getNumOperands() != 1)
+      return rewriter.notifyMatchFailure(
+          globalOp, "globalOp initializer should return one value exactly");
+
+    auto initializerOp =
+        dyn_cast<OriginOpType>(rop->getOperand(0).getDefiningOp());
+
+    if (!initializerOp)
+      return rewriter.notifyMatchFailure(
+          globalOp, "invalid initializer op type for this pattern");
+
+    return static_cast<CRTP const *>(this)->handleInitializer(
+        globalOp, rewriter, initializerOp);
+  }
+};
+
+struct WasmGlobalWithConstInitConversion
+    : GlobalOpConverter<WasmGlobalWithConstInitConversion, ConstOp> {
+  using GlobalOpConverter::GlobalOpConverter;
+  LogicalResult handleInitializer(GlobalOp globalOp,
+                                  ConversionPatternRewriter &rewriter,
+                                  ConstOp constInit) const {
+    auto initializer =
+        DenseElementsAttr::get(RankedTensorType::get({1}, globalOp.getType()),
+                               ArrayRef<Attribute>{constInit.getValueAttr()});
+    auto globalReplacement = rewriter.replaceOpWithNewOp<memref::GlobalOp>(
+        globalOp, globalOp.getSymNameAttr(), rewriter.getStringAttr("private"),
+        TypeAttr::get(MemRefType::get({1}, globalOp.getType())), initializer,
+        /*constant*/ UnitAttr{},
+        /*alignment*/ IntegerAttr{});
+    globalReplacement.setConstant(!globalOp.getIsMutable());
+    return success();
+  }
+};
+
+struct WasmGlobalWithGetGlobalInitConversion
+    : GlobalOpConverter<WasmGlobalWithGetGlobalInitConversion, GlobalGetOp> {
+  using GlobalOpConverter::GlobalOpConverter;
+  LogicalResult handleInitializer(GlobalOp globalOp,
+                                  ConversionPatternRewriter &rewriter,
+                                  GlobalGetOp constInit) const {
+    auto globalReplacement = rewriter.replaceOpWithNewOp<memref::GlobalOp>(
+        globalOp, globalOp.getSymNameAttr(), rewriter.getStringAttr("private"),
+        TypeAttr::get(MemRefType::get({1}, globalOp.getType())),
+        rewriter.getUnitAttr(),
+        /*constant*/ UnitAttr{},
+        /*alignment*/ IntegerAttr{});
+    globalReplacement.setConstant(!globalOp.getIsMutable());
+    auto loc = globalOp.getLoc();
+    auto initializerName = (globalOp.getSymName() + "::initializer").str();
+    auto globalInitializer =
+        func::FuncOp::create(rewriter, loc, initializerName,
+                             FunctionType::get(getContext(), {}, {}));
+    globalInitializer->setAttr(rewriter.getStringAttr("initializer"),
+                               rewriter.getUnitAttr());
+    auto *initializerBody = globalInitializer.addEntryBlock();
+    auto sip = rewriter.saveInsertionPoint();
+    rewriter.setInsertionPointToStart(initializerBody);
+    auto srcGlobalPtr = memref::GetGlobalOp::create(
+        rewriter, loc, MemRefType::get({1}, constInit.getType()),
+        constInit.getGlobal());
+    auto destGlobalPtr =
+        memref::GetGlobalOp::create(rewriter, loc, globalReplacement.getType(),
+                                    globalReplacement.getSymName());
+    auto idx = arith::ConstantIndexOp::create(rewriter, loc, 0).getResult();
+    auto loadSrc =
+        memref::LoadOp::create(rewriter, loc, srcGlobalPtr, ValueRange{idx});
+    memref::StoreOp::create(rewriter, loc, loadSrc.getResult(),
+                            destGlobalPtr.getResult(), ValueRange{idx});
+    func::ReturnOp::create(rewriter, loc);
+    rewriter.restoreInsertionPoint(sip);
+    return success();
+  }
+};
+
+inline TypedAttr getInitializerAttr(Type t) {
+  assert(t.isIntOrFloat() &&
+         "This helper is intended to use with int and float types");
+  if (t.isInteger())
+    return IntegerAttr::get(t, 0);
+  if (t.isFloat())
+    return FloatAttr::get(t, 0.);
+  return TypedAttr{};
+}
+
+struct WasmLocalConversion : OpConversionPattern<LocalOp> {
+  using OpConversionPattern::OpConversionPattern;
+  LogicalResult
+  matchAndRewrite(LocalOp localOp, LocalOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    auto alloca = rewriter.replaceOpWithNewOp<memref::AllocaOp>(
+        localOp,
+        MemRefType::get({}, localOp.getResult().getType().getElementType()));
+    auto initializer = arith::ConstantOp::create(
+        rewriter, localOp->getLoc(),
+        getInitializerAttr(localOp.getResult().getType().getElementType()));
+    memref::StoreOp::create(rewriter, localOp->getLoc(),
+                            initializer.getResult(), alloca.getResult());
+    return success();
+  }
+};
+
+struct WasmLocalGetConversion : OpConversionPattern<LocalGetOp> {
+  using OpConversionPattern::OpConversionPattern;
+  LogicalResult
+  matchAndRewrite(LocalGetOp localGetOp, LocalGetOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<memref::LoadOp>(
+        localGetOp, localGetOp.getResult().getType(), adaptor.getLocalVar(),
+        ValueRange{});
+    return success();
+  }
+};
+
+struct WasmLocalSetConversion : OpConversionPattern<LocalSetOp> {
+  using OpConversionPattern::OpConversionPattern;
+  LogicalResult
+  matchAndRewrite(LocalSetOp localSetOp, LocalSetOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<memref::StoreOp>(
+        localSetOp, adaptor.getValue(), adaptor.getLocalVar(), ValueRange{});
+    return success();
+  }
+};
+
+struct WasmLocalTeeConversion : OpConversionPattern<LocalTeeOp> {
+  using OpConversionPattern::OpConversionPattern;
+  LogicalResult
+  matchAndRewrite(LocalTeeOp localTeeOp, LocalTeeOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    memref::StoreOp::create(rewriter, localTeeOp->getLoc(), adaptor.getValue(),
+                            adaptor.getLocalVar());
+    rewriter.replaceOp(localTeeOp, adaptor.getValue());
+    return success();
+  }
+};
+
+struct WasmReturnOpConversion : OpConversionPattern<ReturnOp> {
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(ReturnOp returnOp, ReturnOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<func::ReturnOp>(returnOp,
+                                                adaptor.getOperands());
+    return success();
+  }
+};
+
+struct RaiseWasmMLIRPass : public impl::RaiseWasmMLIRBase<RaiseWasmMLIRPass> {
+  void runOnOperation() override {
+    ConversionTarget target{getContext()};
+    target.addIllegalDialect<WasmSSADialect>();
+    target.addLegalDialect<arith::ArithDialect, BuiltinDialect,
+                           cf::ControlFlowDialect, func::FuncDialect,
+                           memref::MemRefDialect, math::MathDialect>();
+    RewritePatternSet patterns(&getContext());
+    TypeConverter tc{};
+    tc.addConversion([](Type type) -> std::optional<Type> { return type; });
+    tc.addConversion([](LocalRefType type) -> std::optional<Type> {
+      return MemRefType::get({}, type.getElementType());
+    });
+    tc.addTargetMaterialization([](OpBuilder &builder, MemRefType destType,
+                                   ValueRange values, Location loc) -> Value {
+      if (values.size() != 1 ||
+          values.front().getType() != destType.getElementType())
+        return {};
+      auto localVar = memref::AllocaOp::create(builder, loc, destType);
+      memref::StoreOp::create(builder, loc, values.front(),
+                              localVar.getResult());
+      return localVar.getResult();
+    });
+    populateRaiseWasmMLIRConversionPatterns(tc, patterns);
+
+    llvm::DenseMap<StringAttr, StringAttr> idxSymToImportSym{};
+    auto *topOp = getOperation();
+    topOp->walk([&idxSymToImportSym, this](ImportOpInterface importOp) {
+      auto const qualifiedImportName = importOp.getQualifiedImportName();
+      auto qualNameAttr = StringAttr::get(&getContext(), qualifiedImportName);
+      idxSymToImportSym.insert(
+          std::make_pair(importOp.getSymbolName(), qualNameAttr));
+    });
+
+    if (failed(applyFullConversion(topOp, target, std::move(patterns))))
+      return signalPassFailure();
+
+    auto symTable = SymbolTable{topOp};
+    for (auto &[oldName, newName] : idxSymToImportSym) {
+      if (failed(symTable.rename(oldName, newName)))
+        return signalPassFailure();
+    }
+  }
+};
+} // namespace
+
+void mlir::populateRaiseWasmMLIRConversionPatterns(
+    TypeConverter &tc, RewritePatternSet &patternSet) {
+  auto *ctx = patternSet.getContext();
+  // Disable clang-format in patternSet for readability + small 
diff s.
+  // clang-format off
+  patternSet
+      .add<
+           WasmAbsOpConversion,
+           WasmAddOpConversion,
+           WasmAndOpConversion,
+           WasmCallOpConversion,
+           WasmCeilOpConversion,
+           WasmClzOpConversion,
+           WasmConstOpConversion,
+           WasmConvertSOpConversion,
+           WasmConvertUOpConversion,
+           WasmCopySignOpConversion,
+           WasmCtzOpConversion,
+           WasmDemoteOpConversion,
+           WasmDivFPOpConversion,
+           WasmDivSIOpConversion,
+           WasmDivUIOpConversion,
+           WasmExtendSOpConversion,
+           WasmExtendUOpConversion,
+           WasmFloorOpConversion,
+           WasmFuncImportOpConversion,
+           WasmFuncOpConversion,
+           WasmGlobalImportOpConverter,
+           WasmGlobalWithConstInitConversion,
+           WasmGlobalWithGetGlobalInitConversion,
+           WasmLocalConversion,
+           WasmLocalGetConversion,
+           WasmLocalSetConversion,
+           WasmLocalTeeConversion,
+           WasmMaxOpConversion,
+           WasmMinOpConversion,
+           WasmMulOpConversion,
+           WasmNegOpConversion,
+           WasmOrOpConversion,
+           WasmPopCntOpConversion,
+           WasmPromoteOpConversion,
+           WasmReinterpretOpConversion,
+           WasmRemSIOpConversion,
+           WasmRemUIOpConversion,
+           WasmReturnOpConversion,
+           WasmShLOpConversion,
+           WasmShRSOpConversion,
+           WasmShRUOpConversion,
+           WasmSqrtOpConversion,
+           WasmSubOpConversion,
+           WasmTruncOpConversion,
+           WasmWrapOpConversion,
+           WasmXOrOpConversion
+           >(tc, ctx);
+  // clang-format on
+}
+
+std::unique_ptr<Pass> createRaiseWasmMLIRPass() {
+  return std::make_unique<RaiseWasmMLIRPass>();
+}

diff  --git a/mlir/lib/Dialect/WasmSSA/IR/WasmSSAOps.cpp b/mlir/lib/Dialect/WasmSSA/IR/WasmSSAOps.cpp
index f3eb601bed5c3..08de887a56a97 100644
--- a/mlir/lib/Dialect/WasmSSA/IR/WasmSSAOps.cpp
+++ b/mlir/lib/Dialect/WasmSSA/IR/WasmSSAOps.cpp
@@ -246,6 +246,16 @@ void FuncImportOp::build(OpBuilder &odsBuilder, OperationState &odsState,
 //===----------------------------------------------------------------------===//
 // GlobalOp
 //===----------------------------------------------------------------------===//
+namespace {
+Operation *getGlobalOpTerminatorOp(GlobalOp gop) {
+  return gop.getInitializer().begin()->getTerminator();
+}
+} // namespace
+
+ReturnOp GlobalOp::getInitTerminator() {
+  return llvm::cast<wasmssa::ReturnOp>(getGlobalOpTerminatorOp(*this));
+}
+
 // Custom formats
 ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
   StringAttr symbolName;
@@ -292,6 +302,10 @@ void GlobalOp::print(OpAsmPrinter &printer) {
   }
 }
 
+LogicalResult GlobalOp::verify() {
+  return success(llvm::isa<ReturnOp>(getGlobalOpTerminatorOp(*this)));
+}
+
 //===----------------------------------------------------------------------===//
 // GlobalGetOp
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-abs-to-math-abs.mlir b/mlir/test/Conversion/RaiseWasm/wasm-abs-to-math-abs.mlir
new file mode 100644
index 0000000000000..eee03772589b9
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-abs-to-math-abs.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @abs_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = math.absf %[[VAL_1]] : f32
+// CHECK:           return %[[VAL_2]] : f32
+wasmssa.func @abs_f32(%arg0: !wasmssa<local ref to f32>) -> f32 {
+    %val = wasmssa.local_get %arg0 : ref to f32
+    %op = wasmssa.abs %val : f32
+    wasmssa.return %op : f32
+}
+
+// CHECK-LABEL:   func.func @abs_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = math.absf %[[VAL_1]] : f64
+// CHECK:           return %[[VAL_2]] : f64
+wasmssa.func @abs_f64(%arg0: !wasmssa<local ref to f64>) -> f64 {
+    %val = wasmssa.local_get %arg0 : ref to f64
+    %op = wasmssa.abs %val : f64
+    wasmssa.return %op : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-add-to-arith-add.mlir b/mlir/test/Conversion/RaiseWasm/wasm-add-to-arith-add.mlir
new file mode 100644
index 0000000000000..377be5d1a2f1e
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-add-to-arith-add.mlir
@@ -0,0 +1,79 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @func_1(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32,
+// CHECK-SAME:                      %[[ARG1:.*]]: i32) -> i32 {
+wasmssa.func @func_1(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+%v1 = wasmssa.local_get %arg1 : ref to i32
+// CHECK:           %[[VAL_4:.*]] = arith.addi %[[VAL_2]], %[[VAL_3]] : i32
+%0 = wasmssa.add %v0 %v1 : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.return %0 : i32
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @func_2(
+// CHECK-SAME:                      %[[ARG0:.*]]: i64,
+// CHECK-SAME:                      %[[ARG1:.*]]: i64) -> i64 {
+wasmssa.func @func_2(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+%v0 = wasmssa.local_get %arg0 : ref to i64
+%v1 = wasmssa.local_get %arg1 : ref to i64
+// CHECK:           %[[VAL_4:.*]] = arith.addi %[[VAL_2]], %[[VAL_3]] : i64
+%0 = wasmssa.add %v0 %v1 : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.return %0 : i64
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @func_3(
+// CHECK-SAME:                      %[[ARG0:.*]]: f32,
+// CHECK-SAME:                      %[[ARG1:.*]]: f32) -> f32 {
+wasmssa.func @func_3(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+%v0 = wasmssa.local_get %arg0 : ref to f32
+%v1 = wasmssa.local_get %arg1 : ref to f32
+// CHECK:           %[[VAL_4:.*]] = arith.addf %[[VAL_2]], %[[VAL_3]] : f32
+%0 = wasmssa.add %v0 %v1 : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.return %0 : f32
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @func_4(
+// CHECK-SAME:                      %[[ARG0:.*]]: f64,
+// CHECK-SAME:                      %[[ARG1:.*]]: f64) -> f64 {
+wasmssa.func @func_4(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+%v0 = wasmssa.local_get %arg0 : ref to f64
+%v1 = wasmssa.local_get %arg1 : ref to f64
+// CHECK:           %[[VAL_4:.*]] = arith.addf %[[VAL_2]], %[[VAL_3]] : f64
+%0 = wasmssa.add %v0 %v1 : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.return %0 : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-and-to-arith-and.mlir b/mlir/test/Conversion/RaiseWasm/wasm-and-to-arith-and.mlir
new file mode 100644
index 0000000000000..eebc76e7322ae
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-and-to-arith-and.mlir
@@ -0,0 +1,38 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @and_i32(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32,
+// CHECK-SAME:                      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.andi %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @and_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %v1 = wasmssa.local_get %arg1 : ref to i32
+    %and = wasmssa.and %v0 %v1 : i32
+    wasmssa.return %and : i32
+}
+
+// CHECK-LABEL:   func.func @and_i64(
+// CHECK-SAME:                      %[[ARG0:.*]]: i64,
+// CHECK-SAME:                      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.andi %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @and_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %v1 = wasmssa.local_get %arg1 : ref to i64
+    %and = wasmssa.and %v0 %v1 : i64
+    wasmssa.return %and : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-ceil-to-math-ceil.mlir b/mlir/test/Conversion/RaiseWasm/wasm-ceil-to-math-ceil.mlir
new file mode 100644
index 0000000000000..15875f60c1c43
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-ceil-to-math-ceil.mlir
@@ -0,0 +1,24 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+module {
+  wasmssa.func exported @func_0() -> f64 {
+    %0 = wasmssa.const -1.210000e+01 : f64
+    %1 = wasmssa.ceil %0 : f64
+    wasmssa.return %1 : f64
+  }
+  wasmssa.func exported @func_1() -> f32 {
+    %0 = wasmssa.const 1.618000e+00 : f32
+    %1 = wasmssa.ceil %0 : f32
+    wasmssa.return %1 : f32
+  }
+}
+
+// CHECK-LABEL:   func.func @func_0() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1.210000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = math.ceil %[[VAL_0]] : f64
+// CHECK:           return %[[VAL_1]] : f64
+
+// CHECK-LABEL:   func.func @func_1() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 1.618000e+00 : f32
+// CHECK:           %[[VAL_1:.*]] = math.ceil %[[VAL_0]] : f32
+// CHECK:           return %[[VAL_1]] : f32

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-clz-to-math-clz.mlir b/mlir/test/Conversion/RaiseWasm/wasm-clz-to-math-clz.mlir
new file mode 100644
index 0000000000000..944cf24ff40c2
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-clz-to-math-clz.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @clz_i32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = math.ctlz %[[VAL_1]] : i32
+// CHECK:           return %[[VAL_2]] : i32
+wasmssa.func exported @clz_i32(%arg0: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %op = wasmssa.clz %v0 : i32
+    wasmssa.return %op : i32
+}
+
+// CHECK-LABEL:   func.func @clz_i64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = math.ctlz %[[VAL_1]] : i64
+// CHECK:           return %[[VAL_2]] : i64
+wasmssa.func exported @clz_i64(%arg0: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %op = wasmssa.clz %v0 : i64
+    wasmssa.return %op : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-const-to-arith-const.mlir b/mlir/test/Conversion/RaiseWasm/wasm-const-to-arith-const.mlir
new file mode 100644
index 0000000000000..06bd0acab4f96
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-const-to-arith-const.mlir
@@ -0,0 +1,15 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @get_some_const() -> (i32, i64, f32, f64) {
+wasmssa.func exported @get_some_const() -> (i32, i64, f32, f64) {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 17 : i32
+%0 = wasmssa.const 17: i32
+// CHECK:           %[[VAL_1:.*]] = arith.constant -163 : i64
+%1 = wasmssa.const -163 : i64
+// CHECK:           %[[VAL_2:.*]] = arith.constant 3.140000e+00 : f32
+%2 = wasmssa.const 3.14 : f32
+// CHECK:           %[[VAL_3:.*]] = arith.constant -1.575000e+02 : f64
+%3 = wasmssa.const -157.5 : f64
+// CHECK:           return %[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]] : i32, i64, f32, f64
+wasmssa.return %0, %1, %2, %3 : i32, i64, f32, f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-convert-to-arith-tofp.mlir b/mlir/test/Conversion/RaiseWasm/wasm-convert-to-arith-tofp.mlir
new file mode 100644
index 0000000000000..4eeea757d48d0
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-convert-to-arith-tofp.mlir
@@ -0,0 +1,81 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @convert_i32_u_to_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 10 : i32
+// CHECK:           %[[VAL_1:.*]] = arith.uitofp %[[VAL_0]] : i32 to f32
+// CHECK:           return %[[VAL_1]] : f32
+wasmssa.func @convert_i32_u_to_f32() -> f32 {
+  %0 = wasmssa.const 10 : i32
+  %1 = wasmssa.convert_u %0 : i32 to f32
+  wasmssa.return %1 : f32
+}
+
+// CHECK-LABEL:   func.func @convert_i32_s_to_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 42 : i32
+// CHECK:           %[[VAL_1:.*]] = arith.sitofp %[[VAL_0]] : i32 to f32
+// CHECK:           return %[[VAL_1]] : f32
+wasmssa.func @convert_i32_s_to_f32() -> f32 {
+  %0 = wasmssa.const 42 : i32
+  %1 = wasmssa.convert_s %0 : i32 to f32
+  wasmssa.return %1 : f32
+}
+
+// CHECK-LABEL:   func.func @convert_i64_u_to_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 17 : i64
+// CHECK:           %[[VAL_1:.*]] = arith.uitofp %[[VAL_0]] : i64 to f32
+// CHECK:           return %[[VAL_1]] : f32
+wasmssa.func @convert_i64_u_to_f32() -> f32 {
+  %0 = wasmssa.const 17 : i64
+  %1 = wasmssa.convert_u %0 : i64 to f32
+  wasmssa.return %1 : f32
+}
+
+// CHECK-LABEL:   func.func @convert_i64s_to_f32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 10 : i64
+// CHECK:           %[[VAL_1:.*]] = arith.sitofp %[[VAL_0]] : i64 to f32
+// CHECK:           return %[[VAL_1]] : f32
+wasmssa.func @convert_i64s_to_f32() -> f32 {
+  %0 = wasmssa.const 10 : i64
+  %1 = wasmssa.convert_s %0 : i64 to f32
+  wasmssa.return %1 : f32
+}
+
+// CHECK-LABEL:   func.func @convert_i32_u_to_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 10 : i32
+// CHECK:           %[[VAL_1:.*]] = arith.uitofp %[[VAL_0]] : i32 to f64
+// CHECK:           return %[[VAL_1]] : f64
+wasmssa.func @convert_i32_u_to_f64() -> f64 {
+  %0 = wasmssa.const 10 : i32
+  %1 = wasmssa.convert_u %0 : i32 to f64
+  wasmssa.return %1 : f64
+}
+
+// CHECK-LABEL:   func.func @convert_i32_s_to_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 42 : i32
+// CHECK:           %[[VAL_1:.*]] = arith.sitofp %[[VAL_0]] : i32 to f64
+// CHECK:           return %[[VAL_1]] : f64
+wasmssa.func @convert_i32_s_to_f64() -> f64 {
+  %0 = wasmssa.const 42 : i32
+  %1 = wasmssa.convert_s %0 : i32 to f64
+  wasmssa.return %1 : f64
+}
+
+// CHECK-LABEL:   func.func @convert_i64_u_to_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 17 : i64
+// CHECK:           %[[VAL_1:.*]] = arith.uitofp %[[VAL_0]] : i64 to f64
+// CHECK:           return %[[VAL_1]] : f64
+wasmssa.func @convert_i64_u_to_f64() -> f64 {
+  %0 = wasmssa.const 17 : i64
+  %1 = wasmssa.convert_u %0 : i64 to f64
+  wasmssa.return %1 : f64
+}
+
+// CHECK-LABEL:   func.func @convert_i64s_to_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 10 : i64
+// CHECK:           %[[VAL_1:.*]] = arith.sitofp %[[VAL_0]] : i64 to f64
+// CHECK:           return %[[VAL_1]] : f64
+wasmssa.func @convert_i64s_to_f64() -> f64 {
+  %0 = wasmssa.const 10 : i64
+  %1 = wasmssa.convert_s %0 : i64 to f64
+  wasmssa.return %1 : f64
+}
\ No newline at end of file

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-copysign-to-math-copysign.mlir b/mlir/test/Conversion/RaiseWasm/wasm-copysign-to-math-copysign.mlir
new file mode 100644
index 0000000000000..9ab2b7990e7c0
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-copysign-to-math-copysign.mlir
@@ -0,0 +1,38 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @copysign_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32,
+// CHECK-SAME:      %[[ARG1:.*]]: f32) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_4:.*]] = math.copysign %[[VAL_2]], %[[VAL_3]] : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.func exported @copysign_f32(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+    %v0 = wasmssa.local_get %arg0 : ref to f32
+    %v1 = wasmssa.local_get %arg1 : ref to f32
+    %op = wasmssa.copysign %v0 %v1: f32
+    wasmssa.return %op : f32
+}
+
+// CHECK-LABEL:   func.func @copysign_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64,
+// CHECK-SAME:      %[[ARG1:.*]]: f64) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_4:.*]] = math.copysign %[[VAL_2]], %[[VAL_3]] : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.func exported @copysign_f64(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+    %v0 = wasmssa.local_get %arg0 : ref to f64
+    %v1 = wasmssa.local_get %arg1 : ref to f64
+    %op = wasmssa.copysign %v0 %v1: f64
+    wasmssa.return %op : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-ctz-to-math-ctz.mlir b/mlir/test/Conversion/RaiseWasm/wasm-ctz-to-math-ctz.mlir
new file mode 100644
index 0000000000000..6cc9394eea99c
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-ctz-to-math-ctz.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @ctz_i32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = math.cttz %[[VAL_1]] : i32
+// CHECK:           return %[[VAL_2]] : i32
+wasmssa.func exported @ctz_i32(%arg0: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %op = wasmssa.ctz %v0 : i32
+    wasmssa.return %op : i32
+}
+
+// CHECK-LABEL:   func.func @ctz_i64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = math.cttz %[[VAL_1]] : i64
+// CHECK:           return %[[VAL_2]] : i64
+wasmssa.func exported @ctz_i64(%arg0: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %op = wasmssa.ctz %v0 : i64
+    wasmssa.return %op : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-demote-to-arith-trunc.mlir b/mlir/test/Conversion/RaiseWasm/wasm-demote-to-arith-trunc.mlir
new file mode 100644
index 0000000000000..342886e3bda00
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-demote-to-arith-trunc.mlir
@@ -0,0 +1,14 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+module {
+  wasmssa.func @func_0() -> f32 {
+    %0 = wasmssa.const 2.240000e+00 : f64
+    %1 = wasmssa.demote %0 : f64 to f32
+    wasmssa.return %1 : f32
+  }
+}
+
+// CHECK-LABEL:   func.func @func_0() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 2.240000e+00 : f64
+// CHECK:           %[[VAL_1:.*]] = arith.truncf %[[VAL_0]] : f64 to f32
+// CHECK:           return %[[VAL_1]] : f32

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-div-to-arith-div.mlir b/mlir/test/Conversion/RaiseWasm/wasm-div-to-arith-div.mlir
new file mode 100644
index 0000000000000..3d6fa9af95442
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-div-to-arith-div.mlir
@@ -0,0 +1,109 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @div_i32_si(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+wasmssa.func @div_i32_si(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+%v1 = wasmssa.local_get %arg1 : ref to i32
+// CHECK:           %[[VAL_4:.*]] = arith.divsi %[[VAL_2]], %[[VAL_3]] : i32
+%0 = wasmssa.div_si %v0 %v1 : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.return %0 : i32
+}
+
+// CHECK-LABEL:   func.func @div_i64_si(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+wasmssa.func @div_i64_si(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+%v0 = wasmssa.local_get %arg0 : ref to i64
+%v1 = wasmssa.local_get %arg1 : ref to i64
+// CHECK:           %[[VAL_4:.*]] = arith.divsi %[[VAL_2]], %[[VAL_3]] : i64
+%0 = wasmssa.div_si %v0 %v1 : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.return %0 : i64
+}
+
+// CHECK-LABEL:   func.func @div_i32_ui(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+wasmssa.func @div_i32_ui(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+%v1 = wasmssa.local_get %arg1 : ref to i32
+// CHECK:           %[[VAL_4:.*]] = arith.divui %[[VAL_2]], %[[VAL_3]] : i32
+%0 = wasmssa.div_ui %v0 %v1 : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.return %0 : i32
+}
+
+// CHECK-LABEL:   func.func @div_i64_ui(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+wasmssa.func @div_i64_ui(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+%v0 = wasmssa.local_get %arg0 : ref to i64
+%v1 = wasmssa.local_get %arg1 : ref to i64
+// CHECK:           %[[VAL_4:.*]] = arith.divui %[[VAL_2]], %[[VAL_3]] : i64
+%0 = wasmssa.div_ui %v0 %v1 : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.return %0 : i64
+}
+
+// CHECK-LABEL:   func.func @div_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32,
+// CHECK-SAME:      %[[ARG1:.*]]: f32) -> f32 {
+wasmssa.func @div_f32(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+%v0 = wasmssa.local_get %arg0 : ref to f32
+%v1 = wasmssa.local_get %arg1 : ref to f32
+// CHECK:           %[[VAL_4:.*]] = arith.divf %[[VAL_2]], %[[VAL_3]] : f32
+%0 = wasmssa.div %v0 %v1 : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.return %0 : f32
+}
+
+// CHECK-LABEL:   func.func @div_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64,
+// CHECK-SAME:      %[[ARG1:.*]]: f64) -> f64 {
+wasmssa.func @div_f64(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+%v0 = wasmssa.local_get %arg0 : ref to f64
+%v1 = wasmssa.local_get %arg1 : ref to f64
+// CHECK:           %[[VAL_4:.*]] = arith.divf %[[VAL_2]], %[[VAL_3]] : f64
+%0 = wasmssa.div %v0 %v1 : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.return %0 : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-floor-to-math-floor.mlir b/mlir/test/Conversion/RaiseWasm/wasm-floor-to-math-floor.mlir
new file mode 100644
index 0000000000000..5ca4694bdb824
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-floor-to-math-floor.mlir
@@ -0,0 +1,24 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+module {
+  wasmssa.func @func_0() -> f64 {
+    %0 = wasmssa.const -1.210000e+01 : f64
+    %1 = wasmssa.floor %0 : f64
+    wasmssa.return %1 : f64
+  }
+  wasmssa.func @func_1() -> f32 {
+    %0 = wasmssa.const 1.618000e+00 : f32
+    %1 = wasmssa.floor %0 : f32
+    wasmssa.return %1 : f32
+  }
+}
+
+// CHECK-LABEL:   func.func @func_0() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1.210000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = math.floor %[[VAL_0]] : f64
+// CHECK:           return %[[VAL_1]] : f64
+
+// CHECK-LABEL:   func.func @func_1() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 1.618000e+00 : f32
+// CHECK:           %[[VAL_1:.*]] = math.floor %[[VAL_0]] : f32
+// CHECK:           return %[[VAL_1]] : f32

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-func-to-func.mlir b/mlir/test/Conversion/RaiseWasm/wasm-func-to-func.mlir
new file mode 100644
index 0000000000000..65a6831b442ca
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-func-to-func.mlir
@@ -0,0 +1,35 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @callee(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32) -> i32 {
+wasmssa.func exported @callee(%arg0: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+// CHECK:           return %[[VAL_1]] : i32
+wasmssa.return %v0 : i32
+}
+
+wasmssa.func exported @caller(%arg0: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+// CHECK:           %[[VAL_2:.*]] = call @callee(%[[VAL_1]]) : (i32) -> i32
+%0 = wasmssa.call @callee (%v0) : (i32) -> i32
+// CHECK:           return %[[VAL_2]] : i32
+wasmssa.return %0 : i32
+}
+
+// CHECK-LABEL:         func.func private @"my_module::foo"() -> i32
+wasmssa.import_func "foo" from "my_module" as @func_0 {sym_visibility = "nested", type = () -> (i32)}
+
+// CHECK-LABEL:   func.func @user_of_func0() -> i32 {
+wasmssa.func exported @user_of_func0() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = call @"my_module::foo"() : () -> i32
+%0 = wasmssa.call @func_0 : () -> i32
+// CHECK:           return %[[VAL_0]] : i32
+wasmssa.return %0 : i32
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-global-to-memref-global.mlir b/mlir/test/Conversion/RaiseWasm/wasm-global-to-memref-global.mlir
new file mode 100644
index 0000000000000..45a6636d89c22
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-global-to-memref-global.mlir
@@ -0,0 +1,43 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir | FileCheck %s
+
+wasmssa.global @global_i32 i32 mutable : {
+  %0 = wasmssa.const 66560 : i32
+  wasmssa.return %0 : i32
+}
+
+wasmssa.global @global_i64 i64 mutable : {
+  %0 = wasmssa.const 37017 : i64
+  wasmssa.return %0 : i64
+}
+
+wasmssa.global @global_f32 f32 mutable : {
+  %0 = wasmssa.const 0.125 : f32
+  wasmssa.return %0 : f32
+}
+
+wasmssa.global @global_f64 f64 mutable : {
+  %0 = wasmssa.const 3.14 : f64
+  wasmssa.return %0 : f64
+}
+
+wasmssa.global @global_user0 i32 mutable : {
+  %0 = wasmssa.global_get @global_top_define : i32
+  wasmssa.return %0 : i32
+}
+
+wasmssa.import_global "extern_global_var" from "module" as @global_top_define nested : i32
+
+// CHECK-LABEL:   memref.global "private" @global_i32 : memref<1xi32> = dense<66560>
+// CHECK:         memref.global "private" @global_i64 : memref<1xi64> = dense<37017>
+// CHECK:         memref.global "private" @global_f32 : memref<1xf32> = dense<1.250000e-01>
+// CHECK:         memref.global "private" @global_f64 : memref<1xf64> = dense<3.140000e+00>
+// CHECK:         memref.global "private" @global_user0 : memref<1xi32> = uninitialized
+
+// CHECK-LABEL:   func.func @"global_user0::initializer"() attributes {initializer} {
+// CHECK:           %[[VAL_0:.*]] = memref.get_global @"module::extern_global_var" : memref<1xi32>
+// CHECK:           %[[VAL_1:.*]] = memref.get_global @global_user0 : memref<1xi32>
+// CHECK:           %[[VAL_2:.*]] = arith.constant 0 : index
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]]{{\[}}%[[VAL_2]]] : memref<1xi32>
+// CHECK:           memref.store %[[VAL_3]], %[[VAL_1]]{{\[}}%[[VAL_2]]] : memref<1xi32>
+// CHECK:           return
+// CHECK:         memref.global "nested" constant @"module::extern_global_var" : memref<1xi32>

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-local-to-memref.mlir b/mlir/test/Conversion/RaiseWasm/wasm-local-to-memref.mlir
new file mode 100644
index 0000000000000..839975ab87daa
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-local-to-memref.mlir
@@ -0,0 +1,68 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @func_0() -> f32 {
+wasmssa.func exported @func_0() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32
+// CHECK:           memref.store %[[VAL_1]], %[[VAL_0]][] : memref<f32>
+  %0 = wasmssa.local of type f32
+// CHECK:           %[[VAL_2:.*]] = memref.alloca() : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
+// CHECK:           memref.store %[[VAL_3]], %[[VAL_2]][] : memref<f32>
+  %1 = wasmssa.local of type f32
+// CHECK:           %[[VAL_4:.*]] = arith.constant 8.000000e+00 : f32
+  %2 = wasmssa.const 8.000000e+00 : f32
+// CHECK:           memref.store %[[VAL_4]], %[[VAL_0]][] : memref<f32>
+  wasmssa.local_set %0 : ref to f32 to %2 : f32
+// CHECK:           %[[VAL_5:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+  %3 = wasmssa.local_get %0 : ref to f32
+// CHECK:           %[[VAL_6:.*]] = arith.constant 1.200000e+01 : f32
+  %4 = wasmssa.const 1.200000e+01 : f32
+// CHECK:           memref.store %[[VAL_6]], %[[VAL_2]][] : memref<f32>
+  %5 = wasmssa.local_tee %1 : ref to f32 to %4 : f32
+// CHECK:           %[[VAL_7:.*]] = arith.addf %[[VAL_5]], %[[VAL_6]] : f32
+  %6 = wasmssa.add %3 %5 : f32
+// CHECK:           return %[[VAL_7]] : f32
+  wasmssa.return %6 : f32
+}
+
+// CHECK-LABEL:   func.func @func_1() -> i32 {
+wasmssa.func exported @func_1() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = arith.constant 0 : i32
+// CHECK:           memref.store %[[VAL_1]], %[[VAL_0]][] : memref<i32>
+  %0 = wasmssa.local of type i32
+// CHECK:           %[[VAL_2:.*]] = memref.alloca() : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = arith.constant 0 : i32
+// CHECK:           memref.store %[[VAL_3]], %[[VAL_2]][] : memref<i32>
+  %1 = wasmssa.local of type i32
+// CHECK:           %[[VAL_4:.*]] = arith.constant 8 : i32
+  %2 = wasmssa.const 8 : i32
+// CHECK:           memref.store %[[VAL_4]], %[[VAL_0]][] : memref<i32>
+  wasmssa.local_set %0 : ref to i32 to %2 : i32
+// CHECK:           %[[VAL_5:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+  %3 = wasmssa.local_get %0 : ref to i32
+// CHECK:           %[[VAL_6:.*]] = arith.constant 12 : i32
+  %4 = wasmssa.const 12 : i32
+// CHECK:           memref.store %[[VAL_6]], %[[VAL_2]][] : memref<i32>
+  %5 = wasmssa.local_tee %1 : ref to i32 to %4 : i32
+// CHECK:           %[[VAL_7:.*]] = arith.addi %[[VAL_5]], %[[VAL_6]] : i32
+  %6 = wasmssa.add %3 %5 : i32
+// CHECK:           return %[[VAL_7]] : i32
+  wasmssa.return %6 : i32
+}
+
+// CHECK-LABEL:   func.func @func_2(
+// CHECK-SAME:                      %[[VAL_0:.*]]: i32) -> i32 {
+wasmssa.func exported @func_2(%arg0: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[VAL_0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = arith.constant 3 : i32
+  %1 = wasmssa.const 3 : i32
+// CHECK:           memref.store %[[VAL_2]], %[[VAL_1]][] : memref<i32>
+  wasmssa.local_set %arg0 : ref to i32 to %1 : i32
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+  %2 = wasmssa.local_get %arg0 : ref to i32
+// CHECK:           return %[[VAL_3]] : i32
+  wasmssa.return %2 : i32
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-max-to-arith-maximumf.mlir b/mlir/test/Conversion/RaiseWasm/wasm-max-to-arith-maximumf.mlir
new file mode 100644
index 0000000000000..2f0d10788f03c
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-max-to-arith-maximumf.mlir
@@ -0,0 +1,37 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @max_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32,
+// CHECK-SAME:      %[[ARG1:.*]]: f32) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_4:.*]] = arith.maximumf %[[VAL_2]], %[[VAL_3]] : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.func exported @max_f32(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+    %v0 = wasmssa.local_get %arg0 : ref to f32
+    %v1 = wasmssa.local_get %arg1 : ref to f32
+    %op = wasmssa.max %v0 %v1 : f32
+    wasmssa.return %op : f32
+}
+
+// CHECK-LABEL:   func.func @max_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64,
+// CHECK-SAME:      %[[ARG1:.*]]: f64) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_4:.*]] = arith.maximumf %[[VAL_2]], %[[VAL_3]] : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.func exported @max_f64(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+    %v0 = wasmssa.local_get %arg0 : ref to f64
+    %v1 = wasmssa.local_get %arg1 : ref to f64
+    %op = wasmssa.max %v0 %v1 : f64
+    wasmssa.return %op : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-min-to-arith-minimumf.mlir b/mlir/test/Conversion/RaiseWasm/wasm-min-to-arith-minimumf.mlir
new file mode 100644
index 0000000000000..d6a0141a5199f
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-min-to-arith-minimumf.mlir
@@ -0,0 +1,37 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @min_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32,
+// CHECK-SAME:      %[[ARG1:.*]]: f32) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_4:.*]] = arith.minimumf %[[VAL_2]], %[[VAL_3]] : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.func exported @min_f32(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+    %v0 = wasmssa.local_get %arg0 : ref to f32
+    %v1 = wasmssa.local_get %arg1 : ref to f32
+    %op = wasmssa.min %v0 %v1 : f32
+    wasmssa.return %op : f32
+}
+
+// CHECK-LABEL:   func.func @min_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64,
+// CHECK-SAME:      %[[ARG1:.*]]: f64) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_4:.*]] = arith.minimumf %[[VAL_2]], %[[VAL_3]] : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.func exported @min_f64(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+    %v0 = wasmssa.local_get %arg0 : ref to f64
+    %v1 = wasmssa.local_get %arg1 : ref to f64
+    %op = wasmssa.min %v0 %v1 : f64
+    wasmssa.return %op : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-mul-to-arith-mul.mlir b/mlir/test/Conversion/RaiseWasm/wasm-mul-to-arith-mul.mlir
new file mode 100644
index 0000000000000..51c8b43d980b5
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-mul-to-arith-mul.mlir
@@ -0,0 +1,78 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @mul_i32(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32,
+// CHECK-SAME:                      %[[ARG1:.*]]: i32) -> i32 {
+wasmssa.func @mul_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+%v1 = wasmssa.local_get %arg1 : ref to i32
+// CHECK:           %[[VAL_4:.*]] = arith.muli %[[VAL_2]], %[[VAL_3]] : i32
+%0 = wasmssa.mul %v0 %v1 : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.return %0 : i32
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @mul_i64(
+// CHECK-SAME:                      %[[ARG0:.*]]: i64,
+// CHECK-SAME:                      %[[ARG1:.*]]: i64) -> i64 {
+wasmssa.func @mul_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+%v0 = wasmssa.local_get %arg0 : ref to i64
+%v1 = wasmssa.local_get %arg1 : ref to i64
+// CHECK:           %[[VAL_4:.*]] = arith.muli %[[VAL_2]], %[[VAL_3]] : i64
+%0 = wasmssa.mul %v0 %v1 : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.return %0 : i64
+}
+// -----
+
+// CHECK-LABEL:   func.func @mul_f32(
+// CHECK-SAME:                      %[[ARG0:.*]]: f32,
+// CHECK-SAME:                      %[[ARG1:.*]]: f32) -> f32 {
+wasmssa.func @mul_f32(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+%v0 = wasmssa.local_get %arg0 : ref to f32
+%v1 = wasmssa.local_get %arg1 : ref to f32
+// CHECK:           %[[VAL_4:.*]] = arith.mulf %[[VAL_2]], %[[VAL_3]] : f32
+%0 = wasmssa.mul %v0 %v1 : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.return %0 : f32
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @mul_f64(
+// CHECK-SAME:                      %[[ARG0:.*]]: f64,
+// CHECK-SAME:                      %[[ARG1:.*]]: f64) -> f64 {
+wasmssa.func @mul_f64(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+%v0 = wasmssa.local_get %arg0 : ref to f64
+%v1 = wasmssa.local_get %arg1 : ref to f64
+// CHECK:           %[[VAL_4:.*]] = arith.mulf %[[VAL_2]], %[[VAL_3]] : f64
+%0 = wasmssa.mul %v0 %v1 : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.return %0 : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-neg-to-arith-neg.mlir b/mlir/test/Conversion/RaiseWasm/wasm-neg-to-arith-neg.mlir
new file mode 100644
index 0000000000000..a15b9a6c25990
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-neg-to-arith-neg.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @neg_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = arith.negf %[[VAL_1]] : f32
+// CHECK:           return %[[VAL_2]] : f32
+wasmssa.func @neg_f32(%arg0: !wasmssa<local ref to f32>) -> f32 {
+    %val = wasmssa.local_get %arg0 : ref to f32
+    %op = wasmssa.neg %val : f32
+    wasmssa.return %op : f32
+}
+
+// CHECK-LABEL:   func.func @neg_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = arith.negf %[[VAL_1]] : f64
+// CHECK:           return %[[VAL_2]] : f64
+wasmssa.func @neg_f64(%arg0: !wasmssa<local ref to f64>) -> f64 {
+    %val = wasmssa.local_get %arg0 : ref to f64
+    %op = wasmssa.neg %val : f64
+    wasmssa.return %op : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-or-to-arith-or.mlir b/mlir/test/Conversion/RaiseWasm/wasm-or-to-arith-or.mlir
new file mode 100644
index 0000000000000..44ce35209511d
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-or-to-arith-or.mlir
@@ -0,0 +1,38 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @or_i32(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32,
+// CHECK-SAME:                      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.ori %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @or_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %v1 = wasmssa.local_get %arg1 : ref to i32
+    %or = wasmssa.or %v0 %v1 : i32
+    wasmssa.return %or : i32
+}
+
+// CHECK-LABEL:   func.func @or_i64(
+// CHECK-SAME:                      %[[ARG0:.*]]: i64,
+// CHECK-SAME:                      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.ori %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @or_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %v1 = wasmssa.local_get %arg1 : ref to i64
+    %or = wasmssa.or %v0 %v1 : i64
+    wasmssa.return %or : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-popcnt-to-math-ctpop.mlir b/mlir/test/Conversion/RaiseWasm/wasm-popcnt-to-math-ctpop.mlir
new file mode 100644
index 0000000000000..1c027cf1972e8
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-popcnt-to-math-ctpop.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @popcnt_i32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = math.ctpop %[[VAL_1]] : i32
+// CHECK:           return %[[VAL_2]] : i32
+wasmssa.func exported @popcnt_i32(%arg0: !wasmssa<local ref to i32>) -> i32 {
+    %v = wasmssa.local_get %arg0 : ref to i32
+    %op = wasmssa.popcnt %v : i32
+    wasmssa.return %op : i32
+}
+
+// CHECK-LABEL:   func.func @popcnt_i64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = math.ctpop %[[VAL_1]] : i64
+// CHECK:           return %[[VAL_2]] : i64
+wasmssa.func exported @popcnt_i64(%arg0: !wasmssa<local ref to i64>) -> i64 {
+    %v = wasmssa.local_get %arg0 : ref to i64
+    %op = wasmssa.popcnt %v : i64
+    wasmssa.return %op : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-promote-to-arith-ext.mlir b/mlir/test/Conversion/RaiseWasm/wasm-promote-to-arith-ext.mlir
new file mode 100644
index 0000000000000..5cf04a0ccbd3c
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-promote-to-arith-ext.mlir
@@ -0,0 +1,11 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @promote_f32_to_f64() -> f64 {
+wasmssa.func @promote_f32_to_f64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 3.140000e+00 : f32
+  %0 = wasmssa.const 3.14 : f32
+// CHECK:           %[[VAL_1:.*]] = arith.extf %[[VAL_0]] : f32 to f64
+  %1 = wasmssa.promote %0 : f32 to f64
+// CHECK:           return %[[VAL_1]] : f64
+  wasmssa.return %1 : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-reinterpret-to-arith-bitcast.mlir b/mlir/test/Conversion/RaiseWasm/wasm-reinterpret-to-arith-bitcast.mlir
new file mode 100644
index 0000000000000..78e3984870d6b
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-reinterpret-to-arith-bitcast.mlir
@@ -0,0 +1,42 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+module {
+// CHECK-LABEL:   func.func @i32.reinterpret_f32() -> i32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1.000000e+00 : f32
+// CHECK:           %[[VAL_1:.*]] = arith.bitcast %[[VAL_0]] : f32 to i32
+// CHECK:           return %[[VAL_1]] : i32
+  wasmssa.func @i32.reinterpret_f32() -> i32 {
+    %0 = wasmssa.const -1.000000e+00 : f32
+    %1 = wasmssa.reinterpret %0 : f32 as i32
+    wasmssa.return %1 : i32
+  }
+
+// CHECK-LABEL:   func.func @i64.reinterpret_f64() -> i64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1.000000e+00 : f64
+// CHECK:           %[[VAL_1:.*]] = arith.bitcast %[[VAL_0]] : f64 to i64
+// CHECK:           return %[[VAL_1]] : i64
+  wasmssa.func @i64.reinterpret_f64() -> i64 {
+    %0 = wasmssa.const -1.000000e+00 : f64
+    %1 = wasmssa.reinterpret %0 : f64 as i64
+    wasmssa.return %1 : i64
+  }
+
+// CHECK-LABEL:   func.func @f32.reinterpret_i32() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1 : i32
+// CHECK:           %[[VAL_1:.*]] = arith.bitcast %[[VAL_0]] : i32 to f32
+// CHECK:           return %[[VAL_1]] : f32
+  wasmssa.func @f32.reinterpret_i32() -> f32 {
+    %0 = wasmssa.const -1 : i32
+    %1 = wasmssa.reinterpret %0 : i32 as f32
+    wasmssa.return %1 : f32
+  }
+
+// CHECK-LABEL:   func.func @f64.reinterpret_i64() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1 : i64
+// CHECK:           %[[VAL_1:.*]] = arith.bitcast %[[VAL_0]] : i64 to f64
+// CHECK:           return %[[VAL_1]] : f64
+  wasmssa.func @f64.reinterpret_i64() -> f64 {
+    %0 = wasmssa.const -1 : i64
+    %1 = wasmssa.reinterpret %0 : i64 as f64
+    wasmssa.return %1 : f64
+  }
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-rem-to-arith-rem.mlir b/mlir/test/Conversion/RaiseWasm/wasm-rem-to-arith-rem.mlir
new file mode 100644
index 0000000000000..05a5b5bd10cfa
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-rem-to-arith-rem.mlir
@@ -0,0 +1,74 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @rem_ui_32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.remui %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @rem_ui_32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0: ref to i32
+    %v1 = wasmssa.local_get %arg1: ref to i32
+    %rem = wasmssa.rem_ui %v0 %v1 : i32
+    wasmssa.return %rem : i32
+}
+
+// CHECK-LABEL:   func.func @rem_si_32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.remsi %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @rem_si_32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0: ref to i32
+    %v1 = wasmssa.local_get %arg1: ref to i32
+    %rem = wasmssa.rem_si %v0 %v1 : i32
+    wasmssa.return %rem : i32
+}
+
+// CHECK-LABEL:   func.func @rem_ui_64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.remui %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @rem_ui_64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0: ref to i64
+    %v1 = wasmssa.local_get %arg1: ref to i64
+    %rem = wasmssa.rem_ui %v0 %v1 : i64
+    wasmssa.return %rem : i64
+}
+
+// CHECK-LABEL:   func.func @rem_si_64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.remsi %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @rem_si_64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0: ref to i64
+    %v1 = wasmssa.local_get %arg1: ref to i64
+    %rem = wasmssa.rem_si %v0 %v1 : i64
+    wasmssa.return %rem : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-shl-to-arith-shl.mlir b/mlir/test/Conversion/RaiseWasm/wasm-shl-to-arith-shl.mlir
new file mode 100644
index 0000000000000..efc4b5ca49225
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-shl-to-arith-shl.mlir
@@ -0,0 +1,38 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @shl_i32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.shli %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @shl_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %v1 = wasmssa.local_get %arg1 : ref to i32
+    %op = wasmssa.shl %v0 by %v1 bits : i32
+    wasmssa.return %op : i32
+}
+
+// CHECK-LABEL:   func.func @shl_i64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.shli %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @shl_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %v1 = wasmssa.local_get %arg1 : ref to i64
+    %op = wasmssa.shl %v0 by %v1 bits : i64
+    wasmssa.return %op : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-shr_s-to-arith-shrs.mlir b/mlir/test/Conversion/RaiseWasm/wasm-shr_s-to-arith-shrs.mlir
new file mode 100644
index 0000000000000..d0c3a94e611a8
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-shr_s-to-arith-shrs.mlir
@@ -0,0 +1,38 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+
+// CHECK-LABEL:   func.func @shr_s_i32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.shrsi %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @shr_s_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %v1 = wasmssa.local_get %arg1 : ref to i32
+    %op = wasmssa.shr_s %v0 by %v1 bits : i32
+    wasmssa.return %op : i32
+}
+
+// CHECK-LABEL:   func.func @shr_s_i64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.shrsi %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @shr_s_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %v1 = wasmssa.local_get %arg1 : ref to i64
+    %op = wasmssa.shr_s %v0 by %v1 bits : i64
+    wasmssa.return %op : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-shr_u-to-arith-shru.mlir b/mlir/test/Conversion/RaiseWasm/wasm-shr_u-to-arith-shru.mlir
new file mode 100644
index 0000000000000..38925b6899c4b
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-shr_u-to-arith-shru.mlir
@@ -0,0 +1,37 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @shr_u_i32(
+// CHECK-SAME:      %[[ARG0:.*]]: i32,
+// CHECK-SAME:      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.shrui %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func exported @shr_u_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %v1 = wasmssa.local_get %arg1 : ref to i32
+    %op = wasmssa.shr_u %v0 by %v1 bits : i32
+    wasmssa.return %op : i32
+}
+
+// CHECK-LABEL:   func.func @shr_u_i64(
+// CHECK-SAME:      %[[ARG0:.*]]: i64,
+// CHECK-SAME:      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.shrui %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func exported @shr_u_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %v1 = wasmssa.local_get %arg1 : ref to i64
+    %op = wasmssa.shr_u %v0 by %v1 bits : i64
+    wasmssa.return %op : i64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-sqrt-to-math-sqrt.mlir b/mlir/test/Conversion/RaiseWasm/wasm-sqrt-to-math-sqrt.mlir
new file mode 100644
index 0000000000000..394dc9e3216af
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-sqrt-to-math-sqrt.mlir
@@ -0,0 +1,27 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @sqrt_f32(
+// CHECK-SAME:      %[[ARG0:.*]]: f32) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = math.sqrt %[[VAL_1]] : f32
+// CHECK:           return %[[VAL_2]] : f32
+wasmssa.func @sqrt_f32(%arg0: !wasmssa<local ref to f32>) -> f32 {
+    %local = wasmssa.local_get %arg0 : ref to f32
+    %op = wasmssa.sqrt %local : f32
+    wasmssa.return %op : f32
+}
+
+// CHECK-LABEL:   func.func @sqrt_f64(
+// CHECK-SAME:      %[[ARG0:.*]]: f64) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = math.sqrt %[[VAL_1]] : f64
+// CHECK:           return %[[VAL_2]] : f64
+wasmssa.func @sqrt_f64(%arg0: !wasmssa<local ref to f64>) -> f64 {
+    %local = wasmssa.local_get %arg0 : ref to f64
+    %op = wasmssa.sqrt %local : f64
+    wasmssa.return %op : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-sub-to-arith-sub.mlir b/mlir/test/Conversion/RaiseWasm/wasm-sub-to-arith-sub.mlir
new file mode 100644
index 0000000000000..933d3d16add7b
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-sub-to-arith-sub.mlir
@@ -0,0 +1,80 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir | FileCheck %s
+
+// CHECK-LABEL:   func.func @func_1(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32,
+// CHECK-SAME:                      %[[ARG1:.*]]: i32) -> i32 {
+wasmssa.func @func_1(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+%v0 = wasmssa.local_get %arg0 : ref to i32
+%v1 = wasmssa.local_get %arg1 : ref to i32
+// CHECK:           %[[VAL_4:.*]] = arith.subi %[[VAL_2]], %[[VAL_3]] : i32
+%res = wasmssa.sub %v0 %v1 : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.return %res : i32
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @func_2(
+// CHECK-SAME:                      %[[ARG0:.*]]: i64,
+// CHECK-SAME:                      %[[ARG1:.*]]: i64) -> i64 {
+wasmssa.func @func_2(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+%v0 = wasmssa.local_get %arg0 : ref to i64
+%v1 = wasmssa.local_get %arg1 : ref to i64
+// CHECK:           %[[VAL_4:.*]] = arith.subi %[[VAL_2]], %[[VAL_3]] : i64
+%res = wasmssa.sub %v0 %v1 : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.return %res : i64
+}
+
+// -----
+
+// CHECK-LABEL:   func.func @func_3(
+// CHECK-SAME:                      %[[ARG0:.*]]: f32,
+// CHECK-SAME:                      %[[ARG1:.*]]: f32) -> f32 {
+wasmssa.func @func_3(%arg0: !wasmssa<local ref to f32>, %arg1: !wasmssa<local ref to f32>) -> f32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f32>
+%v0 = wasmssa.local_get %arg0 : ref to f32
+%v1 = wasmssa.local_get %arg1 : ref to f32
+// CHECK:           %[[VAL_4:.*]] = arith.subf %[[VAL_2]], %[[VAL_3]] : f32
+%res = wasmssa.sub %v0 %v1 : f32
+// CHECK:           return %[[VAL_4]] : f32
+wasmssa.return %res : f32
+}
+
+
+// -----
+
+// CHECK-LABEL:   func.func @func_4(
+// CHECK-SAME:                      %[[ARG0:.*]]: f64,
+// CHECK-SAME:                      %[[ARG1:.*]]: f64) -> f64 {
+wasmssa.func @func_4(%arg0: !wasmssa<local ref to f64>, %arg1: !wasmssa<local ref to f64>) -> f64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<f64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<f64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<f64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<f64>
+%v0 = wasmssa.local_get %arg0 : ref to f64
+%v1 = wasmssa.local_get %arg1 : ref to f64
+// CHECK:           %[[VAL_4:.*]] = arith.subf %[[VAL_2]], %[[VAL_3]] : f64
+%res = wasmssa.sub %v0 %v1 : f64
+// CHECK:           return %[[VAL_4]] : f64
+wasmssa.return %res : f64
+}

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-trunc-to-math-trunc.mlir b/mlir/test/Conversion/RaiseWasm/wasm-trunc-to-math-trunc.mlir
new file mode 100644
index 0000000000000..a120967bc3c0e
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-trunc-to-math-trunc.mlir
@@ -0,0 +1,24 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+module {
+  wasmssa.func @func_4() -> f64 {
+    %0 = wasmssa.const -1.210000e+01 : f64
+    %1 = wasmssa.trunc %0 : f64
+    wasmssa.return %1 : f64
+  }
+  wasmssa.func @func_5() -> f32 {
+    %0 = wasmssa.const 1.618000e+00 : f32
+    %1 = wasmssa.trunc %0 : f32
+    wasmssa.return %1 : f32
+  }
+}
+
+// CHECK-LABEL:   func.func @func_4() -> f64 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant -1.210000e+01 : f64
+// CHECK:           %[[VAL_1:.*]] = math.trunc %[[VAL_0]] : f64
+// CHECK:           return %[[VAL_1]] : f64
+
+// CHECK-LABEL:   func.func @func_5() -> f32 {
+// CHECK:           %[[VAL_0:.*]] = arith.constant 1.618000e+00 : f32
+// CHECK:           %[[VAL_1:.*]] = math.trunc %[[VAL_0]] : f32
+// CHECK:           return %[[VAL_1]] : f32

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-wrap-to-arith-trunc.mlir b/mlir/test/Conversion/RaiseWasm/wasm-wrap-to-arith-trunc.mlir
new file mode 100644
index 0000000000000..6164525626086
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-wrap-to-arith-trunc.mlir
@@ -0,0 +1,17 @@
+// RUN: mlir-opt %s --raise-wasm-mlir | FileCheck %s
+
+module {
+  wasmssa.func @i64_wrap(%arg0: !wasmssa<local ref to i64>) -> i32 {
+    %0 = wasmssa.local_get %arg0 :  ref to i64
+    %1 = wasmssa.wrap %0 : i64 to i32
+    wasmssa.return %1 : i32
+  }
+}
+
+// CHECK-LABEL:   func.func @i64_wrap(
+// CHECK-SAME:      %[[ARG0:.*]]: i64) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = arith.trunci %[[VAL_1]] : i64 to i32
+// CHECK:           return %[[VAL_2]] : i32

diff  --git a/mlir/test/Conversion/RaiseWasm/wasm-xor-to-arith-xor.mlir b/mlir/test/Conversion/RaiseWasm/wasm-xor-to-arith-xor.mlir
new file mode 100644
index 0000000000000..810729d883c61
--- /dev/null
+++ b/mlir/test/Conversion/RaiseWasm/wasm-xor-to-arith-xor.mlir
@@ -0,0 +1,37 @@
+// RUN: mlir-opt --split-input-file %s --raise-wasm-mlir -o - | FileCheck %s
+
+// CHECK-LABEL:   func.func @xor_i32(
+// CHECK-SAME:                      %[[ARG0:.*]]: i32,
+// CHECK-SAME:                      %[[ARG1:.*]]: i32) -> i32 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i32>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i32>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i32>
+// CHECK:           %[[VAL_4:.*]] = arith.xori %[[VAL_2]], %[[VAL_3]] : i32
+// CHECK:           return %[[VAL_4]] : i32
+wasmssa.func @xor_i32(%arg0: !wasmssa<local ref to i32>, %arg1: !wasmssa<local ref to i32>) -> i32 {
+    %v0 = wasmssa.local_get %arg0 : ref to i32
+    %v1 = wasmssa.local_get %arg1 : ref to i32
+    %xor = wasmssa.xor %v0 %v1 : i32
+    wasmssa.return %xor : i32
+}
+
+// CHECK-LABEL:   func.func @xor_i64(
+// CHECK-SAME:                      %[[ARG0:.*]]: i64,
+// CHECK-SAME:                      %[[ARG1:.*]]: i64) -> i64 {
+// CHECK:           %[[VAL_0:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG1]], %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_1:.*]] = memref.alloca() : memref<i64>
+// CHECK:           memref.store %[[ARG0]], %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_2:.*]] = memref.load %[[VAL_1]][] : memref<i64>
+// CHECK:           %[[VAL_3:.*]] = memref.load %[[VAL_0]][] : memref<i64>
+// CHECK:           %[[VAL_4:.*]] = arith.xori %[[VAL_2]], %[[VAL_3]] : i64
+// CHECK:           return %[[VAL_4]] : i64
+wasmssa.func @xor_i64(%arg0: !wasmssa<local ref to i64>, %arg1: !wasmssa<local ref to i64>) -> i64 {
+    %v0 = wasmssa.local_get %arg0 : ref to i64
+    %v1 = wasmssa.local_get %arg1 : ref to i64
+    %xor = wasmssa.xor %v0 %v1 : i64
+    wasmssa.return %xor : i64
+}


        


More information about the Mlir-commits mailing list