diff options
author | Alon Zakai <azakai@google.com> | 2021-04-19 16:15:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-19 16:15:25 -0700 |
commit | f180f6c11d2ddf9acc806333c0a452bb57f8acf9 (patch) | |
tree | 2163cef56d35724cfc70bb7ed4ab44400bdb60cf /test | |
parent | 069c9b8034f965023a4db0449e6bf6f5215b6199 (diff) | |
download | binaryen-f180f6c11d2ddf9acc806333c0a452bb57f8acf9.tar.gz binaryen-f180f6c11d2ddf9acc806333c0a452bb57f8acf9.tar.bz2 binaryen-f180f6c11d2ddf9acc806333c0a452bb57f8acf9.zip |
[Wasm GC] Reorder ref.as_non_null with tee and cast (#3820)
In both cases doing the ref.as_non_null last is beneficial as we have
optimizations that can remove it based on where it is consumed.
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/optimize-instructions-gc.wast | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index 33f7bef78..78a08d9b1 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -5,6 +5,8 @@ (module (import "env" "get-i32" (func $get-i32 (result i32))) + (type $empty (struct)) + (type $struct (struct (field $i8 (mut i8)) (field $i16 (mut i16)) @@ -716,4 +718,115 @@ ) ) ) + + ;; CHECK: (func $flip-cast-of-as-non-null (param $x anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get_u $struct $i8 + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.as_func + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.as_data + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.as_i31 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $flip-cast-of-as-non-null (param $x anyref) + (drop + (ref.cast + ;; this can be moved through the ref.cast outward. + (ref.as_non_null + (local.get $x) + ) + (rtt.canon $struct) + ) + ) + (drop + ;; an example of how this helps: the struct.get will trap on null anyhow + (struct.get_u $struct 0 + (ref.cast + ;; this can be moved through the ref.cast outward. + (ref.as_non_null + (local.get $x) + ) + (rtt.canon $struct) + ) + ) + ) + ;; other ref.as* operations are ignored for now + (drop + (ref.cast + (ref.as_func + (local.get $x) + ) + (rtt.canon $struct) + ) + ) + (drop + (ref.cast + (ref.as_data + (local.get $x) + ) + (rtt.canon $struct) + ) + ) + (drop + (ref.cast + (ref.as_i31 + (local.get $x) + ) + (rtt.canon $struct) + ) + ) + ) + ;; CHECK: (func $flip-tee-of-as-non-null (param $x anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $flip-tee-of-as-non-null (param $x anyref) + (drop + (local.tee $x + ;; this can be moved through the tee outward. + (ref.as_non_null + (local.get $x) + ) + (rtt.canon $struct) + ) + ) + ) ) |