[Mlir-commits] [mlir] [MLIR][WASM] Re-Introduce the RaiseWasmMLIRPass to convert WasmSSA MLIR to core dialects (PR #205483)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jun 23 22:32:32 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Ferdinand Lemaire (flemairen6)

<details>
<summary>Changes</summary>

See the previous PR here: https://github.com/llvm/llvm-project/pull/164562

It was reverted by @<!-- -->lforg37 because of some build bot issue: see https://github.com/llvm/llvm-project/pull/164562#issuecomment-4756828598.

However, after checking on my end, I could not reproduce the buildbot issue. Seeing that the problem triggered in `flang` which is completely unrelated to this work, I assume that it was a builder problem so I'm re-opening this PR as it had been initially merged.

---

Patch is 97.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/205483.diff


40 Files Affected:

- (modified) mlir/include/mlir/Conversion/Passes.h (+1) 
- (modified) mlir/include/mlir/Conversion/Passes.td (+13) 
- (added) mlir/include/mlir/Conversion/RaiseWasm/RaiseWasmMLIR.h (+29) 
- (modified) mlir/include/mlir/Dialect/WasmSSA/IR/WasmSSAOps.td (+4-1) 
- (modified) mlir/lib/Conversion/CMakeLists.txt (+1) 
- (added) mlir/lib/Conversion/RaiseWasm/CMakeLists.txt (+19) 
- (added) mlir/lib/Conversion/RaiseWasm/RaiseWasmMLIR.cpp (+469) 
- (modified) mlir/lib/Dialect/WasmSSA/IR/WasmSSAOps.cpp (+14) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-abs-to-math-abs.mlir (+27) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-add-to-arith-add.mlir (+79) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-and-to-arith-and.mlir (+38) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-ceil-to-math-ceil.mlir (+24) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-clz-to-math-clz.mlir (+27) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-const-to-arith-const.mlir (+15) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-convert-to-arith-tofp.mlir (+81) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-copysign-to-math-copysign.mlir (+38) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-ctz-to-math-ctz.mlir (+27) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-demote-to-arith-trunc.mlir (+14) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-div-to-arith-div.mlir (+109) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-floor-to-math-floor.mlir (+24) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-func-to-func.mlir (+35) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-global-to-memref-global.mlir (+43) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-local-to-memref.mlir (+68) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-max-to-arith-maximumf.mlir (+37) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-min-to-arith-minimumf.mlir (+37) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-mul-to-arith-mul.mlir (+78) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-neg-to-arith-neg.mlir (+27) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-or-to-arith-or.mlir (+38) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-popcnt-to-math-ctpop.mlir (+27) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-promote-to-arith-ext.mlir (+11) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-reinterpret-to-arith-bitcast.mlir (+42) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-rem-to-arith-rem.mlir (+74) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-shl-to-arith-shl.mlir (+38) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-shr_s-to-arith-shrs.mlir (+38) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-shr_u-to-arith-shru.mlir (+37) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-sqrt-to-math-sqrt.mlir (+27) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-sub-to-arith-sub.mlir (+80) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-trunc-to-math-trunc.mlir (+24) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-wrap-to-arith-trunc.mlir (+17) 
- (added) mlir/test/Conversion/RaiseWasm/wasm-xor-to-arith-xor.mlir (+37) 


``````````diff
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 550e6b853057d..340ff8fdf2a8a 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -1724,6 +1724,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(...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/205483


More information about the Mlir-commits mailing list