diff options
Diffstat (limited to 'test/lit/passes/optimize-instructions-eh.wast')
-rw-r--r-- | test/lit/passes/optimize-instructions-eh.wast | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/test/lit/passes/optimize-instructions-eh.wast b/test/lit/passes/optimize-instructions-eh.wast new file mode 100644 index 000000000..50ae665e2 --- /dev/null +++ b/test/lit/passes/optimize-instructions-eh.wast @@ -0,0 +1,249 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --remove-unused-names --optimize-instructions -all -S -o - \ +;; RUN: | filecheck %s + +(module + (func $dummy) + (event $e (attr 0) (param i32)) + + ;; The following are the unit tests for Properties::getFallthrough for EH + ;; instructions, which are used in one of binary optimizations in + ;; OptimizeInstructions::visitBinary(). + + ;; When a pattern of (i32.add (expr) (expr with all 1s)) is detected and + ;; 'expr' is guaranteed to take equal or less bits than the number of bits in + ;; the second expression, the i32.add can be dropped and we can only leave + ;; (expr). For example: + ;; (i32.add (local.get $x) (i32.const 7)) can be just (local.get $x) when $x + ;; is guaranteed to contain a value equal to or less than 7. + + ;; CHECK: (func $getFallthrough-try-no-throw + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (try (result i32) + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $getFallthrough-try-no-throw + (local $x i32) + (local.set $x + (try (result i32) + (do + (i32.const 1) + ) + (catch_all + (i32.const 3) + ) + ) + ) + ;; The 'try' above is guaranteed not to throw, so we can be sure the $x + ;; contains 1 at this point, which is smaller than 7 (0b111), so we know the + ;; masking with 0b111 is not ncessary and we can only leave (local.set $x). + (drop (i32.and (local.get $x) (i32.const 7))) + ) + + ;; CHECK: (func $getFallthrough-try-may-throw + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (try (result i32) + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (call $dummy) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $getFallthrough-try-may-throw + (local $x i32) + (local.set $x + (try (result i32) + (do + (call $dummy) + (i32.const 1) + ) + (catch_all + (i32.const 3) + ) + ) + ) + ;; The 'try' body above may throw because of the call, so we are not sure + ;; what $x contains at this point, so we can't remove the masking here. + (drop (i32.and (local.get $x) (i32.const 7))) + ) + + ;; CHECK: (func $getFallthrough-nested-try-0 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (try (result i32) + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (try + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (call $dummy) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch $e + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (pop i32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch $e + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (pop i32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $getFallthrough-nested-try-0 + (local $x i32) + (local.set $x + (try (result i32) + (do + (try + (do + (call $dummy) + ) + (catch $e + (drop (pop i32)) + ) + ) + (i32.const 1) + ) + (catch $e + (drop (pop i32)) + (i32.const 3) + ) + ) + ) + ;; The inner 'try' may throw and it may not be caught by both the inner and + ;; outer catches, so we are not sure what $x contains at this point, which + ;; prevents the masking optimization. + (drop (i32.and (local.get $x) (i32.const 7))) + ) + + ;; CHECK: (func $getFallthrough-nested-try-1 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (try (result i32) + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (try + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (call $dummy) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $getFallthrough-nested-try-1 + (local $x i32) + (local.set $x + (try (result i32) + (do + (try + (do + (call $dummy) + ) + (catch_all) + ) + (i32.const 1) + ) + (catch_all + (i32.const 3) + ) + ) + ) + ;; The inner try may throw, but it will caught by the inner catch_all, and + ;; $x will be set to 1. So we can do the masking optimization and remove + ;; i32.and here. + (drop (i32.and (local.get $x) (i32.const 7))) + ) + + ;; CHECK: (func $getFallthrough-nested-try-2 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (try (result i32) + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (try + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (call $dummy) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $getFallthrough-nested-try-2 + (local $x i32) + (local.set $x + (try (result i32) + (do + (try + (do) + (catch_all + (call $dummy) + ) + ) + (i32.const 3) + ) + (catch_all + (i32.const 1) + ) + ) + ) + ;; Depending on whether (call $dummy) throws or not, we are not sure whether + ;; $x will contain 1 or 3 at this point, which prevents the masking + ;; optimization. + (drop (i32.and (local.get $x) (i32.const 7))) + ) +) |