diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/rse-gc.wast | 201 |
1 files changed, 200 insertions, 1 deletions
diff --git a/test/lit/passes/rse-gc.wast b/test/lit/passes/rse-gc.wast index 50657cf06..71d9baea1 100644 --- a/test/lit/passes/rse-gc.wast +++ b/test/lit/passes/rse-gc.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. -;; RUN: wasm-opt %s --rse --enable-gc-nn-locals -all -S -o - | filecheck %s +;; RUN: wasm-opt %s --rse -all -S -o - | filecheck %s (module ;; CHECK: (type $B (struct (field (ref data)))) @@ -49,4 +49,203 @@ ) ) ) + + ;; CHECK: (func $pick-refined (param $A (ref null $A)) (param $x i32) + ;; CHECK-NEXT: (local $B (ref null $B)) + ;; CHECK-NEXT: (local.set $B + ;; CHECK-NEXT: (ref.cast_static $B + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $pick-refined (param $A (ref null $A)) (param $x i32) + (local $B (ref null $B)) + (local.set $B + (ref.cast_static $B + (local.get $A) + ) + ) + ;; All these can refer to $B, the more refined type, even in branching and + ;; merging control flow later. + (drop + (local.get $A) + ) + (drop + (local.get $B) + ) + (if + (local.get $x) + (drop + (local.get $A) + ) + (drop + (local.get $B) + ) + ) + (drop + (local.get $A) + ) + (drop + (local.get $B) + ) + ) + + ;; CHECK: (func $pick-refined-nn (param $A (ref $A)) + ;; CHECK-NEXT: (local $B (ref $B)) + ;; CHECK-NEXT: (local.set $B + ;; CHECK-NEXT: (ref.cast_static $B + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $pick-refined-nn (param $A (ref $A)) + (local $B (ref $B)) + ;; As above, but now the types are both non-nullable. We should still switch + ;; to $B. + (local.set $B + (ref.cast_static $B + (local.get $A) + ) + ) + (drop + (local.get $A) + ) + (drop + (local.get $B) + ) + ) + + ;; CHECK: (func $avoid-unrefined (param $A (ref $A)) + ;; CHECK-NEXT: (local $B (ref null $B)) + ;; CHECK-NEXT: (local.set $B + ;; CHECK-NEXT: (ref.cast_static $B + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $avoid-unrefined (param $A (ref $A)) + (local $B (ref null $B)) + ;; As above, but now the local is nullable. Since the parameter is non- + ;; nullable, that means neither is a subtype of the other, and we will make + ;; no changes. + (local.set $B + (ref.cast_static $B + (local.get $A) + ) + ) + (drop + (local.get $A) + ) + (drop + (local.get $B) + ) + ) + + ;; CHECK: (func $pick-refined-earlier (param $A (ref $A)) + ;; CHECK-NEXT: (local $A2 (ref null $A)) + ;; CHECK-NEXT: (local.set $A2 + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $pick-refined-earlier (param $A (ref $A)) + ;; As above but now the local has the same heap type but is nullable. Now we + ;; prefer the non-nullable parameter. + (local $A2 (ref null $A)) + (local.set $A2 + (local.get $A) + ) + (drop + (local.get $A) + ) + (drop + (local.get $A2) + ) + ) + + ;; CHECK: (func $different-choices (param $non-nullable (ref $A)) + ;; CHECK-NEXT: (local $nullable (ref null $A)) + ;; CHECK-NEXT: (local.set $nullable + ;; CHECK-NEXT: (local.get $non-nullable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $non-nullable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $nullable + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $nullable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $nullable + ;; CHECK-NEXT: (local.get $non-nullable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $non-nullable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $different-choices (param $non-nullable (ref $A)) + (local $nullable (ref null $A)) + (local.set $nullable + (local.get $non-nullable) + ) + ;; Here we can switch to the non-nullable one. + (drop + (local.get $nullable) + ) + + (local.set $nullable + (ref.null $A) + ) + ;; Here we cannot. + (drop + (local.get $nullable) + ) + + (local.set $nullable + (local.get $non-nullable) + ) + ;; Here we can switch once more. + (drop + (local.get $nullable) + ) + ) ) |