summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2020-11-12 20:18:44 +0200
committerGitHub <noreply@github.com>2020-11-12 10:18:44 -0800
commitdb64c53579dd925fc48260d4979d1bb9c1dfed9f (patch)
treedc7376c34f2eb5fcd1b8a75d8bf349601aef7ce8
parent1eb48a4f506a31e79be41f3bec091f799c6f5201 (diff)
downloadbinaryen-db64c53579dd925fc48260d4979d1bb9c1dfed9f.tar.gz
binaryen-db64c53579dd925fc48260d4979d1bb9c1dfed9f.tar.bz2
binaryen-db64c53579dd925fc48260d4979d1bb9c1dfed9f.zip
Some refactorings in addition to #3338 (#3336)
See discussion in #3303
-rw-r--r--src/passes/OptimizeInstructions.cpp26
-rw-r--r--test/passes/optimize-instructions_all-features.txt52
-rw-r--r--test/passes/optimize-instructions_all-features.wast52
3 files changed, 114 insertions, 16 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 83bee9a0f..019d6bda1 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1936,31 +1936,27 @@ private:
}
}
}
- // signed(x - y) <=> 0 => x <=> y
- //
+ // x - y == 0 => x == y
+ // x - y != 0 => x != y
// unsigned(x - y) > 0 => x != y
// unsigned(x - y) <= 0 => x == y
{
+ using namespace Abstract;
using namespace Match;
- BinaryOp op;
Binary* inner;
// unsigned(x - y) > 0 => x != y
if (matches(curr,
- binary(Abstract::GtU,
- binary(&inner, Abstract::Sub, any(), any()),
- ival(0)))) {
- curr->op = Abstract::getBinary(type, Abstract::Ne);
+ binary(GtU, binary(&inner, Sub, any(), any()), ival(0)))) {
+ curr->op = Abstract::getBinary(type, Ne);
curr->right = inner->right;
curr->left = inner->left;
return curr;
}
// unsigned(x - y) <= 0 => x == y
if (matches(curr,
- binary(Abstract::LeU,
- binary(&inner, Abstract::Sub, any(), any()),
- ival(0)))) {
- curr->op = Abstract::getBinary(type, Abstract::Eq);
+ binary(LeU, binary(&inner, Sub, any(), any()), ival(0)))) {
+ curr->op = Abstract::getBinary(type, Eq);
curr->right = inner->right;
curr->left = inner->left;
return curr;
@@ -1970,11 +1966,9 @@ private:
// This is not true for signed comparisons like x -y < 0 due to overflow
// effects (e.g. 8 - 0x80000000 < 0 is not the same as 8 < 0x80000000).
if (matches(curr,
- binary(&op,
- binary(&inner, Abstract::Sub, any(), any()),
- ival(0))) &&
- (op == Abstract::getBinary(type, Abstract::Eq) ||
- op == Abstract::getBinary(type, Abstract::Ne))) {
+ binary(Eq, binary(&inner, Sub, any(), any()), ival(0))) ||
+ matches(curr,
+ binary(Ne, binary(&inner, Sub, any(), any()), ival(0)))) {
curr->right = inner->right;
curr->left = inner->left;
return curr;
diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt
index 7d223020f..2cf034c7a 100644
--- a/test/passes/optimize-instructions_all-features.txt
+++ b/test/passes/optimize-instructions_all-features.txt
@@ -4842,6 +4842,58 @@
(local.get $y)
)
)
+ (drop
+ (i32.eq
+ (local.get $x)
+ (i32.const -2147483648)
+ )
+ )
+ (drop
+ (i32.ne
+ (local.get $x)
+ (i32.const -2147483648)
+ )
+ )
+ (drop
+ (i32.lt_s
+ (i32.sub
+ (local.get $x)
+ (i32.const -2147483648)
+ )
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.ge_s
+ (i32.sub
+ (local.get $x)
+ (i32.const -2147483648)
+ )
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.gt_s
+ (i32.sub
+ (local.get $x)
+ (block $block (result i32)
+ (i32.const -2147483648)
+ )
+ )
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.gt_s
+ (i32.sub
+ (local.get $x)
+ (block $block30 (result i32)
+ (i32.const -2147483648)
+ )
+ )
+ (i32.const 0)
+ )
+ )
)
(func $unsigned-context (param $x i32) (param $y i64)
(drop
diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast
index 5804c1b2a..24e8a9d61 100644
--- a/test/passes/optimize-instructions_all-features.wast
+++ b/test/passes/optimize-instructions_all-features.wast
@@ -5360,6 +5360,58 @@
)
(i32.const 0)
))
+ ;; i32(x - 0x80000000) == 0 -> x == 0x80000000
+ (drop (i32.eq
+ (i32.sub
+ (local.get $x)
+ (i32.const 0x80000000)
+ )
+ (i32.const 0)
+ ))
+ ;; i32(x - 0x80000000) != 0 -> x == 0x80000000
+ (drop (i32.ne
+ (i32.sub
+ (local.get $x)
+ (i32.const 0x80000000)
+ )
+ (i32.const 0)
+ ))
+ ;; i32(x - { 0x80000000 }) < 0 -> skip
+ (drop (i32.lt_s
+ (i32.sub
+ (local.get $x)
+ (i32.const 0x80000000)
+ )
+ (i32.const 0)
+ ))
+ ;; i32(x - { 0x80000000 }) >= 0 -> skip
+ (drop (i32.ge_s
+ (i32.sub
+ (local.get $x)
+ (i32.const 0x80000000)
+ )
+ (i32.const 0)
+ ))
+ ;; i32(x - { 0x80000000 }) > 0 -> skip
+ (drop (i32.gt_s
+ (i32.sub
+ (local.get $x)
+ (block (result i32)
+ (i32.const 0x80000000)
+ )
+ )
+ (i32.const 0)
+ ))
+ ;; i32(x - { 0x80000000 }) <= 0 -> skip
+ (drop (i32.gt_s
+ (i32.sub
+ (local.get $x)
+ (block (result i32)
+ (i32.const 0x80000000)
+ )
+ )
+ (i32.const 0)
+ ))
)
(func $unsigned-context (param $x i32) (param $y i64)
(drop (i32.div_s