summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp28
-rw-r--r--test/emcc_hello_world.fromasm300
-rw-r--r--test/emcc_hello_world.fromasm.imprecise300
-rw-r--r--test/passes/optimize-instructions.txt77
-rw-r--r--test/passes/optimize-instructions.wast15
5 files changed, 342 insertions, 378 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index f467b395e..7547f332a 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -223,6 +223,19 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
return Builder(*getModule()).makeUnary(EqZInt32, binary->right);
}
}
+ } else if (binary->op == AndInt32) {
+ if (auto* load = binary->left->dynCast<Load>()) {
+ if (auto* right = binary->right->dynCast<Const>()) {
+ if (right->type == i32) {
+ auto mask = right->value.geti32();
+ if ((load->bytes == 1 && mask == 0xff) ||
+ (load->bytes == 2 && mask == 0xffff)) {
+ load->signed_ = false;
+ return load;
+ }
+ }
+ }
+ }
}
} else if (auto* unary = curr->dynCast<Unary>()) {
// de-morgan's laws
@@ -294,6 +307,21 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
if (br->condition) {
br->condition = optimizeBoolean(br->condition);
}
+ } else if (auto* store = curr->dynCast<Store>()) {
+ // stores of fewer bits truncates anyhow
+ if (auto* value = store->value->dynCast<Binary>()) {
+ if (value->op == AndInt32) {
+ if (auto* right = value->right->dynCast<Const>()) {
+ if (right->type == i32) {
+ auto mask = right->value.geti32();
+ if ((store->bytes == 1 && mask == 0xff) ||
+ (store->bytes == 2 && mask == 0xffff)) {
+ store->value = value->left;
+ }
+ }
+ }
+ }
+ }
}
return nullptr;
}
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index ddcd0c5de..e5f68f021 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -314,11 +314,8 @@
(loop $while-in
(br_if $jumpthreading$inner$0
(i32.eq
- (i32.and
- (i32.load8_s offset=687
- (get_local $1)
- )
- (i32.const 255)
+ (i32.load8_u offset=687
+ (get_local $1)
)
(get_local $0)
)
@@ -1651,15 +1648,12 @@
)
(i32.store8
(get_local $2)
- (i32.and
- (i32.or
- (i32.add
- (get_local $1)
- (i32.const 255)
- )
+ (i32.or
+ (i32.add
(get_local $1)
+ (i32.const 255)
)
- (i32.const 255)
+ (get_local $1)
)
)
(if i32
@@ -1728,10 +1722,7 @@
(block
(i32.store8
(get_local $0)
- (i32.and
- (get_local $1)
- (i32.const 255)
- )
+ (get_local $1)
)
(br $do-once
(i32.const 1)
@@ -1746,28 +1737,22 @@
(block
(i32.store8
(get_local $0)
- (i32.and
- (i32.or
- (i32.shr_u
- (get_local $1)
- (i32.const 6)
- )
- (i32.const 192)
+ (i32.or
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 6)
)
- (i32.const 255)
+ (i32.const 192)
)
)
(i32.store8 offset=1
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 63)
- )
- (i32.const 128)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(br $do-once
@@ -1792,44 +1777,35 @@
(block
(i32.store8
(get_local $0)
- (i32.and
- (i32.or
- (i32.shr_u
- (get_local $1)
- (i32.const 12)
- )
- (i32.const 224)
+ (i32.or
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 12)
)
- (i32.const 255)
+ (i32.const 224)
)
)
(i32.store8 offset=1
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $1)
- (i32.const 6)
- )
- (i32.const 63)
+ (i32.or
+ (i32.and
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 6)
)
- (i32.const 128)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.store8 offset=2
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 63)
- )
- (i32.const 128)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(br $do-once
@@ -1848,60 +1824,48 @@
(block i32
(i32.store8
(get_local $0)
- (i32.and
- (i32.or
- (i32.shr_u
- (get_local $1)
- (i32.const 18)
- )
- (i32.const 240)
+ (i32.or
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 18)
)
- (i32.const 255)
+ (i32.const 240)
)
)
(i32.store8 offset=1
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $1)
- (i32.const 12)
- )
- (i32.const 63)
+ (i32.or
+ (i32.and
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 12)
)
- (i32.const 128)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.store8 offset=2
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $1)
- (i32.const 6)
- )
- (i32.const 63)
+ (i32.or
+ (i32.and
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 6)
)
- (i32.const 128)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.store8 offset=3
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 63)
- )
- (i32.const 128)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.const 4)
@@ -3737,10 +3701,7 @@
(i32.load
(get_local $18)
)
- (i32.and
- (get_local $15)
- (i32.const 65535)
- )
+ (get_local $15)
)
(set_local $1
(get_local $5)
@@ -3754,10 +3715,7 @@
(i32.load
(get_local $18)
)
- (i32.and
- (get_local $15)
- (i32.const 255)
- )
+ (get_local $15)
)
(set_local $1
(get_local $5)
@@ -3884,15 +3842,12 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 7)
- )
- (i32.const 48)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 7)
)
- (i32.const 255)
+ (i32.const 48)
)
)
(br_if $while-in32
@@ -4077,11 +4032,8 @@
)
(i32.store8
(get_local $46)
- (i32.and
- (i32.load
- (get_local $1)
- )
- (i32.const 255)
+ (i32.load
+ (get_local $1)
)
)
(set_local $6
@@ -4440,18 +4392,15 @@
)
(i32.const -1)
)
- (i32.and
- (i32.add
- (i32.and
- (i32.shr_s
- (get_local $5)
- (i32.const 31)
- )
- (i32.const 2)
+ (i32.add
+ (i32.and
+ (i32.shr_s
+ (get_local $5)
+ (i32.const 31)
)
- (i32.const 43)
+ (i32.const 2)
)
- (i32.const 255)
+ (i32.const 43)
)
)
(i32.store8
@@ -4461,12 +4410,9 @@
(i32.const -2)
)
)
- (i32.and
- (i32.add
- (get_local $16)
- (i32.const 15)
- )
- (i32.const 255)
+ (i32.add
+ (get_local $16)
+ (i32.const 15)
)
)
(set_local $12
@@ -4489,24 +4435,18 @@
(loop $while-in56
(i32.store8
(get_local $5)
- (i32.and
- (i32.or
- (i32.and
- (i32.load8_s
- (i32.add
- (tee_local $6
- (call $f64-to-int
- (get_local $14)
- )
- )
- (i32.const 4075)
+ (i32.or
+ (i32.load8_u
+ (i32.add
+ (tee_local $6
+ (call $f64-to-int
+ (get_local $14)
)
)
- (i32.const 255)
+ (i32.const 4075)
)
- (get_local $9)
)
- (i32.const 255)
+ (get_local $9)
)
)
(set_local $14
@@ -6023,18 +5963,15 @@
(get_local $7)
(i32.const -1)
)
- (i32.and
- (i32.add
- (i32.and
- (i32.shr_s
- (get_local $11)
- (i32.const 31)
- )
- (i32.const 2)
+ (i32.add
+ (i32.and
+ (i32.shr_s
+ (get_local $11)
+ (i32.const 31)
)
- (i32.const 43)
+ (i32.const 2)
)
- (i32.const 255)
+ (i32.const 43)
)
)
(i32.store8
@@ -6044,10 +5981,7 @@
(i32.const -2)
)
)
- (i32.and
- (get_local $6)
- (i32.const 255)
- )
+ (get_local $6)
)
(set_local $6
(i32.sub
@@ -6788,23 +6722,17 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (i32.and
- (i32.load8_s
- (i32.add
- (i32.and
- (get_local $10)
- (i32.const 15)
- )
- (i32.const 4075)
- )
+ (i32.or
+ (i32.load8_u
+ (i32.add
+ (i32.and
+ (get_local $10)
+ (i32.const 15)
)
- (i32.const 255)
+ (i32.const 4075)
)
- (get_local $9)
)
- (i32.const 255)
+ (get_local $9)
)
)
(br_if $while-in123
@@ -7892,12 +7820,9 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (get_local $3)
- (i32.const 48)
- )
- (i32.const 255)
+ (i32.or
+ (get_local $3)
+ (i32.const 48)
)
)
(set_local $3
@@ -7957,18 +7882,15 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (i32.and
- (call $i32u-rem
- (get_local $0)
- (i32.const 10)
- )
- (i32.const -1)
+ (i32.or
+ (i32.and
+ (call $i32u-rem
+ (get_local $0)
+ (i32.const 10)
)
- (i32.const 48)
+ (i32.const -1)
)
- (i32.const 255)
+ (i32.const 48)
)
)
(set_local $2
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index 931831ccc..589114f82 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -307,11 +307,8 @@
(loop $while-in
(br_if $jumpthreading$inner$0
(i32.eq
- (i32.and
- (i32.load8_s offset=687
- (get_local $1)
- )
- (i32.const 255)
+ (i32.load8_u offset=687
+ (get_local $1)
)
(get_local $0)
)
@@ -1644,15 +1641,12 @@
)
(i32.store8
(get_local $2)
- (i32.and
- (i32.or
- (i32.add
- (get_local $1)
- (i32.const 255)
- )
+ (i32.or
+ (i32.add
(get_local $1)
+ (i32.const 255)
)
- (i32.const 255)
+ (get_local $1)
)
)
(if i32
@@ -1721,10 +1715,7 @@
(block
(i32.store8
(get_local $0)
- (i32.and
- (get_local $1)
- (i32.const 255)
- )
+ (get_local $1)
)
(br $do-once
(i32.const 1)
@@ -1739,28 +1730,22 @@
(block
(i32.store8
(get_local $0)
- (i32.and
- (i32.or
- (i32.shr_u
- (get_local $1)
- (i32.const 6)
- )
- (i32.const 192)
+ (i32.or
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 6)
)
- (i32.const 255)
+ (i32.const 192)
)
)
(i32.store8 offset=1
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 63)
- )
- (i32.const 128)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(br $do-once
@@ -1785,44 +1770,35 @@
(block
(i32.store8
(get_local $0)
- (i32.and
- (i32.or
- (i32.shr_u
- (get_local $1)
- (i32.const 12)
- )
- (i32.const 224)
+ (i32.or
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 12)
)
- (i32.const 255)
+ (i32.const 224)
)
)
(i32.store8 offset=1
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $1)
- (i32.const 6)
- )
- (i32.const 63)
+ (i32.or
+ (i32.and
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 6)
)
- (i32.const 128)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.store8 offset=2
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 63)
- )
- (i32.const 128)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(br $do-once
@@ -1841,60 +1817,48 @@
(block i32
(i32.store8
(get_local $0)
- (i32.and
- (i32.or
- (i32.shr_u
- (get_local $1)
- (i32.const 18)
- )
- (i32.const 240)
+ (i32.or
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 18)
)
- (i32.const 255)
+ (i32.const 240)
)
)
(i32.store8 offset=1
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $1)
- (i32.const 12)
- )
- (i32.const 63)
+ (i32.or
+ (i32.and
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 12)
)
- (i32.const 128)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.store8 offset=2
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (i32.shr_u
- (get_local $1)
- (i32.const 6)
- )
- (i32.const 63)
+ (i32.or
+ (i32.and
+ (i32.shr_u
+ (get_local $1)
+ (i32.const 6)
)
- (i32.const 128)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.store8 offset=3
(get_local $0)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 63)
- )
- (i32.const 128)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 63)
)
- (i32.const 255)
+ (i32.const 128)
)
)
(i32.const 4)
@@ -3730,10 +3694,7 @@
(i32.load
(get_local $18)
)
- (i32.and
- (get_local $15)
- (i32.const 65535)
- )
+ (get_local $15)
)
(set_local $1
(get_local $5)
@@ -3747,10 +3708,7 @@
(i32.load
(get_local $18)
)
- (i32.and
- (get_local $15)
- (i32.const 255)
- )
+ (get_local $15)
)
(set_local $1
(get_local $5)
@@ -3877,15 +3835,12 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (i32.and
- (get_local $1)
- (i32.const 7)
- )
- (i32.const 48)
+ (i32.or
+ (i32.and
+ (get_local $1)
+ (i32.const 7)
)
- (i32.const 255)
+ (i32.const 48)
)
)
(br_if $while-in32
@@ -4070,11 +4025,8 @@
)
(i32.store8
(get_local $46)
- (i32.and
- (i32.load
- (get_local $1)
- )
- (i32.const 255)
+ (i32.load
+ (get_local $1)
)
)
(set_local $6
@@ -4433,18 +4385,15 @@
)
(i32.const -1)
)
- (i32.and
- (i32.add
- (i32.and
- (i32.shr_s
- (get_local $5)
- (i32.const 31)
- )
- (i32.const 2)
+ (i32.add
+ (i32.and
+ (i32.shr_s
+ (get_local $5)
+ (i32.const 31)
)
- (i32.const 43)
+ (i32.const 2)
)
- (i32.const 255)
+ (i32.const 43)
)
)
(i32.store8
@@ -4454,12 +4403,9 @@
(i32.const -2)
)
)
- (i32.and
- (i32.add
- (get_local $16)
- (i32.const 15)
- )
- (i32.const 255)
+ (i32.add
+ (get_local $16)
+ (i32.const 15)
)
)
(set_local $12
@@ -4482,24 +4428,18 @@
(loop $while-in56
(i32.store8
(get_local $5)
- (i32.and
- (i32.or
- (i32.and
- (i32.load8_s
- (i32.add
- (tee_local $6
- (i32.trunc_s/f64
- (get_local $14)
- )
- )
- (i32.const 4075)
+ (i32.or
+ (i32.load8_u
+ (i32.add
+ (tee_local $6
+ (i32.trunc_s/f64
+ (get_local $14)
)
)
- (i32.const 255)
+ (i32.const 4075)
)
- (get_local $9)
)
- (i32.const 255)
+ (get_local $9)
)
)
(set_local $14
@@ -6016,18 +5956,15 @@
(get_local $7)
(i32.const -1)
)
- (i32.and
- (i32.add
- (i32.and
- (i32.shr_s
- (get_local $11)
- (i32.const 31)
- )
- (i32.const 2)
+ (i32.add
+ (i32.and
+ (i32.shr_s
+ (get_local $11)
+ (i32.const 31)
)
- (i32.const 43)
+ (i32.const 2)
)
- (i32.const 255)
+ (i32.const 43)
)
)
(i32.store8
@@ -6037,10 +5974,7 @@
(i32.const -2)
)
)
- (i32.and
- (get_local $6)
- (i32.const 255)
- )
+ (get_local $6)
)
(set_local $6
(i32.sub
@@ -6781,23 +6715,17 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (i32.and
- (i32.load8_s
- (i32.add
- (i32.and
- (get_local $10)
- (i32.const 15)
- )
- (i32.const 4075)
- )
+ (i32.or
+ (i32.load8_u
+ (i32.add
+ (i32.and
+ (get_local $10)
+ (i32.const 15)
)
- (i32.const 255)
+ (i32.const 4075)
)
- (get_local $9)
)
- (i32.const 255)
+ (get_local $9)
)
)
(br_if $while-in123
@@ -7885,12 +7813,9 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (get_local $3)
- (i32.const 48)
- )
- (i32.const 255)
+ (i32.or
+ (get_local $3)
+ (i32.const 48)
)
)
(set_local $3
@@ -7950,18 +7875,15 @@
(i32.const -1)
)
)
- (i32.and
- (i32.or
- (i32.and
- (i32.rem_u
- (get_local $0)
- (i32.const 10)
- )
- (i32.const -1)
+ (i32.or
+ (i32.and
+ (i32.rem_u
+ (get_local $0)
+ (i32.const 10)
)
- (i32.const 48)
+ (i32.const -1)
)
- (i32.const 255)
+ (i32.const 48)
)
)
(set_local $2
diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt
index bda6fd97f..07cc7e895 100644
--- a/test/passes/optimize-instructions.txt
+++ b/test/passes/optimize-instructions.txt
@@ -1,5 +1,6 @@
(module
(type $0 (func (param i32 i64)))
+ (type $1 (func))
(memory $0 0)
(func $f (type $0) (param $i1 i32) (param $i2 i64)
(if
@@ -213,4 +214,80 @@
)
)
)
+ (func $load-store (type $1)
+ (drop
+ (i32.load8_u
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.load8_u
+ (i32.const 1)
+ )
+ )
+ (drop
+ (i32.and
+ (i32.load8_s
+ (i32.const 2)
+ )
+ (i32.const 254)
+ )
+ )
+ (drop
+ (i32.and
+ (i32.load8_u
+ (i32.const 3)
+ )
+ (i32.const 1)
+ )
+ )
+ (drop
+ (i32.load16_u
+ (i32.const 4)
+ )
+ )
+ (drop
+ (i32.load16_u
+ (i32.const 5)
+ )
+ )
+ (drop
+ (i32.and
+ (i32.load16_s
+ (i32.const 6)
+ )
+ (i32.const 65534)
+ )
+ )
+ (drop
+ (i32.and
+ (i32.load16_u
+ (i32.const 7)
+ )
+ (i32.const 1)
+ )
+ )
+ (i32.store8
+ (i32.const 8)
+ (i32.const -1)
+ )
+ (i32.store8
+ (i32.const 9)
+ (i32.and
+ (i32.const -2)
+ (i32.const 254)
+ )
+ )
+ (i32.store16
+ (i32.const 10)
+ (i32.const -3)
+ )
+ (i32.store16
+ (i32.const 11)
+ (i32.and
+ (i32.const -4)
+ (i32.const 65534)
+ )
+ )
+ )
)
diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast
index b1a7ab47e..939b07ffc 100644
--- a/test/passes/optimize-instructions.wast
+++ b/test/passes/optimize-instructions.wast
@@ -252,4 +252,19 @@
)
)
)
+ (func $load-store
+ (drop (i32.and (i32.load8_s (i32.const 0)) (i32.const 255)))
+ (drop (i32.and (i32.load8_u (i32.const 1)) (i32.const 255)))
+ (drop (i32.and (i32.load8_s (i32.const 2)) (i32.const 254)))
+ (drop (i32.and (i32.load8_u (i32.const 3)) (i32.const 1)))
+ (drop (i32.and (i32.load16_s (i32.const 4)) (i32.const 65535)))
+ (drop (i32.and (i32.load16_u (i32.const 5)) (i32.const 65535)))
+ (drop (i32.and (i32.load16_s (i32.const 6)) (i32.const 65534)))
+ (drop (i32.and (i32.load16_u (i32.const 7)) (i32.const 1)))
+ ;;
+ (i32.store8 (i32.const 8) (i32.and (i32.const -1) (i32.const 255)))
+ (i32.store8 (i32.const 9) (i32.and (i32.const -2) (i32.const 254)))
+ (i32.store16 (i32.const 10) (i32.and (i32.const -3) (i32.const 65535)))
+ (i32.store16 (i32.const 11) (i32.and (i32.const -4) (i32.const 65534)))
+ )
)