summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp64
-rw-r--r--test/lit/passes/asyncify_optimize-level=1.wast22
-rw-r--r--test/lit/passes/optimize-instructions.wast19
3 files changed, 63 insertions, 42 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index b50f99fbc..9379d8588 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -2370,21 +2370,6 @@ private:
// order using a temp local, which would be bad
}
{
- // Flip select to remove eqz if we can reorder
- Select* s;
- Expression *ifTrue, *ifFalse, *c;
- if (matches(
- curr,
- select(
- &s, any(&ifTrue), any(&ifFalse), unary(EqZInt32, any(&c)))) &&
- canReorder(ifTrue, ifFalse)) {
- s->ifTrue = ifFalse;
- s->ifFalse = ifTrue;
- s->condition = c;
- return s;
- }
- }
- {
// TODO: Remove this after landing SCCP pass. See: #4161
// i32(x) ? i32(x) : 0 ==> x
@@ -2436,6 +2421,25 @@ private:
return curr->type == Type::i64 ? builder.makeUnary(ExtendUInt32, c) : c;
}
}
+ if (curr->type == Type::i32 &&
+ Bits::getMaxBits(curr->condition, this) <= 1 &&
+ Bits::getMaxBits(curr->ifTrue, this) <= 1 &&
+ Bits::getMaxBits(curr->ifFalse, this) <= 1) {
+ // The condition and both arms are i32 booleans, which allows us to do
+ // boolean optimizations.
+ Expression* x;
+ Expression* y;
+
+ // x ? y : 0 ==> x & y
+ if (matches(curr, select(any(&y), ival(0), any(&x)))) {
+ return builder.makeBinary(AndInt32, y, x);
+ }
+
+ // x ? 1 : y ==> x | y
+ if (matches(curr, select(ival(1), any(&y), any(&x)))) {
+ return builder.makeBinary(OrInt32, y, x);
+ }
+ }
{
// Simplify x < 0 ? -1 : 1 or x >= 0 ? 1 : -1 to
// i32(x) >> 31 | 1
@@ -2459,23 +2463,19 @@ private:
}
}
}
- if (curr->type == Type::i32 &&
- Bits::getMaxBits(curr->condition, this) <= 1 &&
- Bits::getMaxBits(curr->ifTrue, this) <= 1 &&
- Bits::getMaxBits(curr->ifFalse, this) <= 1) {
- // The condition and both arms are i32 booleans, which allows us to do
- // boolean optimizations.
- Expression* x;
- Expression* y;
-
- // x ? y : 0 ==> x & y
- if (matches(curr, select(any(&y), ival(0), any(&x)))) {
- return builder.makeBinary(AndInt32, y, x);
- }
-
- // x ? 1 : y ==> x | y
- if (matches(curr, select(ival(1), any(&y), any(&x)))) {
- return builder.makeBinary(OrInt32, y, x);
+ {
+ // Flip select to remove eqz if we can reorder
+ Select* s;
+ Expression *ifTrue, *ifFalse, *c;
+ if (matches(
+ curr,
+ select(
+ &s, any(&ifTrue), any(&ifFalse), unary(EqZInt32, any(&c)))) &&
+ canReorder(ifTrue, ifFalse)) {
+ s->ifTrue = ifFalse;
+ s->ifFalse = ifTrue;
+ s->condition = c;
+ return s;
}
}
{
diff --git a/test/lit/passes/asyncify_optimize-level=1.wast b/test/lit/passes/asyncify_optimize-level=1.wast
index 953c04ba6..0affdb757 100644
--- a/test/lit/passes/asyncify_optimize-level=1.wast
+++ b/test/lit/passes/asyncify_optimize-level=1.wast
@@ -752,8 +752,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
- ;; CHECK-NEXT: (select
- ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.and
+ ;; CHECK-NEXT: (i32.eqz
+ ;; CHECK-NEXT: (select
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (global.get $__asyncify_state)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.or
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $2)
@@ -763,11 +769,6 @@
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (select
- ;; CHECK-NEXT: (local.get $1)
- ;; CHECK-NEXT: (i32.const 0)
- ;; CHECK-NEXT: (global.get $__asyncify_state)
- ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (call $import3
@@ -906,8 +907,10 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
- ;; CHECK-NEXT: (select
- ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.and
+ ;; CHECK-NEXT: (i32.eqz
+ ;; CHECK-NEXT: (global.get $__asyncify_state)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.or
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $1)
@@ -917,7 +920,6 @@
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (global.get $__asyncify_state)
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 2)
diff --git a/test/lit/passes/optimize-instructions.wast b/test/lit/passes/optimize-instructions.wast
index 91e08e328..b7b6b810f 100644
--- a/test/lit/passes/optimize-instructions.wast
+++ b/test/lit/passes/optimize-instructions.wast
@@ -732,6 +732,25 @@
)
)
)
+ ;; CHECK: (func $select-and-eqz (param $x i32) (param $y i32) (result i32)
+ ;; CHECK-NEXT: (i32.eqz
+ ;; CHECK-NEXT: (i32.or
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $select-and-eqz (param $x i32) (param $y i32) (result i32)
+ (select
+ (i32.eqz
+ (local.get $x)
+ )
+ (i32.const 0)
+ (i32.eqz
+ (local.get $y)
+ )
+ )
+ )
;; CHECK: (func $select-or-side-effects (param $x i32) (param $y i32) (result i32)
;; CHECK-NEXT: (i32.or
;; CHECK-NEXT: (i32.eq