summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm2wasm.h137
-rw-r--r--src/emscripten-optimizer/parser.cpp3
-rw-r--r--src/emscripten-optimizer/parser.h3
-rw-r--r--src/passes/OptimizeInstructions.cpp22
-rw-r--r--src/passes/Print.cpp56
-rw-r--r--src/wasm-builder.h116
-rw-r--r--src/wasm.h10
-rw-r--r--test/emcc_O2_hello_world.fromasm42
-rw-r--r--test/emcc_O2_hello_world.fromasm.imprecise42
-rw-r--r--test/emcc_hello_world.asm.js14
-rw-r--r--test/emcc_hello_world.fromasm1354
-rw-r--r--test/emcc_hello_world.fromasm.imprecise1354
-rw-r--r--test/memorygrowth.fromasm42
-rw-r--r--test/memorygrowth.fromasm.imprecise42
-rw-r--r--test/min.asm.js4
-rw-r--r--test/min.fromasm7
-rw-r--r--test/min.fromasm.imprecise7
-rw-r--r--test/passes/optimize-instructions.txt32
-rw-r--r--test/passes/optimize-instructions.wast8
-rw-r--r--test/unit.fromasm6
-rw-r--r--test/unit.fromasm.imprecise6
21 files changed, 544 insertions, 2763 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 910134024..72a8b9048 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -29,6 +29,7 @@
#include "asm_v_wasm.h"
#include "pass.h"
#include "ast_utils.h"
+#include "wasm-builder.h"
namespace wasm {
@@ -132,6 +133,8 @@ class Asm2WasmBuilder {
MixedArena &allocator;
+ Builder builder;
+
// globals
unsigned nextGlobal; // next place to put a global
@@ -202,8 +205,14 @@ private:
IString Math_ceil;
IString Math_sqrt;
+ IString llvm_cttz_i32;
+
IString tempDoublePtr; // imported name of tempDoublePtr
+ // possibly-minified names, detected via their exports
+ IString udivmoddi4;
+ IString getTempRet0;
+
// function types. we fill in this information as we see
// uses, in the first pass
@@ -260,6 +269,7 @@ public:
Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth, bool debug, bool imprecise)
: wasm(wasm),
allocator(wasm.allocator),
+ builder(wasm),
nextGlobal(8),
maxGlobal(1000),
memoryGrowth(memoryGrowth),
@@ -486,10 +496,15 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
assert(module[0] == NAME);
moduleName = module[1]->getIString();
if (moduleName == ENV) {
- if (imported[2] == TEMP_DOUBLE_PTR) {
+ auto base = imported[2]->getIString();
+ if (base == TEMP_DOUBLE_PTR) {
assert(tempDoublePtr.isNull());
tempDoublePtr = name;
// we don't return here, as we can only optimize out some uses of tDP. So it remains imported
+ } else if (base == LLVM_CTTZ_I32) {
+ assert(llvm_cttz_i32.isNull());
+ llvm_cttz_i32 = name;
+ return;
}
}
}
@@ -657,6 +672,10 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
// asm.js memory growth provides this special non-asm function, which we don't need (we use grow_memory)
assert(!wasm.checkFunction(value));
continue;
+ } else if (key == UDIVMODDI4) {
+ udivmoddi4 = value;
+ } else if (key == GET_TEMP_RET0) {
+ getTempRet0 = value;
}
assert(wasm.checkFunction(value));
auto export_ = allocator.alloc<Export>();
@@ -739,10 +758,107 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
}
wasm.memory.exportName = MEMORY;
+
+ if (udivmoddi4.is() && getTempRet0.is()) {
+ // generate a wasm-optimized __udivmoddi4 method, which we can do much more efficiently in wasm
+ // we can only do this if we know getTempRet0 as well since we use it to figure out which minified global is tempRet0
+ // (getTempRet0 might be an import, if this is a shared module, so we can't optimize that case)
+ int tempRet0;
+ {
+ Expression* curr = wasm.getFunction(getTempRet0)->body;
+ if (curr->is<Block>()) curr = curr->cast<Block>()->list[0];
+ curr = curr->cast<Return>()->value;
+ auto* load = curr->cast<Load>();
+ auto* ptr = load->ptr->cast<Const>();
+ tempRet0 = ptr->value.geti32() + load->offset;
+ }
+ // udivmoddi4 receives xl, xh, yl, yl, r, and
+ // if r then *r = x % y
+ // returns x / y
+ auto* func = wasm.getFunction(udivmoddi4);
+ assert(!func->type.is());
+ Name xl = func->params[0].name,
+ xh = func->params[1].name,
+ yl = func->params[2].name,
+ yh = func->params[3].name,
+ r = func->params[4].name;
+ func->locals.clear();
+ Name x64("x64"), y64("y64");
+ func->locals.emplace_back(x64, i64);
+ func->locals.emplace_back(y64, i64);
+ auto* body = allocator.alloc<Block>();
+ auto recreateI64 = [&](Name target, Name low, Name high) {
+ return builder.makeSetLocal(
+ target,
+ builder.makeBinary(
+ Or,
+ builder.makeUnary(
+ ExtendUInt32,
+ builder.makeGetLocal(low, i32)
+ ),
+ builder.makeBinary(
+ Shl,
+ builder.makeUnary(
+ ExtendUInt32,
+ builder.makeGetLocal(high, i32)
+ ),
+ builder.makeConst(Literal(int64_t(32)))
+ )
+ )
+ );
+ };
+ body->list.push_back(recreateI64(x64, xl, xh));
+ body->list.push_back(recreateI64(y64, yl, yh));
+ body->list.push_back(
+ builder.makeIf(
+ builder.makeGetLocal(r, i32),
+ builder.makeStore(
+ 8, 0, 8,
+ builder.makeGetLocal(r, i32),
+ builder.makeBinary(
+ RemU,
+ builder.makeGetLocal(x64, i64),
+ builder.makeGetLocal(y64, i64)
+ )
+ )
+ )
+ );
+ body->list.push_back(
+ builder.makeSetLocal(
+ x64,
+ builder.makeBinary(
+ DivU,
+ builder.makeGetLocal(x64, i64),
+ builder.makeGetLocal(y64, i64)
+ )
+ )
+ );
+ body->list.push_back(
+ builder.makeStore(
+ 4, 0, 4,
+ builder.makeConst(Literal(int32_t(tempRet0))),
+ builder.makeUnary(
+ WrapInt64,
+ builder.makeBinary(
+ ShrU,
+ builder.makeGetLocal(x64, i64),
+ builder.makeConst(Literal(int64_t(32)))
+ )
+ )
+ )
+ );
+ body->list.push_back(
+ builder.makeUnary(
+ WrapInt64,
+ builder.makeGetLocal(x64, i64)
+ )
+ );
+ func->body = body;
+ }
}
Function* Asm2WasmBuilder::processFunction(Ref ast) {
- //if (ast[1] != IString("qta")) return nullptr;
+ auto name = ast[1]->getIString();
if (debug) {
std::cout << "\nfunc: " << ast[1]->getIString().str << '\n';
@@ -751,7 +867,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
}
auto function = allocator.alloc<Function>();
- function->name = ast[1]->getIString();
+ function->name = name;
Ref params = ast[2];
Ref body = ast[3];
@@ -1092,10 +1208,10 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
ret->type = WasmType::i32;
return ret;
}
- if (name == Math_clz32) {
+ if (name == Math_clz32 || name == llvm_cttz_i32) {
assert(ast[2]->size() == 1);
auto ret = allocator.alloc<Unary>();
- ret->op = Clz;
+ ret->op = name == Math_clz32 ? Clz : Ctz;
ret->value = process(ast[2][0]);
ret->type = WasmType::i32;
return ret;
@@ -1279,9 +1395,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
Break *breakOut = allocator.alloc<Break>();
breakOut->name = out;
If *condition = allocator.alloc<If>();
- condition->condition = process(ast[1]);
- condition->ifTrue = allocator.alloc<Nop>();
- condition->ifFalse = breakOut;
+ condition->condition = builder.makeUnary(EqZ, process(ast[1]));
+ condition->ifTrue = breakOut;
auto body = allocator.alloc<Block>();
body->list.push_back(condition);
body->list.push_back(process(ast[2]));
@@ -1377,9 +1492,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
Break *breakOut = allocator.alloc<Break>();
breakOut->name = out;
If *condition = allocator.alloc<If>();
- condition->condition = process(fcond);
- condition->ifTrue = allocator.alloc<Nop>();
- condition->ifFalse = breakOut;
+ condition->condition = builder.makeUnary(EqZ, process(fcond));
+ condition->ifTrue = breakOut;
auto body = allocator.alloc<Block>();
body->list.push_back(condition);
body->list.push_back(process(fbody));
@@ -1594,7 +1708,6 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
// cleanups/checks
assert(breakStack.size() == 0 && continueStack.size() == 0);
assert(parentLabel.isNull());
-
return function;
}
diff --git a/src/emscripten-optimizer/parser.cpp b/src/emscripten-optimizer/parser.cpp
index 7005dc4b4..b8297fc29 100644
--- a/src/emscripten-optimizer/parser.cpp
+++ b/src/emscripten-optimizer/parser.cpp
@@ -48,6 +48,9 @@ IString TOPLEVEL("toplevel"),
INF("inf"),
NaN("nan"),
TEMP_RET0("tempRet0"),
+ GET_TEMP_RET0("getTempRet0"),
+ LLVM_CTTZ_I32("_llvm_cttz_i32"),
+ UDIVMODDI4("___udivmoddi4"),
UNARY_PREFIX("unary-prefix"),
UNARY_POSTFIX("unary-postfix"),
MATH_FROUND("Math_fround"),
diff --git a/src/emscripten-optimizer/parser.h b/src/emscripten-optimizer/parser.h
index da3e6f5c7..367c831e2 100644
--- a/src/emscripten-optimizer/parser.h
+++ b/src/emscripten-optimizer/parser.h
@@ -63,6 +63,9 @@ extern IString TOPLEVEL,
INF,
NaN,
TEMP_RET0,
+ GET_TEMP_RET0,
+ LLVM_CTTZ_I32,
+ UDIVMODDI4,
UNARY_PREFIX,
UNARY_POSTFIX,
MATH_FROUND,
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 638977353..de342b43f 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -36,6 +36,28 @@ struct OptimizeInstructions : public WalkerPass<WasmWalker<OptimizeInstructions>
}
}
}
+ void visitUnary(Unary* curr) {
+ if (curr->op == EqZ) {
+ // fold comparisons that flow into an EqZ
+ auto* child = curr->value->dyn_cast<Binary>();
+ if (child && (child->type == i32 || child->type == i64)) {
+ switch (child->op) {
+ case Eq: child->op = Ne; break;
+ case Ne: child->op = Eq; break;
+ case LtS: child->op = GeS; break;
+ case LtU: child->op = GeU; break;
+ case LeS: child->op = GtS; break;
+ case LeU: child->op = GtU; break;
+ case GtS: child->op = LeS; break;
+ case GtU: child->op = LeU; break;
+ case GeS: child->op = LtS; break;
+ case GeU: child->op = LtU; break;
+ default: return;
+ }
+ replaceCurrent(child);
+ }
+ }
+ }
};
static RegisterPass<OptimizeInstructions> registerPass("optimize-instructions", "optimizes instruction combinations");
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 056b61939..8e3d503b8 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -26,17 +26,27 @@ namespace wasm {
struct PrintSExpression : public WasmVisitor<PrintSExpression, void> {
std::ostream& o;
- unsigned indent;
+ unsigned indent = 0;
+
bool minify;
const char *maybeSpace;
const char *maybeNewLine;
- PrintSExpression(std::ostream& o, bool minify = false)
- : o(o), indent(0), minify(minify) {
+ bool fullAST = false; // whether to not elide nodes in output when possible
+ // (like implicit blocks)
+
+ PrintSExpression(std::ostream& o) : o(o) {
+ setMinify(false);
+ }
+
+ void setMinify(bool minify_) {
+ minify = minify_;
maybeSpace = minify ? "" : " ";
maybeNewLine = minify ? "" : "\n";
}
+ void setFullAST(bool fullAST_) { fullAST = fullAST_; }
+
void incIndent() {
if (minify) return;
o << '\n';
@@ -95,13 +105,13 @@ struct PrintSExpression : public WasmVisitor<PrintSExpression, void> {
incIndent();
printFullLine(curr->condition);
// ifTrue and False have implict blocks, avoid printing them if possible
- if (curr->ifTrue->is<Block>() && curr->ifTrue->dyn_cast<Block>()->name.isNull() && curr->ifTrue->dyn_cast<Block>()->list.size() == 1) {
+ if (!fullAST && curr->ifTrue->is<Block>() && curr->ifTrue->dyn_cast<Block>()->name.isNull() && curr->ifTrue->dyn_cast<Block>()->list.size() == 1) {
printFullLine(curr->ifTrue->dyn_cast<Block>()->list.back());
} else {
printFullLine(curr->ifTrue);
}
if (curr->ifFalse) {
- if (curr->ifFalse->is<Block>() && curr->ifFalse->dyn_cast<Block>()->name.isNull() && curr->ifFalse->dyn_cast<Block>()->list.size() == 1) {
+ if (!fullAST && curr->ifFalse->is<Block>() && curr->ifFalse->dyn_cast<Block>()->name.isNull() && curr->ifFalse->dyn_cast<Block>()->list.size() == 1) {
printFullLine(curr->ifFalse->dyn_cast<Block>()->list.back());
} else {
printFullLine(curr->ifFalse);
@@ -120,7 +130,7 @@ struct PrintSExpression : public WasmVisitor<PrintSExpression, void> {
}
incIndent();
auto block = curr->body->dyn_cast<Block>();
- if (block && block->name.isNull()) {
+ if (!fullAST && block && block->name.isNull()) {
// wasm spec has loops containing children directly, while our ast
// has a single child for simplicity. print out the optimal form.
for (auto expression : block->list) {
@@ -435,7 +445,7 @@ struct PrintSExpression : public WasmVisitor<PrintSExpression, void> {
}
// It is ok to emit a block here, as a function can directly contain a list, even if our
// ast avoids that for simplicity. We can just do that optimization here..
- if (curr->body->is<Block>() && curr->body->cast<Block>()->name.isNull()) {
+ if (!fullAST && curr->body->is<Block>() && curr->body->cast<Block>()->name.isNull()) {
Block* block = curr->body->cast<Block>();
for (auto item : block->list) {
printFullLine(item);
@@ -526,8 +536,6 @@ struct PrintSExpression : public WasmVisitor<PrintSExpression, void> {
}
};
-// Pass entry point. Eventually this will direct printing to one of various options.
-
void Printer::run(PassRunner* runner, Module* module) {
PrintSExpression print(o);
print.visitModule(module);
@@ -536,26 +544,42 @@ void Printer::run(PassRunner* runner, Module* module) {
static RegisterPass<Printer> registerPass("print", "print in s-expression format");
// Prints out a minified module
+
class MinifiedPrinter : public Printer {
public:
MinifiedPrinter() : Printer() {}
MinifiedPrinter(std::ostream& o) : Printer(o) {}
- void run(PassRunner* runner, Module* module) override;
+ void run(PassRunner* runner, Module* module) override {
+ PrintSExpression print(o);
+ print.setMinify(true);
+ print.visitModule(module);
+ }
};
-void MinifiedPrinter::run(PassRunner* runner, Module* module) {
- PrintSExpression print(o, true);
- print.visitModule(module);
-}
+static RegisterPass<MinifiedPrinter> registerMinifyPass("print-minified", "print in minified s-expression format");
+// Prints out a module withough elision, i.e., the full ast
-static RegisterPass<MinifiedPrinter> registerMinifyPass("print-minified", "print in minified s-expression format");
+class FullPrinter : public Printer {
+ public:
+ FullPrinter() : Printer() {}
+ FullPrinter(std::ostream& o) : Printer(o) {}
+
+ void run(PassRunner* runner, Module* module) override {
+ PrintSExpression print(o);
+ print.setFullAST(true);
+ print.visitModule(module);
+ }
+};
+
+static RegisterPass<FullPrinter> registerFullASTPass("print-full", "print in full s-expression format");
// Print individual expressions
std::ostream& WasmPrinter::printExpression(Expression* expression, std::ostream& o, bool minify) {
- PrintSExpression print(o, minify);
+ PrintSExpression print(o);
+ print.setMinify(minify);
print.visit(expression);
return o;
}
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
new file mode 100644
index 000000000..de3371274
--- /dev/null
+++ b/src/wasm-builder.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wasm_builder_h
+#define wasm_builder_h
+
+#include <wasm.h>
+
+namespace wasm {
+
+class Builder {
+ MixedArena &allocator;
+
+public:
+ Builder(AllocatingModule& wasm) : allocator(wasm.allocator) {}
+
+ // Nop TODO: add all the rest
+ // Block
+ If* makeIf(Expression* condition, Expression* ifTrue, Expression* ifFalse=nullptr) {
+ auto* ret = allocator.alloc<If>();
+ ret->condition = condition; ret->ifTrue = ifTrue; ret->ifFalse = ifFalse;
+ ret->finalize();
+ return ret;
+ }
+ // Loop
+ // Break
+ // Switch
+ // CallBase
+ // Call
+ // CallImport
+ // FunctionType
+ GetLocal* makeGetLocal(Name name, WasmType type) {
+ auto* ret = allocator.alloc<GetLocal>();
+ ret->name = name;
+ ret->type = type;
+ return ret;
+ }
+ SetLocal* makeSetLocal(Name name, Expression* value) {
+ auto* ret = allocator.alloc<SetLocal>();
+ ret->name = name;
+ ret->value = value;
+ ret->type = value->type;
+ return ret;
+ }
+ // Load
+ Store* makeStore(unsigned bytes, uint32_t offset, unsigned align, Expression *ptr, Expression *value) {
+ auto* ret = allocator.alloc<Store>();
+ ret->bytes = bytes; ret->offset = offset; ret->align = align; ret->ptr = ptr; ret->value = value;
+ ret->type = value->type;
+ return ret;
+ }
+ Const* makeConst(Literal value) {
+ auto* ret = allocator.alloc<Const>();
+ ret->value = value;
+ ret->type = value.type;
+ return ret;
+ }
+ Unary* makeUnary(UnaryOp op, Expression *value, WasmType type=none) {
+ auto* ret = allocator.alloc<Unary>();
+ ret->op = op; ret->value = value;
+ if (type != none) {
+ ret->type = type; // some opcodes have more than one type, user must provide it
+ } else {
+ switch (op) {
+ case Clz:
+ case Ctz:
+ case Popcnt:
+ case Neg:
+ case Abs:
+ case Ceil:
+ case Floor:
+ case Trunc:
+ case Nearest:
+ case Sqrt: ret->type = value->type; break;
+ case EqZ: ret->type = i32; break;
+ case ExtendSInt32: case ExtendUInt32: ret->type = i64; break;
+ case WrapInt64: ret->type = i32; break;
+ case PromoteFloat32: ret->type = f64; break;
+ case DemoteFloat64: ret->type = f32; break;
+ case TruncSFloat32: case TruncUFloat32: case TruncSFloat64: case TruncUFloat64: case ReinterpretFloat:
+ case ConvertSInt32: case ConvertUInt32: case ConvertSInt64: case ConvertUInt64: case ReinterpretInt: abort(); // user needs to say the type
+ default: abort();
+ }
+ }
+ return ret;
+ }
+ Binary* makeBinary(BinaryOp op, Expression *left, Expression *right) {
+ auto* ret = allocator.alloc<Binary>();
+ ret->op = op; ret->left = left; ret->right = right;
+ ret->finalize();
+ return ret;
+ }
+ // Select
+ // Return
+ // Host
+ // Unreachable
+
+};
+
+} // namespace wasm
+
+#endif // wasm_builder_h
+
diff --git a/src/wasm.h b/src/wasm.h
index f985e9b59..c9494d4d6 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -742,7 +742,8 @@ public:
ReturnId,
HostId,
NopId,
- UnreachableId
+ UnreachableId,
+ NumExpressionIds
};
Id _id;
@@ -827,7 +828,7 @@ public:
Expression *condition, *ifTrue, *ifFalse;
void finalize() {
- if (condition) {
+ if (ifFalse) {
type = getReachableWasmType(ifTrue->type, ifFalse->type);
}
}
@@ -975,10 +976,9 @@ public:
UnaryOp op;
Expression *value;
- // the type is always the type of the operands,
- // except for relationals
-
bool isRelational() { return op == EqZ; }
+
+ // no finalize since some opcodes have more than one type, so user must set it anyhow
};
class Binary : public Expression {
diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm
index 62eb5d4a9..8ca7f7436 100644
--- a/test/emcc_O2_hello_world.fromasm
+++ b/test/emcc_O2_hello_world.fromasm
@@ -9543,13 +9543,13 @@
)
(block
(loop $while-out$0 $while-in$1
- (if
- (i32.and
- (get_local $i1)
- (i32.const 3)
+ (br_if $while-out$0
+ (i32.eqz
+ (i32.and
+ (get_local $i1)
+ (i32.const 3)
+ )
)
- (nop)
- (br $while-out$0)
)
(if
(i32.eqz
@@ -9586,13 +9586,11 @@
(br $while-in$1)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.ge_s
+ (br_if $while-out$2
+ (i32.lt_s
(get_local $i3)
(i32.const 4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $i1)
@@ -9623,13 +9621,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.gt_s
+ (br_if $while-out$4
+ (i32.le_s
(get_local $i3)
(i32.const 0)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $i1)
@@ -9736,13 +9732,11 @@
)
)
(loop $while-out$0 $while-in$1
- (if
- (i32.lt_s
+ (br_if $while-out$0
+ (i32.ge_s
(get_local $i1)
(get_local $i5)
)
- (nop)
- (br $while-out$0)
)
(i32.store8
(get_local $i1)
@@ -9759,13 +9753,11 @@
)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.lt_s
+ (br_if $while-out$2
+ (i32.ge_s
(get_local $i1)
(get_local $i7)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $i1)
@@ -9782,13 +9774,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.lt_s
+ (br_if $while-out$4
+ (i32.ge_s
(get_local $i1)
(get_local $i4)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $i1)
diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise
index 62eb5d4a9..8ca7f7436 100644
--- a/test/emcc_O2_hello_world.fromasm.imprecise
+++ b/test/emcc_O2_hello_world.fromasm.imprecise
@@ -9543,13 +9543,13 @@
)
(block
(loop $while-out$0 $while-in$1
- (if
- (i32.and
- (get_local $i1)
- (i32.const 3)
+ (br_if $while-out$0
+ (i32.eqz
+ (i32.and
+ (get_local $i1)
+ (i32.const 3)
+ )
)
- (nop)
- (br $while-out$0)
)
(if
(i32.eqz
@@ -9586,13 +9586,11 @@
(br $while-in$1)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.ge_s
+ (br_if $while-out$2
+ (i32.lt_s
(get_local $i3)
(i32.const 4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $i1)
@@ -9623,13 +9621,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.gt_s
+ (br_if $while-out$4
+ (i32.le_s
(get_local $i3)
(i32.const 0)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $i1)
@@ -9736,13 +9732,11 @@
)
)
(loop $while-out$0 $while-in$1
- (if
- (i32.lt_s
+ (br_if $while-out$0
+ (i32.ge_s
(get_local $i1)
(get_local $i5)
)
- (nop)
- (br $while-out$0)
)
(i32.store8
(get_local $i1)
@@ -9759,13 +9753,11 @@
)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.lt_s
+ (br_if $while-out$2
+ (i32.ge_s
(get_local $i1)
(get_local $i7)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $i1)
@@ -9782,13 +9774,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.lt_s
+ (br_if $while-out$4
+ (i32.ge_s
(get_local $i1)
(get_local $i4)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $i1)
diff --git a/test/emcc_hello_world.asm.js b/test/emcc_hello_world.asm.js
index 6b904c741..cd188303e 100644
--- a/test/emcc_hello_world.asm.js
+++ b/test/emcc_hello_world.asm.js
@@ -77,6 +77,7 @@ Module["asm"] = (function(global, env, buffer) {
var _pthread_cleanup_push=env._pthread_cleanup_push;
var _sysconf=env._sysconf;
var ___syscall146=env.___syscall146;
+ var _llvm_cttz_i32=env._llvm_cttz_i32;
var tempFloat = 0.0;
// EMSCRIPTEN_START_FUNCS
@@ -6757,17 +6758,6 @@ function _bitshift64Ashr(low, high, bits) {
tempRet0 = (high|0) < 0 ? -1 : 0;
return (high >> (bits - 32))|0;
}
-function _llvm_cttz_i32(x) {
- x = x|0;
- var ret = 0;
- ret = ((HEAP8[(((cttz_i8)+(x & 0xff))>>0)])|0);
- if ((ret|0) < 8) return ret|0;
- ret = ((HEAP8[(((cttz_i8)+((x >> 8)&0xff))>>0)])|0);
- if ((ret|0) < 8) return (ret + 8)|0;
- ret = ((HEAP8[(((cttz_i8)+((x >> 16)&0xff))>>0)])|0);
- if ((ret|0) < 8) return (ret + 16)|0;
- return (((HEAP8[(((cttz_i8)+(x >>> 24))>>0)])|0) + 24)|0;
- }
// ======== compiled code from system/lib/compiler-rt , see readme therein
function ___muldsi3($a, $b) {
@@ -7106,6 +7096,6 @@ var FUNCTION_TABLE_ii = [b0,___stdio_close];
var FUNCTION_TABLE_iiii = [b1,b1,___stdout_write,___stdio_seek,___stdio_write,b1,b1,b1];
var FUNCTION_TABLE_vi = [b2,b2,b2,b2,b2,_cleanup,b2,b2];
- return { _i64Subtract: _i64Subtract, _free: _free, _main: _main, _i64Add: _i64Add, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, _bitshift64Lshr: _bitshift64Lshr, _fflush: _fflush, ___errno_location: ___errno_location, _bitshift64Shl: _bitshift64Shl, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, establishStackSpace: establishStackSpace, setThrew: setThrew, setTempRet0: setTempRet0, getTempRet0: getTempRet0, dynCall_ii: dynCall_ii, dynCall_iiii: dynCall_iiii, dynCall_vi: dynCall_vi };
+ return { _i64Subtract: _i64Subtract, _free: _free, _main: _main, _i64Add: _i64Add, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, _bitshift64Lshr: _bitshift64Lshr, _fflush: _fflush, ___errno_location: ___errno_location, _bitshift64Shl: _bitshift64Shl, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, establishStackSpace: establishStackSpace, setThrew: setThrew, setTempRet0: setTempRet0, getTempRet0: getTempRet0, dynCall_ii: dynCall_ii, dynCall_iiii: dynCall_iiii, dynCall_vi: dynCall_vi, ___udivmoddi4: ___udivmoddi4 };
})
;
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index be7a45cec..60394be4f 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -50,6 +50,7 @@
(export "dynCall_ii" $dynCall_ii)
(export "dynCall_iiii" $dynCall_iiii)
(export "dynCall_vi" $dynCall_vi)
+ (export "___udivmoddi4" $___udivmoddi4)
(table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2)
(func $stackAlloc (param $size i32) (result i32)
(local $ret i32)
@@ -28142,13 +28143,11 @@
)
)
(loop $while-out$0 $while-in$1
- (if
- (i32.lt_s
+ (br_if $while-out$0
+ (i32.ge_s
(get_local $ptr)
(get_local $unaligned)
)
- (nop)
- (br $while-out$0)
)
(i32.store8
(get_local $ptr)
@@ -28165,13 +28164,11 @@
)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.lt_s
+ (br_if $while-out$2
+ (i32.ge_s
(get_local $ptr)
(get_local $stop4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $ptr)
@@ -28188,13 +28185,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.lt_s
+ (br_if $while-out$4
+ (i32.ge_s
(get_local $ptr)
(get_local $stop)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $ptr)
@@ -28368,13 +28363,13 @@
)
(block
(loop $while-out$0 $while-in$1
- (if
- (i32.and
- (get_local $dest)
- (i32.const 3)
+ (br_if $while-out$0
+ (i32.eqz
+ (i32.and
+ (get_local $dest)
+ (i32.const 3)
+ )
)
- (nop)
- (br $while-out$0)
)
(if
(i32.eq
@@ -28412,13 +28407,11 @@
(br $while-in$1)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.ge_s
+ (br_if $while-out$2
+ (i32.lt_s
(get_local $num)
(i32.const 4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $dest)
@@ -28449,13 +28442,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.gt_s
+ (br_if $while-out$4
+ (i32.le_s
(get_local $num)
(i32.const 0)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $dest)
@@ -28552,100 +28543,6 @@
)
)
)
- (func $_llvm_cttz_i32 (param $x i32) (result i32)
- (local $ret i32)
- (if
- (i32.lt_s
- (set_local $ret
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.and
- (get_local $x)
- (i32.const 255)
- )
- )
- )
- )
- (i32.const 8)
- )
- (return
- (get_local $ret)
- )
- )
- (if
- (i32.lt_s
- (set_local $ret
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.and
- (i32.shr_s
- (get_local $x)
- (i32.const 8)
- )
- (i32.const 255)
- )
- )
- )
- )
- (i32.const 8)
- )
- (return
- (i32.add
- (get_local $ret)
- (i32.const 8)
- )
- )
- )
- (if
- (i32.lt_s
- (set_local $ret
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.and
- (i32.shr_s
- (get_local $x)
- (i32.const 16)
- )
- (i32.const 255)
- )
- )
- )
- )
- (i32.const 8)
- )
- (return
- (i32.add
- (get_local $ret)
- (i32.const 16)
- )
- )
- )
- (return
- (i32.add
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.shr_u
- (get_local $x)
- (i32.const 24)
- )
- )
- )
- (i32.const 24)
- )
- )
- )
(func $___muldsi3 (param $$a i32) (param $$b i32) (result i32)
(local $$8 i32)
(local $$6 i32)
@@ -29240,1209 +29137,60 @@
)
)
(func $___udivmoddi4 (param $$a$0 i32) (param $$a$1 i32) (param $$b$0 i32) (param $$b$1 i32) (param $$rem i32) (result i32)
- (local $$_0$1 i32)
- (local $$_0$0 i32)
- (local $$n_sroa_1_4_extract_trunc i32)
- (local $$n_sroa_0_0_extract_trunc i32)
- (local $$d_sroa_0_0_extract_trunc i32)
- (local $$d_sroa_1_4_extract_trunc i32)
- (local $$88 i32)
- (local $$sr_1_ph i32)
- (local $$r_sroa_1_1_ph i32)
- (local $$r_sroa_0_1_ph i32)
- (local $$q_sroa_1_1_ph i32)
- (local $$q_sroa_0_1_ph i32)
- (local $$r_sroa_0_1201 i32)
- (local $$q_sroa_1_1198 i32)
- (local $$q_sroa_0_1199 i32)
- (local $$q_sroa_0_0_insert_ext75$0 i32)
- (local $$n_sroa_1_4_extract_shift$0 i32)
- (local $$91 i32)
- (local $$78 i32)
- (local $$57 i32)
- (local $$150$1 i32)
- (local $$125 i32)
- (local $$119 i32)
- (local $$sr_1202 i32)
- (local $$r_sroa_1_4_extract_trunc i32)
- (local $$r_sroa_1_1_lcssa i32)
- (local $$r_sroa_1_1200 i32)
- (local $$r_sroa_0_1_lcssa i32)
- (local $$r_sroa_0_0_insert_insert42$1 i32)
- (local $$r_sroa_0_0_insert_insert42$0 i32)
- (local $$r_sroa_0_0_extract_trunc i32)
- (local $$q_sroa_1_1_lcssa i32)
- (local $$q_sroa_0_1_lcssa i32)
- (local $$q_sroa_0_0_insert_ext75$1 i32)
- (local $$d_sroa_0_0_insert_insert99$1 i32)
- (local $$d_sroa_0_0_insert_insert99$0 i32)
- (local $$carry_0_lcssa$1 i32)
- (local $$carry_0_lcssa$0 i32)
- (local $$carry_0203 i32)
- (local $$95 i32)
- (local $$92 i32)
- (local $$89 i32)
- (local $$58 i32)
- (local $$51 i32)
- (local $$4 i32)
- (local $$17 i32)
- (local $$152 i32)
- (local $$149 i32)
- (local $$147 i32)
- (local $$130 i32)
- (local $$126 i32)
- (local $$105 i32)
- (local $$q_sroa_0_0_insert_insert77$1 i32)
- (local $$d_sroa_1_4_extract_shift$0 i32)
- (local $$66 i32)
- (local $$37 i32)
- (local $$155 i32)
- (local $$151$0 i32)
- (local $$137$1 i32)
- (local $$137$0 i32)
- (local $$86 i32)
- (local $$49 i32)
- (local $$154$0 i32)
- (local $$117 i32)
- (set_local $$n_sroa_0_0_extract_trunc
- (get_local $$a$0)
- )
- (set_local $$n_sroa_1_4_extract_trunc
- (set_local $$n_sroa_1_4_extract_shift$0
- (get_local $$a$1)
- )
- )
- (set_local $$d_sroa_0_0_extract_trunc
- (get_local $$b$0)
- )
- (set_local $$d_sroa_1_4_extract_trunc
- (set_local $$d_sroa_1_4_extract_shift$0
- (get_local $$b$1)
- )
- )
- (if
- (i32.eq
- (get_local $$n_sroa_1_4_extract_trunc)
- (i32.const 0)
- )
- (block
- (set_local $$4
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- )
- (if
- (i32.eq
- (get_local $$d_sroa_1_4_extract_trunc)
- (i32.const 0)
- )
- (block
- (if
- (get_local $$4)
- (block
- (i32.store
- (get_local $$rem)
- (i32.rem_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.div_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- (block
- (if
- (i32.eqz
- (get_local $$4)
- )
- (block
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (i32.store
- (get_local $$rem)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- )
- )
- (set_local $$17
- (i32.eq
- (get_local $$d_sroa_1_4_extract_trunc)
- (i32.const 0)
- )
- )
- (block $do-once$0
- (if
- (i32.eq
- (get_local $$d_sroa_0_0_extract_trunc)
- (i32.const 0)
- )
- (block
- (if
- (get_local $$17)
- (block
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.rem_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.div_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.eq
- (get_local $$n_sroa_0_0_extract_trunc)
- (i32.const 0)
- )
- (block
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.const 0)
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.rem_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.div_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.eq
- (i32.and
- (set_local $$37
- (i32.sub
- (get_local $$d_sroa_1_4_extract_trunc)
- (i32.const 1)
- )
- )
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- (i32.const 0)
- )
- (block
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.or
- (i32.and
- (get_local $$37)
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (call $_llvm_cttz_i32
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.le_u
- (set_local $$51
- (i32.sub
- (set_local $$49
- (i32.clz
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- (i32.clz
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- )
- )
- (i32.const 30)
- )
- (block
- (set_local $$57
- (i32.add
- (get_local $$51)
- (i32.const 1)
- )
- )
- (set_local $$58
- (i32.sub
- (i32.const 31)
- (get_local $$51)
- )
- )
- (set_local $$sr_1_ph
- (get_local $$57)
- )
- (set_local $$r_sroa_0_1_ph
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$58)
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$57)
- )
- )
- )
- (set_local $$r_sroa_1_1_ph
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$57)
- )
- )
- (set_local $$q_sroa_0_1_ph
- (i32.const 0)
- )
- (set_local $$q_sroa_1_1_ph
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$58)
- )
- )
- (br $do-once$0)
- )
- )
- (if
- (i32.eq
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.or
- (get_local $$n_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
+ (local $x64 i64)
+ (local $y64 i64)
+ (set_local $x64
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $$a$0)
)
- (block
- (if
- (i32.eqz
- (get_local $$17)
- )
- (block
- (if
- (i32.le_u
- (set_local $$119
- (i32.sub
- (set_local $$117
- (i32.clz
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- (i32.clz
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- )
- )
- (i32.const 31)
- )
- (block
- (set_local $$125
- (i32.add
- (get_local $$119)
- (i32.const 1)
- )
- )
- (set_local $$126
- (i32.sub
- (i32.const 31)
- (get_local $$119)
- )
- )
- (set_local $$130
- (i32.shr_s
- (i32.sub
- (get_local $$119)
- (i32.const 31)
- )
- (i32.const 31)
- )
- )
- (set_local $$sr_1_ph
- (get_local $$125)
- )
- (set_local $$r_sroa_0_1_ph
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$125)
- )
- (get_local $$130)
- )
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$126)
- )
- )
- )
- (set_local $$r_sroa_1_1_ph
- (i32.and
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$125)
- )
- (get_local $$130)
- )
- )
- (set_local $$q_sroa_0_1_ph
- (i32.const 0)
- )
- (set_local $$q_sroa_1_1_ph
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$126)
- )
- )
- (br $do-once$0)
- )
- )
- (if
- (i32.eq
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.or
- (get_local $$n_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.ne
- (i32.and
- (set_local $$66
- (i32.sub
- (get_local $$d_sroa_0_0_extract_trunc)
- (i32.const 1)
- )
- )
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- (i32.const 0)
- )
- (block
- (set_local $$89
- (i32.sub
- (i32.const 64)
- (set_local $$88
- (i32.sub
- (set_local $$86
- (i32.add
- (i32.clz
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- (i32.const 33)
- )
- )
- (i32.clz
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- )
- )
- )
- )
- (set_local $$92
- (i32.shr_s
- (set_local $$91
- (i32.sub
- (i32.const 32)
- (get_local $$88)
- )
- )
- (i32.const 31)
- )
- )
- (set_local $$105
- (i32.shr_s
- (set_local $$95
- (i32.sub
- (get_local $$88)
- (i32.const 32)
- )
- )
- (i32.const 31)
- )
- )
- (set_local $$sr_1_ph
- (get_local $$88)
- )
- (set_local $$r_sroa_0_1_ph
- (i32.or
- (i32.and
- (i32.shr_s
- (i32.sub
- (get_local $$91)
- (i32.const 1)
- )
- (i32.const 31)
- )
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$95)
- )
- )
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$91)
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$88)
- )
- )
- (get_local $$105)
- )
- )
- )
- (set_local $$r_sroa_1_1_ph
- (i32.and
- (get_local $$105)
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$88)
- )
- )
- )
- (set_local $$q_sroa_0_1_ph
- (i32.and
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$89)
- )
- (get_local $$92)
- )
- )
- (set_local $$q_sroa_1_1_ph
- (i32.or
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$89)
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$95)
- )
- )
- (get_local $$92)
- )
- (i32.and
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$91)
- )
- (i32.shr_s
- (i32.sub
- (get_local $$88)
- (i32.const 33)
- )
- (i32.const 31)
- )
- )
- )
- )
- (br $do-once$0)
- )
- )
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.and
- (get_local $$66)
- (get_local $$n_sroa_0_0_extract_trunc)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.const 0)
- )
- )
- )
- (if
- (i32.eq
- (get_local $$d_sroa_0_0_extract_trunc)
- (i32.const 1)
- )
- (block
- (set_local $$_0$1
- (i32.or
- (get_local $$n_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$0
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- (block
- (set_local $$78
- (call $_llvm_cttz_i32
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (set_local $$_0$1
- (i32.or
- (i32.const 0)
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$78)
- )
- )
- )
- (set_local $$_0$0
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (i32.sub
- (i32.const 32)
- (get_local $$78)
- )
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$78)
- )
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $$a$1)
)
+ (i64.const 32)
)
)
)
- (if
- (i32.eq
- (get_local $$sr_1_ph)
- (i32.const 0)
- )
- (block
- (set_local $$q_sroa_1_1_lcssa
- (get_local $$q_sroa_1_1_ph)
- )
- (set_local $$q_sroa_0_1_lcssa
- (get_local $$q_sroa_0_1_ph)
- )
- (set_local $$r_sroa_1_1_lcssa
- (get_local $$r_sroa_1_1_ph)
- )
- (set_local $$r_sroa_0_1_lcssa
- (get_local $$r_sroa_0_1_ph)
- )
- (set_local $$carry_0_lcssa$1
- (i32.const 0)
- )
- (set_local $$carry_0_lcssa$0
- (i32.const 0)
- )
- )
- (block
- (set_local $$d_sroa_0_0_insert_insert99$0
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$b$0)
- (i32.const -1)
- )
- )
- )
- (set_local $$d_sroa_0_0_insert_insert99$1
- (i32.or
- (get_local $$d_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$b$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$137$0
- (call $_i64Add
- (get_local $$d_sroa_0_0_insert_insert99$0)
- (get_local $$d_sroa_0_0_insert_insert99$1)
- (i32.const -1)
- (i32.const -1)
- )
- )
- (set_local $$137$1
- (i32.load
- (i32.const 168)
- )
- )
- (set_local $$q_sroa_1_1198
- (get_local $$q_sroa_1_1_ph)
- )
- (set_local $$q_sroa_0_1199
- (get_local $$q_sroa_0_1_ph)
- )
- (set_local $$r_sroa_1_1200
- (get_local $$r_sroa_1_1_ph)
- )
- (set_local $$r_sroa_0_1201
- (get_local $$r_sroa_0_1_ph)
- )
- (set_local $$sr_1202
- (get_local $$sr_1_ph)
- )
- (set_local $$carry_0203
- (i32.const 0)
+ (set_local $y64
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $$b$0)
)
- (loop $while-out$2 $while-in$3
- (set_local $$147
- (i32.or
- (i32.shr_u
- (get_local $$q_sroa_0_1199)
- (i32.const 31)
- )
- (i32.shl
- (get_local $$q_sroa_1_1198)
- (i32.const 1)
- )
- )
- )
- (set_local $$149
- (i32.or
- (get_local $$carry_0203)
- (i32.shl
- (get_local $$q_sroa_0_1199)
- (i32.const 1)
- )
- )
- )
- (set_local $$r_sroa_0_0_insert_insert42$0
- (i32.or
- (i32.const 0)
- (i32.or
- (i32.shl
- (get_local $$r_sroa_0_1201)
- (i32.const 1)
- )
- (i32.shr_u
- (get_local $$q_sroa_1_1198)
- (i32.const 31)
- )
- )
- )
- )
- (set_local $$r_sroa_0_0_insert_insert42$1
- (i32.or
- (i32.shr_u
- (get_local $$r_sroa_0_1201)
- (i32.const 31)
- )
- (i32.shl
- (get_local $$r_sroa_1_1200)
- (i32.const 1)
- )
- )
- )
- (call $_i64Subtract
- (get_local $$137$0)
- (get_local $$137$1)
- (get_local $$r_sroa_0_0_insert_insert42$0)
- (get_local $$r_sroa_0_0_insert_insert42$1)
- )
- (set_local $$152
- (i32.and
- (set_local $$151$0
- (i32.or
- (i32.shr_s
- (set_local $$150$1
- (i32.load
- (i32.const 168)
- )
- )
- (i32.const 31)
- )
- (i32.shl
- (if
- (i32.lt_s
- (get_local $$150$1)
- (i32.const 0)
- )
- (i32.const -1)
- (i32.const 0)
- )
- (i32.const 1)
- )
- )
- )
- (i32.const 1)
- )
- )
- (set_local $$r_sroa_0_0_extract_trunc
- (set_local $$154$0
- (call $_i64Subtract
- (get_local $$r_sroa_0_0_insert_insert42$0)
- (get_local $$r_sroa_0_0_insert_insert42$1)
- (i32.and
- (get_local $$151$0)
- (get_local $$d_sroa_0_0_insert_insert99$0)
- )
- (i32.and
- (i32.or
- (i32.shr_s
- (if
- (i32.lt_s
- (get_local $$150$1)
- (i32.const 0)
- )
- (i32.const -1)
- (i32.const 0)
- )
- (i32.const 31)
- )
- (i32.shl
- (if
- (i32.lt_s
- (get_local $$150$1)
- (i32.const 0)
- )
- (i32.const -1)
- (i32.const 0)
- )
- (i32.const 1)
- )
- )
- (get_local $$d_sroa_0_0_insert_insert99$1)
- )
- )
- )
- )
- (set_local $$r_sroa_1_4_extract_trunc
- (i32.load
- (i32.const 168)
- )
- )
- (if
- (i32.eq
- (set_local $$155
- (i32.sub
- (get_local $$sr_1202)
- (i32.const 1)
- )
- )
- (i32.const 0)
- )
- (br $while-out$2)
- (block
- (set_local $$q_sroa_1_1198
- (get_local $$147)
- )
- (set_local $$q_sroa_0_1199
- (get_local $$149)
- )
- (set_local $$r_sroa_1_1200
- (get_local $$r_sroa_1_4_extract_trunc)
- )
- (set_local $$r_sroa_0_1201
- (get_local $$r_sroa_0_0_extract_trunc)
- )
- (set_local $$sr_1202
- (get_local $$155)
- )
- (set_local $$carry_0203
- (get_local $$152)
- )
- )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $$b$1)
)
- (br $while-in$3)
- )
- (set_local $$q_sroa_1_1_lcssa
- (get_local $$147)
+ (i64.const 32)
)
- (set_local $$q_sroa_0_1_lcssa
- (get_local $$149)
- )
- (set_local $$r_sroa_1_1_lcssa
- (get_local $$r_sroa_1_4_extract_trunc)
- )
- (set_local $$r_sroa_0_1_lcssa
- (get_local $$r_sroa_0_0_extract_trunc)
- )
- (set_local $$carry_0_lcssa$1
- (i32.const 0)
- )
- (set_local $$carry_0_lcssa$0
- (get_local $$152)
- )
- )
- )
- (set_local $$q_sroa_0_0_insert_ext75$0
- (get_local $$q_sroa_0_1_lcssa)
- )
- (set_local $$q_sroa_0_0_insert_ext75$1
- (i32.const 0)
- )
- (set_local $$q_sroa_0_0_insert_insert77$1
- (i32.or
- (get_local $$q_sroa_1_1_lcssa)
- (get_local $$q_sroa_0_0_insert_ext75$1)
)
)
(if
- (i32.ne
+ (get_local $$rem)
+ (i64.store
(get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (get_local $$r_sroa_0_1_lcssa)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (get_local $$r_sroa_1_1_lcssa)
+ (i64.rem_u
+ (get_local $x64)
+ (get_local $y64)
)
)
)
- (set_local $$_0$1
- (i32.or
- (i32.or
- (i32.or
- (i32.shr_u
- (i32.or
- (i32.const 0)
- (get_local $$q_sroa_0_0_insert_ext75$0)
- )
- (i32.const 31)
- )
- (i32.shl
- (get_local $$q_sroa_0_0_insert_insert77$1)
- (i32.const 1)
- )
- )
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$q_sroa_0_0_insert_ext75$1)
- (i32.const 1)
- )
- (i32.shr_u
- (get_local $$q_sroa_0_0_insert_ext75$0)
- (i32.const 31)
- )
- )
- (i32.const 0)
- )
- )
- (get_local $$carry_0_lcssa$1)
- )
- )
- (set_local $$_0$0
- (i32.or
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$q_sroa_0_0_insert_ext75$0)
- (i32.const 1)
- )
- (i32.shr_u
- (i32.const 0)
- (i32.const 31)
+ (i32.store
+ (i32.const 168)
+ (i32.wrap/i64
+ (i64.shr_u
+ (set_local $x64
+ (i64.div_u
+ (get_local $x64)
+ (get_local $y64)
)
)
- (i32.const -2)
+ (i64.const 32)
)
- (get_local $$carry_0_lcssa$0)
)
)
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
+ (i32.wrap/i64
+ (get_local $x64)
)
)
(func $dynCall_ii (param $index i32) (param $a1 i32) (result i32)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index fc4418930..75ec71e5d 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -48,6 +48,7 @@
(export "dynCall_ii" $dynCall_ii)
(export "dynCall_iiii" $dynCall_iiii)
(export "dynCall_vi" $dynCall_vi)
+ (export "___udivmoddi4" $___udivmoddi4)
(table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2)
(func $stackAlloc (param $size i32) (result i32)
(local $ret i32)
@@ -28140,13 +28141,11 @@
)
)
(loop $while-out$0 $while-in$1
- (if
- (i32.lt_s
+ (br_if $while-out$0
+ (i32.ge_s
(get_local $ptr)
(get_local $unaligned)
)
- (nop)
- (br $while-out$0)
)
(i32.store8
(get_local $ptr)
@@ -28163,13 +28162,11 @@
)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.lt_s
+ (br_if $while-out$2
+ (i32.ge_s
(get_local $ptr)
(get_local $stop4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $ptr)
@@ -28186,13 +28183,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.lt_s
+ (br_if $while-out$4
+ (i32.ge_s
(get_local $ptr)
(get_local $stop)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $ptr)
@@ -28366,13 +28361,13 @@
)
(block
(loop $while-out$0 $while-in$1
- (if
- (i32.and
- (get_local $dest)
- (i32.const 3)
+ (br_if $while-out$0
+ (i32.eqz
+ (i32.and
+ (get_local $dest)
+ (i32.const 3)
+ )
)
- (nop)
- (br $while-out$0)
)
(if
(i32.eq
@@ -28410,13 +28405,11 @@
(br $while-in$1)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.ge_s
+ (br_if $while-out$2
+ (i32.lt_s
(get_local $num)
(i32.const 4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $dest)
@@ -28447,13 +28440,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.gt_s
+ (br_if $while-out$4
+ (i32.le_s
(get_local $num)
(i32.const 0)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $dest)
@@ -28550,100 +28541,6 @@
)
)
)
- (func $_llvm_cttz_i32 (param $x i32) (result i32)
- (local $ret i32)
- (if
- (i32.lt_s
- (set_local $ret
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.and
- (get_local $x)
- (i32.const 255)
- )
- )
- )
- )
- (i32.const 8)
- )
- (return
- (get_local $ret)
- )
- )
- (if
- (i32.lt_s
- (set_local $ret
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.and
- (i32.shr_s
- (get_local $x)
- (i32.const 8)
- )
- (i32.const 255)
- )
- )
- )
- )
- (i32.const 8)
- )
- (return
- (i32.add
- (get_local $ret)
- (i32.const 8)
- )
- )
- )
- (if
- (i32.lt_s
- (set_local $ret
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.and
- (i32.shr_s
- (get_local $x)
- (i32.const 16)
- )
- (i32.const 255)
- )
- )
- )
- )
- (i32.const 8)
- )
- (return
- (i32.add
- (get_local $ret)
- (i32.const 16)
- )
- )
- )
- (return
- (i32.add
- (i32.load8_s
- (i32.add
- (i32.load
- (i32.const 40)
- )
- (i32.shr_u
- (get_local $x)
- (i32.const 24)
- )
- )
- )
- (i32.const 24)
- )
- )
- )
(func $___muldsi3 (param $$a i32) (param $$b i32) (result i32)
(local $$8 i32)
(local $$6 i32)
@@ -29238,1209 +29135,60 @@
)
)
(func $___udivmoddi4 (param $$a$0 i32) (param $$a$1 i32) (param $$b$0 i32) (param $$b$1 i32) (param $$rem i32) (result i32)
- (local $$_0$1 i32)
- (local $$_0$0 i32)
- (local $$n_sroa_1_4_extract_trunc i32)
- (local $$n_sroa_0_0_extract_trunc i32)
- (local $$d_sroa_0_0_extract_trunc i32)
- (local $$d_sroa_1_4_extract_trunc i32)
- (local $$88 i32)
- (local $$sr_1_ph i32)
- (local $$r_sroa_1_1_ph i32)
- (local $$r_sroa_0_1_ph i32)
- (local $$q_sroa_1_1_ph i32)
- (local $$q_sroa_0_1_ph i32)
- (local $$r_sroa_0_1201 i32)
- (local $$q_sroa_1_1198 i32)
- (local $$q_sroa_0_1199 i32)
- (local $$q_sroa_0_0_insert_ext75$0 i32)
- (local $$n_sroa_1_4_extract_shift$0 i32)
- (local $$91 i32)
- (local $$78 i32)
- (local $$57 i32)
- (local $$150$1 i32)
- (local $$125 i32)
- (local $$119 i32)
- (local $$sr_1202 i32)
- (local $$r_sroa_1_4_extract_trunc i32)
- (local $$r_sroa_1_1_lcssa i32)
- (local $$r_sroa_1_1200 i32)
- (local $$r_sroa_0_1_lcssa i32)
- (local $$r_sroa_0_0_insert_insert42$1 i32)
- (local $$r_sroa_0_0_insert_insert42$0 i32)
- (local $$r_sroa_0_0_extract_trunc i32)
- (local $$q_sroa_1_1_lcssa i32)
- (local $$q_sroa_0_1_lcssa i32)
- (local $$q_sroa_0_0_insert_ext75$1 i32)
- (local $$d_sroa_0_0_insert_insert99$1 i32)
- (local $$d_sroa_0_0_insert_insert99$0 i32)
- (local $$carry_0_lcssa$1 i32)
- (local $$carry_0_lcssa$0 i32)
- (local $$carry_0203 i32)
- (local $$95 i32)
- (local $$92 i32)
- (local $$89 i32)
- (local $$58 i32)
- (local $$51 i32)
- (local $$4 i32)
- (local $$17 i32)
- (local $$152 i32)
- (local $$149 i32)
- (local $$147 i32)
- (local $$130 i32)
- (local $$126 i32)
- (local $$105 i32)
- (local $$q_sroa_0_0_insert_insert77$1 i32)
- (local $$d_sroa_1_4_extract_shift$0 i32)
- (local $$66 i32)
- (local $$37 i32)
- (local $$155 i32)
- (local $$151$0 i32)
- (local $$137$1 i32)
- (local $$137$0 i32)
- (local $$86 i32)
- (local $$49 i32)
- (local $$154$0 i32)
- (local $$117 i32)
- (set_local $$n_sroa_0_0_extract_trunc
- (get_local $$a$0)
- )
- (set_local $$n_sroa_1_4_extract_trunc
- (set_local $$n_sroa_1_4_extract_shift$0
- (get_local $$a$1)
- )
- )
- (set_local $$d_sroa_0_0_extract_trunc
- (get_local $$b$0)
- )
- (set_local $$d_sroa_1_4_extract_trunc
- (set_local $$d_sroa_1_4_extract_shift$0
- (get_local $$b$1)
- )
- )
- (if
- (i32.eq
- (get_local $$n_sroa_1_4_extract_trunc)
- (i32.const 0)
- )
- (block
- (set_local $$4
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- )
- (if
- (i32.eq
- (get_local $$d_sroa_1_4_extract_trunc)
- (i32.const 0)
- )
- (block
- (if
- (get_local $$4)
- (block
- (i32.store
- (get_local $$rem)
- (i32.rem_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.div_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- (block
- (if
- (i32.eqz
- (get_local $$4)
- )
- (block
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (i32.store
- (get_local $$rem)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- )
- )
- (set_local $$17
- (i32.eq
- (get_local $$d_sroa_1_4_extract_trunc)
- (i32.const 0)
- )
- )
- (block $do-once$0
- (if
- (i32.eq
- (get_local $$d_sroa_0_0_extract_trunc)
- (i32.const 0)
- )
- (block
- (if
- (get_local $$17)
- (block
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.rem_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.div_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.eq
- (get_local $$n_sroa_0_0_extract_trunc)
- (i32.const 0)
- )
- (block
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.const 0)
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.rem_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.div_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.eq
- (i32.and
- (set_local $$37
- (i32.sub
- (get_local $$d_sroa_1_4_extract_trunc)
- (i32.const 1)
- )
- )
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- (i32.const 0)
- )
- (block
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.or
- (i32.and
- (get_local $$37)
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (call $_llvm_cttz_i32
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.le_u
- (set_local $$51
- (i32.sub
- (set_local $$49
- (i32.clz
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- (i32.clz
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- )
- )
- (i32.const 30)
- )
- (block
- (set_local $$57
- (i32.add
- (get_local $$51)
- (i32.const 1)
- )
- )
- (set_local $$58
- (i32.sub
- (i32.const 31)
- (get_local $$51)
- )
- )
- (set_local $$sr_1_ph
- (get_local $$57)
- )
- (set_local $$r_sroa_0_1_ph
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$58)
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$57)
- )
- )
- )
- (set_local $$r_sroa_1_1_ph
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$57)
- )
- )
- (set_local $$q_sroa_0_1_ph
- (i32.const 0)
- )
- (set_local $$q_sroa_1_1_ph
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$58)
- )
- )
- (br $do-once$0)
- )
- )
- (if
- (i32.eq
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.or
- (get_local $$n_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
+ (local $x64 i64)
+ (local $y64 i64)
+ (set_local $x64
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $$a$0)
)
- (block
- (if
- (i32.eqz
- (get_local $$17)
- )
- (block
- (if
- (i32.le_u
- (set_local $$119
- (i32.sub
- (set_local $$117
- (i32.clz
- (get_local $$d_sroa_1_4_extract_trunc)
- )
- )
- (i32.clz
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- )
- )
- (i32.const 31)
- )
- (block
- (set_local $$125
- (i32.add
- (get_local $$119)
- (i32.const 1)
- )
- )
- (set_local $$126
- (i32.sub
- (i32.const 31)
- (get_local $$119)
- )
- )
- (set_local $$130
- (i32.shr_s
- (i32.sub
- (get_local $$119)
- (i32.const 31)
- )
- (i32.const 31)
- )
- )
- (set_local $$sr_1_ph
- (get_local $$125)
- )
- (set_local $$r_sroa_0_1_ph
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$125)
- )
- (get_local $$130)
- )
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$126)
- )
- )
- )
- (set_local $$r_sroa_1_1_ph
- (i32.and
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$125)
- )
- (get_local $$130)
- )
- )
- (set_local $$q_sroa_0_1_ph
- (i32.const 0)
- )
- (set_local $$q_sroa_1_1_ph
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$126)
- )
- )
- (br $do-once$0)
- )
- )
- (if
- (i32.eq
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.or
- (get_local $$n_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$1
- (i32.const 0)
- )
- (set_local $$_0$0
- (i32.const 0)
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- )
- (if
- (i32.ne
- (i32.and
- (set_local $$66
- (i32.sub
- (get_local $$d_sroa_0_0_extract_trunc)
- (i32.const 1)
- )
- )
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- (i32.const 0)
- )
- (block
- (set_local $$89
- (i32.sub
- (i32.const 64)
- (set_local $$88
- (i32.sub
- (set_local $$86
- (i32.add
- (i32.clz
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- (i32.const 33)
- )
- )
- (i32.clz
- (get_local $$n_sroa_1_4_extract_trunc)
- )
- )
- )
- )
- )
- (set_local $$92
- (i32.shr_s
- (set_local $$91
- (i32.sub
- (i32.const 32)
- (get_local $$88)
- )
- )
- (i32.const 31)
- )
- )
- (set_local $$105
- (i32.shr_s
- (set_local $$95
- (i32.sub
- (get_local $$88)
- (i32.const 32)
- )
- )
- (i32.const 31)
- )
- )
- (set_local $$sr_1_ph
- (get_local $$88)
- )
- (set_local $$r_sroa_0_1_ph
- (i32.or
- (i32.and
- (i32.shr_s
- (i32.sub
- (get_local $$91)
- (i32.const 1)
- )
- (i32.const 31)
- )
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$95)
- )
- )
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$91)
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$88)
- )
- )
- (get_local $$105)
- )
- )
- )
- (set_local $$r_sroa_1_1_ph
- (i32.and
- (get_local $$105)
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$88)
- )
- )
- )
- (set_local $$q_sroa_0_1_ph
- (i32.and
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$89)
- )
- (get_local $$92)
- )
- )
- (set_local $$q_sroa_1_1_ph
- (i32.or
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$89)
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$95)
- )
- )
- (get_local $$92)
- )
- (i32.and
- (i32.shl
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$91)
- )
- (i32.shr_s
- (i32.sub
- (get_local $$88)
- (i32.const 33)
- )
- (i32.const 31)
- )
- )
- )
- )
- (br $do-once$0)
- )
- )
- (if
- (i32.ne
- (get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.and
- (get_local $$66)
- (get_local $$n_sroa_0_0_extract_trunc)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (i32.const 0)
- )
- )
- )
- (if
- (i32.eq
- (get_local $$d_sroa_0_0_extract_trunc)
- (i32.const 1)
- )
- (block
- (set_local $$_0$1
- (i32.or
- (get_local $$n_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$a$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$_0$0
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$a$0)
- (i32.const -1)
- )
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
- (block
- (set_local $$78
- (call $_llvm_cttz_i32
- (get_local $$d_sroa_0_0_extract_trunc)
- )
- )
- (set_local $$_0$1
- (i32.or
- (i32.const 0)
- (i32.shr_u
- (get_local $$n_sroa_1_4_extract_trunc)
- (get_local $$78)
- )
- )
- )
- (set_local $$_0$0
- (i32.or
- (i32.shl
- (get_local $$n_sroa_1_4_extract_trunc)
- (i32.sub
- (i32.const 32)
- (get_local $$78)
- )
- )
- (i32.shr_u
- (get_local $$n_sroa_0_0_extract_trunc)
- (get_local $$78)
- )
- )
- )
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
- )
- )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $$a$1)
)
+ (i64.const 32)
)
)
)
- (if
- (i32.eq
- (get_local $$sr_1_ph)
- (i32.const 0)
- )
- (block
- (set_local $$q_sroa_1_1_lcssa
- (get_local $$q_sroa_1_1_ph)
- )
- (set_local $$q_sroa_0_1_lcssa
- (get_local $$q_sroa_0_1_ph)
- )
- (set_local $$r_sroa_1_1_lcssa
- (get_local $$r_sroa_1_1_ph)
- )
- (set_local $$r_sroa_0_1_lcssa
- (get_local $$r_sroa_0_1_ph)
- )
- (set_local $$carry_0_lcssa$1
- (i32.const 0)
- )
- (set_local $$carry_0_lcssa$0
- (i32.const 0)
- )
- )
- (block
- (set_local $$d_sroa_0_0_insert_insert99$0
- (i32.or
- (i32.const 0)
- (i32.and
- (get_local $$b$0)
- (i32.const -1)
- )
- )
- )
- (set_local $$d_sroa_0_0_insert_insert99$1
- (i32.or
- (get_local $$d_sroa_1_4_extract_shift$0)
- (i32.and
- (get_local $$b$1)
- (i32.const 0)
- )
- )
- )
- (set_local $$137$0
- (call $_i64Add
- (get_local $$d_sroa_0_0_insert_insert99$0)
- (get_local $$d_sroa_0_0_insert_insert99$1)
- (i32.const -1)
- (i32.const -1)
- )
- )
- (set_local $$137$1
- (i32.load
- (i32.const 168)
- )
- )
- (set_local $$q_sroa_1_1198
- (get_local $$q_sroa_1_1_ph)
- )
- (set_local $$q_sroa_0_1199
- (get_local $$q_sroa_0_1_ph)
- )
- (set_local $$r_sroa_1_1200
- (get_local $$r_sroa_1_1_ph)
- )
- (set_local $$r_sroa_0_1201
- (get_local $$r_sroa_0_1_ph)
- )
- (set_local $$sr_1202
- (get_local $$sr_1_ph)
- )
- (set_local $$carry_0203
- (i32.const 0)
+ (set_local $y64
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $$b$0)
)
- (loop $while-out$2 $while-in$3
- (set_local $$147
- (i32.or
- (i32.shr_u
- (get_local $$q_sroa_0_1199)
- (i32.const 31)
- )
- (i32.shl
- (get_local $$q_sroa_1_1198)
- (i32.const 1)
- )
- )
- )
- (set_local $$149
- (i32.or
- (get_local $$carry_0203)
- (i32.shl
- (get_local $$q_sroa_0_1199)
- (i32.const 1)
- )
- )
- )
- (set_local $$r_sroa_0_0_insert_insert42$0
- (i32.or
- (i32.const 0)
- (i32.or
- (i32.shl
- (get_local $$r_sroa_0_1201)
- (i32.const 1)
- )
- (i32.shr_u
- (get_local $$q_sroa_1_1198)
- (i32.const 31)
- )
- )
- )
- )
- (set_local $$r_sroa_0_0_insert_insert42$1
- (i32.or
- (i32.shr_u
- (get_local $$r_sroa_0_1201)
- (i32.const 31)
- )
- (i32.shl
- (get_local $$r_sroa_1_1200)
- (i32.const 1)
- )
- )
- )
- (call $_i64Subtract
- (get_local $$137$0)
- (get_local $$137$1)
- (get_local $$r_sroa_0_0_insert_insert42$0)
- (get_local $$r_sroa_0_0_insert_insert42$1)
- )
- (set_local $$152
- (i32.and
- (set_local $$151$0
- (i32.or
- (i32.shr_s
- (set_local $$150$1
- (i32.load
- (i32.const 168)
- )
- )
- (i32.const 31)
- )
- (i32.shl
- (if
- (i32.lt_s
- (get_local $$150$1)
- (i32.const 0)
- )
- (i32.const -1)
- (i32.const 0)
- )
- (i32.const 1)
- )
- )
- )
- (i32.const 1)
- )
- )
- (set_local $$r_sroa_0_0_extract_trunc
- (set_local $$154$0
- (call $_i64Subtract
- (get_local $$r_sroa_0_0_insert_insert42$0)
- (get_local $$r_sroa_0_0_insert_insert42$1)
- (i32.and
- (get_local $$151$0)
- (get_local $$d_sroa_0_0_insert_insert99$0)
- )
- (i32.and
- (i32.or
- (i32.shr_s
- (if
- (i32.lt_s
- (get_local $$150$1)
- (i32.const 0)
- )
- (i32.const -1)
- (i32.const 0)
- )
- (i32.const 31)
- )
- (i32.shl
- (if
- (i32.lt_s
- (get_local $$150$1)
- (i32.const 0)
- )
- (i32.const -1)
- (i32.const 0)
- )
- (i32.const 1)
- )
- )
- (get_local $$d_sroa_0_0_insert_insert99$1)
- )
- )
- )
- )
- (set_local $$r_sroa_1_4_extract_trunc
- (i32.load
- (i32.const 168)
- )
- )
- (if
- (i32.eq
- (set_local $$155
- (i32.sub
- (get_local $$sr_1202)
- (i32.const 1)
- )
- )
- (i32.const 0)
- )
- (br $while-out$2)
- (block
- (set_local $$q_sroa_1_1198
- (get_local $$147)
- )
- (set_local $$q_sroa_0_1199
- (get_local $$149)
- )
- (set_local $$r_sroa_1_1200
- (get_local $$r_sroa_1_4_extract_trunc)
- )
- (set_local $$r_sroa_0_1201
- (get_local $$r_sroa_0_0_extract_trunc)
- )
- (set_local $$sr_1202
- (get_local $$155)
- )
- (set_local $$carry_0203
- (get_local $$152)
- )
- )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $$b$1)
)
- (br $while-in$3)
- )
- (set_local $$q_sroa_1_1_lcssa
- (get_local $$147)
+ (i64.const 32)
)
- (set_local $$q_sroa_0_1_lcssa
- (get_local $$149)
- )
- (set_local $$r_sroa_1_1_lcssa
- (get_local $$r_sroa_1_4_extract_trunc)
- )
- (set_local $$r_sroa_0_1_lcssa
- (get_local $$r_sroa_0_0_extract_trunc)
- )
- (set_local $$carry_0_lcssa$1
- (i32.const 0)
- )
- (set_local $$carry_0_lcssa$0
- (get_local $$152)
- )
- )
- )
- (set_local $$q_sroa_0_0_insert_ext75$0
- (get_local $$q_sroa_0_1_lcssa)
- )
- (set_local $$q_sroa_0_0_insert_ext75$1
- (i32.const 0)
- )
- (set_local $$q_sroa_0_0_insert_insert77$1
- (i32.or
- (get_local $$q_sroa_1_1_lcssa)
- (get_local $$q_sroa_0_0_insert_ext75$1)
)
)
(if
- (i32.ne
+ (get_local $$rem)
+ (i64.store
(get_local $$rem)
- (i32.const 0)
- )
- (block
- (i32.store
- (get_local $$rem)
- (i32.or
- (i32.const 0)
- (get_local $$r_sroa_0_1_lcssa)
- )
- )
- (i32.store offset=4
- (get_local $$rem)
- (get_local $$r_sroa_1_1_lcssa)
+ (i64.rem_u
+ (get_local $x64)
+ (get_local $y64)
)
)
)
- (set_local $$_0$1
- (i32.or
- (i32.or
- (i32.or
- (i32.shr_u
- (i32.or
- (i32.const 0)
- (get_local $$q_sroa_0_0_insert_ext75$0)
- )
- (i32.const 31)
- )
- (i32.shl
- (get_local $$q_sroa_0_0_insert_insert77$1)
- (i32.const 1)
- )
- )
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$q_sroa_0_0_insert_ext75$1)
- (i32.const 1)
- )
- (i32.shr_u
- (get_local $$q_sroa_0_0_insert_ext75$0)
- (i32.const 31)
- )
- )
- (i32.const 0)
- )
- )
- (get_local $$carry_0_lcssa$1)
- )
- )
- (set_local $$_0$0
- (i32.or
- (i32.and
- (i32.or
- (i32.shl
- (get_local $$q_sroa_0_0_insert_ext75$0)
- (i32.const 1)
- )
- (i32.shr_u
- (i32.const 0)
- (i32.const 31)
+ (i32.store
+ (i32.const 168)
+ (i32.wrap/i64
+ (i64.shr_u
+ (set_local $x64
+ (i64.div_u
+ (get_local $x64)
+ (get_local $y64)
)
)
- (i32.const -2)
+ (i64.const 32)
)
- (get_local $$carry_0_lcssa$0)
)
)
- (return
- (block
- (i32.store
- (i32.const 168)
- (get_local $$_0$1)
- )
- (get_local $$_0$0)
- )
+ (i32.wrap/i64
+ (get_local $x64)
)
)
(func $dynCall_ii (param $index i32) (param $a1 i32) (result i32)
diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm
index 99ae1f394..872ac6db1 100644
--- a/test/memorygrowth.fromasm
+++ b/test/memorygrowth.fromasm
@@ -9609,13 +9609,13 @@
)
(block
(loop $while-out$0 $while-in$1
- (if
- (i32.and
- (get_local $a)
- (i32.const 3)
+ (br_if $while-out$0
+ (i32.eqz
+ (i32.and
+ (get_local $a)
+ (i32.const 3)
+ )
)
- (nop)
- (br $while-out$0)
)
(if
(i32.eqz
@@ -9652,13 +9652,11 @@
(br $while-in$1)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.ge_s
+ (br_if $while-out$2
+ (i32.lt_s
(get_local $c)
(i32.const 4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $a)
@@ -9689,13 +9687,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.gt_s
+ (br_if $while-out$4
+ (i32.le_s
(get_local $c)
(i32.const 0)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $a)
@@ -9802,13 +9798,11 @@
)
)
(loop $while-out$0 $while-in$1
- (if
- (i32.lt_s
+ (br_if $while-out$0
+ (i32.ge_s
(get_local $a)
(get_local $e)
)
- (nop)
- (br $while-out$0)
)
(i32.store8
(get_local $a)
@@ -9825,13 +9819,11 @@
)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.lt_s
+ (br_if $while-out$2
+ (i32.ge_s
(get_local $a)
(get_local $g)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $a)
@@ -9848,13 +9840,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.lt_s
+ (br_if $while-out$4
+ (i32.ge_s
(get_local $a)
(get_local $d)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $a)
diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise
index 99ae1f394..872ac6db1 100644
--- a/test/memorygrowth.fromasm.imprecise
+++ b/test/memorygrowth.fromasm.imprecise
@@ -9609,13 +9609,13 @@
)
(block
(loop $while-out$0 $while-in$1
- (if
- (i32.and
- (get_local $a)
- (i32.const 3)
+ (br_if $while-out$0
+ (i32.eqz
+ (i32.and
+ (get_local $a)
+ (i32.const 3)
+ )
)
- (nop)
- (br $while-out$0)
)
(if
(i32.eqz
@@ -9652,13 +9652,11 @@
(br $while-in$1)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.ge_s
+ (br_if $while-out$2
+ (i32.lt_s
(get_local $c)
(i32.const 4)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $a)
@@ -9689,13 +9687,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.gt_s
+ (br_if $while-out$4
+ (i32.le_s
(get_local $c)
(i32.const 0)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $a)
@@ -9802,13 +9798,11 @@
)
)
(loop $while-out$0 $while-in$1
- (if
- (i32.lt_s
+ (br_if $while-out$0
+ (i32.ge_s
(get_local $a)
(get_local $e)
)
- (nop)
- (br $while-out$0)
)
(i32.store8
(get_local $a)
@@ -9825,13 +9819,11 @@
)
)
(loop $while-out$2 $while-in$3
- (if
- (i32.lt_s
+ (br_if $while-out$2
+ (i32.ge_s
(get_local $a)
(get_local $g)
)
- (nop)
- (br $while-out$2)
)
(i32.store
(get_local $a)
@@ -9848,13 +9840,11 @@
)
)
(loop $while-out$4 $while-in$5
- (if
- (i32.lt_s
+ (br_if $while-out$4
+ (i32.ge_s
(get_local $a)
(get_local $d)
)
- (nop)
- (br $while-out$4)
)
(i32.store8
(get_local $a)
diff --git a/test/min.asm.js b/test/min.asm.js
index ed5d186f5..b72002f97 100644
--- a/test/min.asm.js
+++ b/test/min.asm.js
@@ -7,6 +7,7 @@ function (global, env, buffer) {
var fr = global.Math.fround;
var tDP = env.tempDoublePtr | 0;
+ var ctz32 = env._llvm_cttz_i32;
var h8 = new global.Int8Array(buffer);
var h16 = new global.Int16Array(buffer);
@@ -36,6 +37,9 @@ function (global, env, buffer) {
(h32[tDP >> 2] = i, +hF32[tDP >> 2]); // i32->f32, no fround
(hF32[tDP >> 2] = f, h32[tDP >> 2] | 0); // f32->i32
}
+ function ctzzzz() {
+ return ctz32(0x1234) | 0;
+ }
return { floats: floats };
}
diff --git a/test/min.fromasm b/test/min.fromasm
index 199056e42..f4c170b62 100644
--- a/test/min.fromasm
+++ b/test/min.fromasm
@@ -42,4 +42,11 @@
(get_local $f)
)
)
+ (func $ctzzzz (result i32)
+ (return
+ (i32.ctz
+ (i32.const 4660)
+ )
+ )
+ )
)
diff --git a/test/min.fromasm.imprecise b/test/min.fromasm.imprecise
index 199056e42..f4c170b62 100644
--- a/test/min.fromasm.imprecise
+++ b/test/min.fromasm.imprecise
@@ -42,4 +42,11 @@
(get_local $f)
)
)
+ (func $ctzzzz (result i32)
+ (return
+ (i32.ctz
+ (i32.const 4660)
+ )
+ )
+ )
)
diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt
index ea6e78908..c64115f49 100644
--- a/test/passes/optimize-instructions.txt
+++ b/test/passes/optimize-instructions.txt
@@ -19,5 +19,37 @@
(i32.const 11)
(i32.const 12)
)
+ (i32.le_s
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.lt_s
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.ge_s
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.gt_s
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.le_u
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.lt_u
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.ge_u
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (i32.gt_u
+ (i32.const 1)
+ (i32.const 2)
+ )
)
)
diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast
index 058aee042..b579a2054 100644
--- a/test/passes/optimize-instructions.wast
+++ b/test/passes/optimize-instructions.wast
@@ -21,6 +21,14 @@
(i32.const 11)
(i32.const 12)
)
+ (i32.eqz (i32.gt_s (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.ge_s (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.lt_s (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.le_s (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.gt_u (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.ge_u (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.lt_u (i32.const 1) (i32.const 2)))
+ (i32.eqz (i32.le_u (i32.const 1) (i32.const 2)))
)
)
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 8a8b2ebd9..3d66f1c28 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -442,13 +442,11 @@
(i32.const 1)
)
(loop $for-out$0 $for-in$1
- (if
- (i32.lt_s
+ (br_if $for-out$0
+ (i32.ge_s
(get_local $i)
(i32.const 200)
)
- (nop)
- (br $for-out$0)
)
(call_import $h
(get_local $i)
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index 677336c09..0c8da43e9 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -438,13 +438,11 @@
(i32.const 1)
)
(loop $for-out$0 $for-in$1
- (if
- (i32.lt_s
+ (br_if $for-out$0
+ (i32.ge_s
(get_local $i)
(i32.const 200)
)
- (nop)
- (br $for-out$0)
)
(call_import $h
(get_local $i)