diff options
-rw-r--r-- | src/passes/CodeFolding.cpp | 9 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 29 | ||||
-rw-r--r-- | src/passes/RemoveUnusedModuleElements.cpp | 1 | ||||
-rw-r--r-- | src/tools/translate-to-fuzz.h | 88 | ||||
-rw-r--r-- | test/passes/code-folding.txt | 24 | ||||
-rw-r--r-- | test/passes/code-folding.wast | 23 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 34 | ||||
-rw-r--r-- | test/passes/optimize-instructions.wast | 21 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz.txt | 1718 |
9 files changed, 930 insertions, 1017 deletions
diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp index ae2f81283..047eee452 100644 --- a/src/passes/CodeFolding.cpp +++ b/src/passes/CodeFolding.cpp @@ -226,13 +226,17 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> { // optimize returns at the end, so we can benefit from a fallthrough if there is a value TODO: separate passes for them? optimizeTerminatingTails(returnTails); // TODO add fallthrough for returns - // TODO optimzier returns not in blocks, a big return value can be worth it + // TODO optimize returns not in blocks, a big return value can be worth it // clean up breakTails.clear(); unreachableTails.clear(); returnTails.clear(); unoptimizables.clear(); modifieds.clear(); + // if we did any work, types may need to be propagated + if (anotherPass) { + ReFinalize().walkFunctionInModule(func, getModule()); + } } } @@ -371,8 +375,7 @@ private: if (!tail.isFallthrough()) { tail.block->list.push_back(last); } - // the blocks lose their endings, so any values are gone, and the blocks - // are now either none or unreachable + // the block type may change if we removed final values tail.block->finalize(); } // since we managed a merge, then it might open up more opportunities later diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 1f2f07110..ad667f888 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -622,16 +622,33 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, std::swap(iff->ifTrue, iff->ifFalse); } } - if (ExpressionAnalyzer::equal(iff->ifTrue, iff->ifFalse)) { + if (iff->condition->type != unreachable && ExpressionAnalyzer::equal(iff->ifTrue, iff->ifFalse)) { // sides are identical, fold - if (!EffectAnalyzer(getPassOptions(), iff->condition).hasSideEffects()) { + // if we can replace the if with one arm, and no side effects in the condition, do that + auto needCondition = EffectAnalyzer(getPassOptions(), iff->condition).hasSideEffects(); + auto typeIsIdentical = iff->ifTrue->type == iff->type; + if (typeIsIdentical && !needCondition) { return iff->ifTrue; } else { Builder builder(*getModule()); - return builder.makeSequence( - builder.makeDrop(iff->condition), - iff->ifTrue - ); + if (typeIsIdentical) { + return builder.makeSequence( + builder.makeDrop(iff->condition), + iff->ifTrue + ); + } else { + // the types diff. as the condition is reachable, that means the if must be + // concrete while the arm is not + assert(isConcreteWasmType(iff->type) && iff->ifTrue->type == unreachable); + // emit a block with a forced type + auto* ret = builder.makeBlock(); + if (needCondition) { + ret->list.push_back(builder.makeDrop(iff->condition)); + } + ret->list.push_back(iff->ifTrue); + ret->finalize(iff->type); + return ret; + } } } } diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index 259c5b942..d9f6a7978 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -185,6 +185,7 @@ struct RemoveUnusedModuleElements : public Pass { std::unordered_map<std::string, FunctionType*> canonicals; std::unordered_set<FunctionType*> needed; auto canonicalize = [&](Name name) { + if (!name.is()) return name; FunctionType* type = module->getFunctionType(name); auto sig = getSig(type); auto iter = canonicals.find(sig); diff --git a/src/tools/translate-to-fuzz.h b/src/tools/translate-to-fuzz.h index 74a457013..0d2eb47f3 100644 --- a/src/tools/translate-to-fuzz.h +++ b/src/tools/translate-to-fuzz.h @@ -19,7 +19,15 @@ // This is helpful for fuzzing. // +/* +memory too +high chance for set at start of loop + high chance of get of a set local in the scope of that scope + high chance of a tee in that case => loop var +*/ + #include <wasm-builder.h> +#include <ast/literal-utils.h> namespace wasm { @@ -132,6 +140,7 @@ private: void build() { setupMemory(); + setupTable(); // keep adding functions until we run out of input while (!finishedInput) { addFunction(); @@ -142,6 +151,7 @@ private: if (DE_NAN) { addDeNanSupport(); } + finalizeTable(); } void setupMemory() { @@ -150,6 +160,16 @@ private: wasm.memory.initial = wasm.memory.max = 1; } + void setupTable() { + wasm.table.exists = true; + wasm.table.segments.emplace_back(builder.makeConst(Literal(int32_t(0)))); + } + + void finalizeTable() { + wasm.table.initial = wasm.table.segments[0].data.size(); + wasm.table.max = oneIn(2) ? Address(Table::kMaxSize) : wasm.table.initial; + } + const Name HANG_LIMIT_GLOBAL = "hangLimit"; void addHangLimitSupport() { @@ -282,12 +302,17 @@ private: // export some, but not all (to allow inlining etc.). make sure to // export at least one, though, to keep each testcase interesting if (num == 0 || oneIn(2)) { + func->type = ensureFunctionType(getSig(func), &wasm)->name; auto* export_ = new Export; export_->name = func->name; export_->value = func->name; export_->kind = ExternalKind::Function; wasm.addExport(export_); } + // add some to the table + while (oneIn(3)) { + wasm.table.segments[0].data.push_back(func->name); + } // cleanup typeLocals.clear(); } @@ -651,7 +676,41 @@ private: } Expression* makeCallIndirect(WasmType type) { - return make(type); // TODO + auto& data = wasm.table.segments[0].data; + if (data.empty()) return make(type); + // look for a call target with the right type + Index start = upTo(data.size()); + Index i = start; + Function* func; + while (1) { + // TODO: handle unreachable + func = wasm.getFunction(data[i]); + if (func->result == type) { + break; + } + i++; + if (i == data.size()) i = 0; + if (i == start) return make(type); + } + // with high probability, make sure the type is valid otherwise, most are + // going to trap + Expression* target; + if (!oneIn(10)) { + target = builder.makeConst(Literal(int32_t(i))); + } else { + target = make(i32); + } + std::vector<Expression*> args; + for (auto type : func->params) { + args.push_back(make(type)); + } + func->type = ensureFunctionType(getSig(func), &wasm)->name; + return builder.makeCallIndirect( + func->type, + target, + args, + func->result + ); } Expression* makeGetLocal(WasmType type) { @@ -775,7 +834,7 @@ private: Expression* makeConst(WasmType type) { Literal value; - switch (upTo(3)) { + switch (upTo(4)) { case 0: { // totally random, entire range switch (type) { @@ -789,12 +848,14 @@ private: } case 1: { // small range - int32_t small; - switch (upTo(4)) { + int64_t small; + switch (upTo(6)) { case 0: small = int8_t(get()); break; case 1: small = uint8_t(get()); break; case 2: small = int16_t(get16()); break; case 3: small = uint16_t(get16()); break; + case 4: small = int32_t(get32()); break; + case 5: small = uint32_t(get32()); break; default: WASM_UNREACHABLE(); } switch (type) { @@ -840,8 +901,26 @@ private: std::numeric_limits<uint64_t>::max())); break; default: WASM_UNREACHABLE(); } + // tweak around special values + if (oneIn(3)) { + value = value.add(LiteralUtils::makeLiteralFromInt32(upTo(3) - 1, type)); + } break; } + case 3: { + // powers of 2 + switch (type) { + case i32: value = Literal(int32_t(1) << upTo(32)); break; + case i64: value = Literal(int64_t(1) << upTo(64)); break; + case f32: value = Literal(float(int64_t(1) << upTo(64))); break; + case f64: value = Literal(double(int64_t(1) << upTo(64))); break; + default: WASM_UNREACHABLE(); + } + // maybe negative + if (oneIn(2)) { + value = value.mul(LiteralUtils::makeLiteralFromInt32(-1, type)); + } + } } auto* ret = wasm.allocator.alloc<Const>(); ret->value = value; @@ -1069,7 +1148,6 @@ private: // pick from a vector template<typename T> const T& vectorPick(const std::vector<T>& vec) { - // TODO: get32? assert(!vec.empty()); auto index = upTo(vec.size()); return vec[index]; diff --git a/test/passes/code-folding.txt b/test/passes/code-folding.txt new file mode 100644 index 000000000..9143b9615 --- /dev/null +++ b/test/passes/code-folding.txt @@ -0,0 +1,24 @@ +(module + (type $13 (func (param f32))) + (type $1 (func)) + (table 282 282 anyfunc) + (memory $0 1 1) + (func $0 (type $1) + (block $label$1 + (if + (i32.const 1) + (block + (block $label$3 + (call_indirect $13 + (block $label$4 + (br $label$3) + ) + (i32.const 105) + ) + ) + (nop) + ) + ) + ) + ) +) diff --git a/test/passes/code-folding.wast b/test/passes/code-folding.wast new file mode 100644 index 000000000..2310f9721 --- /dev/null +++ b/test/passes/code-folding.wast @@ -0,0 +1,23 @@ +(module + (type $13 (func (param f32))) + (table 282 282 anyfunc) + (memory $0 1 1) + (func $0 + (block $label$1 + (if + (i32.const 1) + (block $label$3 + (call_indirect $13 + (block $label$4 (result f32) ;; but this type may change dangerously + (nop) ;; fold this + (br $label$3) + ) + (i32.const 105) + ) + (nop) ;; with this + ) + ) + ) + ) +) + diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt index 6a99ee106..aae0724a0 100644 --- a/test/passes/optimize-instructions.txt +++ b/test/passes/optimize-instructions.txt @@ -1913,6 +1913,40 @@ ) ) ) + (drop + (block (result i32) + (i32.add + (get_local $1) + (unreachable) + ) + ) + ) + (drop + (block (result i32) + (drop + (tee_local $0 + (get_local $1) + ) + ) + (i32.add + (get_local $1) + (unreachable) + ) + ) + ) + (drop + (if (result i32) + (unreachable) + (i32.add + (get_local $1) + (unreachable) + ) + (i32.add + (get_local $1) + (unreachable) + ) + ) + ) ) (func $select-parallel (type $4) (param $0 i32) (param $1 i32) (drop diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast index c26aad196..f84be8330 100644 --- a/test/passes/optimize-instructions.wast +++ b/test/passes/optimize-instructions.wast @@ -2321,6 +2321,27 @@ (i32.add (get_local $1) (i32.const 1)) ) ) + (drop + (if (result i32) + (get_local $0) + (i32.add (get_local $1) (unreachable)) ;; folding them would change the type of the if + (i32.add (get_local $1) (unreachable)) + ) + ) + (drop + (if (result i32) + (tee_local $0 (get_local $1)) ;; side effects! + (i32.add (get_local $1) (unreachable)) ;; folding them would change the type of the if + (i32.add (get_local $1) (unreachable)) + ) + ) + (drop + (if (result i32) + (unreachable) ;; !!! + (i32.add (get_local $1) (unreachable)) ;; folding them would change the type of the if + (i32.add (get_local $1) (unreachable)) + ) + ) ) (func $select-parallel (param $0 i32) (param $1 i32) (drop diff --git a/test/passes/translate-to-fuzz.txt b/test/passes/translate-to-fuzz.txt index b966a4164..21053fd2e 100644 --- a/test/passes/translate-to-fuzz.txt +++ b/test/passes/translate-to-fuzz.txt @@ -1,10 +1,23 @@ (module + (type $FUNCSIG$i (func (result i32))) + (type $FUNCSIG$ffdj (func (param f32 f64 i64) (result f32))) + (type $FUNCSIG$ffj (func (param f32 i64) (result f32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$j (func (result i64))) + (type $FUNCSIG$fd (func (param f64) (result f32))) (global $hangLimit (mut i32) (i32.const 100)) + (table 8 8 anyfunc) + (elem (i32.const 0) $func_0 $func_0 $func_2 $func_3 $func_3 $func_8 $func_9 $func_9) (memory $0 1 1) (export "func_0" (func $func_0)) - (export "func_6" (func $func_6)) + (export "func_3" (func $func_3)) + (export "func_4" (func $func_4)) + (export "func_5" (func $func_5)) + (export "func_7" (func $func_7)) + (export "func_8" (func $func_8)) + (export "func_9" (func $func_9)) (export "hangLimitInitializer" (func $hangLimitInitializer)) - (func $func_0 (result i32) + (func $func_0 (type $FUNCSIG$i) (result i32) (local $0 f32) (local $1 i64) (local $2 f32) @@ -14,7 +27,7 @@ (get_global $hangLimit) ) (return - (i32.const -11) + (i32.const 9014) ) ) (set_global $hangLimit @@ -31,7 +44,7 @@ (get_global $hangLimit) ) (return - (i32.const 26963) + (i32.const 2321) ) ) (set_global $hangLimit @@ -43,41 +56,160 @@ ) (i64.trunc_u/f64 (drop - (loop $label$3 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (i32.const 32767) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (return - (i32.const -73) - ) + (unreachable) + ) + ) + ) + ) + (func $func_1 (param $0 i32) (param $1 i64) (result f32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const 28) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result f32) + (return + (f32.const 291395360) + ) + ) + ) + (func $func_2 (type $FUNCSIG$fd) (param $0 f64) (result f32) + (local $1 i32) + (local $2 i32) + (local $3 f64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const -1) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result f32) + (nop) + (nop) + (return + (f32.const -nan:0x7fffad) + ) + ) + ) + (func $func_3 (type $FUNCSIG$ffdj) (param $0 f32) (param $1 f64) (param $2 i64) (result f32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const 2010888862731133267687117e5) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result f32) + (return + (f32.const -2147483648) + ) + ) + ) + (func $func_4 (type $FUNCSIG$ffj) (param $0 f32) (param $1 i64) (result f32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const 0) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result f32) + (return + (f32.const 4035018963812352) + ) + ) + ) + (func $func_5 (type $FUNCSIG$v) + (local $0 i64) + (local $1 i32) + (local $2 f32) + (local $3 i64) + (local $4 i32) + (local $5 f32) + (local $6 i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (loop $label$0 + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) ) + (block $label$1 + (br_if $label$0 + (i32.const 13609) + ) + ) ) ) - (func $func_1 (result f64) - (local $0 i32) - (local $1 f64) + (func $func_6 (result f64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f64.const 9223372036854775808) + (f64.const 512) ) ) (set_global $hangLimit @@ -88,198 +220,133 @@ ) ) (block $label$0 (result f64) - (drop - (if (result i64) - (select - (get_local $0) - (i32.const 84414006) - (select - (i32.const 32767) - (i32.const -1) - (loop $label$1 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) + (return + (f64.const 25444) + ) + ) + ) + (func $func_7 (type $FUNCSIG$j) (result i64) + (local $0 f64) + (local $1 f64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 268435456) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (i64.rem_s + (i64.shr_u + (select + (loop $label$0 (result i64) + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (block $label$2 (result i32) - (return - (get_local $1) - ) + (return + (i64.const 65535) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) ) + (i64.const -72057594037927936) ) (if (result i64) - (i32.eqz - (loop $label$9 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const 19) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$10 (result i32) - (i32.load8_s offset=3 - (i32.and - (tee_local $0 - (tee_local $0 - (select - (i32.load16_u offset=4 align=1 - (i32.and - (select - (get_local $0) - (get_local $0) + (call $func_0) + (select + (i64.const 576460752303423488) + (if (result i64) + (i32.eqz + (i32.reinterpret/f32 + (call $deNan32 + (f32.demote/f64 + (call $deNan64 + (f64.promote/f32 + (call $deNan32 + (select + (f32.const -nan:0x7fffe4) + (call $deNan32 (select - (i64.lt_s - (loop $label$12 (result i64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (i64.const 32767) - ) - (i64.const 251) - ) - (i32.trunc_u/f64 - (get_local $1) - ) - (br_if $label$10 - (i32.load16_u offset=3 - (i32.and - (i32.const 20) - (i32.const 31) - ) - ) - (get_local $0) - ) - ) - ) - (i32.const 31) - ) - ) - (loop $label$13 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (f32.const -2147483648) + (f32.const 29298) + (i32.const 2105480203) ) ) - ) - (block $label$14 (result i32) - (return - (get_local $1) - ) - ) - ) - (if (result i32) - (i32.eqz - (get_local $0) - ) - (block $label$11 (result i32) - (get_local $0) - ) - (i32.popcnt - (get_local $0) + (i32.const 1) ) ) ) ) ) - (i32.const 31) ) ) ) - ) - ) - (block $label$15 (result i64) - (block $label$16 (result i64) (select - (br_if $label$16 - (i64.const 1) - (i32.eqz - (tee_local $0 - (select - (get_local $0) - (get_local $0) - (get_local $0) - ) - ) - ) - ) - (loop $label$21 (result i64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (i64.const 2147483647) + (if (result i64) + (call $func_0) + (block $label$1 (result i64) + (return + (i64.const -77) ) ) - (block $label$22 (result i64) + (block $label$2 (result i64) (return - (get_local $1) + (i64.const 9223372036854775807) ) ) ) - (loop $label$17 (result i32) + (i32.reinterpret/f32 + (f32.const -nan:0x7fffa1) + ) + ) + (block $label$3 (result i64) + (return + (i64.const -26) + ) + ) + ) + (select + (i32.const 1212760647) + (call $func_0) + (i32.const 4625) + ) + ) + (block $label$4 (result i64) + (if (result i64) + (i32.eqz + (i64.lt_u + (i64.const 13856) + (i64.const 274075651) + ) + ) + (block $label$5 (result i64) + (i64.const 32767) + ) + (block $label$6 (result i64) + (loop $label$7 (block (if (i32.eqz (get_global $hangLimit) ) (return - (f64.const -9223372036854775808) + (i64.const 3840) ) ) (set_global $hangLimit @@ -289,101 +356,190 @@ ) ) ) - (block $label$18 (result i32) - (if - (i32.eqz - (select - (i32.const -128) - (i32.const -12) - (i32.const 1561467741) - ) - ) - (block $label$19 - (nop) - ) - (loop $label$20 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const -nan:0xfffffffffff83) + (block $label$8 + (drop + (call_indirect $FUNCSIG$ffdj + (f32.const 225300085833990144) + (get_local $1) + (loop $label$9 (result i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const -22) + ) ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) ) ) - ) - (set_local $0 - (get_local $0) - ) - ) - ) - (tee_local $0 - (f32.lt - (call $deNan32 - (f32.min - (f32.const 18446744073709551615) - (f32.const 11) - ) - ) - (call $deNan32 - (select - (f32.const 2147483648) - (f32.const 18446744073709551615) - (get_local $0) + (block $label$10 (result i64) + (br $label$8) ) ) + (i32.const 3) ) ) ) ) + (i64.const 539369059) ) ) ) - (select - (i64.load32_u offset=3 align=2 - (i32.and - (i32.load16_u offset=4 - (i32.and - (tee_local $0 - (if (result i32) - (i32.trunc_u/f64 - (get_local $1) - ) - (block $label$27 (result i32) - (get_local $0) + ) + (call $func_0) + ) + (i64.trunc_s/f32 + (call $func_2 + (f64.const 106) + ) + ) + ) + (if (result i64) + (i32.load16_s offset=2 align=1 + (i32.and + (if (result i32) + (loop $label$11 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const -262144) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (i32.reinterpret/f32 + (call_indirect $FUNCSIG$ffdj + (block $label$12 (result f32) + (call $deNan32 + (f32.div + (call $func_4 + (f32.const -8589934592) + (i64.const -1) ) - (block $label$28 (result i32) - (get_local $0) + (block $label$13 (result f32) + (return + (i64.const 16220) + ) ) ) ) - (i32.const 31) ) + (tee_local $1 + (f64.const 65536) + ) + (block $label$14 (result i64) + (return + (i64.const 13366) + ) + ) + (i32.const 4) + ) + ) + ) + (block $label$15 (result i32) + (nop) + (drop + (f64.const -nan:0xfffffffffffb4) + ) + (br_if $label$15 + (block $label$19 (result i32) + (return + (i64.const 1152921504606846976) + ) + ) + (i32.eqz + (i32.const -2147483648) ) - (i32.const 31) ) ) - (i64.const 80) - (i32.trunc_s/f32 + (block $label$20 (result i32) + (nop) + (i32.const 8388608) + ) + ) + (i32.const 31) + ) + ) + (block $label$21 (result i64) + (i64.const -128) + ) + (select + (i64.const 3684262436118999851) + (i64.const 3830371123687603251) + (loop $label$22 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 1603) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$23 (result i32) + (nop) + (f32.lt (call $deNan32 - (f32.copysign - (f32.const 1.8061622339155704e-31) + (f32.add (if (result f32) (i32.eqz - (loop $label$23 (result i32) + (i32.trunc_s/f32 + (f32.load offset=3 align=2 + (i32.and + (loop $label$24 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 117769221) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (i32.const 16777216) + ) + (i32.const 31) + ) + ) + ) + ) + (block $label$25 (result f32) + (loop $label$26 (result f32) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f64.const 2.1384722118162242e-260) + (i64.const -32768) ) ) (set_global $hangLimit @@ -393,320 +549,157 @@ ) ) ) - (i32.wrap/i64 - (if (result i64) - (i32.eqz - (get_local $0) - ) - (i64.const 18752) - (select - (i64.const 650785547958815753) - (i64.const 8463519829359949880) - (block $label$24 (result i32) - (select - (get_local $0) - (i32.const 65535) - (get_local $0) - ) - ) - ) + (block $label$27 (result f32) + (return + (i64.const 4096) ) ) ) ) - (block $label$25 (result f32) - (f32.const 14385) - ) - (f32.const 4.2612939233197215e-37) - ) - ) - ) - ) - ) - ) - (block $label$29 (result i64) - (block $label$30 (result i64) - (return - (get_local $1) - ) - ) - ) - ) - ) - (if - (block $label$31 (result i32) - (block $label$32 - (if - (block $label$33 (result i32) - (loop $label$34 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const -nan:0xffffffffffff8) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (if (result i32) - (i32.eqz - (if (result i32) - (block $label$35 (result i32) - (return - (get_local $1) - ) - ) - (i32.trunc_s/f64 - (call $deNan64 - (f64.convert_u/i32 - (select - (get_local $0) - (if (result i32) - (i32.eqz - (block $label$36 (result i32) - (get_local $0) - ) - ) - (i64.gt_u - (i64.const 155730402379) - (i64.const 15) - ) - (i32.const -2147483648) + (block $label$28 (result f32) + (call $func_3 + (f32.const -16384) + (f64.const -nan:0xfffffffffffea) + (loop $label$29 (result i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 7451608453167213680) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) - (get_local $0) ) ) + (i64.const 795183340788647946) ) ) - (block $label$37 (result i32) - (drop - (f64.const 65483) - ) - (select - (get_local $0) - (i32.trunc_s/f64 - (block $label$38 (result f64) - (loop $label$39 (result f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) + ) + ) + (call $func_2 + (if (result f64) + (i32.eqz + (i32.trunc_s/f32 + (call $deNan32 + (f32.reinterpret/i32 + (br_if $label$23 + (loop $label$30 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 0) + ) ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) ) ) + (i32.const 10558) ) - (call $deNan64 - (f64.add - (get_local $1) - (get_local $1) + (i32.eqz + (select + (i32.const -83) + (i32.const 2) + (i32.const 2147483647) ) ) ) ) ) - (i32.const 1751457892) - ) - ) - ) - ) - (i32.reinterpret/f32 - (f32.const 9223372036854775808) - ) - (get_local $0) - ) - ) - ) - (nop) - (block $label$40 - (set_local $1 - (call $deNan64 - (select - (f64.load offset=22 align=4 - (i32.and - (if (result i32) - (i32.const -124) - (block $label$43 (result i32) - (br $label$32) - ) - (block $label$44 (result i32) - (get_local $0) - ) ) - (i32.const 31) ) - ) - (call $deNan64 - (f64.copysign - (call $deNan64 - (f64.reinterpret/i64 - (i64.ctz - (i64.trunc_u/f32 - (f32.const 65525) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$41 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const 9) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (get_local $1) + (block $label$31 (result f64) + (return + (i64.const 87) ) ) - (block $label$42 (result i32) - (br $label$40) - ) ) ) ) ) + (f32.const 24415) ) ) ) - (return - (get_local $1) - ) ) - (block $label$45 - (block $label$46 - (br_if $label$45 - (tee_local $0 - (i32.trunc_s/f64 - (loop $label$47 (result f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$48 (result f64) - (br $label$45) - ) - ) - ) - ) - ) - ) + ) + ) + ) + (func $func_8 (type $FUNCSIG$i) (result i32) + (local $0 f64) + (local $1 i32) + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (block $label$49 - (nop) - (br_if $label$49 - (get_local $0) - ) + (return + (get_local $1) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) - (if (result f64) + ) + (block $label$0 (result i32) + (return + (i32.const 745163300) + ) + ) + ) + (func $func_9 (type $FUNCSIG$j) (result i64) + (local $0 f64) + (block + (if (i32.eqz - (i32.trunc_u/f32 - (f32.const 2.0658355161339533e-21) - ) + (get_global $hangLimit) ) - (call $deNan64 - (select - (get_local $1) - (if (result f64) - (i32.eqz - (get_local $0) - ) - (block $label$50 (result f64) - (return - (get_local $1) - ) - ) - (block $label$51 (result f64) - (return - (get_local $1) - ) - ) - ) - (get_local $0) - ) + (return + (i64.const -16384) ) - (block $label$52 (result f64) - (if - (i32.reinterpret/f32 - (f32.const -nan:0x7fffb9) - ) - (nop) - (drop - (f64.const 8.308760937752171e-246) - ) - ) - (drop - (loop $label$53 (result i64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$54 (result i64) - (i64.const -48) - ) - ) - ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result i64) + (i64.popcnt + (block $label$1 (result i64) (return - (f64.const 65520) + (i64.const 1) ) ) ) ) ) - (func $func_2 (param $0 f32) + (func $func_10 (result i64) (block (if (i32.eqz (get_global $hangLimit) ) - (return) + (return + (i64.const 33) + ) ) (set_global $hangLimit (i32.sub @@ -715,20 +708,49 @@ ) ) ) - (block $label$0 + (block $label$0 (result i64) + (return + (i64.const -20) + ) + ) + ) + (func $func_11 (param $0 f64) (param $1 i64) (param $2 i64) (result i64) + (local $3 i64) + (block (if (i32.eqz - (if (result i32) - (call $func_0) - (block $label$1 (result i32) - (block $label$2 - (loop $label$3 + (get_global $hangLimit) + ) + (return + (get_local $2) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 (result i64) + (i64.load32_u offset=22 align=2 + (i32.and + (select + (i32.const -1) + (i32.le_s + (call_indirect $FUNCSIG$i + (i32.const 1) + ) + (block $label$11 (result i32) + (loop $label$12 (block (if (i32.eqz (get_global $hangLimit) ) - (return) + (return + (i64.const -2) + ) ) (set_global $hangLimit (i32.sub @@ -737,193 +759,81 @@ ) ) ) - (block $label$4 - (nop) - ) - ) - ) - (if (result i32) - (i32.eqz - (if (result i32) - (i32.load8_s offset=4 - (i32.and - (if (result i32) - (i32.eqz - (call $func_0) - ) - (block $label$5 (result i32) - (br $label$0) - ) - (block $label$6 (result i32) - (br $label$0) - ) + (loop $label$13 + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (i32.const 31) - ) - ) - (i32.const 359492883) - (call $func_0) - ) - ) - (block $label$7 (result i32) - (br $label$0) - ) - (block $label$8 (result i32) - (i32.const 22536) - ) - ) - ) - (block $label$9 (result i32) - (nop) - (br_if $label$0 - (i32.eqz - (block $label$10 (result i32) - (br $label$0) - ) - ) - ) - (br $label$0) - ) - ) - ) - (if - (i32.const 65441) - (nop) - (block $label$11 - (loop $label$12 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$13 - (nop) - ) - ) - ) - ) - (block $label$14 - (if - (i32.eqz - (call $func_0) - ) - (block $label$15 - (loop $label$16 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$17 - (block $label$18 - (loop $label$19 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) + (return + (get_local $1) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) - (nop) ) + (nop) ) ) - ) - ) - (block $label$20 - (loop $label$21 - (block - (if - (i32.eqz - (get_global $hangLimit) + (loop $label$14 + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 14657) + ) ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) ) ) + (nop) ) - (if - (i32.trunc_u/f64 - (call $deNan64 - (f64.convert_u/i32 - (i32.clz - (call $func_0) + (if (result i32) + (if (result i32) + (i32.eqz + (block $label$15 (result i32) + (return + (i64.const 520) ) ) ) - ) - (nop) - (drop - (if (result i64) - (i32.eqz - (loop $label$22 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) + (i32.ctz + (loop $label$16 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (return + (get_local $1) ) ) - (block $label$23 (result i32) - (select - (i32.const 2113936401) - (i32.const 0) - (select - (i32.const 2147483647) - (i32.const 1297751887) - (i32.const 5191) - ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) ) - ) - (block $label$24 (result i64) - (br $label$0) - ) - (block $label$25 (result i64) - (loop $label$26 (result i64) + (loop $label$17 (result i32) (block (if (i32.eqz (get_global $hangLimit) ) - (return) + (return + (i64.const -4294967296) + ) ) (set_global $hangLimit (i32.sub @@ -932,131 +842,140 @@ ) ) ) - (block $label$27 (result i64) - (i64.reinterpret/f64 - (f64.const -nan:0xfffffffffffb7) + (call_indirect $FUNCSIG$i + (i32.trunc_u/f32 + (block $label$18 (result f32) + (return + (i64.const -2147483648) + ) + ) ) ) ) ) ) + (i32.const -2147483648) ) - ) - ) - (drop - (call $func_1) - ) - (block $label$28 - (if - (i32.const 18500) - (nop) - (if - (i32.eqz - (i32.const -122) - ) - (block $label$29 - (set_local $0 - (loop $label$30 (result f32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) + (block $label$19 (result i32) + (drop + (loop $label$20 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (return + (get_local $3) ) ) - (f32.load offset=22 align=2 - (i32.and - (block $label$31 (result i32) - (i64.eqz - (i64.const -2147483648) - ) - ) - (i32.const 31) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) ) + (i32.const 190322462) ) ) - (f32.store offset=4 align=1 + (i32.load8_u offset=22 (i32.and - (loop $label$32 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) + (f32.eq + (call $deNan32 + (f32.sub + (loop $label$21 (result f32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const -8) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$22 (result f32) + (return + (get_local $3) + ) + ) ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (f32.load offset=22 align=2 + (i32.and + (br_if $label$19 + (call_indirect $FUNCSIG$i + (i32.const 0) + ) + (loop $label$23 (result i32) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i64.const 2147483646) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (if (result i32) + (i32.eqz + (i32.const 65535) + ) + (i32.const -2147483648) + (i32.const 14) + ) + ) + ) + (i32.const 31) + ) ) ) ) - (i32.wrap/i64 - (i64.const -125) + (block $label$24 (result f32) + (return + (i64.const -32768) + ) ) ) (i32.const 31) ) - (f32.load offset=4 align=1 - (i32.and - (i32.const 23) - (i32.const 31) - ) - ) ) ) - ) - (br_if $label$0 - (i32.eqz - (i32.const -128) + (block $label$25 (result i32) + (return + (get_local $3) + ) ) ) ) ) + (i32.const -32768) ) - ) - ) - (br_if $label$0 - (loop $label$33 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$34 (result i32) - (br $label$0) - ) + (i32.const 31) ) ) ) ) - (func $func_3 (param $0 f64) (param $1 f64) (param $2 f64) (result f32) + (func $func_12 (result f64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (f32.const -nan:0x7fff97) + (f64.const 112) ) ) (set_global $hangLimit @@ -1066,113 +985,34 @@ ) ) ) - (call $deNan32 - (f32.sqrt - (if (result f32) - (loop $label$0 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 9223372036854775808) - ) + (call $deNan64 + (select + (call $deNan64 + (f64.promote/f32 + (if (result f32) + (i32.eqz + (i32.const -74) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (block $label$2 (result f32) + (nop) + (nop) + (f32.const 103176e4) ) - ) - (block $label$1 (result i32) - (return - (f32.const 9223372036854775808) + (block $label$3 (result f32) + (f32.const 4) ) ) ) - (block $label$2 (result f32) - (block $label$3 (result f32) - (f32.const 2147483648) - ) - ) - (f32.const 8764) ) - ) - ) - ) - (func $func_4 - (local $0 i64) - (local $1 i64) - (local $2 f32) - (local $3 f64) - (local $4 f64) - (local $5 f64) - (local $6 f32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (nop) - ) - (func $func_5 (param $0 i64) (param $1 i64) (result f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f64.const -100) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (f64.const 1) - ) - (func $func_6 (result i32) - (local $0 f64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (i32.const 2147483647) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (select - (select - (loop $label$1 (result i32) + (f64.const 2199023255552) + (loop $label$0 (result i32) (block (if (i32.eqz (get_global $hangLimit) ) (return - (i32.const 0) + (f64.const -562949953421312) ) ) (set_global $hangLimit @@ -1182,139 +1022,11 @@ ) ) ) - (block $label$2 (result i32) - (i32.load offset=4 - (br_if $label$2 - (i32.const -76) - (i32.eqz - (i32.load8_s offset=4 - (i32.and - (i32.load offset=22 align=1 - (i32.and - (i32.const 92) - (i32.const 31) - ) - ) - (i32.const 31) - ) - ) - ) - ) - ) - ) - ) - (block $label$3 (result i32) - (return - (i32.const 26) - ) - ) - (call $func_0) - ) - (select - (block $label$9 (result i32) - (loop $label$10 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (i32.const 1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$11 - (i32.store16 offset=2 align=1 - (i32.const -91) - (i32.load16_s offset=4 align=1 - (i32.ctz - (block $label$12 (result i32) - (select - (i32.load offset=4 align=2 - (i32.and - (i32.const -113) - (i32.const 31) - ) - ) - (call $func_0) - (block $label$13 (result i32) - (return - (i32.const -32768) - ) - ) - ) - ) - ) - ) - ) - ) - ) - (i32.const 255) - ) - (i32.const 127) - (select - (if (result i32) - (block $label$4 (result i32) - (i32.load offset=22 - (i32.and - (br_if $label$4 - (i32.load16_u offset=2 - (i32.and - (i32.const 226) - (i32.const 31) - ) - ) - (i32.eqz - (select - (block $label$5 (result i32) - (i32.const -32768) - ) - (i32.const 354161438) - (i64.gt_s - (i64.const -18) - (i64.const 2835340575676513842) - ) - ) - ) - ) - (i32.const 31) - ) - ) - ) - (i32.const -128) - (block $label$6 (result i32) - (return - (i32.const 65442) - ) - ) - ) - (block $label$7 (result i32) - (i32.load offset=22 align=1 - (i32.and - (block $label$8 (result i32) - (return - (i32.const 255) - ) - ) - (i32.const 31) - ) + (block $label$1 (result i32) + (return + (f64.const 3402823466385288598117041e14) ) ) - (i32.lt_s - (i32.const -20) - (i32.const -2147483648) - ) - ) - ) - (block $label$0 (result i32) - (return - (i32.const -86) ) ) ) |