summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Flatten.cpp16
-rw-r--r--test/binaryen.js/kitchen-sink.js2
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt4
-rw-r--r--test/passes/flatten.txt121
-rw-r--r--test/passes/flatten.wast5
-rw-r--r--test/passes/inlining.txt2
-rw-r--r--test/passes/inlining.wast2
7 files changed, 110 insertions, 42 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp
index 00130838e..53fd6a02b 100644
--- a/src/passes/Flatten.cpp
+++ b/src/passes/Flatten.cpp
@@ -46,6 +46,8 @@
// anything else is written to a local earlier.
// 2. Disallow block, loop, and if return values, i.e., do not use
// control flow to pass around values.
+// 3. Disallow tee_local, setting a local is always done in a set_local
+// on a non-nested-expression location.
//
#include <wasm.h>
@@ -185,7 +187,19 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress
ourPreludes.swap(iter->second);
}
// special handling
- if (auto* br = curr->dynCast<Break>()) {
+ if (auto* set = curr->dynCast<SetLocal>()) {
+ if (set->isTee()) {
+ // we disallow tee_local
+ if (set->value->type == unreachable) {
+ replaceCurrent(set->value); // trivial, no set happens
+ } else {
+ // use a set in a prelude + a get
+ set->setTee(false);
+ ourPreludes.push_back(set);
+ replaceCurrent(builder.makeGetLocal(set->index, set->value->type));
+ }
+ }
+ } else if (auto* br = curr->dynCast<Break>()) {
if (br->value) {
auto type = br->value->type;
if (isConcreteWasmType(type)) {
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index bd55dc8a0..3205de702 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -214,7 +214,7 @@ function test_core() {
console.log("getExpressionType=" + Binaryen.getExpressionType(valueList[3]));
console.log(Binaryen.emitText(valueList[3])); // test printing a standalone expression
console.log(Binaryen.getConstValueI32(module.i32.const(5)));
- console.log(Binaryen.getConstValueI64(module.i64.const(6, 7)));
+ console.log(JSON.stringify(Binaryen.getConstValueI64(module.i64.const(6, 7))));
console.log(Binaryen.getConstValueF32(module.f32.const(8.5)));
console.log(Binaryen.getConstValueF64(module.f64.const(9.5)));
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index d097e9a7f..f585d28d8 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -38,7 +38,7 @@ getExpressionType=3
)
5
-{ low: 6, high: 7 }
+{"low":6,"high":7}
8.5
9.5
(module
@@ -1403,7 +1403,7 @@ getExpressionType=3
expressions[248] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078));
BinaryenConstGetValueI64Low(expressions[248]);
BinaryenConstGetValueI64High(expressions[248]);
-{ low: 6, high: 7 }
+{"low":6,"high":7}
expressions[249] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5));
BinaryenConstGetValueF32(expressions[249]);
8.5
diff --git a/test/passes/flatten.txt b/test/passes/flatten.txt
index 946c45ebe..c09305cb8 100644
--- a/test/passes/flatten.txt
+++ b/test/passes/flatten.txt
@@ -112,10 +112,11 @@
(local $6 i32)
(local $7 i32)
(block $block
+ (set_local $x
+ (i32.const 0)
+ )
(set_local $1
- (tee_local $x
- (i32.const 0)
- )
+ (get_local $x)
)
(set_local $2
(get_local $1)
@@ -125,10 +126,11 @@
(get_local $2)
)
(block $block1
+ (set_local $x
+ (i32.const 1)
+ )
(set_local $4
- (tee_local $x
- (i32.const 1)
- )
+ (get_local $x)
)
(set_local $5
(get_local $4)
@@ -160,10 +162,11 @@
(local $9 i32)
(block $block
(block $block2
+ (set_local $x
+ (i32.const 0)
+ )
(set_local $1
- (tee_local $x
- (i32.const 0)
- )
+ (get_local $x)
)
(set_local $2
(get_local $1)
@@ -173,10 +176,11 @@
(get_local $2)
)
(block $block3
+ (set_local $x
+ (i32.const 1)
+ )
(set_local $4
- (tee_local $x
- (i32.const 1)
- )
+ (get_local $x)
)
(set_local $5
(get_local $4)
@@ -240,10 +244,11 @@
)
(br $outer)
(unreachable)
+ (set_local $x
+ (i32.const 3)
+ )
(set_local $5
- (tee_local $x
- (i32.const 3)
- )
+ (get_local $x)
)
(set_local $6
(get_local $5)
@@ -344,10 +349,11 @@
(get_local $2)
)
(nop)
+ (set_local $x
+ (i32.const 2)
+ )
(set_local $3
- (tee_local $x
- (i32.const 2)
- )
+ (get_local $x)
)
(set_local $1
(get_local $3)
@@ -362,10 +368,11 @@
(get_local $4)
)
(nop)
+ (set_local $x
+ (i32.const 5)
+ )
(set_local $5
- (tee_local $x
- (i32.const 5)
- )
+ (get_local $x)
)
(set_local $1
(i32.const 4)
@@ -380,15 +387,17 @@
(get_local $6)
)
(nop)
+ (set_local $x
+ (i32.const 6)
+ )
(set_local $7
- (tee_local $x
- (i32.const 6)
- )
+ (get_local $x)
+ )
+ (set_local $x
+ (i32.const 7)
)
(set_local $8
- (tee_local $x
- (i32.const 7)
- )
+ (get_local $x)
)
(set_local $1
(get_local $7)
@@ -556,10 +565,11 @@
(local $6 i32)
(local $7 i32)
(block $label$1
+ (set_local $x
+ (i32.const 1)
+ )
(set_local $1
- (tee_local $x
- (i32.const 1)
- )
+ (get_local $x)
)
(block $label$2
(set_local $x
@@ -612,10 +622,11 @@
(set_local $1
(get_local $var$0)
)
+ (set_local $var$0
+ (f32.const -137438953472)
+ )
(set_local $2
- (tee_local $var$0
- (f32.const -137438953472)
- )
+ (get_local $var$0)
)
(set_local $3
(get_local $var$0)
@@ -1128,9 +1139,7 @@
(i32.const 11)
(block
(unreachable)
- (tee_local $x
- (unreachable)
- )
+ (unreachable)
(unreachable)
)
)
@@ -2399,4 +2408,44 @@
(get_local $9)
)
)
+ (func $tees (; 41 ;) (type $ii) (param $x i32) (param $y i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (block
+ (set_local $x
+ (i32.const 1)
+ )
+ (set_local $2
+ (get_local $x)
+ )
+ (drop
+ (get_local $2)
+ )
+ (nop)
+ (unreachable)
+ (unreachable)
+ (drop
+ (unreachable)
+ )
+ (unreachable)
+ (set_local $x
+ (i32.const 2)
+ )
+ (set_local $3
+ (get_local $x)
+ )
+ (set_local $y
+ (get_local $3)
+ )
+ (set_local $4
+ (get_local $y)
+ )
+ (drop
+ (get_local $4)
+ )
+ (nop)
+ )
+ (unreachable)
+ )
)
diff --git a/test/passes/flatten.wast b/test/passes/flatten.wast
index 35b009939..6b71158f6 100644
--- a/test/passes/flatten.wast
+++ b/test/passes/flatten.wast
@@ -1011,4 +1011,9 @@
)
)
)
+ (func $tees (param $x i32) (param $y i32)
+ (drop (tee_local $x (i32.const 1)))
+ (drop (tee_local $x (unreachable)))
+ (drop (tee_local $y (tee_local $x (i32.const 2))))
+ )
)
diff --git a/test/passes/inlining.txt b/test/passes/inlining.txt
index 67604971d..8a195b96d 100644
--- a/test/passes/inlining.txt
+++ b/test/passes/inlining.txt
@@ -225,7 +225,7 @@
(memory $0 0)
(func $0 (; 0 ;) (type $1)
(block $__inlined_func$1
- (call_indirect $T
+ (call_indirect (type $T)
(if (result i32)
(i32.const 0)
(unreachable)
diff --git a/test/passes/inlining.wast b/test/passes/inlining.wast
index f68fb6703..eda8b9cc1 100644
--- a/test/passes/inlining.wast
+++ b/test/passes/inlining.wast
@@ -152,7 +152,7 @@
(call $1)
)
(func $1
- (call_indirect $T
+ (call_indirect (type $T)
(if (result i32) ;; if copy must preserve the forced type
(i32.const 0)
(unreachable)