mirror of
https://github.com/intel/llvm.git
synced 2026-01-18 16:50:51 +08:00
[MLIR][WASM] Control flow, conversion and comparison in Wasm importer (#154674)
This is the following of PR #154452. It extend Wasm binary to Wasm SSA importer with support of control flow operations, comparison operations and conversion operations. --------- Co-authored-by: Ferdinand Lemaire <ferdinand.lemaire@woven-planet.global> Co-authored-by: Jessica Paquette <jessica.paquette@woven-planet.global> Co-authored-by: Luc Forget <luc.forget@woven.toyota>
This commit is contained in:
@@ -43,9 +43,41 @@ class WasmSSA_BlockLikeOp<string mnemonic, string summaryStr> :
|
||||
let assemblyFormat = "(`(`$inputs^`)` `:` type($inputs))? attr-dict `:` $body `>` $target";
|
||||
}
|
||||
|
||||
def WasmSSA_BlockOp : WasmSSA_BlockLikeOp<"block", "Create a nesting level"> {}
|
||||
def WasmSSA_BlockOp : WasmSSA_BlockLikeOp<
|
||||
"block",
|
||||
"Create a nesting level with a label at its exit."> {
|
||||
let description = [{
|
||||
Defines a Wasm block, creating a new nested scope.
|
||||
A block contains a body region and an optional list of input values.
|
||||
Control can enter the block and later branch out to the block target.
|
||||
Example:
|
||||
|
||||
def WasmSSA_LoopOp : WasmSSA_BlockLikeOp<"loop", "Create a nesting level similar to Block Op, except that it has itself as a successor."> {}
|
||||
```mlir
|
||||
|
||||
wasmssa.block {
|
||||
|
||||
// instructions
|
||||
|
||||
} > ^successor
|
||||
}];
|
||||
}
|
||||
|
||||
def WasmSSA_LoopOp : WasmSSA_BlockLikeOp<
|
||||
"loop",
|
||||
"Create a nesting level that define its entry as jump target."> {
|
||||
let description = [{
|
||||
Represents a Wasm loop construct. This defines a nesting level with
|
||||
a label at the entry of the region.
|
||||
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
|
||||
wasmssa.loop {
|
||||
|
||||
} > ^successor
|
||||
}];
|
||||
}
|
||||
|
||||
def WasmSSA_BlockReturnOp : WasmSSA_Op<"block_return", [Terminator,
|
||||
DeclareOpInterfaceMethods<LabelBranchingOpInterface>]> {
|
||||
@@ -55,9 +87,16 @@ def WasmSSA_BlockReturnOp : WasmSSA_Op<"block_return", [Terminator,
|
||||
::mlir::Block* getTarget();
|
||||
}];
|
||||
let description = [{
|
||||
Marks a return from the current block.
|
||||
Escape from the current nesting level and return the control flow to its successor.
|
||||
Optionally, mark the arguments that should be transfered to the successor block.
|
||||
|
||||
Example:
|
||||
This shouldn't be confused with branch operations that targets the label defined
|
||||
by the nesting level operation.
|
||||
|
||||
For instance, a `wasmssa.block_return` in a loop will give back control to the
|
||||
successor of the loop, where a `branch` targeting the loop will flow back to the entry block of the loop.
|
||||
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
wasmssa.block_return
|
||||
@@ -127,12 +166,18 @@ def WasmSSA_FuncOp : WasmSSA_Op<"func", [
|
||||
- Arguments of the entry block of type `!wasm<local T>`, with T the corresponding type
|
||||
in the function type.
|
||||
|
||||
By default, `wasmssa.func` have nested visibility. Functions exported by the module
|
||||
are marked with the exported attribute. This gives them public visibility.
|
||||
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
// A simple function with no arguments that returns a float32
|
||||
// Internal function with no arguments that returns a float32
|
||||
wasmssa.func @my_f32_func() -> f32
|
||||
|
||||
// Exported function with no arguments that returns a float32
|
||||
wasmssa.func exported @my_f32_func() -> f32
|
||||
|
||||
// A function that takes a local ref argument
|
||||
wasmssa.func @i64_wrap(%a: !wasmssa<local ref to i64>) -> i32
|
||||
```
|
||||
@@ -141,7 +186,7 @@ def WasmSSA_FuncOp : WasmSSA_Op<"func", [
|
||||
WasmSSA_FuncTypeAttr: $functionType,
|
||||
OptionalAttr<DictArrayAttr>:$arg_attrs,
|
||||
OptionalAttr<DictArrayAttr>:$res_attrs,
|
||||
DefaultValuedAttr<StrAttr, "\"nested\"">:$sym_visibility);
|
||||
UnitAttr: $exported);
|
||||
let regions = (region AnyRegion: $body);
|
||||
let extraClassDeclaration = [{
|
||||
|
||||
@@ -162,6 +207,12 @@ def WasmSSA_FuncOp : WasmSSA_Op<"func", [
|
||||
|
||||
/// Returns the result types of this function.
|
||||
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return getExported() ?
|
||||
::mlir::SymbolTable::Visibility::Public :
|
||||
::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
|
||||
let builders = [
|
||||
@@ -207,8 +258,7 @@ def WasmSSA_FuncImportOp : WasmSSA_Op<"import_func", [
|
||||
StrAttr: $importName,
|
||||
WasmSSA_FuncTypeAttr: $type,
|
||||
OptionalAttr<DictArrayAttr>:$arg_attrs,
|
||||
OptionalAttr<DictArrayAttr>:$res_attrs,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
OptionalAttr<DictArrayAttr>:$res_attrs);
|
||||
let extraClassDeclaration = [{
|
||||
bool isDeclaration() const { return true; }
|
||||
|
||||
@@ -221,6 +271,10 @@ def WasmSSA_FuncImportOp : WasmSSA_Op<"import_func", [
|
||||
::llvm::ArrayRef<Type> getResultTypes() {
|
||||
return getType().getResults();
|
||||
}
|
||||
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return ::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
let builders = [
|
||||
OpBuilder<(ins "StringRef":$symbol,
|
||||
@@ -238,30 +292,41 @@ def WasmSSA_GlobalOp : WasmSSA_Op<"global", [
|
||||
let arguments = (ins SymbolNameAttr: $sym_name,
|
||||
WasmSSA_ValTypeAttr: $type,
|
||||
UnitAttr: $isMutable,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
UnitAttr: $exported);
|
||||
let description = [{
|
||||
WebAssembly global variable.
|
||||
Body contains the initialization instructions for the variable value.
|
||||
The body must contain only instructions considered `const` in a webassembly context,
|
||||
such as `wasmssa.const` or `global.get`.
|
||||
|
||||
By default, `wasmssa.global` have nested visibility. Global exported by the module
|
||||
are marked with the exported attribute. This gives them public visibility.
|
||||
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
// Define a global_var, a mutable i32 global variable equal to 10.
|
||||
wasmssa.global @global_var i32 mutable nested : {
|
||||
// Define module_global_var, an internal mutable i32 global variable equal to 10.
|
||||
wasmssa.global @module_global_var i32 mutable : {
|
||||
%[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
wasmssa.return %[[VAL_0]] : i32
|
||||
}
|
||||
|
||||
// Define global_var, an exported constant i32 global variable equal to 42.
|
||||
wasmssa.global @global_var i32 : {
|
||||
%[[VAL_0:.*]] = wasmssa.const 42 : i32
|
||||
wasmssa.return %[[VAL_0]] : i32
|
||||
}
|
||||
```
|
||||
}];
|
||||
let regions = (region AnyRegion: $initializer);
|
||||
|
||||
let builders = [
|
||||
OpBuilder<(ins "StringRef":$symbol,
|
||||
"Type": $type,
|
||||
"bool": $isMutable)>
|
||||
];
|
||||
let extraClassDeclaration = [{
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return getExported() ?
|
||||
::mlir::SymbolTable::Visibility::Public :
|
||||
::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
let hasCustomAssemblyFormat = 1;
|
||||
}
|
||||
|
||||
@@ -283,18 +348,14 @@ def WasmSSA_GlobalImportOp : WasmSSA_Op<"import_global", [
|
||||
StrAttr: $moduleName,
|
||||
StrAttr: $importName,
|
||||
WasmSSA_ValTypeAttr: $type,
|
||||
UnitAttr: $isMutable,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
UnitAttr: $isMutable);
|
||||
let extraClassDeclaration = [{
|
||||
bool isDeclaration() const { return true; }
|
||||
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return ::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
let builders = [
|
||||
OpBuilder<(ins "StringRef":$symbol,
|
||||
"StringRef":$moduleName,
|
||||
"StringRef":$importName,
|
||||
"Type": $type,
|
||||
"bool": $isMutable)>
|
||||
];
|
||||
let hasCustomAssemblyFormat = 1;
|
||||
}
|
||||
|
||||
@@ -442,23 +503,33 @@ def WasmSSA_MemOp : WasmSSA_Op<"memory", [Symbol]> {
|
||||
Define a memory to be used by the program.
|
||||
Multiple memories can be defined in the same module.
|
||||
|
||||
By default, `wasmssa.memory` have nested visibility. Memory exported by
|
||||
the module are marked with the exported attribute. This gives them public
|
||||
visibility.
|
||||
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
// Define the `mem_0` memory with defined bounds of 0 -> 65536
|
||||
// Define the `mem_0` (internal) memory with defined size bounds of [0:65536]
|
||||
wasmssa.memory @mem_0 !wasmssa<limit[0:65536]>
|
||||
|
||||
// Define the `mem_1` exported memory with minimal size of 512
|
||||
wasmssa.memory exported @mem_1 !wasmssa<limit[512:]>
|
||||
```
|
||||
}];
|
||||
let arguments = (ins SymbolNameAttr: $sym_name,
|
||||
WasmSSA_LimitTypeAttr: $limits,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
let builders = [
|
||||
OpBuilder<(ins
|
||||
"::llvm::StringRef":$symbol,
|
||||
"wasmssa::LimitType":$limit)>
|
||||
];
|
||||
UnitAttr: $exported);
|
||||
|
||||
let assemblyFormat = "$sym_name custom<WasmVisibility>($sym_visibility) $limits attr-dict";
|
||||
let extraClassDeclaration = [{
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return getExported() ?
|
||||
::mlir::SymbolTable::Visibility::Public :
|
||||
::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
|
||||
let assemblyFormat = "(`exported` $exported^)? $sym_name $limits attr-dict";
|
||||
}
|
||||
|
||||
def WasmSSA_MemImportOp : WasmSSA_Op<"import_mem", [Symbol, ImportOpInterface]> {
|
||||
@@ -476,16 +547,13 @@ def WasmSSA_MemImportOp : WasmSSA_Op<"import_mem", [Symbol, ImportOpInterface]>
|
||||
let arguments = (ins SymbolNameAttr: $sym_name,
|
||||
StrAttr: $moduleName,
|
||||
StrAttr: $importName,
|
||||
WasmSSA_LimitTypeAttr: $limits,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
WasmSSA_LimitTypeAttr: $limits);
|
||||
let extraClassDeclaration = [{
|
||||
bool isDeclaration() const { return true; }
|
||||
bool isDeclaration() const { return true; }
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return ::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
let builders = [OpBuilder<(ins
|
||||
"::llvm::StringRef":$symbol,
|
||||
"::llvm::StringRef":$moduleName,
|
||||
"::llvm::StringRef":$importName,
|
||||
"wasmssa::LimitType":$limits)>];
|
||||
let assemblyFormat = "$importName `from` $moduleName `as` $sym_name attr-dict";
|
||||
}
|
||||
|
||||
@@ -493,11 +561,15 @@ def WasmSSA_TableOp : WasmSSA_Op<"table", [Symbol]> {
|
||||
let summary= "WebAssembly table value";
|
||||
let arguments = (ins SymbolNameAttr: $sym_name,
|
||||
WasmSSA_TableTypeAttr: $type,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
let builders = [OpBuilder<(ins
|
||||
"::llvm::StringRef":$symbol,
|
||||
"wasmssa::TableType":$type)>];
|
||||
let assemblyFormat = "$sym_name custom<WasmVisibility>($sym_visibility) $type attr-dict";
|
||||
UnitAttr: $exported);
|
||||
let extraClassDeclaration = [{
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return getExported() ?
|
||||
::mlir::SymbolTable::Visibility::Public :
|
||||
::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
let assemblyFormat = "(`exported` $exported^)? $sym_name $type attr-dict";
|
||||
}
|
||||
|
||||
def WasmSSA_TableImportOp : WasmSSA_Op<"import_table", [Symbol, ImportOpInterface]> {
|
||||
@@ -515,17 +587,14 @@ def WasmSSA_TableImportOp : WasmSSA_Op<"import_table", [Symbol, ImportOpInterfac
|
||||
let arguments = (ins SymbolNameAttr: $sym_name,
|
||||
StrAttr: $moduleName,
|
||||
StrAttr: $importName,
|
||||
WasmSSA_TableTypeAttr: $type,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
WasmSSA_TableTypeAttr: $type);
|
||||
let extraClassDeclaration = [{
|
||||
bool isDeclaration() const { return true; }
|
||||
::mlir::SymbolTable::Visibility getVisibility() {
|
||||
return ::mlir::SymbolTable::Visibility::Nested;
|
||||
};
|
||||
}];
|
||||
let assemblyFormat = "$importName `from` $moduleName `as` $sym_name attr-dict";
|
||||
let builders = [OpBuilder<(ins
|
||||
"::llvm::StringRef":$symbol,
|
||||
"::llvm::StringRef":$moduleName,
|
||||
"::llvm::StringRef":$importName,
|
||||
"wasmssa::TableType":$type)>];
|
||||
}
|
||||
|
||||
def WasmSSA_ReturnOp : WasmSSA_Op<"return", [Terminator]> {
|
||||
|
||||
@@ -19,6 +19,14 @@ namespace mlir {
|
||||
struct WasmBinaryEncoding {
|
||||
/// Byte encodings for Wasm instructions.
|
||||
struct OpCode {
|
||||
// Control instructions.
|
||||
static constexpr std::byte block{0x02};
|
||||
static constexpr std::byte loop{0x03};
|
||||
static constexpr std::byte ifOpCode{0x04};
|
||||
static constexpr std::byte elseOpCode{0x05};
|
||||
static constexpr std::byte branchIf{0x0D};
|
||||
static constexpr std::byte call{0x10};
|
||||
|
||||
// Locals, globals, constants.
|
||||
static constexpr std::byte localGet{0x20};
|
||||
static constexpr std::byte localSet{0x21};
|
||||
@@ -29,6 +37,42 @@ struct WasmBinaryEncoding {
|
||||
static constexpr std::byte constFP32{0x43};
|
||||
static constexpr std::byte constFP64{0x44};
|
||||
|
||||
// Comparisons.
|
||||
static constexpr std::byte eqzI32{0x45};
|
||||
static constexpr std::byte eqI32{0x46};
|
||||
static constexpr std::byte neI32{0x47};
|
||||
static constexpr std::byte ltSI32{0x48};
|
||||
static constexpr std::byte ltUI32{0x49};
|
||||
static constexpr std::byte gtSI32{0x4A};
|
||||
static constexpr std::byte gtUI32{0x4B};
|
||||
static constexpr std::byte leSI32{0x4C};
|
||||
static constexpr std::byte leUI32{0x4D};
|
||||
static constexpr std::byte geSI32{0x4E};
|
||||
static constexpr std::byte geUI32{0x4F};
|
||||
static constexpr std::byte eqzI64{0x50};
|
||||
static constexpr std::byte eqI64{0x51};
|
||||
static constexpr std::byte neI64{0x52};
|
||||
static constexpr std::byte ltSI64{0x53};
|
||||
static constexpr std::byte ltUI64{0x54};
|
||||
static constexpr std::byte gtSI64{0x55};
|
||||
static constexpr std::byte gtUI64{0x56};
|
||||
static constexpr std::byte leSI64{0x57};
|
||||
static constexpr std::byte leUI64{0x58};
|
||||
static constexpr std::byte geSI64{0x59};
|
||||
static constexpr std::byte geUI64{0x5A};
|
||||
static constexpr std::byte eqF32{0x5B};
|
||||
static constexpr std::byte neF32{0x5C};
|
||||
static constexpr std::byte ltF32{0x5D};
|
||||
static constexpr std::byte gtF32{0x5E};
|
||||
static constexpr std::byte leF32{0x5F};
|
||||
static constexpr std::byte geF32{0x60};
|
||||
static constexpr std::byte eqF64{0x61};
|
||||
static constexpr std::byte neF64{0x62};
|
||||
static constexpr std::byte ltF64{0x63};
|
||||
static constexpr std::byte gtF64{0x64};
|
||||
static constexpr std::byte leF64{0x65};
|
||||
static constexpr std::byte geF64{0x66};
|
||||
|
||||
// Numeric operations.
|
||||
static constexpr std::byte clzI32{0x67};
|
||||
static constexpr std::byte ctzI32{0x68};
|
||||
@@ -93,6 +137,33 @@ struct WasmBinaryEncoding {
|
||||
static constexpr std::byte maxF64{0xA5};
|
||||
static constexpr std::byte copysignF64{0xA6};
|
||||
static constexpr std::byte wrap{0xA7};
|
||||
|
||||
// Conversion operations
|
||||
static constexpr std::byte extendS{0xAC};
|
||||
static constexpr std::byte extendU{0xAD};
|
||||
static constexpr std::byte convertSI32F32{0xB2};
|
||||
static constexpr std::byte convertUI32F32{0xB3};
|
||||
static constexpr std::byte convertSI64F32{0xB4};
|
||||
static constexpr std::byte convertUI64F32{0xB5};
|
||||
|
||||
static constexpr std::byte demoteF64ToF32{0xB6};
|
||||
|
||||
static constexpr std::byte convertSI32F64{0xB7};
|
||||
static constexpr std::byte convertUI32F64{0xB8};
|
||||
static constexpr std::byte convertSI64F64{0xB9};
|
||||
static constexpr std::byte convertUI64F64{0xBA};
|
||||
|
||||
static constexpr std::byte promoteF32ToF64{0xBB};
|
||||
static constexpr std::byte reinterpretF32AsI32{0xBC};
|
||||
static constexpr std::byte reinterpretF64AsI64{0xBD};
|
||||
static constexpr std::byte reinterpretI32AsF32{0xBE};
|
||||
static constexpr std::byte reinterpretI64AsF64{0xBF};
|
||||
|
||||
static constexpr std::byte extendI328S{0xC0};
|
||||
static constexpr std::byte extendI3216S{0xC1};
|
||||
static constexpr std::byte extendI648S{0xC2};
|
||||
static constexpr std::byte extendI6416S{0xC3};
|
||||
static constexpr std::byte extendI6432S{0xC4};
|
||||
};
|
||||
|
||||
/// Byte encodings of types in Wasm binaries
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "mlir/IR/Attributes.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/BuiltinAttributes.h"
|
||||
#include "mlir/IR/Diagnostics.h"
|
||||
#include "mlir/IR/Dialect.h"
|
||||
#include "mlir/IR/Region.h"
|
||||
#include "mlir/IR/SymbolTable.h"
|
||||
@@ -39,28 +40,6 @@ void printElseRegion(OpAsmPrinter &opPrinter, Operation *op,
|
||||
opPrinter.printKeywordOrString("else ");
|
||||
opPrinter.printRegion(elseRegion);
|
||||
}
|
||||
|
||||
ParseResult parseWasmVisibility(OpAsmParser &opParser, StringAttr &visibility) {
|
||||
std::string keyword;
|
||||
auto initLocation = opParser.getCurrentLocation();
|
||||
std::ignore = opParser.parseOptionalKeywordOrString(&keyword);
|
||||
if (keyword == "nested" or keyword == "") {
|
||||
visibility = StringAttr::get(opParser.getContext(), "nested");
|
||||
return ParseResult::success();
|
||||
}
|
||||
|
||||
if (keyword == "public" || keyword == "private") {
|
||||
visibility = StringAttr::get(opParser.getContext(), keyword);
|
||||
return ParseResult::success();
|
||||
}
|
||||
opParser.emitError(initLocation, "expecting symbol visibility");
|
||||
return ParseResult::failure();
|
||||
}
|
||||
|
||||
void printWasmVisibility(OpAsmPrinter &opPrinter, Operation *op,
|
||||
Attribute visibility) {
|
||||
opPrinter.printKeywordOrString(cast<StringAttr>(visibility).strref());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#define GET_OP_CLASSES
|
||||
@@ -167,10 +146,23 @@ Block *FuncOp::addEntryBlock() {
|
||||
|
||||
void FuncOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, FunctionType funcType) {
|
||||
FuncOp::build(odsBuilder, odsState, symbol, funcType, {}, {}, "nested");
|
||||
FuncOp::build(odsBuilder, odsState, symbol, funcType, {}, {});
|
||||
}
|
||||
|
||||
ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
auto *ctx = parser.getContext();
|
||||
std::string visibilityString;
|
||||
auto loc = parser.getNameLoc();
|
||||
ParseResult res = parser.parseOptionalKeywordOrString(&visibilityString);
|
||||
bool exported{false};
|
||||
if (res.succeeded()) {
|
||||
if (visibilityString != "exported")
|
||||
return parser.emitError(
|
||||
loc, "expecting either `exported` or symbol name. got ")
|
||||
<< visibilityString;
|
||||
exported = true;
|
||||
}
|
||||
|
||||
auto buildFuncType = [&parser](Builder &builder, ArrayRef<Type> argTypes,
|
||||
ArrayRef<Type> results,
|
||||
function_interface_impl::VariadicFlag,
|
||||
@@ -191,11 +183,13 @@ ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
|
||||
return builder.getFunctionType(argTypesWithoutLocal, results);
|
||||
};
|
||||
|
||||
return function_interface_impl::parseFunctionOp(
|
||||
auto funcParseRes = function_interface_impl::parseFunctionOp(
|
||||
parser, result, /*allowVariadic=*/false,
|
||||
getFunctionTypeAttrName(result.name), buildFuncType,
|
||||
getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));
|
||||
if (exported)
|
||||
result.addAttribute(getExportedAttrName(result.name), UnitAttr::get(ctx));
|
||||
return funcParseRes;
|
||||
}
|
||||
|
||||
LogicalResult FuncOp::verifyBody() {
|
||||
@@ -224,9 +218,18 @@ LogicalResult FuncOp::verifyBody() {
|
||||
}
|
||||
|
||||
void FuncOp::print(OpAsmPrinter &p) {
|
||||
/// If exported, print it before and mask it before printing
|
||||
/// using generic interface.
|
||||
auto exported = getExported();
|
||||
if (exported) {
|
||||
p << " exported";
|
||||
removeExportedAttr();
|
||||
}
|
||||
function_interface_impl::printFunctionOp(
|
||||
p, *this, /*isVariadic=*/false, getFunctionTypeAttrName(),
|
||||
getArgAttrsAttrName(), getResAttrsAttrName());
|
||||
if (exported)
|
||||
setExported(true);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -237,38 +240,37 @@ void FuncImportOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, StringRef moduleName,
|
||||
StringRef importName, FunctionType type) {
|
||||
FuncImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
|
||||
type, {}, {}, odsBuilder.getStringAttr("nested"));
|
||||
type, {}, {});
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GlobalOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, Type type, bool isMutable) {
|
||||
GlobalOp::build(odsBuilder, odsState, symbol, type, isMutable,
|
||||
odsBuilder.getStringAttr("nested"));
|
||||
}
|
||||
|
||||
// Custom formats
|
||||
ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
StringAttr symbolName;
|
||||
Type globalType;
|
||||
auto *ctx = parser.getContext();
|
||||
ParseResult res = parser.parseSymbolName(
|
||||
symbolName, SymbolTable::getSymbolAttrName(), result.attributes);
|
||||
std::string visibilityString;
|
||||
auto loc = parser.getNameLoc();
|
||||
ParseResult res = parser.parseOptionalKeywordOrString(&visibilityString);
|
||||
if (res.succeeded()) {
|
||||
if (visibilityString != "exported")
|
||||
return parser.emitError(
|
||||
loc, "expecting either `exported` or symbol name. got ")
|
||||
<< visibilityString;
|
||||
result.addAttribute(getExportedAttrName(result.name), UnitAttr::get(ctx));
|
||||
}
|
||||
|
||||
res = parser.parseSymbolName(symbolName, SymbolTable::getSymbolAttrName(),
|
||||
result.attributes);
|
||||
res = parser.parseType(globalType);
|
||||
result.addAttribute(getTypeAttrName(result.name), TypeAttr::get(globalType));
|
||||
std::string mutableString;
|
||||
res = parser.parseOptionalKeywordOrString(&mutableString);
|
||||
if (res.succeeded() && mutableString == "mutable")
|
||||
result.addAttribute("isMutable", UnitAttr::get(ctx));
|
||||
std::string visibilityString;
|
||||
res = parser.parseOptionalKeywordOrString(&visibilityString);
|
||||
if (res.succeeded())
|
||||
result.addAttribute("sym_visibility",
|
||||
StringAttr::get(ctx, visibilityString));
|
||||
|
||||
res = parser.parseColon();
|
||||
Region *globalInitRegion = result.addRegion();
|
||||
res = parser.parseRegion(*globalInitRegion);
|
||||
@@ -276,11 +278,11 @@ ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
}
|
||||
|
||||
void GlobalOp::print(OpAsmPrinter &printer) {
|
||||
if (getExported())
|
||||
printer << " exported";
|
||||
printer << " @" << getSymName().str() << " " << getType();
|
||||
if (getIsMutable())
|
||||
printer << " mutable";
|
||||
if (auto vis = getSymVisibility())
|
||||
printer << " " << *vis;
|
||||
printer << " :";
|
||||
Region &body = getRegion();
|
||||
if (!body.empty()) {
|
||||
@@ -319,13 +321,6 @@ GlobalGetOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
|
||||
// GlobalImportOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void GlobalImportOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, StringRef moduleName,
|
||||
StringRef importName, Type type, bool isMutable) {
|
||||
GlobalImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
|
||||
type, isMutable, odsBuilder.getStringAttr("nested"));
|
||||
}
|
||||
|
||||
ParseResult GlobalImportOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
auto *ctx = parser.getContext();
|
||||
ParseResult res = parseImportOp(parser, result);
|
||||
@@ -335,12 +330,8 @@ ParseResult GlobalImportOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
res = parser.parseOptionalKeywordOrString(&mutableOrSymVisString);
|
||||
if (res.succeeded() && mutableOrSymVisString == "mutable") {
|
||||
result.addAttribute("isMutable", UnitAttr::get(ctx));
|
||||
res = parser.parseOptionalKeywordOrString(&mutableOrSymVisString);
|
||||
}
|
||||
|
||||
if (res.succeeded())
|
||||
result.addAttribute("sym_visibility",
|
||||
StringAttr::get(ctx, mutableOrSymVisString));
|
||||
res = parser.parseColon();
|
||||
|
||||
Type importedType;
|
||||
@@ -356,8 +347,6 @@ void GlobalImportOp::print(OpAsmPrinter &printer) {
|
||||
<< "\" as @" << getSymName();
|
||||
if (getIsMutable())
|
||||
printer << " mutable";
|
||||
if (auto vis = getSymVisibility())
|
||||
printer << " " << *vis;
|
||||
printer << " : " << getType();
|
||||
}
|
||||
|
||||
@@ -430,27 +419,6 @@ LogicalResult LocalTeeOp::verify() {
|
||||
|
||||
Block *LoopOp::getLabelTarget() { return &getBody().front(); }
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MemOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void MemOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, LimitType limit) {
|
||||
MemOp::build(odsBuilder, odsState, symbol, limit,
|
||||
odsBuilder.getStringAttr("nested"));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MemImportOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void MemImportOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, StringRef moduleName,
|
||||
StringRef importName, LimitType limits) {
|
||||
MemImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
|
||||
limits, odsBuilder.getStringAttr("nested"));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ReinterpretOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -471,24 +439,3 @@ LogicalResult ReinterpretOp::verify() {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ReturnOp::build(OpBuilder &odsBuilder, OperationState &odsState) {}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TableOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void TableOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, TableType type) {
|
||||
TableOp::build(odsBuilder, odsState, symbol, type,
|
||||
odsBuilder.getStringAttr("nested"));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TableImportOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void TableImportOp::build(OpBuilder &odsBuilder, OperationState &odsState,
|
||||
StringRef symbol, StringRef moduleName,
|
||||
StringRef importName, TableType type) {
|
||||
TableImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
|
||||
type, odsBuilder.getStringAttr("nested"));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "mlir/IR/Attributes.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/BuiltinAttributeInterfaces.h"
|
||||
#include "mlir/IR/BuiltinAttributes.h"
|
||||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/Location.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
@@ -138,6 +139,10 @@ using ImportDesc =
|
||||
|
||||
using parsed_inst_t = FailureOr<SmallVector<Value>>;
|
||||
|
||||
struct EmptyBlockMarker {};
|
||||
using BlockTypeParseResult =
|
||||
std::variant<EmptyBlockMarker, TypeIdxRecord, Type>;
|
||||
|
||||
struct WasmModuleSymbolTables {
|
||||
SmallVector<FunctionSymbolRefContainer> funcSymbols;
|
||||
SmallVector<GlobalSymbolRefContainer> globalSymbols;
|
||||
@@ -175,6 +180,9 @@ class ParserHead;
|
||||
/// Wrapper around SmallVector to only allow access as push and pop on the
|
||||
/// stack. Makes sure that there are no "free accesses" on the stack to preserve
|
||||
/// its state.
|
||||
/// This class also keep tracks of the Wasm labels defined by different ops,
|
||||
/// which can be targeted by control flow ops. This can be modeled as part of
|
||||
/// the Value Stack as Wasm control flow ops can only target enclosing labels.
|
||||
class ValueStack {
|
||||
private:
|
||||
struct LabelLevel {
|
||||
@@ -206,6 +214,16 @@ public:
|
||||
/// if an error occurs.
|
||||
LogicalResult pushResults(ValueRange results, Location *opLoc);
|
||||
|
||||
void addLabelLevel(LabelLevelOpInterface levelOp) {
|
||||
labelLevel.push_back({values.size(), levelOp});
|
||||
LDBG() << "Adding a new frame context to ValueStack";
|
||||
}
|
||||
|
||||
void dropLabelLevel() {
|
||||
assert(!labelLevel.empty() && "Trying to drop a frame from empty context");
|
||||
auto newSize = labelLevel.pop_back_val().stackIdx;
|
||||
values.truncate(newSize);
|
||||
}
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
/// A simple dump function for debugging.
|
||||
/// Writes output to llvm::dbgs().
|
||||
@@ -214,6 +232,7 @@ public:
|
||||
|
||||
private:
|
||||
SmallVector<Value> values;
|
||||
SmallVector<LabelLevel> labelLevel;
|
||||
};
|
||||
|
||||
using local_val_t = TypedValue<wasmssa::LocalRefType>;
|
||||
@@ -248,6 +267,19 @@ private:
|
||||
buildNumericOp(OpBuilder &builder,
|
||||
std::enable_if_t<std::is_arithmetic_v<valueType>> * = nullptr);
|
||||
|
||||
/// Construct a conversion operation of type \p opType that takes a value from
|
||||
/// type \p inputType on the stack and will produce a value of type
|
||||
/// \p outputType.
|
||||
///
|
||||
/// \p opType - The WASM dialect operation to build.
|
||||
/// \p inputType - The operand type for the built instruction.
|
||||
/// \p outputType - The result type for the built instruction.
|
||||
///
|
||||
/// \returns The parsed instruction result, or failure.
|
||||
template <typename opType, typename inputType, typename outputType,
|
||||
typename... extraArgsT>
|
||||
inline parsed_inst_t buildConvertOp(OpBuilder &builder, extraArgsT...);
|
||||
|
||||
/// This function generates a dispatch tree to associate an opcode with a
|
||||
/// parser. Parsers are registered by specialising the
|
||||
/// `parseSpecificInstruction` function for the op code to handle.
|
||||
@@ -280,11 +312,105 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// RAII guard class for creating a nesting level
|
||||
///
|
||||
struct NestingContextGuard {
|
||||
NestingContextGuard(ExpressionParser &parser, LabelLevelOpInterface levelOp)
|
||||
: parser{parser} {
|
||||
parser.addNestingContextLevel(levelOp);
|
||||
}
|
||||
NestingContextGuard(NestingContextGuard &&other) : parser{other.parser} {
|
||||
other.shouldDropOnDestruct = false;
|
||||
}
|
||||
NestingContextGuard(NestingContextGuard const &) = delete;
|
||||
~NestingContextGuard() {
|
||||
if (shouldDropOnDestruct)
|
||||
parser.dropNestingContextLevel();
|
||||
}
|
||||
ExpressionParser &parser;
|
||||
bool shouldDropOnDestruct = true;
|
||||
};
|
||||
|
||||
void addNestingContextLevel(LabelLevelOpInterface levelOp) {
|
||||
valueStack.addLabelLevel(levelOp);
|
||||
}
|
||||
|
||||
void dropNestingContextLevel() {
|
||||
// Should always succeed as we are droping the frame that was previously
|
||||
// created.
|
||||
valueStack.dropLabelLevel();
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType> getFuncTypeFor(OpBuilder &builder,
|
||||
EmptyBlockMarker) {
|
||||
return builder.getFunctionType({}, {});
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType> getFuncTypeFor(OpBuilder &builder,
|
||||
TypeIdxRecord type) {
|
||||
if (type.id >= symbols.moduleFuncTypes.size())
|
||||
return emitError(*currentOpLoc,
|
||||
"type index references nonexistent type (")
|
||||
<< type.id << "). Only " << symbols.moduleFuncTypes.size()
|
||||
<< " types are registered";
|
||||
return symbols.moduleFuncTypes[type.id];
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType> getFuncTypeFor(OpBuilder &builder,
|
||||
Type valType) {
|
||||
return builder.getFunctionType({}, {valType});
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType>
|
||||
getFuncTypeFor(OpBuilder &builder, BlockTypeParseResult parseResult) {
|
||||
return std::visit(
|
||||
[this, &builder](auto value) { return getFuncTypeFor(builder, value); },
|
||||
parseResult);
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType>
|
||||
getFuncTypeFor(OpBuilder &builder,
|
||||
llvm::FailureOr<BlockTypeParseResult> parseResult) {
|
||||
if (llvm::failed(parseResult))
|
||||
return failure();
|
||||
return getFuncTypeFor(builder, *parseResult);
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType> parseBlockFuncType(OpBuilder &builder);
|
||||
|
||||
struct ParseResultWithInfo {
|
||||
SmallVector<Value> opResults;
|
||||
std::byte endingByte;
|
||||
};
|
||||
|
||||
template <typename FilterT = ByteSequence<WasmBinaryEncoding::endByte>>
|
||||
/// @param blockToFill: the block which content will be populated
|
||||
/// @param resType: the type that this block is supposed to return
|
||||
llvm::FailureOr<std::byte>
|
||||
parseBlockContent(OpBuilder &builder, Block *blockToFill, TypeRange resTypes,
|
||||
Location opLoc, LabelLevelOpInterface levelOp,
|
||||
FilterT parseEndBytes = {}) {
|
||||
OpBuilder::InsertionGuard guard{builder};
|
||||
builder.setInsertionPointToStart(blockToFill);
|
||||
LDBG() << "parsing a block of type "
|
||||
<< builder.getFunctionType(blockToFill->getArgumentTypes(),
|
||||
resTypes);
|
||||
auto nC = addNesting(levelOp);
|
||||
|
||||
if (failed(pushResults(blockToFill->getArguments())))
|
||||
return failure();
|
||||
auto bodyParsingRes = parse(builder, parseEndBytes);
|
||||
if (failed(bodyParsingRes))
|
||||
return failure();
|
||||
auto returnOperands = popOperands(resTypes);
|
||||
if (failed(returnOperands))
|
||||
return failure();
|
||||
builder.create<BlockReturnOp>(opLoc, *returnOperands);
|
||||
LDBG() << "end of parsing of a block";
|
||||
return bodyParsingRes->endingByte;
|
||||
}
|
||||
|
||||
public:
|
||||
template <std::byte ParseEndByte = WasmBinaryEncoding::endByte>
|
||||
parsed_inst_t parse(OpBuilder &builder, UniqueByte<ParseEndByte> = {});
|
||||
@@ -294,7 +420,11 @@ public:
|
||||
parse(OpBuilder &builder,
|
||||
ByteSequence<ExpressionParseEnd...> parsingEndFilters);
|
||||
|
||||
FailureOr<SmallVector<Value>> popOperands(TypeRange operandTypes) {
|
||||
NestingContextGuard addNesting(LabelLevelOpInterface levelOp) {
|
||||
return NestingContextGuard{*this, levelOp};
|
||||
}
|
||||
|
||||
FailureOr<llvm::SmallVector<Value>> popOperands(TypeRange operandTypes) {
|
||||
return valueStack.popOperands(operandTypes, ¤tOpLoc.value());
|
||||
}
|
||||
|
||||
@@ -308,6 +438,12 @@ public:
|
||||
template <typename OpToCreate>
|
||||
parsed_inst_t parseSetOrTee(OpBuilder &);
|
||||
|
||||
/// Blocks and Loops have a similar format and differ only in how their exit
|
||||
/// is handled which doesn´t matter at parsing time. Factorizes in one
|
||||
/// function.
|
||||
template <typename OpToCreate>
|
||||
parsed_inst_t parseBlockLikeOp(OpBuilder &);
|
||||
|
||||
private:
|
||||
std::optional<Location> currentOpLoc;
|
||||
ParserHead &parser;
|
||||
@@ -586,6 +722,29 @@ public:
|
||||
return success();
|
||||
}
|
||||
|
||||
llvm::FailureOr<BlockTypeParseResult> parseBlockType(MLIRContext *ctx) {
|
||||
auto loc = getLocation();
|
||||
auto blockIndicator = peek();
|
||||
if (failed(blockIndicator))
|
||||
return failure();
|
||||
if (*blockIndicator == WasmBinaryEncoding::Type::emptyBlockType) {
|
||||
offset += 1;
|
||||
return {EmptyBlockMarker{}};
|
||||
}
|
||||
if (isValueOneOf(*blockIndicator, valueTypesEncodings))
|
||||
return parseValueType(ctx);
|
||||
/// Block type idx is a 32 bit positive integer encoded as a 33 bit signed
|
||||
/// value
|
||||
auto typeIdx = parseI64();
|
||||
if (failed(typeIdx))
|
||||
return failure();
|
||||
if (*typeIdx < 0 || *typeIdx > std::numeric_limits<uint32_t>::max())
|
||||
return emitError(loc, "type ID should be representable with an unsigned "
|
||||
"32 bits integer. Got ")
|
||||
<< *typeIdx;
|
||||
return {TypeIdxRecord{static_cast<uint32_t>(*typeIdx)}};
|
||||
}
|
||||
|
||||
bool end() const { return curHead().empty(); }
|
||||
|
||||
ParserHead copy() const { return *this; }
|
||||
@@ -701,17 +860,41 @@ inline parsed_inst_t ExpressionParser::parseSpecificInstruction(OpBuilder &) {
|
||||
void ValueStack::dump() const {
|
||||
llvm::dbgs() << "================= Wasm ValueStack =======================\n";
|
||||
llvm::dbgs() << "size: " << size() << "\n";
|
||||
llvm::dbgs() << "nbFrames: " << labelLevel.size() << '\n';
|
||||
llvm::dbgs() << "<Top>"
|
||||
<< "\n";
|
||||
// Stack is pushed to via push_back. Therefore the top of the stack is the
|
||||
// end of the vector. Iterate in reverse so that the first thing we print
|
||||
// is the top of the stack.
|
||||
auto indexGetter = [this]() {
|
||||
size_t idx = labelLevel.size();
|
||||
return [this, idx]() mutable -> std::optional<std::pair<size_t, size_t>> {
|
||||
llvm::dbgs() << "IDX: " << idx << '\n';
|
||||
if (idx == 0)
|
||||
return std::nullopt;
|
||||
auto frameId = idx - 1;
|
||||
auto frameLimit = labelLevel[frameId].stackIdx;
|
||||
idx -= 1;
|
||||
return {{frameId, frameLimit}};
|
||||
};
|
||||
};
|
||||
auto getNextFrameIndex = indexGetter();
|
||||
auto nextFrameIdx = getNextFrameIndex();
|
||||
size_t stackSize = size();
|
||||
for (size_t idx = 0; idx < stackSize; idx++) {
|
||||
for (size_t idx = 0; idx < stackSize; ++idx) {
|
||||
size_t actualIdx = stackSize - 1 - idx;
|
||||
while (nextFrameIdx && (nextFrameIdx->second > actualIdx)) {
|
||||
llvm::dbgs() << " --------------- Frame (" << nextFrameIdx->first
|
||||
<< ")\n";
|
||||
nextFrameIdx = getNextFrameIndex();
|
||||
}
|
||||
llvm::dbgs() << " ";
|
||||
values[actualIdx].dump();
|
||||
}
|
||||
while (nextFrameIdx) {
|
||||
llvm::dbgs() << " --------------- Frame (" << nextFrameIdx->first << ")\n";
|
||||
nextFrameIdx = getNextFrameIndex();
|
||||
}
|
||||
llvm::dbgs() << "<Bottom>"
|
||||
<< "\n";
|
||||
llvm::dbgs() << "=========================================================\n";
|
||||
@@ -726,7 +909,7 @@ parsed_inst_t ValueStack::popOperands(TypeRange operandTypes, Location *opLoc) {
|
||||
return emitError(*opLoc,
|
||||
"stack doesn't contain enough values. trying to get ")
|
||||
<< operandTypes.size() << " operands on a stack containing only "
|
||||
<< values.size() << " values.";
|
||||
<< values.size() << " values";
|
||||
size_t stackIdxOffset = values.size() - operandTypes.size();
|
||||
SmallVector<Value> res{};
|
||||
res.reserve(operandTypes.size());
|
||||
@@ -735,8 +918,7 @@ parsed_inst_t ValueStack::popOperands(TypeRange operandTypes, Location *opLoc) {
|
||||
Type stackType = operand.getType();
|
||||
if (stackType != operandTypes[i])
|
||||
return emitError(*opLoc, "invalid operand type on stack. expecting ")
|
||||
<< operandTypes[i] << ", value on stack is of type " << stackType
|
||||
<< ".";
|
||||
<< operandTypes[i] << ", value on stack is of type " << stackType;
|
||||
LDBG() << " POP: " << operand;
|
||||
res.push_back(operand);
|
||||
}
|
||||
@@ -792,6 +974,151 @@ ExpressionParser::parse(OpBuilder &builder,
|
||||
}
|
||||
}
|
||||
|
||||
llvm::FailureOr<FunctionType>
|
||||
ExpressionParser::parseBlockFuncType(OpBuilder &builder) {
|
||||
return getFuncTypeFor(builder, parser.parseBlockType(builder.getContext()));
|
||||
}
|
||||
|
||||
template <typename OpToCreate>
|
||||
parsed_inst_t ExpressionParser::parseBlockLikeOp(OpBuilder &builder) {
|
||||
auto opLoc = currentOpLoc;
|
||||
auto funcType = parseBlockFuncType(builder);
|
||||
if (failed(funcType))
|
||||
return failure();
|
||||
|
||||
auto inputTypes = funcType->getInputs();
|
||||
auto inputOps = popOperands(inputTypes);
|
||||
if (failed(inputOps))
|
||||
return failure();
|
||||
|
||||
Block *curBlock = builder.getBlock();
|
||||
Region *curRegion = curBlock->getParent();
|
||||
auto resTypes = funcType->getResults();
|
||||
llvm::SmallVector<Location> locations{};
|
||||
locations.resize(resTypes.size(), *currentOpLoc);
|
||||
auto *successor =
|
||||
builder.createBlock(curRegion, curRegion->end(), resTypes, locations);
|
||||
builder.setInsertionPointToEnd(curBlock);
|
||||
auto blockOp =
|
||||
builder.create<OpToCreate>(*currentOpLoc, *inputOps, successor);
|
||||
auto *blockBody = blockOp.createBlock();
|
||||
if (failed(parseBlockContent(builder, blockBody, resTypes, *opLoc, blockOp)))
|
||||
return failure();
|
||||
builder.setInsertionPointToStart(successor);
|
||||
return {ValueRange{successor->getArguments()}};
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t
|
||||
ExpressionParser::parseSpecificInstruction<WasmBinaryEncoding::OpCode::block>(
|
||||
OpBuilder &builder) {
|
||||
return parseBlockLikeOp<BlockOp>(builder);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t
|
||||
ExpressionParser::parseSpecificInstruction<WasmBinaryEncoding::OpCode::loop>(
|
||||
OpBuilder &builder) {
|
||||
return parseBlockLikeOp<LoopOp>(builder);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
|
||||
WasmBinaryEncoding::OpCode::ifOpCode>(OpBuilder &builder) {
|
||||
auto opLoc = currentOpLoc;
|
||||
auto funcType = parseBlockFuncType(builder);
|
||||
if (failed(funcType))
|
||||
return failure();
|
||||
|
||||
LDBG() << "Parsing an if instruction of type " << *funcType;
|
||||
auto inputTypes = funcType->getInputs();
|
||||
auto conditionValue = popOperands(builder.getI32Type());
|
||||
if (failed(conditionValue))
|
||||
return failure();
|
||||
auto inputOps = popOperands(inputTypes);
|
||||
if (failed(inputOps))
|
||||
return failure();
|
||||
|
||||
Block *curBlock = builder.getBlock();
|
||||
Region *curRegion = curBlock->getParent();
|
||||
auto resTypes = funcType->getResults();
|
||||
llvm::SmallVector<Location> locations{};
|
||||
locations.resize(resTypes.size(), *currentOpLoc);
|
||||
auto *successor =
|
||||
builder.createBlock(curRegion, curRegion->end(), resTypes, locations);
|
||||
builder.setInsertionPointToEnd(curBlock);
|
||||
auto ifOp = builder.create<IfOp>(*currentOpLoc, conditionValue->front(),
|
||||
*inputOps, successor);
|
||||
auto *ifEntryBlock = ifOp.createIfBlock();
|
||||
constexpr auto ifElseFilter =
|
||||
ByteSequence<WasmBinaryEncoding::endByte,
|
||||
WasmBinaryEncoding::OpCode::elseOpCode>{};
|
||||
auto parseIfRes = parseBlockContent(builder, ifEntryBlock, resTypes, *opLoc,
|
||||
ifOp, ifElseFilter);
|
||||
if (failed(parseIfRes))
|
||||
return failure();
|
||||
if (*parseIfRes == WasmBinaryEncoding::OpCode::elseOpCode) {
|
||||
LDBG() << " else block is present.";
|
||||
Block *elseEntryBlock = ifOp.createElseBlock();
|
||||
auto parseElseRes =
|
||||
parseBlockContent(builder, elseEntryBlock, resTypes, *opLoc, ifOp);
|
||||
if (failed(parseElseRes))
|
||||
return failure();
|
||||
}
|
||||
builder.setInsertionPointToStart(successor);
|
||||
return {ValueRange{successor->getArguments()}};
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
|
||||
WasmBinaryEncoding::OpCode::branchIf>(OpBuilder &builder) {
|
||||
auto level = parser.parseLiteral<uint32_t>();
|
||||
if (failed(level))
|
||||
return failure();
|
||||
Block *curBlock = builder.getBlock();
|
||||
Region *curRegion = curBlock->getParent();
|
||||
auto sip = builder.saveInsertionPoint();
|
||||
Block *elseBlock = builder.createBlock(curRegion, curRegion->end());
|
||||
auto condition = popOperands(builder.getI32Type());
|
||||
if (failed(condition))
|
||||
return failure();
|
||||
builder.restoreInsertionPoint(sip);
|
||||
auto targetOp =
|
||||
LabelBranchingOpInterface::getTargetOpFromBlock(curBlock, *level);
|
||||
if (failed(targetOp))
|
||||
return failure();
|
||||
auto inputTypes = targetOp->getLabelTarget()->getArgumentTypes();
|
||||
auto branchArgs = popOperands(inputTypes);
|
||||
if (failed(branchArgs))
|
||||
return failure();
|
||||
builder.create<BranchIfOp>(*currentOpLoc, condition->front(),
|
||||
builder.getUI32IntegerAttr(*level), *branchArgs,
|
||||
elseBlock);
|
||||
builder.setInsertionPointToStart(elseBlock);
|
||||
return {*branchArgs};
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t
|
||||
ExpressionParser::parseSpecificInstruction<WasmBinaryEncoding::OpCode::call>(
|
||||
OpBuilder &builder) {
|
||||
auto loc = *currentOpLoc;
|
||||
auto funcIdx = parser.parseLiteral<uint32_t>();
|
||||
if (failed(funcIdx))
|
||||
return failure();
|
||||
if (*funcIdx >= symbols.funcSymbols.size())
|
||||
return emitError(loc, "Invalid function index: ") << *funcIdx;
|
||||
auto callee = symbols.funcSymbols[*funcIdx];
|
||||
llvm::ArrayRef<Type> inTypes = callee.functionType.getInputs();
|
||||
llvm::ArrayRef<Type> resTypes = callee.functionType.getResults();
|
||||
parsed_inst_t inOperands = popOperands(inTypes);
|
||||
if (failed(inOperands))
|
||||
return failure();
|
||||
auto callOp =
|
||||
builder.create<FuncCallOp>(loc, resTypes, callee.symbol, *inOperands);
|
||||
return {callOp.getResults()};
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
|
||||
WasmBinaryEncoding::OpCode::localGet>(OpBuilder &builder) {
|
||||
@@ -834,7 +1161,7 @@ parsed_inst_t ExpressionParser::parseSetOrTee(OpBuilder &builder) {
|
||||
if (valueStack.empty())
|
||||
return emitError(
|
||||
*currentOpLoc,
|
||||
"invalid stack access, trying to access a value on an empty stack.");
|
||||
"invalid stack access, trying to access a value on an empty stack");
|
||||
|
||||
parsed_inst_t poppedOp = popOperands(locals[*id].getType().getElementType());
|
||||
if (failed(poppedOp))
|
||||
@@ -1000,11 +1327,23 @@ inline parsed_inst_t ExpressionParser::buildNumericOp(
|
||||
|
||||
BUILD_NUMERIC_BINOP_FP(CopySignOp, copysign)
|
||||
BUILD_NUMERIC_BINOP_FP(DivOp, div)
|
||||
BUILD_NUMERIC_BINOP_FP(GeOp, ge)
|
||||
BUILD_NUMERIC_BINOP_FP(GtOp, gt)
|
||||
BUILD_NUMERIC_BINOP_FP(LeOp, le)
|
||||
BUILD_NUMERIC_BINOP_FP(LtOp, lt)
|
||||
BUILD_NUMERIC_BINOP_FP(MaxOp, max)
|
||||
BUILD_NUMERIC_BINOP_FP(MinOp, min)
|
||||
BUILD_NUMERIC_BINOP_INT(AndOp, and)
|
||||
BUILD_NUMERIC_BINOP_INT(DivSIOp, divS)
|
||||
BUILD_NUMERIC_BINOP_INT(DivUIOp, divU)
|
||||
BUILD_NUMERIC_BINOP_INT(GeSIOp, geS)
|
||||
BUILD_NUMERIC_BINOP_INT(GeUIOp, geU)
|
||||
BUILD_NUMERIC_BINOP_INT(GtSIOp, gtS)
|
||||
BUILD_NUMERIC_BINOP_INT(GtUIOp, gtU)
|
||||
BUILD_NUMERIC_BINOP_INT(LeSIOp, leS)
|
||||
BUILD_NUMERIC_BINOP_INT(LeUIOp, leU)
|
||||
BUILD_NUMERIC_BINOP_INT(LtSIOp, ltS)
|
||||
BUILD_NUMERIC_BINOP_INT(LtUIOp, ltU)
|
||||
BUILD_NUMERIC_BINOP_INT(OrOp, or)
|
||||
BUILD_NUMERIC_BINOP_INT(RemSIOp, remS)
|
||||
BUILD_NUMERIC_BINOP_INT(RemUIOp, remU)
|
||||
@@ -1015,7 +1354,9 @@ BUILD_NUMERIC_BINOP_INT(ShRSOp, shrS)
|
||||
BUILD_NUMERIC_BINOP_INT(ShRUOp, shrU)
|
||||
BUILD_NUMERIC_BINOP_INT(XOrOp, xor)
|
||||
BUILD_NUMERIC_BINOP_INTFP(AddOp, add)
|
||||
BUILD_NUMERIC_BINOP_INTFP(EqOp, eq)
|
||||
BUILD_NUMERIC_BINOP_INTFP(MulOp, mul)
|
||||
BUILD_NUMERIC_BINOP_INTFP(NeOp, ne)
|
||||
BUILD_NUMERIC_BINOP_INTFP(SubOp, sub)
|
||||
BUILD_NUMERIC_UNARY_OP_FP(AbsOp, abs)
|
||||
BUILD_NUMERIC_UNARY_OP_FP(CeilOp, ceil)
|
||||
@@ -1025,6 +1366,7 @@ BUILD_NUMERIC_UNARY_OP_FP(SqrtOp, sqrt)
|
||||
BUILD_NUMERIC_UNARY_OP_FP(TruncOp, trunc)
|
||||
BUILD_NUMERIC_UNARY_OP_INT(ClzOp, clz)
|
||||
BUILD_NUMERIC_UNARY_OP_INT(CtzOp, ctz)
|
||||
BUILD_NUMERIC_UNARY_OP_INT(EqzOp, eqz)
|
||||
BUILD_NUMERIC_UNARY_OP_INT(PopCntOp, popcnt)
|
||||
|
||||
// Don't need these anymore so let's undef them.
|
||||
@@ -1036,6 +1378,105 @@ BUILD_NUMERIC_UNARY_OP_INT(PopCntOp, popcnt)
|
||||
#undef BUILD_NUMERIC_OP
|
||||
#undef BUILD_NUMERIC_CAST_OP
|
||||
|
||||
template <typename opType, typename inputType, typename outputType,
|
||||
typename... extraArgsT>
|
||||
inline parsed_inst_t ExpressionParser::buildConvertOp(OpBuilder &builder,
|
||||
extraArgsT... extraArgs) {
|
||||
static_assert(std::is_arithmetic_v<inputType>,
|
||||
"InputType should be an arithmetic type");
|
||||
static_assert(std::is_arithmetic_v<outputType>,
|
||||
"OutputType should be an arithmetic type");
|
||||
auto intype = buildLiteralType<inputType>(builder);
|
||||
auto outType = buildLiteralType<outputType>(builder);
|
||||
auto operand = popOperands(intype);
|
||||
if (failed(operand))
|
||||
return failure();
|
||||
auto op = builder.create<opType>(*currentOpLoc, outType, operand->front(),
|
||||
extraArgs...);
|
||||
LDBG() << "Built operation: " << op;
|
||||
return {{op.getResult()}};
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
|
||||
WasmBinaryEncoding::OpCode::demoteF64ToF32>(OpBuilder &builder) {
|
||||
return buildConvertOp<DemoteOp, double, float>(builder);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t
|
||||
ExpressionParser::parseSpecificInstruction<WasmBinaryEncoding::OpCode::wrap>(
|
||||
OpBuilder &builder) {
|
||||
return buildConvertOp<WrapOp, int64_t, int32_t>(builder);
|
||||
}
|
||||
|
||||
#define BUILD_CONVERSION_OP(IN_T, OUT_T, SOURCE_OP, TARGET_OP) \
|
||||
template <> \
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction< \
|
||||
WasmBinaryEncoding::OpCode::SOURCE_OP>(OpBuilder & builder) { \
|
||||
return buildConvertOp<TARGET_OP, IN_T, OUT_T>(builder); \
|
||||
}
|
||||
|
||||
#define BUILD_CONVERT_OP_FOR(DEST_T, WIDTH) \
|
||||
BUILD_CONVERSION_OP(uint32_t, DEST_T, convertUI32F##WIDTH, ConvertUOp) \
|
||||
BUILD_CONVERSION_OP(int32_t, DEST_T, convertSI32F##WIDTH, ConvertSOp) \
|
||||
BUILD_CONVERSION_OP(uint64_t, DEST_T, convertUI64F##WIDTH, ConvertUOp) \
|
||||
BUILD_CONVERSION_OP(int64_t, DEST_T, convertSI64F##WIDTH, ConvertSOp)
|
||||
|
||||
BUILD_CONVERT_OP_FOR(float, 32)
|
||||
BUILD_CONVERT_OP_FOR(double, 64)
|
||||
|
||||
#undef BUILD_CONVERT_OP_FOR
|
||||
|
||||
BUILD_CONVERSION_OP(int32_t, int64_t, extendS, ExtendSI32Op)
|
||||
BUILD_CONVERSION_OP(int32_t, int64_t, extendU, ExtendUI32Op)
|
||||
|
||||
#undef BUILD_CONVERSION_OP
|
||||
|
||||
#define BUILD_SLICE_EXTEND_PARSER(IT_WIDTH, EXTRACT_WIDTH) \
|
||||
template <> \
|
||||
parsed_inst_t ExpressionParser::parseSpecificInstruction< \
|
||||
WasmBinaryEncoding::OpCode::extendI##IT_WIDTH##EXTRACT_WIDTH##S>( \
|
||||
OpBuilder & builder) { \
|
||||
using inout_t = int##IT_WIDTH##_t; \
|
||||
auto attr = builder.getUI32IntegerAttr(EXTRACT_WIDTH); \
|
||||
return buildConvertOp<ExtendLowBitsSOp, inout_t, inout_t>(builder, attr); \
|
||||
}
|
||||
|
||||
BUILD_SLICE_EXTEND_PARSER(32, 8)
|
||||
BUILD_SLICE_EXTEND_PARSER(32, 16)
|
||||
BUILD_SLICE_EXTEND_PARSER(64, 8)
|
||||
BUILD_SLICE_EXTEND_PARSER(64, 16)
|
||||
BUILD_SLICE_EXTEND_PARSER(64, 32)
|
||||
|
||||
#undef BUILD_SLICE_EXTEND_PARSER
|
||||
|
||||
template <>
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
|
||||
WasmBinaryEncoding::OpCode::promoteF32ToF64>(OpBuilder &builder) {
|
||||
return buildConvertOp<PromoteOp, float, double>(builder);
|
||||
}
|
||||
|
||||
#define BUILD_REINTERPRET_PARSER(WIDTH, FP_TYPE) \
|
||||
template <> \
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction< \
|
||||
WasmBinaryEncoding::OpCode::reinterpretF##WIDTH##AsI##WIDTH>(OpBuilder & \
|
||||
builder) { \
|
||||
return buildConvertOp<ReinterpretOp, FP_TYPE, int##WIDTH##_t>(builder); \
|
||||
} \
|
||||
\
|
||||
template <> \
|
||||
inline parsed_inst_t ExpressionParser::parseSpecificInstruction< \
|
||||
WasmBinaryEncoding::OpCode::reinterpretI##WIDTH##AsF##WIDTH>(OpBuilder & \
|
||||
builder) { \
|
||||
return buildConvertOp<ReinterpretOp, int##WIDTH##_t, FP_TYPE>(builder); \
|
||||
}
|
||||
|
||||
BUILD_REINTERPRET_PARSER(32, float)
|
||||
BUILD_REINTERPRET_PARSER(64, double)
|
||||
|
||||
#undef BUILD_REINTERPRET_PARSER
|
||||
|
||||
class WasmBinaryParser {
|
||||
private:
|
||||
struct SectionRegistry {
|
||||
@@ -1153,7 +1594,7 @@ private:
|
||||
if (tid.id >= symbols.moduleFuncTypes.size())
|
||||
return emitError(loc, "invalid type id: ")
|
||||
<< tid.id << ". Only " << symbols.moduleFuncTypes.size()
|
||||
<< " type registration.";
|
||||
<< " type registrations";
|
||||
FunctionType type = symbols.moduleFuncTypes[tid.id];
|
||||
std::string symbol = symbols.getNewFuncSymbolName();
|
||||
auto funcOp = FuncImportOp::create(builder, loc, symbol, moduleName,
|
||||
@@ -1221,7 +1662,7 @@ public:
|
||||
FileLineColLoc magicLoc = parser.getLocation();
|
||||
FailureOr<StringRef> magic = parser.consumeNBytes(wasmHeader.size());
|
||||
if (failed(magic) || magic->compare(wasmHeader)) {
|
||||
emitError(magicLoc, "source file does not contain valid Wasm header.");
|
||||
emitError(magicLoc, "source file does not contain valid Wasm header");
|
||||
return;
|
||||
}
|
||||
auto const expectedVersionString = StringRef{"\1\0\0\0", 4};
|
||||
@@ -1391,7 +1832,7 @@ WasmBinaryParser::parseSectionItem<WasmSectionType::EXPORT>(ParserHead &ph,
|
||||
return failure();
|
||||
|
||||
Operation *op = SymbolTable::lookupSymbolIn(mOp, *currentSymbol);
|
||||
SymbolTable::setSymbolVisibility(op, SymbolTable::Visibility::Public);
|
||||
op->setAttr("exported", UnitAttr::get(op->getContext()));
|
||||
StringAttr symName = SymbolTable::getSymbolName(op);
|
||||
return SymbolTable{mOp}.rename(symName, *exportName);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: mlir-opt %s | FileCheck %s
|
||||
|
||||
module {
|
||||
wasmssa.import_global "from_js" from "env" as @global_0 nested : i32
|
||||
wasmssa.import_global "from_js" from "env" as @global_0 : i32
|
||||
|
||||
wasmssa.global @global_1 i32 : {
|
||||
%0 = wasmssa.const 10 : i32
|
||||
@@ -21,7 +21,7 @@ module {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: wasmssa.import_global "from_js" from "env" as @global_0 nested : i32
|
||||
// CHECK-LABEL: wasmssa.import_global "from_js" from "env" as @global_0 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_1 i32 : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: mlir-opt %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_0(
|
||||
// CHECK-LABEL: wasmssa.func @func_0(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: wasmssa.if %[[VAL_0]] : {
|
||||
@@ -12,7 +12,7 @@
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_3:.*]]: f32):
|
||||
// CHECK: wasmssa.return %[[VAL_3]] : f32
|
||||
wasmssa.func nested @func_0(%arg0 : !wasmssa<local ref to i32>) -> i32 {
|
||||
wasmssa.func @func_0(%arg0 : !wasmssa<local ref to i32>) -> i32 {
|
||||
%cond = wasmssa.local_get %arg0 : ref to i32
|
||||
wasmssa.if %cond : {
|
||||
%c0 = wasmssa.const 0.5 : f32
|
||||
@@ -25,7 +25,7 @@ wasmssa.func nested @func_0(%arg0 : !wasmssa<local ref to i32>) -> i32 {
|
||||
wasmssa.return %retVal : f32
|
||||
}
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_1(
|
||||
// CHECK-LABEL: wasmssa.func @func_1(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local of type i32
|
||||
@@ -38,7 +38,7 @@ wasmssa.func nested @func_0(%arg0 : !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.local_get %[[VAL_1]] : ref to i32
|
||||
// CHECK: wasmssa.return %[[VAL_4]] : i32
|
||||
wasmssa.func nested @func_1(%arg0 : !wasmssa<local ref to i32>) -> i32 {
|
||||
wasmssa.func @func_1(%arg0 : !wasmssa<local ref to i32>) -> i32 {
|
||||
%cond = wasmssa.local_get %arg0 : ref to i32
|
||||
%var = wasmssa.local of type i32
|
||||
%zero = wasmssa.const 0
|
||||
|
||||
@@ -5,13 +5,13 @@ module {
|
||||
wasmssa.import_func "bar" from "my_module" as @func_1 {sym_visibility = "nested", type = (i32) -> ()}
|
||||
wasmssa.import_table "table" from "my_module" as @table_0 {sym_visibility = "nested", type = !wasmssa<tabletype !wasmssa.funcref [2:]>}
|
||||
wasmssa.import_mem "mem" from "my_module" as @mem_0 {limits = !wasmssa<limit[2:]>, sym_visibility = "nested"}
|
||||
wasmssa.import_global "glob" from "my_module" as @global_0 nested : i32
|
||||
wasmssa.import_global "glob_mut" from "my_other_module" as @global_1 mutable nested : i32
|
||||
wasmssa.import_global "glob" from "my_module" as @global_0 : i32
|
||||
wasmssa.import_global "glob_mut" from "my_other_module" as @global_1 mutable : i32
|
||||
}
|
||||
|
||||
// CHECK-LABEL: wasmssa.import_func "foo" from "my_module" as @func_0 {sym_visibility = "nested", type = (i32) -> ()}
|
||||
// CHECK: wasmssa.import_func "bar" from "my_module" as @func_1 {sym_visibility = "nested", type = (i32) -> ()}
|
||||
// CHECK: wasmssa.import_table "table" from "my_module" as @table_0 {sym_visibility = "nested", type = !wasmssa<tabletype !wasmssa.funcref [2:]>}
|
||||
// CHECK: wasmssa.import_mem "mem" from "my_module" as @mem_0 {limits = !wasmssa<limit[2:]>, sym_visibility = "nested"}
|
||||
// CHECK: wasmssa.import_global "glob" from "my_module" as @global_0 nested : i32
|
||||
// CHECK: wasmssa.import_global "glob_mut" from "my_other_module" as @global_1 mutable nested : i32
|
||||
// CHECK: wasmssa.import_global "glob" from "my_module" as @global_0 : i32
|
||||
// CHECK: wasmssa.import_global "glob_mut" from "my_other_module" as @global_1 mutable : i32
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: mlir-opt %s | FileCheck %s
|
||||
|
||||
module {
|
||||
wasmssa.func nested @func_0() -> f32 {
|
||||
wasmssa.func @func_0() -> f32 {
|
||||
%0 = wasmssa.local of type f32
|
||||
%1 = wasmssa.local of type f32
|
||||
%2 = wasmssa.const 8.000000e+00 : f32
|
||||
@@ -9,7 +9,7 @@ module {
|
||||
%4 = wasmssa.add %2 %3 : f32
|
||||
wasmssa.return %4 : f32
|
||||
}
|
||||
wasmssa.func nested @func_1() -> i32 {
|
||||
wasmssa.func @func_1() -> i32 {
|
||||
%0 = wasmssa.local of type i32
|
||||
%1 = wasmssa.local of type i32
|
||||
%2 = wasmssa.const 8 : i32
|
||||
@@ -17,13 +17,13 @@ module {
|
||||
%4 = wasmssa.add %2 %3 : i32
|
||||
wasmssa.return %4 : i32
|
||||
}
|
||||
wasmssa.func nested @func_2(%arg0: !wasmssa<local ref to i32>) -> i32 {
|
||||
wasmssa.func @func_2(%arg0: !wasmssa<local ref to i32>) -> i32 {
|
||||
%0 = wasmssa.const 3 : i32
|
||||
wasmssa.return %0 : i32
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_0() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local of type f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local of type f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 8.000000e+00 : f32
|
||||
@@ -31,7 +31,7 @@ module {
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.add %[[VAL_2]] %[[VAL_3]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_4]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_1() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local of type i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local of type i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 8 : i32
|
||||
@@ -39,7 +39,7 @@ module {
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.add %[[VAL_2]] %[[VAL_3]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_4]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_2(
|
||||
// CHECK-LABEL: wasmssa.func @func_2(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 3 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: mlir-opt %s | FileCheck %s
|
||||
|
||||
// CHECK: wasmssa.memory @mem0 public !wasmssa<limit[0: 65536]>
|
||||
wasmssa.memory @mem0 public !wasmssa<limit[0:65536]>
|
||||
|
||||
// CHECK: wasmssa.memory @mem1 nested !wasmssa<limit[512:]>
|
||||
// CHECK: wasmssa.memory @mem1 !wasmssa<limit[512:]>
|
||||
wasmssa.memory @mem1 !wasmssa<limit[512:]>
|
||||
|
||||
// CHECK: wasmssa.memory exported @mem2 !wasmssa<limit[0: 65536]>
|
||||
wasmssa.memory exported @mem2 !wasmssa<limit[0:65536]>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: mlir-opt %s | FileCheck %s
|
||||
|
||||
// CHECK: wasmssa.table @tab0 public !wasmssa<tabletype !wasmssa.externref [0: 65536]>
|
||||
wasmssa.table @tab0 public !wasmssa<tabletype !wasmssa.externref [0:65536]>
|
||||
// CHECK: wasmssa.table exported @tab0 !wasmssa<tabletype !wasmssa.externref [0: 65536]>
|
||||
wasmssa.table exported @tab0 !wasmssa<tabletype !wasmssa.externref [0:65536]>
|
||||
|
||||
// CHECK: wasmssa.table @tab1 nested !wasmssa<tabletype !wasmssa.funcref [348:]>
|
||||
// CHECK: wasmssa.table @tab1 !wasmssa<tabletype !wasmssa.funcref [348:]>
|
||||
wasmssa.table @tab1 !wasmssa<tabletype !wasmssa.funcref [348:]>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
|
||||
|
||||
|
||||
wasmssa.func nested @extend_low_64() -> i32 {
|
||||
wasmssa.func @extend_low_64() -> i32 {
|
||||
%0 = wasmssa.const 10 : i32
|
||||
// expected-error@+1 {{extend op can only take 8, 16 or 32 bits. Got 64}}
|
||||
%1 = wasmssa.extend 64 low bits from %0: i32
|
||||
@@ -10,7 +10,7 @@ wasmssa.func nested @extend_low_64() -> i32 {
|
||||
|
||||
// -----
|
||||
|
||||
wasmssa.func nested @extend_too_much() -> i32 {
|
||||
wasmssa.func @extend_too_much() -> i32 {
|
||||
%0 = wasmssa.const 10 : i32
|
||||
// expected-error@+1 {{trying to extend the 32 low bits from a 'i32' value is illegal}}
|
||||
%1 = wasmssa.extend 32 low bits from %0: i32
|
||||
|
||||
@@ -13,7 +13,7 @@ module {
|
||||
// -----
|
||||
|
||||
module {
|
||||
wasmssa.import_global "glob" from "my_module" as @global_0 mutable nested : i32
|
||||
wasmssa.import_global "glob" from "my_module" as @global_0 mutable : i32
|
||||
wasmssa.global @global_1 i32 : {
|
||||
// expected-error@+1 {{global.get op is considered constant if it's referring to a import.global symbol marked non-mutable}}
|
||||
%0 = wasmssa.global_get @global_0 : i32
|
||||
@@ -30,3 +30,13 @@ module {
|
||||
wasmssa.return %0 : i32
|
||||
}
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
module {
|
||||
// expected-error@+1 {{expecting either `exported` or symbol name. got exproted}}
|
||||
wasmssa.global exproted @global_1 i32 : {
|
||||
%0 = wasmssa.const 17 : i32
|
||||
wasmssa.return %0 : i32
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
|
||||
|
||||
wasmssa.func nested @local_set_err(%arg0: !wasmssa<local ref to i32>) -> i64 {
|
||||
wasmssa.func @local_set_err(%arg0: !wasmssa<local ref to i32>) -> i64 {
|
||||
%0 = wasmssa.const 3 : i64
|
||||
// expected-error@+1 {{input type and result type of local.set do not match}}
|
||||
wasmssa.local_set %arg0 : ref to i32 to %0 : i64
|
||||
@@ -9,7 +9,7 @@ wasmssa.func nested @local_set_err(%arg0: !wasmssa<local ref to i32>) -> i64 {
|
||||
|
||||
// -----
|
||||
|
||||
wasmssa.func nested @local_tee_err(%arg0: !wasmssa<local ref to i32>) -> i32 {
|
||||
wasmssa.func @local_tee_err(%arg0: !wasmssa<local ref to i32>) -> i32 {
|
||||
%0 = wasmssa.const 3 : i64
|
||||
// expected-error@+1 {{input type and output type of local.tee do not match}}
|
||||
%1 = wasmssa.local_tee %arg0 : ref to i32 to %0 : i64
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @abs_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @abs_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.abs %[[VAL_0]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @abs_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @abs_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.abs %[[VAL_0]] : f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
40
mlir/test/Target/Wasm/add_div.mlir
Normal file
40
mlir/test/Target/Wasm/add_div.mlir
Normal file
@@ -0,0 +1,40 @@
|
||||
// RUN: yaml2obj %S/inputs/add_div.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module $test.wasm
|
||||
(type (;0;) (func (param i32) (result i32)))
|
||||
(type (;1;) (func (param i32 i32) (result i32)))
|
||||
(import "env" "twoTimes" (func $twoTimes (type 0)))
|
||||
(func $add (type 1) (param i32 i32) (result i32)
|
||||
local.get 0
|
||||
call $twoTimes
|
||||
local.get 1
|
||||
call $twoTimes
|
||||
i32.add
|
||||
i32.const 2
|
||||
i32.div_s)
|
||||
(memory (;0;) 2)
|
||||
(global $__stack_pointer (mut i32) (i32.const 66560))
|
||||
(export "memory" (memory 0))
|
||||
(export "add" (func $add)))
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.import_func "twoTimes" from "env" as @func_0 {type = (i32) -> i32}
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @add(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>,
|
||||
// CHECK-SAME: %[[ARG1:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.call @func_0(%[[VAL_0]]) : (i32) -> i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.local_get %[[ARG1]] : ref to i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.call @func_0(%[[VAL_2]]) : (i32) -> i32
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.add %[[VAL_1]] %[[VAL_3]] : i32
|
||||
// CHECK: %[[VAL_5:.*]] = wasmssa.const 2 : i32
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.div_si %[[VAL_4]] %[[VAL_5]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_6]] : i32
|
||||
// CHECK: }
|
||||
// CHECK: wasmssa.memory exported @memory !wasmssa<limit[2:]>
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_0 i32 mutable : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 66560 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @and_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @and_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.and %0 %1 : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @and_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @and_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.and %0 %1 : i64
|
||||
|
||||
16
mlir/test/Target/Wasm/block.mlir
Normal file
16
mlir/test/Target/Wasm/block.mlir
Normal file
@@ -0,0 +1,16 @@
|
||||
// RUN: yaml2obj %S/inputs/block.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func(export "i_am_a_block")
|
||||
(block $i_am_a_block)
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @i_am_a_block() {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.return
|
||||
24
mlir/test/Target/Wasm/block_complete_type.mlir
Normal file
24
mlir/test/Target/Wasm/block_complete_type.mlir
Normal file
@@ -0,0 +1,24 @@
|
||||
// RUN: yaml2obj %S/inputs/block_complete_type.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(type (;0;) (func (param i32) (result i32)))
|
||||
(type (;1;) (func (result i32)))
|
||||
(func (;0;) (type 1) (result i32)
|
||||
i32.const 14
|
||||
block (param i32) (result i32) ;; label = @1
|
||||
i32.const 1
|
||||
i32.add
|
||||
end))
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 14 : i32
|
||||
// CHECK: wasmssa.block(%[[VAL_0]]) : i32 : {
|
||||
// CHECK: ^bb0(%[[VAL_1:.*]]: i32):
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.add %[[VAL_1]] %[[VAL_2]] : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_3]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_4:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_4]] : i32
|
||||
19
mlir/test/Target/Wasm/block_value_type.mlir
Normal file
19
mlir/test/Target/Wasm/block_value_type.mlir
Normal file
@@ -0,0 +1,19 @@
|
||||
// RUN: yaml2obj %S/inputs/block_value_type.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(type (;0;) (func (result i32)))
|
||||
(func (;0;) (type 0) (result i32)
|
||||
block (result i32) ;; label = @1
|
||||
i32.const 17
|
||||
end))
|
||||
*/
|
||||
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 17 : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_0]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_1:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
29
mlir/test/Target/Wasm/branch_if.mlir
Normal file
29
mlir/test/Target/Wasm/branch_if.mlir
Normal file
@@ -0,0 +1,29 @@
|
||||
// RUN: yaml2obj %S/inputs/branch_if.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(type $produce_i32 (func (result i32)))
|
||||
(func (type $produce_i32)
|
||||
(block $my_block (type $produce_i32)
|
||||
i32.const 1
|
||||
i32.const 2
|
||||
br_if $my_block
|
||||
i32.const 1
|
||||
i32.add
|
||||
)
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2 : i32
|
||||
// CHECK: wasmssa.branch_if %[[VAL_1]] to level 0 with args(%[[VAL_0]] : i32) else ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.add %[[VAL_0]] %[[VAL_2]] : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_3]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_4:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_4]] : i32
|
||||
17
mlir/test/Target/Wasm/call.mlir
Normal file
17
mlir/test/Target/Wasm/call.mlir
Normal file
@@ -0,0 +1,17 @@
|
||||
// RUN: yaml2obj %S/inputs/call.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $forty_two (result i32)
|
||||
i32.const 42)
|
||||
(func(export "forty_two")(result i32)
|
||||
call $forty_two))
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 42 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @forty_two() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.call @func_0 : () -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
@@ -14,12 +14,12 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @clz_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @clz_i32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.clz %[[VAL_0]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @clz_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @clz_i64() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.clz %[[VAL_0]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
269
mlir/test/Target/Wasm/comparison_ops.mlir
Normal file
269
mlir/test/Target/Wasm/comparison_ops.mlir
Normal file
@@ -0,0 +1,269 @@
|
||||
// RUN: yaml2obj %S/inputs/comparison_ops.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $lt_si32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.lt_s
|
||||
)
|
||||
(func $le_si32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.le_s
|
||||
)
|
||||
(func $lt_ui32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.lt_u
|
||||
)
|
||||
(func $le_ui32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.le_u
|
||||
)
|
||||
(func $gt_si32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.gt_s
|
||||
)
|
||||
(func $gt_ui32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.gt_u
|
||||
)
|
||||
(func $ge_si32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.ge_s
|
||||
)
|
||||
(func $ge_ui32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.ge_u
|
||||
)
|
||||
(func $lt_si64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.lt_s
|
||||
)
|
||||
(func $le_si64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.le_s
|
||||
)
|
||||
(func $lt_ui64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.lt_u
|
||||
)
|
||||
(func $le_ui64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.le_u
|
||||
)
|
||||
(func $gt_si64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.gt_s
|
||||
)
|
||||
(func $gt_ui64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.gt_u
|
||||
)
|
||||
(func $ge_si64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.ge_s
|
||||
)
|
||||
(func $ge_ui64 (result i32)
|
||||
i64.const 12
|
||||
i64.const 50
|
||||
i64.ge_u
|
||||
)
|
||||
(func $lt_f32 (result i32)
|
||||
f32.const 5
|
||||
f32.const 14
|
||||
f32.lt
|
||||
)
|
||||
(func $le_f32 (result i32)
|
||||
f32.const 5
|
||||
f32.const 14
|
||||
f32.le
|
||||
)
|
||||
(func $gt_f32 (result i32)
|
||||
f32.const 5
|
||||
f32.const 14
|
||||
f32.gt
|
||||
)
|
||||
(func $ge_f32 (result i32)
|
||||
f32.const 5
|
||||
f32.const 14
|
||||
f32.ge
|
||||
)
|
||||
(func $lt_f64 (result i32)
|
||||
f64.const 5
|
||||
f64.const 14
|
||||
f64.lt
|
||||
)
|
||||
(func $le_f64 (result i32)
|
||||
f64.const 5
|
||||
f64.const 14
|
||||
f64.le
|
||||
)
|
||||
(func $gt_f64 (result i32)
|
||||
f64.const 5
|
||||
f64.const 14
|
||||
f64.gt
|
||||
)
|
||||
(func $ge_f64 (result i32)
|
||||
f64.const 5
|
||||
f64.const 14
|
||||
f64.ge
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.lt_si %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.le_si %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.lt_ui %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.le_ui %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_4() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.gt_si %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_5() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.gt_ui %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_6() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ge_si %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_7() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ge_ui %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_8() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.lt_si %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_9() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.le_si %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_10() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.lt_ui %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_11() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.le_ui %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_12() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.gt_si %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_13() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.gt_ui %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_14() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ge_si %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_15() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ge_ui %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_16() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.lt %[[VAL_0]] %[[VAL_1]] : f32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_17() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.le %[[VAL_0]] %[[VAL_1]] : f32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_18() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.gt %[[VAL_0]] %[[VAL_1]] : f32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_19() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ge %[[VAL_0]] %[[VAL_1]] : f32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_20() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.lt %[[VAL_0]] %[[VAL_1]] : f64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_21() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.le %[[VAL_0]] %[[VAL_1]] : f64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_22() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.gt %[[VAL_0]] %[[VAL_1]] : f64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_23() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ge %[[VAL_0]] %[[VAL_1]] : f64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
@@ -16,22 +16,22 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_0() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_1() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 3 : i64
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i64
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_2() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 4.000000e+00 : f32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : f32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_3() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 9.000000e+00 : f64
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : f64
|
||||
// CHECK: }
|
||||
|
||||
85
mlir/test/Target/Wasm/convert.mlir
Normal file
85
mlir/test/Target/Wasm/convert.mlir
Normal file
@@ -0,0 +1,85 @@
|
||||
// RUN: yaml2obj %S/inputs/convert.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to generate this test:
|
||||
(module
|
||||
(func (export "convert_i32_u_to_f32") (result f32)
|
||||
i32.const 10
|
||||
f32.convert_i32_u
|
||||
)
|
||||
|
||||
(func (export "convert_i32_s_to_f32") (result f32)
|
||||
i32.const 42
|
||||
f32.convert_i32_s
|
||||
)
|
||||
|
||||
(func (export "convert_i64_u_to_f32") (result f32)
|
||||
i64.const 17
|
||||
f32.convert_i64_u
|
||||
)
|
||||
|
||||
(func (export "convert_i64s_to_f32") (result f32)
|
||||
i64.const 10
|
||||
f32.convert_i64_s
|
||||
)
|
||||
|
||||
(func (export "convert_i32_u_to_f64") (result f64)
|
||||
i32.const 10
|
||||
f64.convert_i32_u
|
||||
)
|
||||
|
||||
(func (export "convert_i32_s_to_f64") (result f64)
|
||||
i32.const 42
|
||||
f64.convert_i32_s
|
||||
)
|
||||
|
||||
(func (export "convert_i64_u_to_f64") (result f64)
|
||||
i64.const 17
|
||||
f64.convert_i64_u
|
||||
)
|
||||
|
||||
(func (export "convert_i64s_to_f64") (result f64)
|
||||
i64.const 10
|
||||
f64.convert_i64_s
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i32_u_to_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_u %[[VAL_0]] : i32 to f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i32_s_to_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 42 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_s %[[VAL_0]] : i32 to f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i64_u_to_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 17 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_u %[[VAL_0]] : i64 to f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i64s_to_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_s %[[VAL_0]] : i64 to f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i32_u_to_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_u %[[VAL_0]] : i32 to f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i32_s_to_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 42 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_s %[[VAL_0]] : i32 to f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i64_u_to_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 17 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_u %[[VAL_0]] : i64 to f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @convert_i64s_to_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.convert_s %[[VAL_0]] : i64 to f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
@@ -16,14 +16,14 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @copysign_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @copysign_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.copysign %[[VAL_0]] %[[VAL_1]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : f32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @copysign_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @copysign_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.copysign %[[VAL_0]] %[[VAL_1]] : f64
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @ctz_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @ctz_i32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.ctz %[[VAL_0]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @ctz_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @ctz_i64() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.ctz %[[VAL_0]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
15
mlir/test/Target/Wasm/demote.mlir
Normal file
15
mlir/test/Target/Wasm/demote.mlir
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: yaml2obj %S/inputs/demote.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $main (result f32)
|
||||
f64.const 2.24
|
||||
f32.demote_f64
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 2.240000e+00 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.demote %[[VAL_0]] : f64 to f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
@@ -66,61 +66,61 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_u_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_u_i32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_u_i32_zero() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_u_i32_zero() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_s_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_s_i32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_s_i32_zero() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_s_i32_zero() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_u_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_u_i64() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_u_i64_zero() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_u_i64_zero() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_ui %[[VAL_0]] %[[VAL_1]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_s_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_s_i64() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_s_i64_zero() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_s_i64_zero() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div_si %[[VAL_0]] %[[VAL_1]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2.000000e+00 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div %[[VAL_0]] %[[VAL_1]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @div_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @div_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 2.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.div %[[VAL_0]] %[[VAL_1]] : f64
|
||||
|
||||
63
mlir/test/Target/Wasm/double_nested_loop.mlir
Normal file
63
mlir/test/Target/Wasm/double_nested_loop.mlir
Normal file
@@ -0,0 +1,63 @@
|
||||
// RUN: yaml2obj %S/inputs/double_nested_loop.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/*
|
||||
(module
|
||||
(func
|
||||
;; create a local variable and initialize it to 0
|
||||
(local $i i32)
|
||||
(local $j i32)
|
||||
|
||||
(loop $my_loop
|
||||
|
||||
;; add one to $i
|
||||
local.get $i
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $i
|
||||
(loop $my_second_loop (result i32)
|
||||
i32.const 1
|
||||
local.get $j
|
||||
i32.const 12
|
||||
i32.add
|
||||
local.tee $j
|
||||
local.get $i
|
||||
i32.gt_s
|
||||
br_if $my_second_loop
|
||||
)
|
||||
i32.const 10
|
||||
i32.lt_s
|
||||
br_if $my_loop
|
||||
)
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local of type i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local of type i32
|
||||
// CHECK: wasmssa.loop : {
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.local_get %[[VAL_0]] : ref to i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.add %[[VAL_2]] %[[VAL_3]] : i32
|
||||
// CHECK: wasmssa.local_set %[[VAL_0]] : ref to i32 to %[[VAL_4]] : i32
|
||||
// CHECK: wasmssa.loop : {
|
||||
// CHECK: %[[VAL_5:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.local_get %[[VAL_1]] : ref to i32
|
||||
// CHECK: %[[VAL_7:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_8:.*]] = wasmssa.add %[[VAL_6]] %[[VAL_7]] : i32
|
||||
// CHECK: %[[VAL_9:.*]] = wasmssa.local_tee %[[VAL_1]] : ref to i32 to %[[VAL_8]] : i32
|
||||
// CHECK: %[[VAL_10:.*]] = wasmssa.local_get %[[VAL_0]] : ref to i32
|
||||
// CHECK: %[[VAL_11:.*]] = wasmssa.gt_si %[[VAL_9]] %[[VAL_10]] : i32 -> i32
|
||||
// CHECK: wasmssa.branch_if %[[VAL_11]] to level 0 else ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.block_return %[[VAL_5]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_12:.*]]: i32):
|
||||
// CHECK: %[[VAL_13:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_14:.*]] = wasmssa.lt_si %[[VAL_12]] %[[VAL_13]] : i32 -> i32
|
||||
// CHECK: wasmssa.branch_if %[[VAL_14]] to level 0 else ^bb2
|
||||
// CHECK: ^bb2:
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.return
|
||||
53
mlir/test/Target/Wasm/empty_blocks_list_and_stack.mlir
Normal file
53
mlir/test/Target/Wasm/empty_blocks_list_and_stack.mlir
Normal file
@@ -0,0 +1,53 @@
|
||||
// RUN: yaml2obj %S/inputs/empty_blocks_list_and_stack.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func (param $num i32)
|
||||
(block $b1
|
||||
(block $b2
|
||||
(block $b3
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (param $num i32)
|
||||
(block $b1)
|
||||
(block $b2)
|
||||
(block $b3)
|
||||
)
|
||||
)
|
||||
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.return
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) {
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb2
|
||||
// CHECK: ^bb2:
|
||||
// CHECK: wasmssa.block : {
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb3
|
||||
// CHECK: ^bb3:
|
||||
// CHECK: wasmssa.return
|
||||
56
mlir/test/Target/Wasm/eq.mlir
Normal file
56
mlir/test/Target/Wasm/eq.mlir
Normal file
@@ -0,0 +1,56 @@
|
||||
// RUN: yaml2obj %S/inputs/eq.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $eq_i32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.eq
|
||||
)
|
||||
|
||||
(func $eq_i64 (result i32)
|
||||
i64.const 20
|
||||
i64.const 5
|
||||
i64.eq
|
||||
)
|
||||
|
||||
(func $eq_f32 (result i32)
|
||||
f32.const 5
|
||||
f32.const 14
|
||||
f32.eq
|
||||
)
|
||||
|
||||
(func $eq_f64 (result i32)
|
||||
f64.const 17
|
||||
f64.const 0
|
||||
f64.eq
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.eq %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 20 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 5 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.eq %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.eq %[[VAL_0]] %[[VAL_1]] : f32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.700000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.eq %[[VAL_0]] %[[VAL_1]] : f64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
// CHECK: }
|
||||
21
mlir/test/Target/Wasm/eqz.mlir
Normal file
21
mlir/test/Target/Wasm/eqz.mlir
Normal file
@@ -0,0 +1,21 @@
|
||||
// RUN: yaml2obj %S/inputs/eqz.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func (export "eqz_i32") (result i32)
|
||||
i32.const 13
|
||||
i32.eqz)
|
||||
|
||||
(func (export "eqz_i64") (result i32)
|
||||
i64.const 13
|
||||
i64.eqz)
|
||||
)
|
||||
*/
|
||||
// CHECK-LABEL: wasmssa.func exported @eqz_i32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 13 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.eqz %[[VAL_0]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @eqz_i64() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 13 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.eqz %[[VAL_0]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
69
mlir/test/Target/Wasm/extend.mlir
Normal file
69
mlir/test/Target/Wasm/extend.mlir
Normal file
@@ -0,0 +1,69 @@
|
||||
// RUN: yaml2obj %S/inputs/extend.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $i32_s (result i64)
|
||||
i32.const 10
|
||||
i64.extend_i32_s
|
||||
)
|
||||
(func $i32_u (result i64)
|
||||
i32.const 10
|
||||
i64.extend_i32_u
|
||||
)
|
||||
(func $extend8_32 (result i32)
|
||||
i32.const 10
|
||||
i32.extend8_s
|
||||
)
|
||||
(func $extend16_32 (result i32)
|
||||
i32.const 10
|
||||
i32.extend16_s
|
||||
)
|
||||
(func $extend8_64 (result i64)
|
||||
i64.const 10
|
||||
i64.extend8_s
|
||||
)
|
||||
(func $extend16_64 (result i64)
|
||||
i64.const 10
|
||||
i64.extend16_s
|
||||
)
|
||||
(func $extend32_64 (result i64)
|
||||
i64.const 10
|
||||
i64.extend32_s
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend_i32_s %[[VAL_0]] to i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend_i32_u %[[VAL_0]] to i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend 8 : ui32 low bits from %[[VAL_0]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend 16 : ui32 low bits from %[[VAL_0]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_4() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend 8 : ui32 low bits from %[[VAL_0]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_5() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend 16 : ui32 low bits from %[[VAL_0]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_6() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.extend 32 : ui32 low bits from %[[VAL_0]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
@@ -29,9 +29,9 @@ i32.add
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.import_global "from_js" from "env" as @global_0 nested : i32
|
||||
// CHECK-LABEL: wasmssa.import_global "from_js" from "env" as @global_0 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_0() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.global_get @global_0 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.global_get @global_1 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.add %[[VAL_0]] %[[VAL_1]] : i32
|
||||
@@ -41,26 +41,26 @@ i32.add
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.add %[[VAL_2]] %[[VAL_5]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_6]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_1 i32 nested : {
|
||||
// CHECK-LABEL: wasmssa.global @global_1 i32 : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_2 i32 mutable nested : {
|
||||
// CHECK-LABEL: wasmssa.global @global_2 i32 mutable : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_3 i32 mutable nested : {
|
||||
// CHECK-LABEL: wasmssa.global @global_3 i32 mutable : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_4 i64 nested : {
|
||||
// CHECK-LABEL: wasmssa.global @global_4 i64 : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 11 : i64
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_5 f32 nested : {
|
||||
// CHECK-LABEL: wasmssa.global @global_5 f32 : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.200000e+01 : f32
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.global @global_6 f64 nested : {
|
||||
// CHECK-LABEL: wasmssa.global @global_6 f64 : {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.300000e+01 : f64
|
||||
// CHECK: wasmssa.return %[[VAL_0]] : f64
|
||||
|
||||
112
mlir/test/Target/Wasm/if.mlir
Normal file
112
mlir/test/Target/Wasm/if.mlir
Normal file
@@ -0,0 +1,112 @@
|
||||
// RUN: yaml2obj %S/inputs/if.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(type $intMapper (func (param $input i32) (result i32)))
|
||||
(func $if_else (type $intMapper)
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.and
|
||||
if $isOdd (result i32)
|
||||
local.get 0
|
||||
i32.const 3
|
||||
i32.mul
|
||||
i32.const 1
|
||||
i32.add
|
||||
else
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
end
|
||||
)
|
||||
|
||||
(func $if_only (type $intMapper)
|
||||
local.get 0
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.and
|
||||
if $isOdd (type $intMapper)
|
||||
i32.const 1
|
||||
i32.add
|
||||
end
|
||||
)
|
||||
|
||||
(func $if_if (type $intMapper)
|
||||
local.get 0
|
||||
i32.ctz
|
||||
if $isEven (result i32)
|
||||
i32.const 2
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
i32.ctz
|
||||
if $isMultipleOfFour (type $intMapper)
|
||||
i32.const 2
|
||||
i32.add
|
||||
end
|
||||
else
|
||||
i32.const 1
|
||||
end
|
||||
)
|
||||
)
|
||||
*/
|
||||
// CHECK-LABEL: wasmssa.func @func_0(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.and %[[VAL_0]] %[[VAL_1]] : i32
|
||||
// CHECK: wasmssa.if %[[VAL_2]] : {
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.const 3 : i32
|
||||
// CHECK: %[[VAL_5:.*]] = wasmssa.mul %[[VAL_3]] %[[VAL_4]] : i32
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_7:.*]] = wasmssa.add %[[VAL_5]] %[[VAL_6]] : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_7]] : i32
|
||||
// CHECK: } "else "{
|
||||
// CHECK: %[[VAL_8:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_9:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_10:.*]] = wasmssa.shr_u %[[VAL_8]] by %[[VAL_9]] bits : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_10]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_11:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_11]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.and %[[VAL_1]] %[[VAL_2]] : i32
|
||||
// CHECK: wasmssa.if %[[VAL_3]](%[[VAL_0]]) : i32 : {
|
||||
// CHECK: ^bb0(%[[VAL_4:.*]]: i32):
|
||||
// CHECK: %[[VAL_5:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.add %[[VAL_4]] %[[VAL_5]] : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_6]] : i32
|
||||
// CHECK: } > ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_7:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_7]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_2(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.ctz %[[VAL_0]] : i32
|
||||
// CHECK: wasmssa.if %[[VAL_1]] : {
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 2 : i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.local_get %[[ARG0]] : ref to i32
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_5:.*]] = wasmssa.shr_u %[[VAL_3]] by %[[VAL_4]] bits : i32
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.ctz %[[VAL_5]] : i32
|
||||
// CHECK: wasmssa.if %[[VAL_6]](%[[VAL_2]]) : i32 : {
|
||||
// CHECK: ^bb0(%[[VAL_7:.*]]: i32):
|
||||
// CHECK: %[[VAL_8:.*]] = wasmssa.const 2 : i32
|
||||
// CHECK: %[[VAL_9:.*]] = wasmssa.add %[[VAL_7]] %[[VAL_8]] : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_9]] : i32
|
||||
// CHECK: } > ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_10:.*]]: i32):
|
||||
// CHECK: wasmssa.block_return %[[VAL_10]] : i32
|
||||
// CHECK: } "else "{
|
||||
// CHECK: %[[VAL_11:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_11]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_12:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_12]] : i32
|
||||
@@ -11,9 +11,9 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.import_func "foo" from "my_module" as @func_0 {sym_visibility = "nested", type = (i32) -> ()}
|
||||
// CHECK: wasmssa.import_func "bar" from "my_module" as @func_1 {sym_visibility = "nested", type = (i32) -> ()}
|
||||
// CHECK: wasmssa.import_table "table" from "my_module" as @table_0 {sym_visibility = "nested", type = !wasmssa<tabletype !wasmssa.funcref [2:]>}
|
||||
// CHECK: wasmssa.import_mem "mem" from "my_module" as @mem_0 {limits = !wasmssa<limit[2:]>, sym_visibility = "nested"}
|
||||
// CHECK: wasmssa.import_global "glob" from "my_module" as @global_0 nested : i32
|
||||
// CHECK: wasmssa.import_global "glob_mut" from "my_other_module" as @global_1 mutable nested : i32
|
||||
// CHECK-LABEL: wasmssa.import_func "foo" from "my_module" as @func_0 {type = (i32) -> ()}
|
||||
// CHECK: wasmssa.import_func "bar" from "my_module" as @func_1 {type = (i32) -> ()}
|
||||
// CHECK: wasmssa.import_table "table" from "my_module" as @table_0 {type = !wasmssa<tabletype !wasmssa.funcref [2:]>}
|
||||
// CHECK: wasmssa.import_mem "mem" from "my_module" as @mem_0 {limits = !wasmssa<limit[2:]>}
|
||||
// CHECK: wasmssa.import_global "glob" from "my_module" as @global_0 : i32
|
||||
// CHECK: wasmssa.import_global "glob_mut" from "my_other_module" as @global_1 mutable : i32
|
||||
|
||||
50
mlir/test/Target/Wasm/inputs/add_div.yaml.wasm
Normal file
50
mlir/test/Target/Wasm/inputs/add_div.yaml.wasm
Normal file
@@ -0,0 +1,50 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Index: 1
|
||||
ParamTypes:
|
||||
- I32
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: IMPORT
|
||||
Imports:
|
||||
- Module: env
|
||||
Field: twoTimes
|
||||
Kind: FUNCTION
|
||||
SigIndex: 0
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 1 ]
|
||||
- Type: MEMORY
|
||||
Memories:
|
||||
- Minimum: 0x2
|
||||
- Type: GLOBAL
|
||||
Globals:
|
||||
- Index: 0
|
||||
Type: I32
|
||||
Mutable: true
|
||||
InitExpr:
|
||||
Opcode: I32_CONST
|
||||
Value: 66560
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: memory
|
||||
Kind: MEMORY
|
||||
Index: 0
|
||||
- Name: add
|
||||
Kind: FUNCTION
|
||||
Index: 1
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 20001000200110006A41026D0B
|
||||
...
|
||||
22
mlir/test/Target/Wasm/inputs/block.yaml.wasm
Normal file
22
mlir/test/Target/Wasm/inputs/block.yaml.wasm
Normal file
@@ -0,0 +1,22 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes: []
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: i_am_a_block
|
||||
Kind: FUNCTION
|
||||
Index: 0
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 02400B0B
|
||||
...
|
||||
23
mlir/test/Target/Wasm/inputs/block_complete_type.yaml.wasm
Normal file
23
mlir/test/Target/Wasm/inputs/block_complete_type.yaml.wasm
Normal file
@@ -0,0 +1,23 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 1 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410E020041016A0B0B
|
||||
...
|
||||
18
mlir/test/Target/Wasm/inputs/block_value_type.yaml.wasm
Normal file
18
mlir/test/Target/Wasm/inputs/block_value_type.yaml.wasm
Normal file
@@ -0,0 +1,18 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 027F41110B0B
|
||||
...
|
||||
18
mlir/test/Target/Wasm/inputs/branch_if.yaml.wasm
Normal file
18
mlir/test/Target/Wasm/inputs/branch_if.yaml.wasm
Normal file
@@ -0,0 +1,18 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 027F410141020D0041016A0B0B
|
||||
...
|
||||
26
mlir/test/Target/Wasm/inputs/call.yaml.wasm
Normal file
26
mlir/test/Target/Wasm/inputs/call.yaml.wasm
Normal file
@@ -0,0 +1,26 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0 ]
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: forty_two
|
||||
Kind: FUNCTION
|
||||
Index: 1
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 412A0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 10000B
|
||||
...
|
||||
88
mlir/test/Target/Wasm/inputs/comparison_ops.yaml.wasm
Normal file
88
mlir/test/Target/Wasm/inputs/comparison_ops.yaml.wasm
Normal file
@@ -0,0 +1,88 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410C4132480B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 410C41324C0B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 410C4132490B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 410C41324D0B
|
||||
- Index: 4
|
||||
Locals: []
|
||||
Body: 410C41324A0B
|
||||
- Index: 5
|
||||
Locals: []
|
||||
Body: 410C41324B0B
|
||||
- Index: 6
|
||||
Locals: []
|
||||
Body: 410C41324E0B
|
||||
- Index: 7
|
||||
Locals: []
|
||||
Body: 410C41324F0B
|
||||
- Index: 8
|
||||
Locals: []
|
||||
Body: 420C4232530B
|
||||
- Index: 9
|
||||
Locals: []
|
||||
Body: 420C4232570B
|
||||
- Index: 10
|
||||
Locals: []
|
||||
Body: 420C4232540B
|
||||
- Index: 11
|
||||
Locals: []
|
||||
Body: 420C4232580B
|
||||
- Index: 12
|
||||
Locals: []
|
||||
Body: 420C4232550B
|
||||
- Index: 13
|
||||
Locals: []
|
||||
Body: 420C4232560B
|
||||
- Index: 14
|
||||
Locals: []
|
||||
Body: 420C4232590B
|
||||
- Index: 15
|
||||
Locals: []
|
||||
Body: 420C42325A0B
|
||||
- Index: 16
|
||||
Locals: []
|
||||
Body: 430000A04043000060415D0B
|
||||
- Index: 17
|
||||
Locals: []
|
||||
Body: 430000A04043000060415F0B
|
||||
- Index: 18
|
||||
Locals: []
|
||||
Body: 430000A04043000060415E0B
|
||||
- Index: 19
|
||||
Locals: []
|
||||
Body: 430000A0404300006041600B
|
||||
- Index: 20
|
||||
Locals: []
|
||||
Body: 440000000000001440440000000000002C40630B
|
||||
- Index: 21
|
||||
Locals: []
|
||||
Body: 440000000000001440440000000000002C40650B
|
||||
- Index: 22
|
||||
Locals: []
|
||||
Body: 440000000000001440440000000000002C40640B
|
||||
- Index: 23
|
||||
Locals: []
|
||||
Body: 440000000000001440440000000000002C40660B
|
||||
...
|
||||
69
mlir/test/Target/Wasm/inputs/convert.yaml.wasm
Normal file
69
mlir/test/Target/Wasm/inputs/convert.yaml.wasm
Normal file
@@ -0,0 +1,69 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F32
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F64
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0, 0, 0, 1, 1, 1, 1 ]
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: convert_i32_u_to_f32
|
||||
Kind: FUNCTION
|
||||
Index: 0
|
||||
- Name: convert_i32_s_to_f32
|
||||
Kind: FUNCTION
|
||||
Index: 1
|
||||
- Name: convert_i64_u_to_f32
|
||||
Kind: FUNCTION
|
||||
Index: 2
|
||||
- Name: convert_i64s_to_f32
|
||||
Kind: FUNCTION
|
||||
Index: 3
|
||||
- Name: convert_i32_u_to_f64
|
||||
Kind: FUNCTION
|
||||
Index: 4
|
||||
- Name: convert_i32_s_to_f64
|
||||
Kind: FUNCTION
|
||||
Index: 5
|
||||
- Name: convert_i64_u_to_f64
|
||||
Kind: FUNCTION
|
||||
Index: 6
|
||||
- Name: convert_i64s_to_f64
|
||||
Kind: FUNCTION
|
||||
Index: 7
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410AB30B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 412AB20B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 4211B50B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 420AB40B
|
||||
- Index: 4
|
||||
Locals: []
|
||||
Body: 410AB80B
|
||||
- Index: 5
|
||||
Locals: []
|
||||
Body: 412AB70B
|
||||
- Index: 6
|
||||
Locals: []
|
||||
Body: 4211BA0B
|
||||
- Index: 7
|
||||
Locals: []
|
||||
Body: 420AB90B
|
||||
...
|
||||
18
mlir/test/Target/Wasm/inputs/demote.yaml.wasm
Normal file
18
mlir/test/Target/Wasm/inputs/demote.yaml.wasm
Normal file
@@ -0,0 +1,18 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 44EC51B81E85EB0140B60B
|
||||
...
|
||||
19
mlir/test/Target/Wasm/inputs/double_nested_loop.yaml.wasm
Normal file
19
mlir/test/Target/Wasm/inputs/double_nested_loop.yaml.wasm
Normal file
@@ -0,0 +1,19 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes: []
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals:
|
||||
- Type: I32
|
||||
Count: 2
|
||||
Body: 0340200041016A2100037F41012001410C6A220120004A0D000B410A480D000B0B
|
||||
...
|
||||
@@ -0,0 +1,21 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes: []
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 0240024002400B0B0B0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 02400B02400B02400B0B
|
||||
...
|
||||
27
mlir/test/Target/Wasm/inputs/eq.yaml.wasm
Normal file
27
mlir/test/Target/Wasm/inputs/eq.yaml.wasm
Normal file
@@ -0,0 +1,27 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0, 0, 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410C4132460B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 42144205510B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 430000A04043000060415B0B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 440000000000003140440000000000000000610B
|
||||
...
|
||||
29
mlir/test/Target/Wasm/inputs/eqz.yaml.wasm
Normal file
29
mlir/test/Target/Wasm/inputs/eqz.yaml.wasm
Normal file
@@ -0,0 +1,29 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0 ]
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: eqz_i32
|
||||
Kind: FUNCTION
|
||||
Index: 0
|
||||
- Name: eqz_i64
|
||||
Kind: FUNCTION
|
||||
Index: 1
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410D450B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 420D500B
|
||||
...
|
||||
40
mlir/test/Target/Wasm/inputs/extend.yaml.wasm
Normal file
40
mlir/test/Target/Wasm/inputs/extend.yaml.wasm
Normal file
@@ -0,0 +1,40 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I64
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0, 1, 1, 0, 0, 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410AAC0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 410AAD0B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 410AC00B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 410AC10B
|
||||
- Index: 4
|
||||
Locals: []
|
||||
Body: 420AC20B
|
||||
- Index: 5
|
||||
Locals: []
|
||||
Body: 420AC30B
|
||||
- Index: 6
|
||||
Locals: []
|
||||
Body: 420AC40B
|
||||
...
|
||||
25
mlir/test/Target/Wasm/inputs/if.yaml.wasm
Normal file
25
mlir/test/Target/Wasm/inputs/if.yaml.wasm
Normal file
@@ -0,0 +1,25 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0, 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 2000410171047F200041036C41016A0520004101760B0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 20002000410171040041016A0B0B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 200068047F4102200041017668040041026A0B0541010B0B
|
||||
...
|
||||
17
mlir/test/Target/Wasm/inputs/loop.yaml.wasm
Normal file
17
mlir/test/Target/Wasm/inputs/loop.yaml.wasm
Normal file
@@ -0,0 +1,17 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes: []
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 03400B0B
|
||||
...
|
||||
20
mlir/test/Target/Wasm/inputs/loop_with_inst.yaml.wasm
Normal file
20
mlir/test/Target/Wasm/inputs/loop_with_inst.yaml.wasm
Normal file
@@ -0,0 +1,20 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals:
|
||||
- Type: I32
|
||||
Count: 1
|
||||
Body: 037F200041016A21002000410A480B0B
|
||||
...
|
||||
27
mlir/test/Target/Wasm/inputs/ne.yaml.wasm
Normal file
27
mlir/test/Target/Wasm/inputs/ne.yaml.wasm
Normal file
@@ -0,0 +1,27 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 0, 0, 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410C4132470B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 42144205520B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 430000A04043000060415C0B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 440000000000003140440000000000000000620B
|
||||
...
|
||||
18
mlir/test/Target/Wasm/inputs/promote.yaml.wasm
Normal file
18
mlir/test/Target/Wasm/inputs/promote.yaml.wasm
Normal file
@@ -0,0 +1,18 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F64
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 4300002841BB0B
|
||||
...
|
||||
53
mlir/test/Target/Wasm/inputs/reinterpret.yaml.wasm
Normal file
53
mlir/test/Target/Wasm/inputs/reinterpret.yaml.wasm
Normal file
@@ -0,0 +1,53 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I64
|
||||
- Index: 2
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F32
|
||||
- Index: 3
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F64
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 1, 2, 3 ]
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: i32.reinterpret_f32
|
||||
Kind: FUNCTION
|
||||
Index: 0
|
||||
- Name: i64.reinterpret_f64
|
||||
Kind: FUNCTION
|
||||
Index: 1
|
||||
- Name: f32.reinterpret_i32
|
||||
Kind: FUNCTION
|
||||
Index: 2
|
||||
- Name: f64.reinterpret_i64
|
||||
Kind: FUNCTION
|
||||
Index: 3
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 43000080BFBC0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 44000000000000F0BFBD0B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 417FBE0B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 427FBF0B
|
||||
...
|
||||
37
mlir/test/Target/Wasm/inputs/rounding.yaml.wasm
Normal file
37
mlir/test/Target/Wasm/inputs/rounding.yaml.wasm
Normal file
@@ -0,0 +1,37 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F64
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- F32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 1, 0, 1, 0, 1 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 4433333333333328C09B0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 43A01ACF3F8D0B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 4433333333333328C09C0B
|
||||
- Index: 3
|
||||
Locals: []
|
||||
Body: 43A01ACF3F8E0B
|
||||
- Index: 4
|
||||
Locals: []
|
||||
Body: 4433333333333328C09D0B
|
||||
- Index: 5
|
||||
Locals: []
|
||||
Body: 43A01ACF3F8F0B
|
||||
...
|
||||
24
mlir/test/Target/Wasm/inputs/wrap.yaml.wasm
Normal file
24
mlir/test/Target/Wasm/inputs/wrap.yaml.wasm
Normal file
@@ -0,0 +1,24 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes:
|
||||
- I64
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: i64_wrap
|
||||
Kind: FUNCTION
|
||||
Index: 0
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 2000A70B
|
||||
...
|
||||
28
mlir/test/Target/Wasm/invalid_block_type_index.yaml
Normal file
28
mlir/test/Target/Wasm/invalid_block_type_index.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
# RUN: yaml2obj %s | not mlir-translate --import-wasm -o - 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: type index references nonexistent type (2)
|
||||
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 1 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 410E020241016A0B0B
|
||||
# -----------------------------^^ Invalid type ID
|
||||
@@ -29,7 +29,7 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_0() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local of type f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local of type f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 8.000000e+00 : f32
|
||||
@@ -40,7 +40,7 @@
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.add %[[VAL_3]] %[[VAL_5]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_6]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_1() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local of type i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local of type i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 8 : i32
|
||||
@@ -51,7 +51,7 @@
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.add %[[VAL_3]] %[[VAL_5]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_6]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_2(
|
||||
// CHECK-LABEL: wasmssa.func @func_2(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i32>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 3 : i32
|
||||
// CHECK: wasmssa.local_set %[[ARG0]] : ref to i32 to %[[VAL_0]] : i32
|
||||
|
||||
17
mlir/test/Target/Wasm/loop.mlir
Normal file
17
mlir/test/Target/Wasm/loop.mlir
Normal file
@@ -0,0 +1,17 @@
|
||||
// RUN: yaml2obj %S/inputs/loop.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* IR generated from:
|
||||
(module
|
||||
(func
|
||||
(loop $my_loop
|
||||
)
|
||||
)
|
||||
)*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() {
|
||||
// CHECK: wasmssa.loop : {
|
||||
// CHECK: wasmssa.block_return
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1:
|
||||
// CHECK: wasmssa.return
|
||||
// CHECK: }
|
||||
33
mlir/test/Target/Wasm/loop_with_inst.mlir
Normal file
33
mlir/test/Target/Wasm/loop_with_inst.mlir
Normal file
@@ -0,0 +1,33 @@
|
||||
// RUN: yaml2obj %S/inputs/loop_with_inst.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Code used to create this test:
|
||||
|
||||
(module
|
||||
(func (result i32)
|
||||
(local $i i32)
|
||||
(loop $my_loop (result i32)
|
||||
local.get $i
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $i
|
||||
local.get $i
|
||||
i32.const 10
|
||||
i32.lt_s
|
||||
)
|
||||
)
|
||||
)*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local of type i32
|
||||
// CHECK: wasmssa.loop : {
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.local_get %[[VAL_0]] : ref to i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.const 1 : i32
|
||||
// CHECK: %[[VAL_3:.*]] = wasmssa.add %[[VAL_1]] %[[VAL_2]] : i32
|
||||
// CHECK: wasmssa.local_set %[[VAL_0]] : ref to i32 to %[[VAL_3]] : i32
|
||||
// CHECK: %[[VAL_4:.*]] = wasmssa.local_get %[[VAL_0]] : ref to i32
|
||||
// CHECK: %[[VAL_5:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_6:.*]] = wasmssa.lt_si %[[VAL_4]] %[[VAL_5]] : i32 -> i32
|
||||
// CHECK: wasmssa.block_return %[[VAL_6]] : i32
|
||||
// CHECK: }> ^bb1
|
||||
// CHECK: ^bb1(%[[VAL_7:.*]]: i32):
|
||||
// CHECK: wasmssa.return %[[VAL_7]] : i32
|
||||
@@ -16,14 +16,14 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @min_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @min_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.max %[[VAL_0]] %[[VAL_1]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : f32
|
||||
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @min_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @min_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.max %[[VAL_0]] %[[VAL_1]] : f64
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
(module (memory 0 0))
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.memory @mem_0 nested !wasmssa<limit[0: 0]>
|
||||
// CHECK-LABEL: wasmssa.memory @mem_0 !wasmssa<limit[0: 0]>
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
(module (memory 0 65536))
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.memory @mem_0 nested !wasmssa<limit[0: 65536]>
|
||||
// CHECK-LABEL: wasmssa.memory @mem_0 !wasmssa<limit[0: 65536]>
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
(module (memory 1))
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.memory @mem_0 nested !wasmssa<limit[1:]>
|
||||
// CHECK-LABEL: wasmssa.memory @mem_0 !wasmssa<limit[1:]>
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @min_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @min_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.min %[[VAL_0]] %[[VAL_1]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @min_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @min_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.min %[[VAL_0]] %[[VAL_1]] : f64
|
||||
|
||||
52
mlir/test/Target/Wasm/ne.mlir
Normal file
52
mlir/test/Target/Wasm/ne.mlir
Normal file
@@ -0,0 +1,52 @@
|
||||
// RUN: yaml2obj %S/inputs/ne.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $ne_i32 (result i32)
|
||||
i32.const 12
|
||||
i32.const 50
|
||||
i32.ne
|
||||
)
|
||||
|
||||
(func $ne_i64 (result i32)
|
||||
i64.const 20
|
||||
i64.const 5
|
||||
i64.ne
|
||||
)
|
||||
|
||||
(func $ne_f32 (result i32)
|
||||
f32.const 5
|
||||
f32.const 14
|
||||
f32.ne
|
||||
)
|
||||
|
||||
(func $ne_f64 (result i32)
|
||||
f64.const 17
|
||||
f64.const 0
|
||||
f64.ne
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ne %[[VAL_0]] %[[VAL_1]] : i32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 20 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 5 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ne %[[VAL_0]] %[[VAL_1]] : i64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ne %[[VAL_0]] %[[VAL_1]] : f32 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.700000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.ne %[[VAL_0]] %[[VAL_1]] : f64 -> i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
@@ -12,12 +12,12 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @neg_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @neg_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.neg %[[VAL_0]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @neg_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @neg_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.neg %[[VAL_0]] : f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @or_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @or_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.or %0 %1 : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @or_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @or_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.or %0 %1 : i64
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @popcnt_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @popcnt_i32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.popcnt %[[VAL_0]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @popcnt_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @popcnt_i64() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.popcnt %[[VAL_0]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
14
mlir/test/Target/Wasm/promote.mlir
Normal file
14
mlir/test/Target/Wasm/promote.mlir
Normal file
@@ -0,0 +1,14 @@
|
||||
// RUN: yaml2obj %S/inputs/promote.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/* Source code used to generate this test:
|
||||
(module
|
||||
(func $main (result f64)
|
||||
f32.const 10.5
|
||||
f64.promote_f32
|
||||
)
|
||||
)*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.050000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.promote %[[VAL_0]] : f32 to f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
46
mlir/test/Target/Wasm/reinterpret.mlir
Normal file
46
mlir/test/Target/Wasm/reinterpret.mlir
Normal file
@@ -0,0 +1,46 @@
|
||||
// RUN: yaml2obj %S/inputs/reinterpret.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
|
||||
/*
|
||||
Test generated from:
|
||||
(module
|
||||
(func (export "i32.reinterpret_f32") (result i32)
|
||||
f32.const -1
|
||||
i32.reinterpret_f32
|
||||
)
|
||||
|
||||
(func (export "i64.reinterpret_f64") (result i64)
|
||||
f64.const -1
|
||||
i64.reinterpret_f64
|
||||
)
|
||||
|
||||
(func (export "f32.reinterpret_i32") (result f32)
|
||||
i32.const -1
|
||||
f32.reinterpret_i32
|
||||
)
|
||||
|
||||
(func (export "f64.reinterpret_i64") (result f64)
|
||||
i64.const -1
|
||||
f64.reinterpret_i64
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @i32.reinterpret_f32() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.reinterpret %[[VAL_0]] : f32 as i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @i64.reinterpret_f64() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1.000000e+00 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.reinterpret %[[VAL_0]] : f64 as i64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @f32.reinterpret_i32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.reinterpret %[[VAL_0]] : i32 as f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @f64.reinterpret_i64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.reinterpret %[[VAL_0]] : i64 as f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
@@ -24,28 +24,28 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rem_u_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rem_u_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.rem_ui %0 %1 : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rem_u_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rem_u_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.rem_ui %0 %1 : i64
|
||||
// CHECK: wasmssa.return %2 : i64
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rem_s_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rem_s_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.rem_si %0 %1 : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
// CHECK: }
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rem_s_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rem_s_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.rem_si %0 %1 : i64
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rotl_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rotl_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.rotl %0 by %1 bits : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rotl_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rotl_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.rotl %0 by %1 bits : i64
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rotr_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rotr_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.rotr %0 by %1 bits : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @rotr_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @rotr_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.rotr %0 by %1 bits : i64
|
||||
|
||||
50
mlir/test/Target/Wasm/rounding.mlir
Normal file
50
mlir/test/Target/Wasm/rounding.mlir
Normal file
@@ -0,0 +1,50 @@
|
||||
// RUN: yaml2obj %S/inputs/rounding.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func $ceil_f64 (result f64)
|
||||
f64.const -12.1
|
||||
f64.ceil
|
||||
)
|
||||
(func $ceil_f32 (result f32)
|
||||
f32.const 1.618
|
||||
f32.ceil
|
||||
)
|
||||
(func $floor_f64 (result f64)
|
||||
f64.const -12.1
|
||||
f64.floor
|
||||
)
|
||||
(func $floor_f32 (result f32)
|
||||
f32.const 1.618
|
||||
f32.floor
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1.210000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.ceil %[[VAL_0]] : f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.618000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.ceil %[[VAL_0]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1.210000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.floor %[[VAL_0]] : f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.618000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.floor %[[VAL_0]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_4() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const -1.210000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.trunc %[[VAL_0]] : f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @func_5() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.618000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.trunc %[[VAL_0]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @shl_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @shl_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.shl %0 by %1 bits : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @shl_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @shl_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.shl %0 by %1 bits : i64
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @shr_s_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @shr_s_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.shr_s %0 by %1 bits : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @shr_s_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @shr_s_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.shr_s %0 by %1 bits : i64
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @shr_u_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @shr_u_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.shr_u %0 by %1 bits : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @shr_u_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @shr_u_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.shr_u %0 by %1 bits : i64
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @sqrt_f32() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @sqrt_f32() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.sqrt %[[VAL_0]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @sqrt_f64() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @sqrt_f64() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.000000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.sqrt %[[VAL_0]] : f64
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : f64
|
||||
|
||||
@@ -27,25 +27,25 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_0() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_0() -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 12 : i32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 50 : i32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : i32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_1() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func @func_1() -> i64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 20 : i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 5 : i64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : i64
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : i64
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_2() -> f32 {
|
||||
// CHECK-LABEL: wasmssa.func @func_2() -> f32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 5.000000e+00 : f32
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 1.400000e+01 : f32
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : f32
|
||||
// CHECK: wasmssa.return %[[VAL_2]] : f32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func nested @func_3() -> f64 {
|
||||
// CHECK-LABEL: wasmssa.func @func_3() -> f64 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.700000e+01 : f64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.const 0.000000e+00 : f64
|
||||
// CHECK: %[[VAL_2:.*]] = wasmssa.sub %[[VAL_0]] %[[VAL_1]] : f64
|
||||
|
||||
15
mlir/test/Target/Wasm/wrap.mlir
Normal file
15
mlir/test/Target/Wasm/wrap.mlir
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: yaml2obj %S/inputs/wrap.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
|
||||
/* Source code used to create this test:
|
||||
(module
|
||||
(func (export "i64_wrap") (param $in i64) (result i32)
|
||||
local.get $in
|
||||
i32.wrap_i64
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func exported @i64_wrap(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !wasmssa<local ref to i64>) -> i32 {
|
||||
// CHECK: %[[VAL_0:.*]] = wasmssa.local_get %[[ARG0]] : ref to i64
|
||||
// CHECK: %[[VAL_1:.*]] = wasmssa.wrap %[[VAL_0]] : i64 to i32
|
||||
// CHECK: wasmssa.return %[[VAL_1]] : i32
|
||||
@@ -14,13 +14,13 @@
|
||||
)
|
||||
*/
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @xor_i32() -> i32 {
|
||||
// CHECK-LABEL: wasmssa.func exported @xor_i32() -> i32 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i32
|
||||
// CHECK: %1 = wasmssa.const 3 : i32
|
||||
// CHECK: %2 = wasmssa.xor %0 %1 : i32
|
||||
// CHECK: wasmssa.return %2 : i32
|
||||
|
||||
// CHECK-LABEL: wasmssa.func @xor_i64() -> i64 {
|
||||
// CHECK-LABEL: wasmssa.func exported @xor_i64() -> i64 {
|
||||
// CHECK: %0 = wasmssa.const 10 : i64
|
||||
// CHECK: %1 = wasmssa.const 3 : i64
|
||||
// CHECK: %2 = wasmssa.xor %0 %1 : i64
|
||||
|
||||
Reference in New Issue
Block a user