summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast_utils.h18
-rw-r--r--test/unit.asm.js15
-rw-r--r--test/unit.fromasm15
-rw-r--r--test/unit.fromasm.imprecise15
-rw-r--r--test/unit.fromasm.imprecise.no-opts48
-rw-r--r--test/unit.fromasm.no-opts48
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)
+ )
)
)