diff options
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 18 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 38 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 38 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 80 | ||||
-rw-r--r-- | test/passes/optimize-instructions.wast | 86 |
5 files changed, 210 insertions, 50 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 026f3f7ec..49d025f82 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -515,6 +515,24 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, binary->left = makeZeroExt(left, bits); binary->right = makeZeroExt(right, bits); return binary; + } else if (auto* load = getFallthroughDynCast<Load>(binary->right)) { + // we are comparing a load to a sign-ext, we may be able to switch to zext + auto leftBits = getSignExtBits(binary->left); + if (load->signed_ && leftBits == load->bytes * 8) { + load->signed_ = false; + binary->left = makeZeroExt(left, leftBits); + return binary; + } + } + } else if (auto* load = getFallthroughDynCast<Load>(binary->left)) { + if (auto* right = getSignExt(binary->right)) { + // we are comparing a load to a sign-ext, we may be able to switch to zext + auto rightBits = getSignExtBits(binary->right); + if (load->signed_ && rightBits == load->bytes * 8) { + load->signed_ = false; + binary->right = makeZeroExt(right, rightBits); + return binary; + } } } // note that both left and right may be consts, but then we let precompute compute the constant result diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index c314d887c..ecbadd304 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -1864,15 +1864,12 @@ (loop $while-in (if (i32.eq - (i32.load8_s + (i32.load8_u (get_local $2) ) - (i32.shr_s - (i32.shl - (get_local $4) - (i32.const 24) - ) - (i32.const 24) + (i32.and + (get_local $4) + (i32.const 255) ) ) (block @@ -1941,20 +1938,14 @@ ) (if (i32.ne - (i32.load8_s + (i32.load8_u (get_local $2) ) - (i32.shr_s - (i32.shl - (tee_local $1 - (i32.and - (get_local $1) - (i32.const 255) - ) - ) - (i32.const 24) + (tee_local $1 + (i32.and + (get_local $1) + (i32.const 255) ) - (i32.const 24) ) ) (block @@ -2035,15 +2026,12 @@ (loop $while-in5 (br_if $label$break$L8 (i32.eq - (i32.load8_s + (i32.load8_u (get_local $2) ) - (i32.shr_s - (i32.shl - (get_local $1) - (i32.const 24) - ) - (i32.const 24) + (i32.and + (get_local $1) + (i32.const 255) ) ) ) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index 1fa81ba43..52fa498da 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -1861,15 +1861,12 @@ (loop $while-in (if (i32.eq - (i32.load8_s + (i32.load8_u (get_local $2) ) - (i32.shr_s - (i32.shl - (get_local $4) - (i32.const 24) - ) - (i32.const 24) + (i32.and + (get_local $4) + (i32.const 255) ) ) (block @@ -1938,20 +1935,14 @@ ) (if (i32.ne - (i32.load8_s + (i32.load8_u (get_local $2) ) - (i32.shr_s - (i32.shl - (tee_local $1 - (i32.and - (get_local $1) - (i32.const 255) - ) - ) - (i32.const 24) + (tee_local $1 + (i32.and + (get_local $1) + (i32.const 255) ) - (i32.const 24) ) ) (block @@ -2032,15 +2023,12 @@ (loop $while-in5 (br_if $label$break$L8 (i32.eq - (i32.load8_s + (i32.load8_u (get_local $2) ) - (i32.shr_s - (i32.shl - (get_local $1) - (i32.const 24) - ) - (i32.const 24) + (i32.and + (get_local $1) + (i32.const 255) ) ) ) diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt index 550859185..d70e6a9c5 100644 --- a/test/passes/optimize-instructions.txt +++ b/test/passes/optimize-instructions.txt @@ -1643,4 +1643,84 @@ ) ) ) + (func $compare-load-s-sign-extend (type $4) (param $0 i32) (param $1 i32) + (drop + (i32.eq + (i32.load8_u + (get_local $0) + ) + (i32.and + (get_local $1) + (i32.const 255) + ) + ) + ) + (drop + (i32.eq + (i32.and + (get_local $1) + (i32.const 255) + ) + (i32.load8_u + (get_local $0) + ) + ) + ) + (drop + (i32.eq + (i32.load8_u + (get_local $0) + ) + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (drop + (i32.eq + (i32.load8_s + (get_local $0) + ) + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.load8_u + (get_local $0) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 16) + ) + (i32.const 16) + ) + (i32.load8_s + (get_local $0) + ) + ) + ) + ) ) diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast index 2f2333867..51bd076d1 100644 --- a/test/passes/optimize-instructions.wast +++ b/test/passes/optimize-instructions.wast @@ -2020,4 +2020,90 @@ ) ) ) + (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32) + (drop + (i32.eq + (i32.load8_s + (get_local $0) + ) + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.load8_s + (get_local $0) ;; flip order, we should canonicalize + ) + ) + ) + (drop + (i32.eq + (i32.load8_u ;; unsigned, bad + (get_local $0) + ) + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (drop + (i32.eq + (i32.load8_s + (get_local $0) + ) + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 16) ;; wrong size + ) + (i32.const 16) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.load8_u ;; unsigned, bad + (get_local $0) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 16) ;; wrong size + ) + (i32.const 16) + ) + (i32.load8_s + (get_local $0) + ) + ) + ) + ) ) |