diff options
author | Alon Zakai <azakai@google.com> | 2019-06-30 08:43:06 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-30 08:43:06 -0700 |
commit | ba6cf2eff312a571fb1964e05aeb285c63a4772c (patch) | |
tree | c8c9e690f8866b2356b17f59a460b23569a87c44 | |
parent | 04c55fd025a972722cfdaf7ff30e8fc6e597e2af (diff) | |
download | binaryen-ba6cf2eff312a571fb1964e05aeb285c63a4772c.tar.gz binaryen-ba6cf2eff312a571fb1964e05aeb285c63a4772c.tar.bz2 binaryen-ba6cf2eff312a571fb1964e05aeb285c63a4772c.zip |
Bysyncify: fix skipping of flattened if condition (#2187)
We assigned it to a local, but didn't run maybeSkip on it. As a result, it was executed during rewinding, which broke restoring the saved value.
Found by the fuzzer.
-rw-r--r-- | src/passes/Bysyncify.cpp | 7 | ||||
-rw-r--r-- | test/passes/bysyncify.txt | 39 | ||||
-rw-r--r-- | test/passes/bysyncify_optimize-level=1.txt | 134 | ||||
-rw-r--r-- | test/passes/bysyncify_pass-arg=bysyncify-ignore-indirect.txt | 13 |
4 files changed, 142 insertions, 51 deletions
diff --git a/src/passes/Bysyncify.cpp b/src/passes/Bysyncify.cpp index 416869194..5e2f73e5c 100644 --- a/src/passes/Bysyncify.cpp +++ b/src/passes/Bysyncify.cpp @@ -658,7 +658,10 @@ private: return iff; } auto conditionTemp = builder->addVar(func, i32); - iff->condition = builder->makeLocalTee(conditionTemp, iff->condition); + // TODO: can avoid pre if the condition is a get or a const + auto* pre = + makeMaybeSkip(builder->makeLocalSet(conditionTemp, iff->condition)); + iff->condition = builder->makeLocalGet(conditionTemp, i32); iff->condition = builder->makeBinary( OrInt32, iff->condition, builder->makeStateCheck(State::Rewinding)); iff->ifTrue = process(iff->ifTrue); @@ -674,7 +677,7 @@ private: builder->makeStateCheck(State::Rewinding)), process(otherArm)); otherIf->finalize(); - return builder->makeSequence(iff, otherIf); + return builder->makeBlock({pre, iff, otherIf}); } else if (auto* loop = curr->dynCast<Loop>()) { loop->body = process(loop->body); return loop; diff --git a/test/passes/bysyncify.txt b/test/passes/bysyncify.txt index 7b5a9eaff..fbbc09d45 100644 --- a/test/passes/bysyncify.txt +++ b/test/passes/bysyncify.txt @@ -1366,10 +1366,17 @@ ) (block (if + (i32.eq + (global.get $__bysyncify_state) + (i32.const 0) + ) + (local.set $2 + (local.get $1) + ) + ) + (if (i32.or - (local.tee $2 - (local.get $1) - ) + (local.get $2) (i32.eq (global.get $__bysyncify_state) (i32.const 2) @@ -1617,10 +1624,17 @@ ) (block (if + (i32.eq + (global.get $__bysyncify_state) + (i32.const 0) + ) + (local.set $4 + (local.get $1) + ) + ) + (if (i32.or - (local.tee $4 - (local.get $1) - ) + (local.get $4) (i32.eq (global.get $__bysyncify_state) (i32.const 2) @@ -1857,10 +1871,17 @@ ) (block (if + (i32.eq + (global.get $__bysyncify_state) + (i32.const 0) + ) + (local.set $4 + (local.get $1) + ) + ) + (if (i32.or - (local.tee $4 - (local.get $1) - ) + (local.get $4) (i32.eq (global.get $__bysyncify_state) (i32.const 2) diff --git a/test/passes/bysyncify_optimize-level=1.txt b/test/passes/bysyncify_optimize-level=1.txt index 89fb33ce4..b09368ec4 100644 --- a/test/passes/bysyncify_optimize-level=1.txt +++ b/test/passes/bysyncify_optimize-level=1.txt @@ -536,6 +536,7 @@ ) (func $calls-import2-if-else (; 9 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) + (local $2 i32) (if (i32.eq (global.get $__bysyncify_state) @@ -548,19 +549,26 @@ (i32.load (global.get $__bysyncify_data) ) - (i32.const -4) + (i32.const -8) ) ) (local.set $0 (i32.load - (i32.load - (global.get $__bysyncify_data) + (local.tee $1 + (i32.load + (global.get $__bysyncify_data) + ) ) ) ) + (local.set $1 + (i32.load offset=4 + (local.get $1) + ) + ) ) ) - (local.set $1 + (local.set $2 (block $__bysyncify_unwind (result i32) (if (i32.eq @@ -577,7 +585,7 @@ (i32.const -4) ) ) - (local.set $1 + (local.set $2 (i32.load (i32.load (global.get $__bysyncify_data) @@ -588,16 +596,22 @@ ) (if (i32.or + (local.tee $1 + (select + (local.get $1) + (local.get $0) + (global.get $__bysyncify_state) + ) + ) (i32.eq (global.get $__bysyncify_state) (i32.const 2) ) - (local.get $0) ) (if (select (i32.eqz - (local.get $1) + (local.get $2) ) (i32.const 1) (global.get $__bysyncify_state) @@ -621,7 +635,7 @@ (if (i32.or (i32.eqz - (local.get $0) + (local.get $1) ) (i32.eq (global.get $__bysyncify_state) @@ -631,7 +645,7 @@ (if (select (i32.eq - (local.get $1) + (local.get $2) (i32.const 1) ) (i32.const 1) @@ -660,7 +674,7 @@ (i32.load (global.get $__bysyncify_data) ) - (local.get $1) + (local.get $2) ) (i32.store (global.get $__bysyncify_data) @@ -672,23 +686,30 @@ ) ) (i32.store - (i32.load - (global.get $__bysyncify_data) + (local.tee $2 + (i32.load + (global.get $__bysyncify_data) + ) ) (local.get $0) ) + (i32.store offset=4 + (local.get $2) + (local.get $1) + ) (i32.store (global.get $__bysyncify_data) (i32.add (i32.load (global.get $__bysyncify_data) ) - (i32.const 4) + (i32.const 8) ) ) ) (func $calls-import2-if-else-oneside (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) + (local $2 i32) (if (i32.eq (global.get $__bysyncify_state) @@ -701,19 +722,26 @@ (i32.load (global.get $__bysyncify_data) ) - (i32.const -4) + (i32.const -8) ) ) (local.set $0 (i32.load - (i32.load - (global.get $__bysyncify_data) + (local.tee $1 + (i32.load + (global.get $__bysyncify_data) + ) ) ) ) + (local.set $1 + (i32.load offset=4 + (local.get $1) + ) + ) ) ) - (local.set $1 + (local.set $2 (block $__bysyncify_unwind (result i32) (if (i32.eq @@ -730,7 +758,7 @@ (i32.const -4) ) ) - (local.set $1 + (local.set $2 (i32.load (i32.load (global.get $__bysyncify_data) @@ -741,11 +769,17 @@ ) (if (i32.or + (local.tee $1 + (select + (local.get $1) + (local.get $0) + (global.get $__bysyncify_state) + ) + ) (i32.eq (global.get $__bysyncify_state) (i32.const 2) ) - (local.get $0) ) (if (i32.eqz @@ -759,7 +793,7 @@ (if (i32.or (i32.eqz - (local.get $0) + (local.get $1) ) (i32.eq (global.get $__bysyncify_state) @@ -769,7 +803,7 @@ (if (select (i32.eqz - (local.get $1) + (local.get $2) ) (i32.const 1) (global.get $__bysyncify_state) @@ -805,7 +839,7 @@ (i32.load (global.get $__bysyncify_data) ) - (local.get $1) + (local.get $2) ) (i32.store (global.get $__bysyncify_data) @@ -817,24 +851,31 @@ ) ) (i32.store - (i32.load - (global.get $__bysyncify_data) + (local.tee $2 + (i32.load + (global.get $__bysyncify_data) + ) ) (local.get $0) ) + (i32.store offset=4 + (local.get $2) + (local.get $1) + ) (i32.store (global.get $__bysyncify_data) (i32.add (i32.load (global.get $__bysyncify_data) ) - (i32.const 4) + (i32.const 8) ) ) (i32.const 0) ) (func $calls-import2-if-else-oneside2 (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) + (local $2 i32) (if (i32.eq (global.get $__bysyncify_state) @@ -847,19 +888,26 @@ (i32.load (global.get $__bysyncify_data) ) - (i32.const -4) + (i32.const -8) ) ) (local.set $0 (i32.load - (i32.load - (global.get $__bysyncify_data) + (local.tee $1 + (i32.load + (global.get $__bysyncify_data) + ) ) ) ) + (local.set $1 + (i32.load offset=4 + (local.get $1) + ) + ) ) ) - (local.set $1 + (local.set $2 (block $__bysyncify_unwind (result i32) (if (i32.eq @@ -876,7 +924,7 @@ (i32.const -4) ) ) - (local.set $1 + (local.set $2 (i32.load (i32.load (global.get $__bysyncify_data) @@ -887,16 +935,22 @@ ) (if (i32.or + (local.tee $1 + (select + (local.get $1) + (local.get $0) + (global.get $__bysyncify_state) + ) + ) (i32.eq (global.get $__bysyncify_state) (i32.const 2) ) - (local.get $0) ) (if (select (i32.eqz - (local.get $1) + (local.get $2) ) (i32.const 1) (global.get $__bysyncify_state) @@ -920,7 +974,7 @@ (if (i32.or (i32.eqz - (local.get $0) + (local.get $1) ) (i32.eq (global.get $__bysyncify_state) @@ -951,7 +1005,7 @@ (i32.load (global.get $__bysyncify_data) ) - (local.get $1) + (local.get $2) ) (i32.store (global.get $__bysyncify_data) @@ -963,18 +1017,24 @@ ) ) (i32.store - (i32.load - (global.get $__bysyncify_data) + (local.tee $2 + (i32.load + (global.get $__bysyncify_data) + ) ) (local.get $0) ) + (i32.store offset=4 + (local.get $2) + (local.get $1) + ) (i32.store (global.get $__bysyncify_data) (i32.add (i32.load (global.get $__bysyncify_data) ) - (i32.const 4) + (i32.const 8) ) ) (i32.const 0) diff --git a/test/passes/bysyncify_pass-arg=bysyncify-ignore-indirect.txt b/test/passes/bysyncify_pass-arg=bysyncify-ignore-indirect.txt index 347ada93e..64e516cf8 100644 --- a/test/passes/bysyncify_pass-arg=bysyncify-ignore-indirect.txt +++ b/test/passes/bysyncify_pass-arg=bysyncify-ignore-indirect.txt @@ -345,10 +345,17 @@ ) (block (if + (i32.eq + (global.get $__bysyncify_state) + (i32.const 0) + ) + (local.set $2 + (local.get $1) + ) + ) + (if (i32.or - (local.tee $2 - (local.get $1) - ) + (local.get $2) (i32.eq (global.get $__bysyncify_state) (i32.const 2) |