diff options
author | Alon Zakai <azakai@google.com> | 2023-01-05 13:20:31 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-05 13:20:31 -0800 |
commit | d623ba4b075aa1d70113fc41172a9ed248e0011d (patch) | |
tree | 07b614fef329165f8effe1b6407e97de12e1427d /test | |
parent | 0293c4649204e11f7db5724dc9477aa1ef6aef18 (diff) | |
download | binaryen-d623ba4b075aa1d70113fc41172a9ed248e0011d.tar.gz binaryen-d623ba4b075aa1d70113fc41172a9ed248e0011d.tar.bz2 binaryen-d623ba4b075aa1d70113fc41172a9ed248e0011d.zip |
[Wasm GC] Fix non-nullable cast optimizations with multiple children (#5396)
This fixes an oversight in #5395
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/optimize-instructions-gc-tnh.wast | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast index d9520b18c..fec4c17f0 100644 --- a/test/lit/passes/optimize-instructions-gc-tnh.wast +++ b/test/lit/passes/optimize-instructions-gc-tnh.wast @@ -446,6 +446,90 @@ ) ) + ;; TNH: (func $set-get-cast (type $dataref_=>_none) (param $ref dataref) + ;; TNH-NEXT: (drop + ;; TNH-NEXT: (struct.get $struct 0 + ;; TNH-NEXT: (ref.cast $struct + ;; TNH-NEXT: (local.get $ref) + ;; TNH-NEXT: ) + ;; TNH-NEXT: ) + ;; TNH-NEXT: ) + ;; TNH-NEXT: (struct.set $struct 0 + ;; TNH-NEXT: (ref.cast $struct + ;; TNH-NEXT: (local.get $ref) + ;; TNH-NEXT: ) + ;; TNH-NEXT: (i32.const 1) + ;; TNH-NEXT: ) + ;; TNH-NEXT: (struct.set $struct 0 + ;; TNH-NEXT: (ref.cast null $struct + ;; TNH-NEXT: (local.get $ref) + ;; TNH-NEXT: ) + ;; TNH-NEXT: (block (result i32) + ;; TNH-NEXT: (return) + ;; TNH-NEXT: (i32.const 1) + ;; TNH-NEXT: ) + ;; TNH-NEXT: ) + ;; TNH-NEXT: ) + ;; NO_TNH: (func $set-get-cast (type $dataref_=>_none) (param $ref dataref) + ;; NO_TNH-NEXT: (drop + ;; NO_TNH-NEXT: (struct.get $struct 0 + ;; NO_TNH-NEXT: (ref.cast $struct + ;; NO_TNH-NEXT: (local.get $ref) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (struct.set $struct 0 + ;; NO_TNH-NEXT: (ref.cast null $struct + ;; NO_TNH-NEXT: (local.get $ref) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (struct.set $struct 0 + ;; NO_TNH-NEXT: (ref.cast null $struct + ;; NO_TNH-NEXT: (local.get $ref) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (block (result i32) + ;; NO_TNH-NEXT: (return) + ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: ) + (func $set-get-cast (param $ref (ref null data)) + ;; A nullable cast flowing into a place that traps on null can become a + ;; non-nullable cast. + (drop + (struct.get $struct 0 + (ref.cast null $struct + (local.get $ref) + ) + ) + ) + ;; Ditto for a set, at least in traps-happen mode. + ;; TODO handle non-TNH as well, but we need to be careful of effects in + ;; other children. + (struct.set $struct 0 + (ref.cast null $struct + (local.get $ref) + ) + (i32.const 1) + ) + ;; Even in TNH mode, a child with an effect of control flow transfer + ;; prevents us from optimizing - if the parent is not necessarily reached, + ;; we cannot infer the child won't trap. + (struct.set $struct 0 + (ref.cast null $struct + (local.get $ref) + ) + (block (result i32) + ;; This block has type i32, to check that we don't just look for + ;; unreachable. We must scan for any transfer of control flow in the + ;; child of the struct.set. + (return) + (i32.const 1) + ) + ) + ) + ;; Helper functions. ;; TNH: (func $get-i32 (type $none_=>_i32) (result i32) |