diff options
-rw-r--r-- | src/asm2wasm.h | 32 | ||||
-rw-r--r-- | test/wasm-only.asm.js | 25 | ||||
-rw-r--r-- | test/wasm-only.fromasm | 52 | ||||
-rw-r--r-- | test/wasm-only.fromasm.clamp | 52 | ||||
-rw-r--r-- | test/wasm-only.fromasm.clamp.no-opts | 95 | ||||
-rw-r--r-- | test/wasm-only.fromasm.imprecise | 52 | ||||
-rw-r--r-- | test/wasm-only.fromasm.imprecise.no-opts | 95 | ||||
-rw-r--r-- | test/wasm-only.fromasm.no-opts | 95 |
8 files changed, 476 insertions, 22 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 9abfe7432..153839065 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -2539,6 +2539,12 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { auto top = allocator.alloc<Block>(); if (canSwitch) { + + // we may need a break for the case where the condition doesn't match + // any of the cases. it should go to the default, if we have one, or + // outside if not + Break* breakWhenNotMatching = nullptr; + if (br->condition->type == i32) { Binary* offsetor = allocator.alloc<Binary>(); offsetor->op = BinaryOp::SubInt32; @@ -2554,7 +2560,28 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { offsetor->left = br->condition; offsetor->right = builder.makeConst(Literal(int64_t(min))); offsetor->type = i64; - br->condition = builder.makeUnary(UnaryOp::WrapInt64, offsetor); // TODO: check this fits in 32 bits + // the switch itself can be 32-bit, as the range is in a reasonable range. so after + // offsetting, we need to make sure there are no high bits, then we can just look + // at the lower 32 bits + auto temp = Builder::addVar(function, i64); + auto* block = builder.makeBlock(); + block->list.push_back(builder.makeSetLocal(temp, offsetor)); + // if high bits, we can break to the default (we'll fill in the name later) + breakWhenNotMatching = builder.makeBreak(Name(), nullptr, + builder.makeUnary( + UnaryOp::WrapInt64, + builder.makeBinary(BinaryOp::ShrUInt64, + builder.makeGetLocal(temp, i64), + builder.makeConst(Literal(int64_t(32))) + ) + ) + ); + block->list.push_back(breakWhenNotMatching); + block->list.push_back( + builder.makeGetLocal(temp, i64) + ); + block->finalize(); + br->condition = builder.makeUnary(UnaryOp::WrapInt64, block); } top->list.push_back(br); @@ -2595,6 +2622,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { if (br->default_.isNull()) { br->default_ = top->name; } + if (breakWhenNotMatching) { + breakWhenNotMatching->name = br->default_; + } for (size_t i = 0; i < br->targets.size(); i++) { if (br->targets[i].isNull()) br->targets[i] = br->default_; } diff --git a/test/wasm-only.asm.js b/test/wasm-only.asm.js index 7287126d0..750ffaa6a 100644 --- a/test/wasm-only.asm.js +++ b/test/wasm-only.asm.js @@ -26,6 +26,7 @@ function asm(global, env, buffer) { var _fabsf = env._fabsf; var do_i64 = env.do_i64; + var abort = env.abort; function loads() { var i = 0, f = fround(0), d = +0; @@ -416,6 +417,28 @@ function asm(global, env, buffer) { return ($cond|0); } + function switch64_big_condition1($x) { + $x = i64($x); + switch (i64($x)) { + case i64_const(0,2146435072): { + abort(); + break; + } + default: { + return; + } + } + } + function switch64_big_condition2($x) { + $x = i64($x); + switch (i64($x)) { + case i64_const(0,2146435072): { + abort(); + break; + } + } + } + function keepAlive() { loads(); stores(); @@ -431,6 +454,8 @@ function asm(global, env, buffer) { unreachable_leftovers(0, 0, 0); _memchr(0, 0, 0) | 0; switch64TOOMUCH(i64(0)) | 0; + switch64_big_condition1(i64(0)); + switch64_big_condition2(i64(0)); } function __emscripten_dceable_type_decls() { // dce-able, but this defines the type of fabsf which has no other use diff --git a/test/wasm-only.fromasm b/test/wasm-only.fromasm index a746c45e3..8811d0cff 100644 --- a/test/wasm-only.fromasm +++ b/test/wasm-only.fromasm @@ -2,6 +2,7 @@ (type $FUNCSIG$vdji (func (param f64 i64 i32))) (type $FUNCSIG$j (func (result i64))) (type $FUNCSIG$ff (func (param f32) (result f32))) + (type $FUNCSIG$v (func)) (type $legaltype$illegalImport (func (param f64 i32 i32 i32))) (type $legaltype$illegalImportResult (func (result i32))) (type $legaltype$_fabsf (func (param f64) (result f64))) @@ -10,6 +11,7 @@ (import "env" "illegalImportResult" (func $illegalImportResult (result i64))) (import "env" "_fabsf" (func $_fabsf (param f32) (result f32))) (import "env" "do_i64" (func $do_i64 (result i64))) + (import "env" "abort" (func $abort)) (import "env" "illegalImport" (func $legalimport$illegalImport (param f64 i32 i32 i32))) (import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32))) (import "env" "_fabsf" (func $legalimport$_fabsf (param f64) (result f64))) @@ -510,14 +512,24 @@ (block $switch-default (block $switch-case0 (block $switch-case - (br_table $switch-case0 $switch-default $switch-case $switch-default + (br_if $switch-default (i32.wrap/i64 - (i64.sub - (get_local $0) - (i64.const 42949672965) + (i64.shr_u + (tee_local $0 + (i64.sub + (get_local $0) + (i64.const 42949672965) + ) + ) + (i64.const 32) ) ) ) + (br_table $switch-case0 $switch-default $switch-case $switch-default + (i32.wrap/i64 + (get_local $0) + ) + ) ) (br $switch (i32.const 11000) @@ -863,6 +875,32 @@ (get_local $0) ) ) + (func $switch64_big_condition1 (param $0 i64) + (local $1 i64) + (block $switch-default + (block $switch-case + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (tee_local $1 + (i64.sub + (get_local $0) + (i64.const 9218868437227405312) + ) + ) + (i64.const 32) + ) + ) + ) + (br_table $switch-case $switch-default + (i32.wrap/i64 + (get_local $1) + ) + ) + ) + (call $abort) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -920,6 +958,12 @@ (i64.const 0) ) ) + (call $switch64_big_condition1 + (i64.const 0) + ) + (call $switch64_big_condition1 + (i64.const 0) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.clamp b/test/wasm-only.fromasm.clamp index a746c45e3..8811d0cff 100644 --- a/test/wasm-only.fromasm.clamp +++ b/test/wasm-only.fromasm.clamp @@ -2,6 +2,7 @@ (type $FUNCSIG$vdji (func (param f64 i64 i32))) (type $FUNCSIG$j (func (result i64))) (type $FUNCSIG$ff (func (param f32) (result f32))) + (type $FUNCSIG$v (func)) (type $legaltype$illegalImport (func (param f64 i32 i32 i32))) (type $legaltype$illegalImportResult (func (result i32))) (type $legaltype$_fabsf (func (param f64) (result f64))) @@ -10,6 +11,7 @@ (import "env" "illegalImportResult" (func $illegalImportResult (result i64))) (import "env" "_fabsf" (func $_fabsf (param f32) (result f32))) (import "env" "do_i64" (func $do_i64 (result i64))) + (import "env" "abort" (func $abort)) (import "env" "illegalImport" (func $legalimport$illegalImport (param f64 i32 i32 i32))) (import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32))) (import "env" "_fabsf" (func $legalimport$_fabsf (param f64) (result f64))) @@ -510,14 +512,24 @@ (block $switch-default (block $switch-case0 (block $switch-case - (br_table $switch-case0 $switch-default $switch-case $switch-default + (br_if $switch-default (i32.wrap/i64 - (i64.sub - (get_local $0) - (i64.const 42949672965) + (i64.shr_u + (tee_local $0 + (i64.sub + (get_local $0) + (i64.const 42949672965) + ) + ) + (i64.const 32) ) ) ) + (br_table $switch-case0 $switch-default $switch-case $switch-default + (i32.wrap/i64 + (get_local $0) + ) + ) ) (br $switch (i32.const 11000) @@ -863,6 +875,32 @@ (get_local $0) ) ) + (func $switch64_big_condition1 (param $0 i64) + (local $1 i64) + (block $switch-default + (block $switch-case + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (tee_local $1 + (i64.sub + (get_local $0) + (i64.const 9218868437227405312) + ) + ) + (i64.const 32) + ) + ) + ) + (br_table $switch-case $switch-default + (i32.wrap/i64 + (get_local $1) + ) + ) + ) + (call $abort) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -920,6 +958,12 @@ (i64.const 0) ) ) + (call $switch64_big_condition1 + (i64.const 0) + ) + (call $switch64_big_condition1 + (i64.const 0) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.clamp.no-opts b/test/wasm-only.fromasm.clamp.no-opts index baac47fba..143fc9892 100644 --- a/test/wasm-only.fromasm.clamp.no-opts +++ b/test/wasm-only.fromasm.clamp.no-opts @@ -2,6 +2,7 @@ (type $FUNCSIG$vdji (func (param f64 i64 i32))) (type $FUNCSIG$j (func (result i64))) (type $FUNCSIG$ff (func (param f32) (result f32))) + (type $FUNCSIG$v (func)) (type $legaltype$illegalImport (func (param f64 i32 i32 i32))) (type $legaltype$illegalImportResult (func (result i32))) (type $legaltype$_fabsf (func (param f64) (result f64))) @@ -11,6 +12,7 @@ (import "env" "illegalImportResult" (func $illegalImportResult (result i64))) (import "env" "_fabsf" (func $_fabsf (param f32) (result f32))) (import "env" "do_i64" (func $do_i64 (result i64))) + (import "env" "abort" (func $abort)) (import "env" "illegalImport" (func $legalimport$illegalImport (param f64 i32 i32 i32))) (import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32))) (import "env" "_fabsf" (func $legalimport$_fabsf (param f64) (result f64))) @@ -779,15 +781,29 @@ ) (func $switch64 (param $$a444 i64) (result i32) (local $$waka i32) + (local $2 i64) (block $switch (block $switch-default (block $switch-case0 (block $switch-case (br_table $switch-case0 $switch-default $switch-case $switch-default (i32.wrap/i64 - (i64.sub - (get_local $$a444) - (i64.const 42949672965) + (block (result i64) + (set_local $2 + (i64.sub + (get_local $$a444) + (i64.const 42949672965) + ) + ) + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 32) + ) + ) + ) + (get_local $2) ) ) ) @@ -1560,6 +1576,73 @@ (get_local $$cond) ) ) + (func $switch64_big_condition1 (param $$x i64) + (local $1 i64) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.wrap/i64 + (block (result i64) + (set_local $1 + (i64.sub + (get_local $$x) + (i64.const 9218868437227405312) + ) + ) + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 32) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (block + (call $abort) + (br $switch) + ) + ) + (return) + ) + ) + (func $switch64_big_condition2 (param $$x i64) + (local $1 i64) + (block $switch + (block $switch-case + (br_table $switch-case $switch + (i32.wrap/i64 + (block (result i64) + (set_local $1 + (i64.sub + (get_local $$x) + (i64.const 9218868437227405312) + ) + ) + (br_if $switch + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 32) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (block + (call $abort) + (br $switch) + ) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -1617,6 +1700,12 @@ (i64.const 0) ) ) + (call $switch64_big_condition1 + (i64.const 0) + ) + (call $switch64_big_condition2 + (i64.const 0) + ) ) (func $__emscripten_dceable_type_decls (drop diff --git a/test/wasm-only.fromasm.imprecise b/test/wasm-only.fromasm.imprecise index 6d013e11a..2255bfc08 100644 --- a/test/wasm-only.fromasm.imprecise +++ b/test/wasm-only.fromasm.imprecise @@ -2,6 +2,7 @@ (type $FUNCSIG$vdji (func (param f64 i64 i32))) (type $FUNCSIG$j (func (result i64))) (type $FUNCSIG$ff (func (param f32) (result f32))) + (type $FUNCSIG$v (func)) (type $legaltype$illegalImport (func (param f64 i32 i32 i32))) (type $legaltype$illegalImportResult (func (result i32))) (type $legaltype$_fabsf (func (param f64) (result f64))) @@ -10,6 +11,7 @@ (import "env" "illegalImportResult" (func $illegalImportResult (result i64))) (import "env" "_fabsf" (func $_fabsf (param f32) (result f32))) (import "env" "do_i64" (func $do_i64 (result i64))) + (import "env" "abort" (func $abort)) (import "env" "illegalImport" (func $legalimport$illegalImport (param f64 i32 i32 i32))) (import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32))) (import "env" "_fabsf" (func $legalimport$_fabsf (param f64) (result f64))) @@ -236,14 +238,24 @@ (block $switch-default (block $switch-case0 (block $switch-case - (br_table $switch-case0 $switch-default $switch-case $switch-default + (br_if $switch-default (i32.wrap/i64 - (i64.sub - (get_local $0) - (i64.const 42949672965) + (i64.shr_u + (tee_local $0 + (i64.sub + (get_local $0) + (i64.const 42949672965) + ) + ) + (i64.const 32) ) ) ) + (br_table $switch-case0 $switch-default $switch-case $switch-default + (i32.wrap/i64 + (get_local $0) + ) + ) ) (br $switch (i32.const 11000) @@ -589,6 +601,32 @@ (get_local $0) ) ) + (func $switch64_big_condition1 (param $0 i64) + (local $1 i64) + (block $switch-default + (block $switch-case + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (tee_local $1 + (i64.sub + (get_local $0) + (i64.const 9218868437227405312) + ) + ) + (i64.const 32) + ) + ) + ) + (br_table $switch-case $switch-default + (i32.wrap/i64 + (get_local $1) + ) + ) + ) + (call $abort) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -646,6 +684,12 @@ (i64.const 0) ) ) + (call $switch64_big_condition1 + (i64.const 0) + ) + (call $switch64_big_condition1 + (i64.const 0) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.imprecise.no-opts b/test/wasm-only.fromasm.imprecise.no-opts index 8c49b41d5..0052a5c93 100644 --- a/test/wasm-only.fromasm.imprecise.no-opts +++ b/test/wasm-only.fromasm.imprecise.no-opts @@ -2,6 +2,7 @@ (type $FUNCSIG$vdji (func (param f64 i64 i32))) (type $FUNCSIG$j (func (result i64))) (type $FUNCSIG$ff (func (param f32) (result f32))) + (type $FUNCSIG$v (func)) (type $legaltype$illegalImport (func (param f64 i32 i32 i32))) (type $legaltype$illegalImportResult (func (result i32))) (type $legaltype$_fabsf (func (param f64) (result f64))) @@ -11,6 +12,7 @@ (import "env" "illegalImportResult" (func $illegalImportResult (result i64))) (import "env" "_fabsf" (func $_fabsf (param f32) (result f32))) (import "env" "do_i64" (func $do_i64 (result i64))) + (import "env" "abort" (func $abort)) (import "env" "illegalImport" (func $legalimport$illegalImport (param f64 i32 i32 i32))) (import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32))) (import "env" "_fabsf" (func $legalimport$_fabsf (param f64) (result f64))) @@ -688,15 +690,29 @@ ) (func $switch64 (param $$a444 i64) (result i32) (local $$waka i32) + (local $2 i64) (block $switch (block $switch-default (block $switch-case0 (block $switch-case (br_table $switch-case0 $switch-default $switch-case $switch-default (i32.wrap/i64 - (i64.sub - (get_local $$a444) - (i64.const 42949672965) + (block (result i64) + (set_local $2 + (i64.sub + (get_local $$a444) + (i64.const 42949672965) + ) + ) + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 32) + ) + ) + ) + (get_local $2) ) ) ) @@ -1469,6 +1485,73 @@ (get_local $$cond) ) ) + (func $switch64_big_condition1 (param $$x i64) + (local $1 i64) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.wrap/i64 + (block (result i64) + (set_local $1 + (i64.sub + (get_local $$x) + (i64.const 9218868437227405312) + ) + ) + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 32) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (block + (call $abort) + (br $switch) + ) + ) + (return) + ) + ) + (func $switch64_big_condition2 (param $$x i64) + (local $1 i64) + (block $switch + (block $switch-case + (br_table $switch-case $switch + (i32.wrap/i64 + (block (result i64) + (set_local $1 + (i64.sub + (get_local $$x) + (i64.const 9218868437227405312) + ) + ) + (br_if $switch + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 32) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (block + (call $abort) + (br $switch) + ) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -1526,6 +1609,12 @@ (i64.const 0) ) ) + (call $switch64_big_condition1 + (i64.const 0) + ) + (call $switch64_big_condition2 + (i64.const 0) + ) ) (func $__emscripten_dceable_type_decls (drop diff --git a/test/wasm-only.fromasm.no-opts b/test/wasm-only.fromasm.no-opts index baac47fba..143fc9892 100644 --- a/test/wasm-only.fromasm.no-opts +++ b/test/wasm-only.fromasm.no-opts @@ -2,6 +2,7 @@ (type $FUNCSIG$vdji (func (param f64 i64 i32))) (type $FUNCSIG$j (func (result i64))) (type $FUNCSIG$ff (func (param f32) (result f32))) + (type $FUNCSIG$v (func)) (type $legaltype$illegalImport (func (param f64 i32 i32 i32))) (type $legaltype$illegalImportResult (func (result i32))) (type $legaltype$_fabsf (func (param f64) (result f64))) @@ -11,6 +12,7 @@ (import "env" "illegalImportResult" (func $illegalImportResult (result i64))) (import "env" "_fabsf" (func $_fabsf (param f32) (result f32))) (import "env" "do_i64" (func $do_i64 (result i64))) + (import "env" "abort" (func $abort)) (import "env" "illegalImport" (func $legalimport$illegalImport (param f64 i32 i32 i32))) (import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32))) (import "env" "_fabsf" (func $legalimport$_fabsf (param f64) (result f64))) @@ -779,15 +781,29 @@ ) (func $switch64 (param $$a444 i64) (result i32) (local $$waka i32) + (local $2 i64) (block $switch (block $switch-default (block $switch-case0 (block $switch-case (br_table $switch-case0 $switch-default $switch-case $switch-default (i32.wrap/i64 - (i64.sub - (get_local $$a444) - (i64.const 42949672965) + (block (result i64) + (set_local $2 + (i64.sub + (get_local $$a444) + (i64.const 42949672965) + ) + ) + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 32) + ) + ) + ) + (get_local $2) ) ) ) @@ -1560,6 +1576,73 @@ (get_local $$cond) ) ) + (func $switch64_big_condition1 (param $$x i64) + (local $1 i64) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.wrap/i64 + (block (result i64) + (set_local $1 + (i64.sub + (get_local $$x) + (i64.const 9218868437227405312) + ) + ) + (br_if $switch-default + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 32) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (block + (call $abort) + (br $switch) + ) + ) + (return) + ) + ) + (func $switch64_big_condition2 (param $$x i64) + (local $1 i64) + (block $switch + (block $switch-case + (br_table $switch-case $switch + (i32.wrap/i64 + (block (result i64) + (set_local $1 + (i64.sub + (get_local $$x) + (i64.const 9218868437227405312) + ) + ) + (br_if $switch + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 32) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (block + (call $abort) + (br $switch) + ) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -1617,6 +1700,12 @@ (i64.const 0) ) ) + (call $switch64_big_condition1 + (i64.const 0) + ) + (call $switch64_big_condition2 + (i64.const 0) + ) ) (func $__emscripten_dceable_type_decls (drop |