diff options
-rw-r--r-- | src/ast_utils.h | 18 | ||||
-rw-r--r-- | test/unit.asm.js | 15 | ||||
-rw-r--r-- | test/unit.fromasm | 15 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 15 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise.no-opts | 48 | ||||
-rw-r--r-- | test/unit.fromasm.no-opts | 48 |
6 files changed, 148 insertions, 11 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index f883d5f66..4664f22ae 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -881,9 +881,21 @@ struct AutoDrop : public WalkerPass<ExpressionStackWalker<AutoDrop, Visitor<Auto } void visitIf(If* curr) { - // if without else does not return a value, so the body must be dropped if it is concrete - if (!curr->ifFalse && isConcreteWasmType(curr->ifTrue->type)) { - curr->ifTrue = Builder(*getModule()).makeDrop(curr->ifTrue); + if (curr->ifFalse) { + if (!isConcreteWasmType(curr->type)) { + // if either side of an if-else not returning a value is concrete, drop it + if (isConcreteWasmType(curr->ifTrue->type)) { + curr->ifTrue = Builder(*getModule()).makeDrop(curr->ifTrue); + } + if (isConcreteWasmType(curr->ifFalse->type)) { + curr->ifFalse = Builder(*getModule()).makeDrop(curr->ifFalse); + } + } + } else { + // if without else does not return a value, so the body must be dropped if it is concrete + if (isConcreteWasmType(curr->ifTrue->type)) { + curr->ifTrue = Builder(*getModule()).makeDrop(curr->ifTrue); + } } } diff --git a/test/unit.asm.js b/test/unit.asm.js index 0decc886c..d4426bd90 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -557,6 +557,21 @@ function asm(global, env, buffer) { } } + function jumpThreadDrop() { + var label = 0, temp = 0; + temp = return_int() | 0; + while (1) { + label = 14; + break; + } + if ((label | 0) == 10) { + } else if ((label | 0) == 12) { + return_int() | 0; // drop in the middle of an if-else chain for threading + } else if ((label | 0) == 14) { + } + return temp | 0; + } + var FUNCTION_TABLE_a = [ z, big_negative, z, z ]; var FUNCTION_TABLE_b = [ w, w, importedDoubles, w ]; var FUNCTION_TABLE_c = [ z, cneg ]; diff --git a/test/unit.fromasm b/test/unit.fromasm index 773cbbd9d..6dd442a36 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -1002,9 +1002,20 @@ ) ) ) - (call $lb - (i32.const 1) + (drop + (call $lb + (i32.const 1) + ) ) ) ) + (func $jumpThreadDrop (result i32) + (local $0 i32) + (set_local $0 + (call_import $return_int) + ) + (block $jumpthreading$outer$2 + ) + (get_local $0) + ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index 80e34dfb9..d007a4d82 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -983,9 +983,20 @@ ) ) ) - (call $lb - (i32.const 1) + (drop + (call $lb + (i32.const 1) + ) ) ) ) + (func $jumpThreadDrop (result i32) + (local $0 i32) + (set_local $0 + (call_import $return_int) + ) + (block $jumpthreading$outer$2 + ) + (get_local $0) + ) ) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 3e532ef2a..1e8b46835 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -1572,9 +1572,53 @@ (br $while-in$1) ) ) - (call $lb - (i32.const 1) + (drop + (call $lb + (i32.const 1) + ) + ) + ) + ) + (func $jumpThreadDrop (result i32) + (local $label i32) + (local $temp i32) + (set_local $temp + (call_import $return_int) + ) + (loop $while-in$1 + (block $while-out$0 + (set_local $label + (i32.const 14) + ) + (br $while-out$0) + (br $while-in$1) + ) + ) + (if + (i32.eq + (get_local $label) + (i32.const 10) + ) + (nop) + (if + (i32.eq + (get_local $label) + (i32.const 12) + ) + (drop + (call_import $return_int) + ) + (if + (i32.eq + (get_local $label) + (i32.const 14) + ) + (nop) + ) ) ) + (return + (get_local $temp) + ) ) ) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index d2c1beec7..846ef21a0 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -1578,9 +1578,53 @@ (br $while-in$1) ) ) - (call $lb - (i32.const 1) + (drop + (call $lb + (i32.const 1) + ) + ) + ) + ) + (func $jumpThreadDrop (result i32) + (local $label i32) + (local $temp i32) + (set_local $temp + (call_import $return_int) + ) + (loop $while-in$1 + (block $while-out$0 + (set_local $label + (i32.const 14) + ) + (br $while-out$0) + (br $while-in$1) + ) + ) + (if + (i32.eq + (get_local $label) + (i32.const 10) + ) + (nop) + (if + (i32.eq + (get_local $label) + (i32.const 12) + ) + (drop + (call_import $return_int) + ) + (if + (i32.eq + (get_local $label) + (i32.const 14) + ) + (nop) + ) ) ) + (return + (get_local $temp) + ) ) ) |