summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/cfp.wast70
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)
+ )
+ )
+)