1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file | mlir-opt -allow-unregistered-dialect | FileCheck %s
2
3// CHECK-LABEL: @primitive
4func.func @primitive() {
5  // CHECK: !llvm.void
6  "some.op"() : () -> !llvm.void
7  // CHECK: !llvm.ppc_fp128
8  "some.op"() : () -> !llvm.ppc_fp128
9  // CHECK: !llvm.x86_mmx
10  "some.op"() : () -> !llvm.x86_mmx
11  // CHECK: !llvm.token
12  "some.op"() : () -> !llvm.token
13  // CHECK: !llvm.label
14  "some.op"() : () -> !llvm.label
15  // CHECK: !llvm.metadata
16  "some.op"() : () -> !llvm.metadata
17  return
18}
19
20// CHECK-LABEL: @func
21func.func @func() {
22  // CHECK: !llvm.func<void ()>
23  "some.op"() : () -> !llvm.func<void ()>
24  // CHECK: !llvm.func<void (i32)>
25  "some.op"() : () -> !llvm.func<void (i32)>
26  // CHECK: !llvm.func<i32 ()>
27  "some.op"() : () -> !llvm.func<i32 ()>
28  // CHECK: !llvm.func<i32 (f16, bf16, f32, f64)>
29  "some.op"() : () -> !llvm.func<i32 (f16, bf16, f32, f64)>
30  // CHECK: !llvm.func<i32 (i32, i32)>
31  "some.op"() : () -> !llvm.func<i32 (i32, i32)>
32  // CHECK: !llvm.func<void (...)>
33  "some.op"() : () -> !llvm.func<void (...)>
34  // CHECK: !llvm.func<void (i32, i32, ...)>
35  "some.op"() : () -> !llvm.func<void (i32, i32, ...)>
36  return
37}
38
39// CHECK-LABEL: @integer
40func.func @integer() {
41  // CHECK: i1
42  "some.op"() : () -> i1
43  // CHECK: i8
44  "some.op"() : () -> i8
45  // CHECK: i16
46  "some.op"() : () -> i16
47  // CHECK: i32
48  "some.op"() : () -> i32
49  // CHECK: i64
50  "some.op"() : () -> i64
51  // CHECK: i57
52  "some.op"() : () -> i57
53  // CHECK: i129
54  "some.op"() : () -> i129
55  return
56}
57
58// CHECK-LABEL: @ptr
59func.func @ptr() {
60  // CHECK: !llvm.ptr<i8>
61  "some.op"() : () -> !llvm.ptr<i8>
62  // CHECK: !llvm.ptr<f32>
63  "some.op"() : () -> !llvm.ptr<f32>
64  // CHECK: !llvm.ptr<ptr<i8>>
65  "some.op"() : () -> !llvm.ptr<ptr<i8>>
66  // CHECK: !llvm.ptr<ptr<ptr<ptr<ptr<i8>>>>>
67  "some.op"() : () -> !llvm.ptr<ptr<ptr<ptr<ptr<i8>>>>>
68  // CHECK: !llvm.ptr<i8>
69  "some.op"() : () -> !llvm.ptr<i8, 0>
70  // CHECK: !llvm.ptr<i8, 1>
71  "some.op"() : () -> !llvm.ptr<i8, 1>
72  // CHECK: !llvm.ptr<i8, 42>
73  "some.op"() : () -> !llvm.ptr<i8, 42>
74  // CHECK: !llvm.ptr<ptr<i8, 42>, 9>
75  "some.op"() : () -> !llvm.ptr<ptr<i8, 42>, 9>
76  // CHECK: !llvm.ptr
77  "some.op"() : () -> !llvm.ptr
78  // CHECK: !llvm.ptr<42>
79  "some.op"() : () -> !llvm.ptr<42>
80  return
81}
82
83// CHECK-LABEL: @vec
84func.func @vec() {
85  // CHECK: vector<4xi32>
86  "some.op"() : () -> vector<4xi32>
87  // CHECK: vector<4xf32>
88  "some.op"() : () -> vector<4xf32>
89  // CHECK: !llvm.vec<? x 4 x i32>
90  "some.op"() : () -> !llvm.vec<? x 4 x i32>
91  // CHECK: !llvm.vec<? x 8 x f16>
92  "some.op"() : () -> !llvm.vec<? x 8 x f16>
93  // CHECK: !llvm.vec<4 x ptr<i8>>
94  "some.op"() : () -> !llvm.vec<4 x ptr<i8>>
95  return
96}
97
98// CHECK-LABEL: @array
99func.func @array() {
100  // CHECK: !llvm.array<10 x i32>
101  "some.op"() : () -> !llvm.array<10 x i32>
102  // CHECK: !llvm.array<8 x f32>
103  "some.op"() : () -> !llvm.array<8 x f32>
104  // CHECK: !llvm.array<10 x ptr<i32, 4>>
105  "some.op"() : () -> !llvm.array<10 x ptr<i32, 4>>
106  // CHECK: !llvm.array<10 x array<4 x f32>>
107  "some.op"() : () -> !llvm.array<10 x array<4 x f32>>
108  return
109}
110
111// CHECK-LABEL: @literal_struct
112func.func @literal_struct() {
113  // CHECK: !llvm.struct<()>
114  "some.op"() : () -> !llvm.struct<()>
115  // CHECK: !llvm.struct<(i32)>
116  "some.op"() : () -> !llvm.struct<(i32)>
117  // CHECK: !llvm.struct<(f32, i32)>
118  "some.op"() : () -> !llvm.struct<(f32, i32)>
119  // CHECK: !llvm.struct<(struct<(i32)>)>
120  "some.op"() : () -> !llvm.struct<(struct<(i32)>)>
121  // CHECK: !llvm.struct<(i32, struct<(i32)>, f32)>
122  "some.op"() : () -> !llvm.struct<(i32, struct<(i32)>, f32)>
123
124  // CHECK: !llvm.struct<packed ()>
125  "some.op"() : () -> !llvm.struct<packed ()>
126  // CHECK: !llvm.struct<packed (i32)>
127  "some.op"() : () -> !llvm.struct<packed (i32)>
128  // CHECK: !llvm.struct<packed (f32, i32)>
129  "some.op"() : () -> !llvm.struct<packed (f32, i32)>
130  // CHECK: !llvm.struct<packed (f32, i32)>
131  "some.op"() : () -> !llvm.struct<packed (f32, i32)>
132  // CHECK: !llvm.struct<packed (struct<(i32)>)>
133  "some.op"() : () -> !llvm.struct<packed (struct<(i32)>)>
134  // CHECK: !llvm.struct<packed (i32, struct<(i32, i1)>, f32)>
135  "some.op"() : () -> !llvm.struct<packed (i32, struct<(i32, i1)>, f32)>
136
137  // CHECK: !llvm.struct<(struct<packed (i32)>)>
138  "some.op"() : () -> !llvm.struct<(struct<packed (i32)>)>
139  // CHECK: !llvm.struct<packed (struct<(i32)>)>
140  "some.op"() : () -> !llvm.struct<packed (struct<(i32)>)>
141  return
142}
143
144// CHECK-LABEL: @identified_struct
145func.func @identified_struct() {
146  // CHECK: !llvm.struct<"empty", ()>
147  "some.op"() : () -> !llvm.struct<"empty", ()>
148  // CHECK: !llvm.struct<"opaque", opaque>
149  "some.op"() : () -> !llvm.struct<"opaque", opaque>
150  // CHECK: !llvm.struct<"long", (i32, struct<(i32, i1)>, f32, ptr<func<void ()>>)>
151  "some.op"() : () -> !llvm.struct<"long", (i32, struct<(i32, i1)>, f32, ptr<func<void ()>>)>
152  // CHECK: !llvm.struct<"self-recursive", (ptr<struct<"self-recursive">>)>
153  "some.op"() : () -> !llvm.struct<"self-recursive", (ptr<struct<"self-recursive">>)>
154  // CHECK: !llvm.struct<"unpacked", (i32)>
155  "some.op"() : () -> !llvm.struct<"unpacked", (i32)>
156  // CHECK: !llvm.struct<"packed", packed (i32)>
157  "some.op"() : () -> !llvm.struct<"packed", packed (i32)>
158  // CHECK: !llvm.struct<"name with spaces and !^$@$#", packed (i32)>
159  "some.op"() : () -> !llvm.struct<"name with spaces and !^$@$#", packed (i32)>
160
161  // CHECK: !llvm.struct<"mutually-a", (ptr<struct<"mutually-b", (ptr<struct<"mutually-a">, 3>)>>)>
162  "some.op"() : () -> !llvm.struct<"mutually-a", (ptr<struct<"mutually-b", (ptr<struct<"mutually-a">, 3>)>>)>
163  // CHECK: !llvm.struct<"mutually-b", (ptr<struct<"mutually-a", (ptr<struct<"mutually-b">>)>, 3>)>
164  "some.op"() : () -> !llvm.struct<"mutually-b", (ptr<struct<"mutually-a", (ptr<struct<"mutually-b">>)>, 3>)>
165  // CHECK: !llvm.struct<"referring-another", (ptr<struct<"unpacked", (i32)>>)>
166  "some.op"() : () -> !llvm.struct<"referring-another", (ptr<struct<"unpacked", (i32)>>)>
167
168  // CHECK: !llvm.struct<"struct-of-arrays", (array<10 x i32>)>
169  "some.op"() : () -> !llvm.struct<"struct-of-arrays", (array<10 x i32>)>
170  // CHECK: !llvm.array<10 x struct<"array-of-structs", (i32)>>
171  "some.op"() : () -> !llvm.array<10 x struct<"array-of-structs", (i32)>>
172  // CHECK: !llvm.ptr<struct<"ptr-to-struct", (i8)>>
173  "some.op"() : () -> !llvm.ptr<struct<"ptr-to-struct", (i8)>>
174  return
175}
176
177func.func @verbose() {
178  // CHECK: !llvm.struct<(i64, struct<(f32)>)>
179  "some.op"() : () -> !llvm.struct<(i64, !llvm.struct<(f32)>)>
180  return
181}
182
183// CHECK-LABEL: @ptr_elem_interface
184// CHECK-COUNT-3: !llvm.ptr<!test.smpla>
185// CHECK: llvm.mlir.undef : !llvm.ptr<!test.smpla>
186func.func @ptr_elem_interface(%arg0: !llvm.ptr<!test.smpla>) {
187  %0 = llvm.load %arg0 : !llvm.ptr<!test.smpla>
188  llvm.store %0, %arg0 : !llvm.ptr<!test.smpla>
189  llvm.mlir.undef : !llvm.ptr<!test.smpla>
190  return
191}
192
193// -----
194
195// Check that type aliases can be used inside LLVM dialect types. Note that
196// currently they are _not_ printed back as this would require
197// DialectAsmPrinter to have a mechanism for querying the presence and
198// usability of an alias outside of its `printType` method.
199
200!baz = i64
201!qux = !llvm.struct<(!baz)>
202
203!rec = !llvm.struct<"a", (ptr<struct<"a">>)>
204
205// CHECK: aliases
206llvm.func @aliases() {
207  // CHECK: !llvm.struct<(i32, f32, struct<(i64)>)>
208  "some.op"() : () -> !llvm.struct<(i32, f32, !qux)>
209  // CHECK: !llvm.struct<"a", (ptr<struct<"a">>)>
210  "some.op"() : () -> !rec
211  llvm.return
212}
213