diff options
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 17 | ||||
-rw-r--r-- | test/passes/optimize-instructions_all-features.txt | 24 | ||||
-rw-r--r-- | test/passes/optimize-instructions_all-features.wast | 20 |
3 files changed, 58 insertions, 3 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 2736c8984..232faab7a 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1454,6 +1454,23 @@ private: right->value = Literal::makeZero(type); return right; } + // i32(x) / i32.min_s ==> x == i32.min_s + if (matches( + curr, + binary(DivSInt32, any(), i32(std::numeric_limits<int32_t>::min())))) { + curr->op = EqInt32; + return curr; + } + // i64(x) / i64.min_s ==> i64(x == i64.min_s) + // only for zero shrink level + if (getPassOptions().shrinkLevel == 0 && + matches( + curr, + binary(DivSInt64, any(), i64(std::numeric_limits<int64_t>::min())))) { + curr->op = EqInt64; + curr->type = Type::i32; + return Builder(*getModule()).makeUnary(ExtendUInt32, curr); + } // (unsigned)x > -1 ==> 0 if (matches(curr, binary(Abstract::GtU, pure(&left), ival(-1)))) { right->value = Literal::makeZero(Type::i32); diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt index f43316f3d..6ef58233f 100644 --- a/test/passes/optimize-instructions_all-features.txt +++ b/test/passes/optimize-instructions_all-features.txt @@ -4174,7 +4174,27 @@ ) ) ) - (func $rhs-is-neg-const (param $x i32) (param $y i64) + (func $rhs-is-const (param $x i32) (param $y i64) + (drop + (i32.eq + (local.get $x) + (i32.const -2147483648) + ) + ) + (drop + (i64.extend_i32_u + (i64.eq + (local.get $y) + (i64.const -9223372036854775808) + ) + ) + ) + (drop + (i64.div_s + (local.get $y) + (i64.const -2147483648) + ) + ) (drop (i32.ge_u (local.get $x) @@ -4337,7 +4357,7 @@ ) ) (drop - (i32.div_s + (i32.eq (i32.and (local.get $x) (i32.const 2147483647) diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast index 934ccc977..60ae8d3c2 100644 --- a/test/passes/optimize-instructions_all-features.wast +++ b/test/passes/optimize-instructions_all-features.wast @@ -4638,7 +4638,25 @@ (i64.const -1) )) ) - (func $rhs-is-neg-const (param $x i32) (param $y i64) + (func $rhs-is-const (param $x i32) (param $y i64) + ;; signed divs + ;; i32(x) / -2147483648 -> x == -2147483648 + (drop (i32.div_s + (local.get $x) + (i32.const -2147483648) + )) + ;; i64(x) / -9223372036854775808 -> x == -9223372036854775808 + (drop (i64.div_s + (local.get $y) + (i64.const -9223372036854775808) + )) + ;; skip + (drop (i64.div_s + (local.get $y) + (i64.const -2147483648) + )) + + ;; unsigned divs ;; u32(x) / -2 => x >= -2 (drop (i32.div_u (local.get $x) |