summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/lit/passes/gufa-refs.wast130
1 files changed, 130 insertions, 0 deletions
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index 48f6edc34..09de96fca 100644
--- a/test/lit/passes/gufa-refs.wast
+++ b/test/lit/passes/gufa-refs.wast
@@ -5195,3 +5195,133 @@
)
)
)
+
+;; Tests for proper inference of imported etc. values - we do know their type,
+;; at least.
+(module
+ ;; CHECK: (type $A (struct_subtype (field (mut i32)) data))
+ (type $A (struct_subtype (field (mut i32)) data))
+
+ ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A))
+ (type $B (struct_subtype (field (mut i32)) $A))
+
+ ;; CHECK: (type $ref|$A|_=>_none (func_subtype (param (ref $A)) func))
+
+ ;; CHECK: (type $none_=>_ref|$A| (func_subtype (result (ref $A)) func))
+
+ ;; CHECK: (import "a" "b" (global $A (ref $A)))
+ (import "a" "b" (global $A (ref $A)))
+
+ ;; CHECK: (import "a" "c" (func $A (result (ref $A))))
+ (import "a" "c" (func $A (result (ref $A))))
+
+ ;; CHECK: (global $mut_A (ref $A) (struct.new $A
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $mut_A (ref $A) (struct.new $A
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (export "mut_A" (global $mut_A))
+ (export "mut_A" (global $mut_A))
+
+ ;; CHECK: (export "yes" (func $yes))
+
+ ;; CHECK: (export "no" (func $no))
+
+ ;; CHECK: (func $yes (type $ref|$A|_=>_none) (param $A (ref $A))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $A)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $yes (export "yes") (param $A (ref $A))
+ ;; An imported global has a known type, at least, which in this case is
+ ;; enough for us to infer a result of 1.
+ (drop
+ (ref.test_static $A
+ (global.get $A)
+ )
+ )
+ ;; Likewise, a function result.
+ (drop
+ (ref.test_static $A
+ (call $A)
+ )
+ )
+ ;; Likewise, a parameter to this function, which is exported, but we do
+ ;; still know the type it will be called with, and can optimize to 1.
+ (drop
+ (ref.test_static $A
+ (local.get $A)
+ )
+ )
+ ;; Likewise, an exported mutable global can be modified by the outside, but
+ ;; the type remains known, and we can optimize to 1.
+ (drop
+ (ref.test_static $A
+ (global.get $A)
+ )
+ )
+ )
+
+ ;; CHECK: (func $no (type $ref|$A|_=>_none) (param $A (ref $A))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.test_static $B
+ ;; CHECK-NEXT: (global.get $A)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.test_static $B
+ ;; CHECK-NEXT: (call $A)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.test_static $B
+ ;; CHECK-NEXT: (local.get $A)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.test_static $B
+ ;; CHECK-NEXT: (global.get $A)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $no (export "no") (param $A (ref $A))
+ ;; Identical to the above function, but now all tests are vs type $B. We
+ ;; cannot optimize any of these, as all we know is the type is $A.
+ (drop
+ (ref.test_static $B
+ (global.get $A)
+ )
+ )
+ (drop
+ (ref.test_static $B
+ (call $A)
+ )
+ )
+ (drop
+ (ref.test_static $B
+ (local.get $A)
+ )
+ )
+ (drop
+ (ref.test_static $B
+ (global.get $A)
+ )
+ )
+ )
+)