summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai (kripken) <alonzakai@gmail.com>2017-07-13 17:55:10 -0700
committerAlon Zakai (kripken) <alonzakai@gmail.com>2017-07-13 17:55:10 -0700
commit9792a40a8704cbae0ee515126c0b63eb9879d626 (patch)
treef411dd761451922a5f4bc2acb5dba3b72daa09be
parent00dd3b97455652113fa36cf639315388052f502d (diff)
downloadbinaryen-9792a40a8704cbae0ee515126c0b63eb9879d626.tar.gz
binaryen-9792a40a8704cbae0ee515126c0b63eb9879d626.tar.bz2
binaryen-9792a40a8704cbae0ee515126c0b63eb9879d626.zip
when removing an if-copy in coalesce-locals, if it's a tee, we do still need the get in that arm. only when it is not a tee can we remove that arm and make the if-else into an if
-rw-r--r--src/passes/CoalesceLocals.cpp4
-rw-r--r--test/passes/coalesce-locals.txt31
-rw-r--r--test/passes/coalesce-locals.wast30
3 files changed, 64 insertions, 1 deletions
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index 87eefb85c..5ab68da23 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -597,11 +597,13 @@ void CoalesceLocals::pickIndices(std::vector<Index>& indices) {
// Remove a copy from a set of an if, where one if arm is a get of the same set
static void removeIfCopy(Expression** origin, SetLocal* set, If* iff, Expression*& copy, Expression*& other, Module* module) {
// replace the origin with the if, and sink the set into the other non-copying arm
+ bool tee = set->isTee();
*origin = iff;
set->value = other;
set->finalize();
other = set;
- if (!isConcreteWasmType(set->type)) {
+ // if this is not a tee, then we can get rid of the copy in that arm
+ if (!tee) {
// we don't need the copy at all
copy = nullptr;
if (!iff->ifTrue) {
diff --git a/test/passes/coalesce-locals.txt b/test/passes/coalesce-locals.txt
index ed6838ae8..32da026ac 100644
--- a/test/passes/coalesce-locals.txt
+++ b/test/passes/coalesce-locals.txt
@@ -7,6 +7,7 @@
(type $FUNCSIG$i (func (result i32)))
(type $FUNCSIG$vi (func (param i32)))
(type $7 (func (param i32) (result i32)))
+ (type $8 (func (param f64 i32) (result i64)))
(import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32)))
(import "env" "get" (func $get (result i32)))
(import "env" "set" (func $set (param i32)))
@@ -1122,4 +1123,34 @@
)
)
)
+ (func $tee_if_with_unreachable_else (type $8) (param $0 f64) (param $1 i32) (result i64)
+ (call $tee_if_with_unreachable_else
+ (if (result f64)
+ (get_local $1)
+ (get_local $0)
+ (tee_local $0
+ (unreachable)
+ )
+ )
+ (f64.lt
+ (f64.const -128)
+ (get_local $0)
+ )
+ )
+ )
+ (func $tee_if_with_unreachable_true (type $8) (param $0 f64) (param $1 i32) (result i64)
+ (call $tee_if_with_unreachable_else
+ (if (result f64)
+ (get_local $1)
+ (tee_local $0
+ (unreachable)
+ )
+ (get_local $0)
+ )
+ (f64.lt
+ (f64.const -128)
+ (get_local $0)
+ )
+ )
+ )
)
diff --git a/test/passes/coalesce-locals.wast b/test/passes/coalesce-locals.wast
index d959cc820..ee92bb05e 100644
--- a/test/passes/coalesce-locals.wast
+++ b/test/passes/coalesce-locals.wast
@@ -1097,4 +1097,34 @@
)
)
)
+ (func $tee_if_with_unreachable_else (param $0 f64) (param $1 i32) (result i64)
+ (call $tee_if_with_unreachable_else
+ (tee_local $0
+ (if (result f64)
+ (get_local $1)
+ (get_local $0)
+ (unreachable)
+ )
+ )
+ (f64.lt
+ (f64.const -128)
+ (get_local $0)
+ )
+ )
+ )
+ (func $tee_if_with_unreachable_true (param $0 f64) (param $1 i32) (result i64)
+ (call $tee_if_with_unreachable_else
+ (tee_local $0
+ (if (result f64)
+ (get_local $1)
+ (unreachable)
+ (get_local $0)
+ )
+ )
+ (f64.lt
+ (f64.const -128)
+ (get_local $0)
+ )
+ )
+ )
)