summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-01-05 13:20:31 -0800
committerGitHub <noreply@github.com>2023-01-05 13:20:31 -0800
commitd623ba4b075aa1d70113fc41172a9ed248e0011d (patch)
tree07b614fef329165f8effe1b6407e97de12e1427d /test
parent0293c4649204e11f7db5724dc9477aa1ef6aef18 (diff)
downloadbinaryen-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.wast84
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)