summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai (kripken) <alonzakai@gmail.com>2017-07-10 20:48:39 -0700
committerAlon Zakai (kripken) <alonzakai@gmail.com>2017-07-11 11:07:46 -0700
commit75162c41b83f67eee967b1d7a1068ba87e17b4eb (patch)
tree72fc847f229639d2e8abe399f59357a7d4498fa4
parentb2445bf12b1ba96209b6ebece3806503411f1c94 (diff)
downloadbinaryen-75162c41b83f67eee967b1d7a1068ba87e17b4eb.tar.gz
binaryen-75162c41b83f67eee967b1d7a1068ba87e17b4eb.tar.bz2
binaryen-75162c41b83f67eee967b1d7a1068ba87e17b4eb.zip
fix block removal in remove-unused-brs, even if not taken, if named, we must preserve it
-rw-r--r--src/passes/RemoveUnusedBrs.cpp4
-rw-r--r--test/passes/remove-unused-brs.txt36
-rw-r--r--test/passes/remove-unused-brs.wast35
3 files changed, 73 insertions, 2 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 572105187..b725de901 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -259,7 +259,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// so only do it if it looks useful, which it definitely is if
// (a) $somewhere is straight out (so the br out vanishes), and
// (b) this br_if is the only branch to that block (so the block will vanish)
- if (brIf->name == block->name && BranchUtils::BranchSeeker::count(block, block->name) == 1) {
+ if (brIf->name == block->name && BranchUtils::BranchSeeker::countNamed(block, block->name) == 1) {
// note that we could drop the last element here, it is a br we know for sure is removable,
// but telling stealSlice to steal all to the end is more efficient, it can just truncate.
list[i] = builder.makeIf(brIf->condition, builder.makeBreak(brIf->name), builder.stealSlice(block, i + 1, list.size()));
@@ -449,7 +449,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto* br = list[0]->dynCast<Break>();
if (br && br->condition && br->name == curr->name) {
assert(!br->value); // can't, it would be dropped or last in the block
- if (BranchUtils::BranchSeeker::count(curr, curr->name) == 1) {
+ if (BranchUtils::BranchSeeker::countNamed(curr, curr->name) == 1) {
// no other breaks to that name, so we can do this
Builder builder(*getModule());
replaceCurrent(builder.makeIf(
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index 62643ae00..07b4575ce 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -4,6 +4,7 @@
(type $2 (func (result i32)))
(type $3 (func (param i32 i32) (result i32)))
(type $4 (func (param i32 i32)))
+ (type $5 (func (param f32 i32 f32 i32 i32 f64 f32) (result i32)))
(memory $0 256 256)
(func $b0-yes (type $0) (param $i1 i32)
(block $topmost
@@ -975,4 +976,39 @@
)
)
)
+ (func $untaken-brs-might-prevent-block-removal (type $5) (param $0 f32) (param $1 i32) (param $2 f32) (param $3 i32) (param $4 i32) (param $5 f64) (param $6 f32) (result i32)
+ (block $label$0 (result i32)
+ (block $label$1
+ (br_if $label$1
+ (i32.const 607395945)
+ )
+ (br_if $label$1
+ (unreachable.load16_s offset=3 align=1
+ (select
+ (call $untaken-brs-might-prevent-block-removal
+ (f32.const 1.4904844647389837e-07)
+ (br_if $label$0
+ (i32.store16 offset=4 align=1
+ (i32.const 1900641)
+ (br $label$0
+ (i32.const 1628075109)
+ )
+ )
+ (i32.const 1764950569)
+ )
+ (f32.const 1.1910939690100655e-32)
+ (i32.const 1628057906)
+ (i32.const 859068982)
+ (f64.const 2.524518840347722e-258)
+ (f32.const -nan:0x40a63)
+ )
+ (i32.const 688529440)
+ (i32.const 1751478890)
+ )
+ )
+ )
+ )
+ (i32.const 1935947830)
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast
index a573a385a..04ebdac33 100644
--- a/test/passes/remove-unused-brs.wast
+++ b/test/passes/remove-unused-brs.wast
@@ -866,5 +866,40 @@
)
)
)
+ (func $untaken-brs-might-prevent-block-removal (param $0 f32) (param $1 i32) (param $2 f32) (param $3 i32) (param $4 i32) (param $5 f64) (param $6 f32) (result i32)
+ (block $label$0 (result i32)
+ (block $label$1 ;; this block has no taken brs, but we can't remove it without removing them first
+ (br_if $label$1
+ (i32.const 607395945)
+ )
+ (br_if $label$1
+ (i32.load16_s offset=3 align=1
+ (select
+ (call $untaken-brs-might-prevent-block-removal
+ (f32.const 1.4904844647389837e-07)
+ (br_if $label$0
+ (i32.store16 offset=4 align=1
+ (i32.const 1900641)
+ (br $label$0
+ (i32.const 1628075109)
+ )
+ )
+ (i32.const 1764950569)
+ )
+ (f32.const 1.1910939690100655e-32)
+ (i32.const 1628057906)
+ (i32.const 859068982)
+ (f64.const 2.524518840347722e-258)
+ (f32.const -nan:0x40a63)
+ )
+ (i32.const 688529440)
+ (i32.const 1751478890)
+ )
+ )
+ )
+ )
+ (i32.const 1935947830)
+ )
+ )
)