summaryrefslogtreecommitdiff
path: root/test/lit/passes/gufa-cast-all.wast
blob: c5b92ee89da79ccb0e72284bcac5c40d8d2a4209 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; RUN: foreach %s %t wasm-opt -all --gufa-cast-all -S -o - | filecheck %s

(module
  ;; CHECK:      (type $none_=>_none (func))
  (type $none_=>_none (func))

  ;; CHECK:      (type $A (sub (struct)))
  (type $A (sub (struct)))

  ;; CHECK:      (type $B (sub $A (struct)))
  (type $B (sub $A (struct)))

  ;; CHECK:      (type $3 (func (result i32)))

  ;; CHECK:      (import "a" "b" (func $import (type $3) (result i32)))
  (import "a" "b" (func $import (result i32)))

  ;; CHECK:      (elem declare func $func $funcs)

  ;; CHECK:      (export "export1" (func $ref))

  ;; CHECK:      (export "export2" (func $int))

  ;; CHECK:      (export "export3" (func $func))

  ;; CHECK:      (export "export4" (func $funcs))

  ;; CHECK:      (export "export5" (func $unreachable))

  ;; CHECK:      (func $ref (type $none_=>_none)
  ;; CHECK-NEXT:  (local $a (ref $A))
  ;; CHECK-NEXT:  (local.set $a
  ;; CHECK-NEXT:   (struct.new_default $B)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (ref.cast (ref $B)
  ;; CHECK-NEXT:    (local.get $a)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $ref (export "export1")
    (local $a (ref $A))
    (local.set $a
      (struct.new $B)
    )
    (drop
      ;; We can infer that this contains B, and add a cast to that type.
      (local.get $a)
    )
  )

  ;; CHECK:      (func $int (type $none_=>_none)
  ;; CHECK-NEXT:  (local $a i32)
  ;; CHECK-NEXT:  (local.set $a
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $int (export "export2")
    (local $a i32)
    (local.set $a
      (i32.const 1)
    )
    (drop
      ;; We can infer that this contains 1, but there is nothing to do regarding
      ;; the type, which is not a reference.
      (local.get $a)
    )
  )

  ;; CHECK:      (func $func (type $none_=>_none)
  ;; CHECK-NEXT:  (local $a funcref)
  ;; CHECK-NEXT:  (local.set $a
  ;; CHECK-NEXT:   (ref.func $func)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (ref.func $func)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $func (export "export3") (type $none_=>_none)
    (local $a funcref)
    (local.set $a
      (ref.func $func)
    )
    (drop
      ;; We can infer that this contains a ref to $func, which we can apply
      ;; here. We don't need to add a cast in addition to that, as the ref.func
      ;; we add has the refined type already.
      (local.get $a)
    )
  )

  ;; CHECK:      (func $funcs (type $none_=>_none)
  ;; CHECK-NEXT:  (local $a funcref)
  ;; CHECK-NEXT:  (local.set $a
  ;; CHECK-NEXT:   (select (result (ref $none_=>_none))
  ;; CHECK-NEXT:    (ref.func $func)
  ;; CHECK-NEXT:    (ref.func $funcs)
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (ref.cast (ref $none_=>_none)
  ;; CHECK-NEXT:    (local.get $a)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $funcs (export "export4") (type $none_=>_none)
    (local $a funcref)
    (local.set $a
      (select
        (ref.func $func)
        (ref.func $funcs)
        (call $import)
      )
    )
    (drop
      ;; We can infer that this contains a ref to $func or $funcs, so all we
      ;; can infer is the type, and we add a cast to $none_=>_none.
      (local.get $a)
    )
  )

  ;; CHECK:      (func $unreachable (type $none_=>_none)
  ;; CHECK-NEXT:  (local $a (ref $A))
  ;; CHECK-NEXT:  (local.tee $a
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $unreachable (export "export5")
    (local $a (ref $A))
    (local.set $a
      (unreachable)
    )
    (drop
      ;; We can infer that the type here is unreachable, and emit that in the
      ;; IR. This checks we don't error on the inferred type not being a ref.
      (local.get $a)
    )
  )
)