diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/cfp.wast | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index 48b1210b7..cc98227b5 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -2222,3 +2222,73 @@ ) ) ) + +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (struct (field (mut i32)))) + (type $A (struct (field (mut i32)))) + ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) + (type $B (struct_subtype (field (mut i32)) $A)) + ) + + ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32))) + + ;; CHECK: (func $test (type $i32_=>_i32) (param $0 i32) (result i32) + ;; CHECK-NEXT: (local $A (ref $A)) + ;; CHECK-NEXT: (local $B (ref $B)) + ;; CHECK-NEXT: (struct.set $A 0 + ;; CHECK-NEXT: (select (result (ref null $A)) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (local.tee $B + ;; CHECK-NEXT: (struct.new $B + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.get $A 0 + ;; CHECK-NEXT: (struct.new $A + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.get $B 0 + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $0 i32) (result i32) + (local $A (ref $A)) + (local $B (ref $B)) + ;; This set is part of a copy, as the value is a struct.get. The copy is on + ;; $A, but the reference we operate on is an instance of $B, actually. So + ;; the value read at the end is in fact 10. That is, this test verifies + ;; that we track the copied value even though the copy is on $A but it + ;; affects $B. + (struct.set $A 0 + ;; This select is used to keep the type that reaches the struct.set $A, + ;; and not $B, so it looks like a perfect copy of $A->$A. + (select (result (ref null $A)) + (ref.null $A) + (local.tee $B + (struct.new $B + (i32.const 20) + ) + ) + (i32.const 0) + ) + (struct.get $A 0 + (struct.new $A + (i32.const 10) + ) + ) + ) + ;; This should not turn into 20, since just based on values flowing to + ;; fields we cannot infer that (the value will be 10, but CFP cannot infer + ;; that either - that would require tracking references through locals + ;; etc.). + (struct.get $B 0 + (local.get $B) + ) + ) +) |