diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/optimize-instructions-mvp.wast | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/test/lit/passes/optimize-instructions-mvp.wast b/test/lit/passes/optimize-instructions-mvp.wast index 8a86e259f..db864087d 100644 --- a/test/lit/passes/optimize-instructions-mvp.wast +++ b/test/lit/passes/optimize-instructions-mvp.wast @@ -16594,4 +16594,303 @@ ) ) ) + + ;; CHECK: (func $skip-added-constants-overflow (result i32) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-overflow (result i32) + ;; If we subtracted 0x80000000 - 1 we'd get something that changes sign if + ;; the comparison is signed (as the sign bit is no longer set). To avoid + ;; that we skip optimizing cases where subtracting the constants might lead + ;; to an overflow. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 1) + ) + (i32.const 0x80000000) + ) + ) + + ;; CHECK: (func $skip-added-constants-overflow-unsigned (result i32) + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-overflow-unsigned (result i32) + ;; As above, but unsigned. This is ok for us to optimize. + (i32.ge_u + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 1) + ) + (i32.const 0x80000000) + ) + ) + + ;; CHECK: (func $skip-added-constants-zero (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $skip-added-constants-zero (result i32) + ;; A zero in either constant means we should not optimize using an added + ;; constant. However, other optimizations kick in here, as adding zero does + ;; nothing, and we end up with [max 31 bits] >=_s MIN_INT which is true. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 0) + ) + (i32.const 0x80000000) + ) + ) + + ;; CHECK: (func $skip-added-constants-zero-a (result i32) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-zero-a (result i32) + ;; A zero in the last constant means we should not optimize. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 0x80000000) + ) + (i32.const 0) + ) + ) + + ;; CHECK: (func $skip-added-constants-zero-b (result i32) + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-zero-b (result i32) + ;; Parallel case to the above, with a zero in the added constant. We do not + ;; optimize. + (i32.ge_u + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 1) + ) + (i32.const 0) + ) + ) + + ;; CHECK: (func $skip-added-constants-negative (result i32) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-negative (result i32) + ;; Reasonable negative constants can be optimized. But the add is + ;; canoncalized into a sub, and atm we do not optimize such added constants. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const -10) + ) + (i32.const -20) + ) + ) + + ;; CHECK: (func $skip-added-constants-negative-flip (result i32) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-negative-flip (result i32) + ;; As above, but flipped. The add is canoncalized into a sub, and atm we do + ;; not optimize such added constants. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const -20) + ) + (i32.const -10) + ) + ) + + ;; CHECK: (func $skip-added-constants-mix (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $skip-added-constants-mix (result i32) + ;; A case of one negative and one positive constant. Here we have + ;; [max 31 bits] + 10 >=_s -20 which is always true. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 10) + ) + (i32.const -20) + ) + ) + + ;; CHECK: (func $skip-added-constants-mix-flip (result i32) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $skip-added-constants-mix-flip (result i32) + ;; As above, but with sign flipped. The add is canoncalized into a sub, and + ;; atm we do not optimize such added constants. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const -20) + ) + (i32.const 10) + ) + ) + + ;; CHECK: (func $skip-added-constants-mix-flip-other (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $skip-added-constants-mix-flip-other (result i32) + ;; As above, but with the sign the same while the absolute values are + ;; flipped. Here we have [max 31 bits] + 20 >=_s -10 which is always true. + (i32.ge_s + (i32.add + (i32.shr_u + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + (i32.const 20) + ) + (i32.const -10) + ) + ) ) |