diff options
author | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-02-13 17:35:39 -0800 |
---|---|---|
committer | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-02-16 22:45:40 -0800 |
commit | ced44f4fd543b50980d4bf674fa6a30f9c31790f (patch) | |
tree | 21dbebbdce5a0e38db3c6438384f5914de93c517 | |
parent | eec567640d154147fb88754fd13aada738a63eef (diff) | |
download | binaryen-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.cpp | 17 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 90 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 90 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 42 | ||||
-rw-r--r-- | test/passes/optimize-instructions.wast | 42 |
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) + ) + ) + ) ) |