summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai (kripken) <alonzakai@gmail.com>2017-02-13 17:35:39 -0800
committerAlon Zakai (kripken) <alonzakai@gmail.com>2017-02-16 22:45:40 -0800
commitced44f4fd543b50980d4bf674fa6a30f9c31790f (patch)
tree21dbebbdce5a0e38db3c6438384f5914de93c517
parenteec567640d154147fb88754fd13aada738a63eef (diff)
downloadbinaryen-ced44f4fd543b50980d4bf674fa6a30f9c31790f.tar.gz
binaryen-ced44f4fd543b50980d4bf674fa6a30f9c31790f.tar.bz2
binaryen-ced44f4fd543b50980d4bf674fa6a30f9c31790f.zip
take into account loads into local info in OptimizeInstructions
-rw-r--r--src/passes/OptimizeInstructions.cpp17
-rw-r--r--test/emcc_hello_world.fromasm90
-rw-r--r--test/emcc_hello_world.fromasm.imprecise90
-rw-r--r--test/passes/optimize-instructions.txt42
-rw-r--r--test/passes/optimize-instructions.wast42
5 files changed, 184 insertions, 97 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 8e5ff6c12..026f3f7ec 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -386,15 +386,18 @@ struct LocalScanner : PostWalker<LocalScanner, Visitor<LocalScanner>> {
// an integer var, worth processing
auto& info = localInfo[curr->index];
info.maxBits = std::max(info.maxBits, getMaxBits(curr->value, this));
+ auto signExtBits = LocalInfo::kUnknown;
if (getSignExt(curr->value)) {
- auto bits = getSignExtBits(curr->value);
- if (info.signExtedBits == 0) {
- info.signExtedBits = bits; // first info we see
- } else if (info.signExtedBits != bits) {
- info.signExtedBits = LocalInfo::kUnknown; // contradictory information, give up
+ signExtBits = getSignExtBits(curr->value);
+ } else if (auto* load = getFallthroughDynCast<Load>(curr->value)) {
+ if (load->signed_) {
+ signExtBits = load->bytes * 8;
}
- } else {
- info.signExtedBits = LocalInfo::kUnknown; // an input which isn't even a sign ext, give up
+ }
+ if (info.signExtedBits == 0) {
+ info.signExtedBits = signExtBits; // first info we see
+ } else if (info.signExtedBits != signExtBits) {
+ info.signExtedBits = LocalInfo::kUnknown; // contradictory information, give up
}
}
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index f01ba2f5d..c314d887c 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -325,7 +325,7 @@
)
)
(if
- (i32.load8_u
+ (i32.load8_s
(get_local $0)
)
(block
@@ -1468,7 +1468,7 @@
)
(if
(i32.ne
- (i32.load8_u
+ (i32.load8_s
(i32.add
(get_local $0)
(tee_local $6
@@ -1864,12 +1864,15 @@
(loop $while-in
(if
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $2)
)
- (i32.and
- (get_local $4)
- (i32.const 255)
+ (i32.shr_s
+ (i32.shl
+ (get_local $4)
+ (i32.const 24)
+ )
+ (i32.const 24)
)
)
(block
@@ -1938,14 +1941,20 @@
)
(if
(i32.ne
- (i32.load8_u
+ (i32.load8_s
(get_local $2)
)
- (tee_local $1
- (i32.and
- (get_local $1)
- (i32.const 255)
+ (i32.shr_s
+ (i32.shl
+ (tee_local $1
+ (i32.and
+ (get_local $1)
+ (i32.const 255)
+ )
+ )
+ (i32.const 24)
)
+ (i32.const 24)
)
)
(block
@@ -2026,12 +2035,15 @@
(loop $while-in5
(br_if $label$break$L8
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $2)
)
- (i32.and
- (get_local $1)
- (i32.const 255)
+ (i32.shr_s
+ (i32.shl
+ (get_local $1)
+ (i32.const 24)
+ )
+ (i32.const 24)
)
)
)
@@ -2498,13 +2510,10 @@
)
(br_if $__rjti$9
(i32.eqz
- (i32.and
- (tee_local $7
- (i32.load8_s
- (get_local $5)
- )
+ (tee_local $7
+ (i32.load8_s
+ (get_local $5)
)
- (i32.const 255)
)
)
)
@@ -2556,7 +2565,7 @@
(loop $while-in
(br_if $label$break$L12
(i32.ne
- (i32.load8_u offset=1
+ (i32.load8_s offset=1
(get_local $6)
)
(i32.const 37)
@@ -2570,7 +2579,7 @@
)
(br_if $while-in
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(tee_local $6
(i32.add
(get_local $6)
@@ -2656,7 +2665,7 @@
(get_local $10)
(tee_local $11
(i32.eq
- (i32.load8_u offset=2
+ (i32.load8_s offset=2
(get_local $6)
)
(i32.const 36)
@@ -2825,7 +2834,7 @@
)
(br_if $__rjti$0
(i32.ne
- (i32.load8_u offset=2
+ (i32.load8_s offset=2
(get_local $10)
)
(i32.const 36)
@@ -3057,7 +3066,7 @@
(set_local $6
(if i32
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $10)
)
(i32.const 46)
@@ -3065,18 +3074,15 @@
(block i32
(if
(i32.ne
- (i32.and
- (tee_local $8
- (i32.load8_s
- (tee_local $6
- (i32.add
- (get_local $10)
- (i32.const 1)
- )
+ (tee_local $8
+ (i32.load8_s
+ (tee_local $6
+ (i32.add
+ (get_local $10)
+ (i32.const 1)
)
)
)
- (i32.const 255)
)
(i32.const 42)
)
@@ -3085,13 +3091,7 @@
(i32.lt_u
(tee_local $9
(i32.add
- (i32.shr_s
- (i32.shl
- (get_local $8)
- (i32.const 24)
- )
- (i32.const 24)
- )
+ (get_local $8)
(i32.const -48)
)
)
@@ -3175,7 +3175,7 @@
)
(if
(i32.eq
- (i32.load8_u offset=3
+ (i32.load8_s offset=3
(get_local $10)
)
(i32.const 36)
@@ -4201,7 +4201,7 @@
)
(if f64
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $9)
)
(i32.const 45)
@@ -5261,7 +5261,7 @@
(block
(br_if $do-once83
(i32.ne
- (i32.load8_u
+ (i32.load8_s
(get_local $31)
)
(i32.const 45)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index 22878e91f..1fa81ba43 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -322,7 +322,7 @@
)
)
(if
- (i32.load8_u
+ (i32.load8_s
(get_local $0)
)
(block
@@ -1465,7 +1465,7 @@
)
(if
(i32.ne
- (i32.load8_u
+ (i32.load8_s
(i32.add
(get_local $0)
(tee_local $6
@@ -1861,12 +1861,15 @@
(loop $while-in
(if
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $2)
)
- (i32.and
- (get_local $4)
- (i32.const 255)
+ (i32.shr_s
+ (i32.shl
+ (get_local $4)
+ (i32.const 24)
+ )
+ (i32.const 24)
)
)
(block
@@ -1935,14 +1938,20 @@
)
(if
(i32.ne
- (i32.load8_u
+ (i32.load8_s
(get_local $2)
)
- (tee_local $1
- (i32.and
- (get_local $1)
- (i32.const 255)
+ (i32.shr_s
+ (i32.shl
+ (tee_local $1
+ (i32.and
+ (get_local $1)
+ (i32.const 255)
+ )
+ )
+ (i32.const 24)
)
+ (i32.const 24)
)
)
(block
@@ -2023,12 +2032,15 @@
(loop $while-in5
(br_if $label$break$L8
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $2)
)
- (i32.and
- (get_local $1)
- (i32.const 255)
+ (i32.shr_s
+ (i32.shl
+ (get_local $1)
+ (i32.const 24)
+ )
+ (i32.const 24)
)
)
)
@@ -2441,13 +2453,10 @@
)
(br_if $__rjti$9
(i32.eqz
- (i32.and
- (tee_local $7
- (i32.load8_s
- (get_local $5)
- )
+ (tee_local $7
+ (i32.load8_s
+ (get_local $5)
)
- (i32.const 255)
)
)
)
@@ -2499,7 +2508,7 @@
(loop $while-in
(br_if $label$break$L12
(i32.ne
- (i32.load8_u offset=1
+ (i32.load8_s offset=1
(get_local $6)
)
(i32.const 37)
@@ -2513,7 +2522,7 @@
)
(br_if $while-in
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(tee_local $6
(i32.add
(get_local $6)
@@ -2599,7 +2608,7 @@
(get_local $10)
(tee_local $11
(i32.eq
- (i32.load8_u offset=2
+ (i32.load8_s offset=2
(get_local $6)
)
(i32.const 36)
@@ -2768,7 +2777,7 @@
)
(br_if $__rjti$0
(i32.ne
- (i32.load8_u offset=2
+ (i32.load8_s offset=2
(get_local $10)
)
(i32.const 36)
@@ -3000,7 +3009,7 @@
(set_local $6
(if i32
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $10)
)
(i32.const 46)
@@ -3008,18 +3017,15 @@
(block i32
(if
(i32.ne
- (i32.and
- (tee_local $8
- (i32.load8_s
- (tee_local $6
- (i32.add
- (get_local $10)
- (i32.const 1)
- )
+ (tee_local $8
+ (i32.load8_s
+ (tee_local $6
+ (i32.add
+ (get_local $10)
+ (i32.const 1)
)
)
)
- (i32.const 255)
)
(i32.const 42)
)
@@ -3028,13 +3034,7 @@
(i32.lt_u
(tee_local $9
(i32.add
- (i32.shr_s
- (i32.shl
- (get_local $8)
- (i32.const 24)
- )
- (i32.const 24)
- )
+ (get_local $8)
(i32.const -48)
)
)
@@ -3118,7 +3118,7 @@
)
(if
(i32.eq
- (i32.load8_u offset=3
+ (i32.load8_s offset=3
(get_local $10)
)
(i32.const 36)
@@ -4162,7 +4162,7 @@
(get_local $15)
)
(i32.eq
- (i32.load8_u
+ (i32.load8_s
(get_local $9)
)
(i32.const 45)
@@ -5198,7 +5198,7 @@
(block
(br_if $do-once83
(i32.ne
- (i32.load8_u
+ (i32.load8_s
(get_local $31)
)
(i32.const 45)
diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt
index 80d264e94..550859185 100644
--- a/test/passes/optimize-instructions.txt
+++ b/test/passes/optimize-instructions.txt
@@ -1601,4 +1601,46 @@
)
)
)
+ (func $local-info-sign-ext-already-exted-by-load (type $4) (param $0 i32) (param $1 i32)
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (set_local $x
+ (i32.load8_s
+ (i32.const 1024)
+ )
+ )
+ (drop
+ (get_local $x)
+ )
+ (set_local $y
+ (i32.load8_u
+ (i32.const 1024)
+ )
+ )
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (get_local $y)
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (set_local $z
+ (i32.load16_s
+ (i32.const 1024)
+ )
+ )
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (get_local $z)
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ )
)
diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast
index 0169bb054..2f2333867 100644
--- a/test/passes/optimize-instructions.wast
+++ b/test/passes/optimize-instructions.wast
@@ -1978,4 +1978,46 @@
)
)
)
+ (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32)
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (set_local $x
+ (i32.load8_s (i32.const 1024)) ;; 8 bits, sign extended, no need to do it again
+ )
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (get_local $x)
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (set_local $y
+ (i32.load8_u (i32.const 1024)) ;; 8 bits, zext, so bad
+ )
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (get_local $y)
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ (set_local $z
+ (i32.load16_s (i32.const 1024)) ;; 16 bits sign-extended, wrong size
+ )
+ (drop
+ (i32.shr_s
+ (i32.shl
+ (get_local $z)
+ (i32.const 24)
+ )
+ (i32.const 24)
+ )
+ )
+ )
)