summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-06 16:14:13 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-07 18:42:14 -0700
commitc2072c3f7c96eed6abbc7901c181bec92e3b9ced (patch)
tree4e76eeb402646a57c2c4fd60776f8d23f1ec53fe
parent779c2a20af50c351fb725b785a0ed6932143280d (diff)
downloadbinaryen-c2072c3f7c96eed6abbc7901c181bec92e3b9ced.tar.gz
binaryen-c2072c3f7c96eed6abbc7901c181bec92e3b9ced.tar.bz2
binaryen-c2072c3f7c96eed6abbc7901c181bec92e3b9ced.zip
optimize loads+shifts into signed loads
-rw-r--r--src/passes/OptimizeInstructions.cpp27
-rw-r--r--test/emcc_hello_world.fromasm284
-rw-r--r--test/emcc_hello_world.fromasm.imprecise284
-rw-r--r--test/unit.asm.js12
-rw-r--r--test/unit.fromasm66
-rw-r--r--test/unit.fromasm.imprecise66
-rw-r--r--test/unit.fromasm.imprecise.no-opts90
-rw-r--r--test/unit.fromasm.no-opts90
8 files changed, 491 insertions, 428 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 2a5e7b8c4..003d2ff60 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -168,6 +168,12 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
void visitExpression(Expression* curr) {
// we may be able to apply multiple patterns, one may open opportunities that look deeper NB: patterns must not have cycles
while (1) {
+ auto* handOptimized = handOptimize(curr);
+ if (handOptimized) {
+ curr = handOptimized;
+ replaceCurrent(curr);
+ continue;
+ }
auto iter = database->patternMap.find(curr->_id);
if (iter == database->patternMap.end()) return;
auto& patterns = iter->second;
@@ -184,6 +190,27 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
if (!more) break;
}
}
+
+ // Optimizations that don't yet fit in the pattern DSL, but could be eventually maybe
+ Expression* handOptimize(Expression* curr) {
+ if (auto* binary = curr->dynCast<Binary>()) {
+ // pattern match a load of 8 bits and a sign extend using a shl of 24 then shr_s of 24 as well, etc.
+ if (binary->op == BinaryOp::ShrSInt32 && binary->right->is<Const>()) {
+ auto shifts = binary->right->cast<Const>()->value.geti32();
+ if (shifts == 24 || shifts == 16) {
+ auto* left = binary->left->dynCast<Binary>();
+ if (left && left->op == ShlInt32 && left->right->is<Const>() && left->right->cast<Const>()->value.geti32() == shifts) {
+ auto* load = left->left->dynCast<Load>();
+ if (load && ((load->bytes == 1 && shifts == 24) || (load->bytes == 2 && shifts == 16))) {
+ load->signed_ = true;
+ return load;
+ }
+ }
+ }
+ }
+ }
+ return nullptr;
+ }
};
Pass *createOptimizeInstructionsPass() {
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index 10da1e436..15b9aa473 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -467,14 +467,8 @@
)
)
(if
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $2)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $2)
)
(set_local $2
(get_local $0)
@@ -1415,14 +1409,8 @@
)
(if
(i32.lt_s
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=74
- (get_local $0)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=74
+ (get_local $0)
)
(i32.const 1)
)
@@ -1697,14 +1685,8 @@
(block $label$break$L10
(if
(i32.gt_s
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=75
- (get_local $2)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=75
+ (get_local $2)
)
(i32.const -1)
)
@@ -1729,22 +1711,16 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
+ (i32.load8_s
+ (i32.add
+ (get_local $0)
+ (tee_local $4
(i32.add
- (get_local $0)
- (tee_local $4
- (i32.add
- (get_local $3)
- (i32.const -1)
- )
- )
+ (get_local $3)
+ (i32.const -1)
)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const 10)
)
@@ -1840,19 +1816,13 @@
(i32.or
(i32.add
(tee_local $1
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $2
- (i32.add
- (get_local $0)
- (i32.const 74)
- )
- )
+ (i32.load8_s
+ (tee_local $2
+ (i32.add
+ (get_local $0)
+ (i32.const 74)
)
- (i32.const 24)
)
- (i32.const 24)
)
)
(i32.const 255)
@@ -2189,14 +2159,8 @@
(block $while-out$1
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $2)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $2)
)
(i32.shr_s
(i32.shl
@@ -2320,14 +2284,8 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $5)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $5)
)
(i32.shr_s
(i32.shl
@@ -2476,14 +2434,8 @@
(block $while-out$7
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $9)
)
(i32.shr_s
(i32.shl
@@ -3066,14 +3018,8 @@
)
(if
(i32.ne
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=1
- (get_local $54)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=1
+ (get_local $54)
)
(i32.const 37)
)
@@ -3095,19 +3041,13 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $1
- (i32.add
- (get_local $54)
- (i32.const 2)
- )
- )
+ (i32.load8_s
+ (tee_local $1
+ (i32.add
+ (get_local $54)
+ (i32.const 2)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const 37)
)
@@ -3211,14 +3151,8 @@
(get_local $5)
(tee_local $7
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=2
- (get_local $41)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=2
+ (get_local $41)
)
(i32.const 36)
)
@@ -3370,19 +3304,13 @@
(i32.lt_u
(tee_local $1
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $6
- (i32.add
- (get_local $9)
- (i32.const 1)
- )
- )
+ (i32.load8_s
+ (tee_local $6
+ (i32.add
+ (get_local $9)
+ (i32.const 1)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3391,14 +3319,8 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=2
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=2
+ (get_local $9)
)
(i32.const 36)
)
@@ -3419,14 +3341,8 @@
(get_local $3)
(i32.shl
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $6)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $6)
)
(i32.const -48)
)
@@ -3601,19 +3517,13 @@
(i32.ge_u
(tee_local $6
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
- )
- )
+ (i32.load8_s
+ (tee_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3663,14 +3573,8 @@
(block $label$break$L46
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $9)
)
(i32.const 46)
)
@@ -3743,19 +3647,13 @@
(i32.ge_u
(tee_local $6
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
- )
- )
+ (i32.load8_s
+ (tee_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3779,19 +3677,13 @@
(i32.lt_u
(tee_local $1
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $6
- (i32.add
- (get_local $9)
- (i32.const 2)
- )
- )
+ (i32.load8_s
+ (tee_local $6
+ (i32.add
+ (get_local $9)
+ (i32.const 2)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3800,14 +3692,8 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=3
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=3
+ (get_local $9)
)
(i32.const 36)
)
@@ -3828,14 +3714,8 @@
(get_local $3)
(i32.shl
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $6)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $6)
)
(i32.const -48)
)
@@ -3921,14 +3801,8 @@
(i32.gt_u
(tee_local $1
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $11)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $11)
)
(i32.const -65)
)
@@ -4143,14 +4017,8 @@
(i32.eq
(i32.and
(tee_local $1
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $11)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $11)
)
)
(i32.const 15)
@@ -5023,14 +4891,8 @@
(get_local $30)
)
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $9)
)
(i32.const 45)
)
@@ -6182,14 +6044,8 @@
(br_if $do-once$90
(get_local $14)
(i32.ne
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $39)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $39)
)
(i32.const 45)
)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index bcdebdd99..9d70778d5 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -460,14 +460,8 @@
)
)
(if
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $2)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $2)
)
(set_local $2
(get_local $0)
@@ -1408,14 +1402,8 @@
)
(if
(i32.lt_s
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=74
- (get_local $0)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=74
+ (get_local $0)
)
(i32.const 1)
)
@@ -1690,14 +1678,8 @@
(block $label$break$L10
(if
(i32.gt_s
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=75
- (get_local $2)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=75
+ (get_local $2)
)
(i32.const -1)
)
@@ -1722,22 +1704,16 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
+ (i32.load8_s
+ (i32.add
+ (get_local $0)
+ (tee_local $4
(i32.add
- (get_local $0)
- (tee_local $4
- (i32.add
- (get_local $3)
- (i32.const -1)
- )
- )
+ (get_local $3)
+ (i32.const -1)
)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const 10)
)
@@ -1833,19 +1809,13 @@
(i32.or
(i32.add
(tee_local $1
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $2
- (i32.add
- (get_local $0)
- (i32.const 74)
- )
- )
+ (i32.load8_s
+ (tee_local $2
+ (i32.add
+ (get_local $0)
+ (i32.const 74)
)
- (i32.const 24)
)
- (i32.const 24)
)
)
(i32.const 255)
@@ -2182,14 +2152,8 @@
(block $while-out$1
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $2)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $2)
)
(i32.shr_s
(i32.shl
@@ -2313,14 +2277,8 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $5)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $5)
)
(i32.shr_s
(i32.shl
@@ -2469,14 +2427,8 @@
(block $while-out$7
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $9)
)
(i32.shr_s
(i32.shl
@@ -3059,14 +3011,8 @@
)
(if
(i32.ne
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=1
- (get_local $54)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=1
+ (get_local $54)
)
(i32.const 37)
)
@@ -3088,19 +3034,13 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $1
- (i32.add
- (get_local $54)
- (i32.const 2)
- )
- )
+ (i32.load8_s
+ (tee_local $1
+ (i32.add
+ (get_local $54)
+ (i32.const 2)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const 37)
)
@@ -3204,14 +3144,8 @@
(get_local $5)
(tee_local $7
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=2
- (get_local $41)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=2
+ (get_local $41)
)
(i32.const 36)
)
@@ -3363,19 +3297,13 @@
(i32.lt_u
(tee_local $1
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $6
- (i32.add
- (get_local $9)
- (i32.const 1)
- )
- )
+ (i32.load8_s
+ (tee_local $6
+ (i32.add
+ (get_local $9)
+ (i32.const 1)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3384,14 +3312,8 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=2
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=2
+ (get_local $9)
)
(i32.const 36)
)
@@ -3412,14 +3334,8 @@
(get_local $3)
(i32.shl
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $6)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $6)
)
(i32.const -48)
)
@@ -3594,19 +3510,13 @@
(i32.ge_u
(tee_local $6
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
- )
- )
+ (i32.load8_s
+ (tee_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3656,14 +3566,8 @@
(block $label$break$L46
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $9)
)
(i32.const 46)
)
@@ -3736,19 +3640,13 @@
(i32.ge_u
(tee_local $6
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
- )
- )
+ (i32.load8_s
+ (tee_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3772,19 +3670,13 @@
(i32.lt_u
(tee_local $1
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (tee_local $6
- (i32.add
- (get_local $9)
- (i32.const 2)
- )
- )
+ (i32.load8_s
+ (tee_local $6
+ (i32.add
+ (get_local $9)
+ (i32.const 2)
)
- (i32.const 24)
)
- (i32.const 24)
)
(i32.const -48)
)
@@ -3793,14 +3685,8 @@
)
(if
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s offset=3
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s offset=3
+ (get_local $9)
)
(i32.const 36)
)
@@ -3821,14 +3707,8 @@
(get_local $3)
(i32.shl
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $6)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $6)
)
(i32.const -48)
)
@@ -3914,14 +3794,8 @@
(i32.gt_u
(tee_local $1
(i32.add
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $11)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $11)
)
(i32.const -65)
)
@@ -4136,14 +4010,8 @@
(i32.eq
(i32.and
(tee_local $1
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $11)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $11)
)
)
(i32.const 15)
@@ -5016,14 +4884,8 @@
(get_local $30)
)
(i32.eq
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $9)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $9)
)
(i32.const 45)
)
@@ -6175,14 +6037,8 @@
(br_if $do-once$90
(get_local $14)
(i32.ne
- (i32.shr_s
- (i32.shl
- (i32.load8_s
- (get_local $39)
- )
- (i32.const 24)
- )
- (i32.const 24)
+ (i32.load8_s
+ (get_local $39)
)
(i32.const 45)
)
diff --git a/test/unit.asm.js b/test/unit.asm.js
index e76ae1ef9..a25e60721 100644
--- a/test/unit.asm.js
+++ b/test/unit.asm.js
@@ -330,6 +330,18 @@ function asm(global, env, buffer) {
y = 3 ? +abort(7) : 4.5;
}
+ function loadSigned(x) {
+ x = x | 0;
+ loadSigned(HEAP8[x >> 0] << 24 >> 24);
+ loadSigned(HEAPU8[x >> 0] << 24 >> 24);
+ loadSigned(HEAP16[x >> 1] << 16 >> 16);
+ loadSigned(HEAPU16[x >> 1] << 16 >> 16);
+ loadSigned(HEAP8[x >> 0] << 24 >> 16);
+ loadSigned(HEAPU8[x >> 0] << 16 >> 24);
+ loadSigned(HEAP16[x >> 1] << 16 >> 24);
+ loadSigned(HEAPU16[x >> 1] << 24 >> 16);
+ }
+
function z() {
}
function w() {
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 33dd153af..bafc17f3f 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -616,4 +616,70 @@
)
)
)
+ (func $loadSigned (param $0 i32)
+ (call $loadSigned
+ (i32.load8_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.load8_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.load16_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.load16_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_s
+ (get_local $0)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_u
+ (get_local $0)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_s
+ (get_local $0)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_u
+ (get_local $0)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ )
)
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index 35b8b1768..cdaca7e10 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -597,4 +597,70 @@
)
)
)
+ (func $loadSigned (param $0 i32)
+ (call $loadSigned
+ (i32.load8_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.load8_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.load16_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.load16_s
+ (get_local $0)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_s
+ (get_local $0)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_u
+ (get_local $0)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_s
+ (get_local $0)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_u
+ (get_local $0)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ )
)
diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts
index c41075df0..244ef7cd8 100644
--- a/test/unit.fromasm.imprecise.no-opts
+++ b/test/unit.fromasm.imprecise.no-opts
@@ -1001,6 +1001,96 @@
)
)
)
+ (func $loadSigned (param $x i32)
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_s
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_u
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_s
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_u
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_s
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_u
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_s
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_u
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ )
(func $z
(nop)
)
diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts
index 2162d9ed7..1c0e87f6a 100644
--- a/test/unit.fromasm.no-opts
+++ b/test/unit.fromasm.no-opts
@@ -1007,6 +1007,96 @@
)
)
)
+ (func $loadSigned (param $x i32)
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_s
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_u
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_s
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_u
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_s
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load8_u
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_s
+ (get_local $x)
+ )
+ (i32.const 16)
+ )
+ (i32.const 24)
+ )
+ )
+ (call $loadSigned
+ (i32.shr_s
+ (i32.shl
+ (i32.load16_u
+ (get_local $x)
+ )
+ (i32.const 24)
+ )
+ (i32.const 16)
+ )
+ )
+ )
(func $z
(nop)
)