;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s --optimize-instructions --ignore-implicit-traps --enable-reference-types --enable-gc -S -o - \ ;; RUN: | filecheck %s (module (type $parent (struct (field i32))) (type $child (struct (field i32) (field f64))) (type $other (struct (field i64) (field f32))) (func $foo) ;; CHECK: (func $ref-cast-iit (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other)) (param $parent-rtt (rtt $parent)) (param $child-rtt (rtt $child)) (param $other-rtt (rtt $other)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $parent)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $parent-rtt) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $parent) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $child)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $parent-rtt) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $child) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast ;; CHECK-NEXT: (local.get $parent) ;; CHECK-NEXT: (local.get $child-rtt) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast ;; CHECK-NEXT: (local.get $child) ;; CHECK-NEXT: (local.get $other-rtt) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ref-cast-iit (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other)) (param $parent-rtt (rtt $parent)) (param $child-rtt (rtt $child)) (param $other-rtt (rtt $other)) ;; a cast of parent to an rtt of parent: static subtyping matches. (drop (ref.cast (local.get $parent) (local.get $parent-rtt) ) ) ;; a cast of child to a supertype: static subtyping matches. (drop (ref.cast (local.get $child) (local.get $parent-rtt) ) ) ;; a cast of parent to a subtype: static subtyping does not match. (drop (ref.cast (local.get $parent) (local.get $child-rtt) ) ) ;; a cast of child to an unrelated type: static subtyping does not match. (drop (ref.cast (local.get $child) (local.get $other-rtt) ) ) ) ;; CHECK: (func $ref-cast-iit-bad (param $parent (ref $parent)) (param $parent-rtt (rtt $parent)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast ;; CHECK-NEXT: (block $block (result (ref $parent)) ;; CHECK-NEXT: (call $foo) ;; CHECK-NEXT: (local.get $parent) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $block0 (result (rtt $parent)) ;; CHECK-NEXT: (call $foo) ;; CHECK-NEXT: (local.get $parent-rtt) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast ;; CHECK-NEXT: (local.get $parent) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (local.get $parent-rtt) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ref-cast-iit-bad (param $parent (ref $parent)) (param $parent-rtt (rtt $parent)) ;; ignore due to the inability to reorder (drop (ref.cast (block (result (ref $parent)) (call $foo) (local.get $parent) ) (block (result (rtt $parent)) (call $foo) (local.get $parent-rtt) ) ) ) ;; ignore unreachability (drop (ref.cast (local.get $parent) (unreachable) ) ) (drop (ref.cast (unreachable) (local.get $parent-rtt) ) ) ) ;; CHECK: (func $ref-eq-ref-cast (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ref-eq-ref-cast (param $x eqref) ;; we can look through a ref.cast if we ignore traps (drop (ref.eq (local.get $x) (ref.cast (local.get $x) (rtt.canon $parent) ) ) ) ) )