1// RUN: mlir-opt --test-data-layout-query --split-input-file --verify-diagnostics %s | FileCheck %s
2
3module {
4  // CHECK: @no_spec
5  func.func @no_spec() {
6    // CHECK: alignment = 8
7    // CHECK: bitsize = 64
8    // CHECK: preferred = 8
9    // CHECK: size = 8
10    "test.data_layout_query"() : () -> !llvm.ptr<i8>
11    // CHECK: alignment = 8
12    // CHECK: bitsize = 64
13    // CHECK: preferred = 8
14    // CHECK: size = 8
15    "test.data_layout_query"() : () -> !llvm.ptr<i32>
16    // CHECK: alignment = 8
17    // CHECK: bitsize = 64
18    // CHECK: preferred = 8
19    // CHECK: size = 8
20    "test.data_layout_query"() : () -> !llvm.ptr<bf16>
21    // CHECK: alignment = 8
22    // CHECK: bitsize = 64
23    // CHECK: preferred = 8
24    // CHECK: size = 8
25    "test.data_layout_query"() : () -> !llvm.ptr<!llvm.ptr<i8>>
26    // CHECK: alignment = 8
27    // CHECK: bitsize = 64
28    // CHECK: preferred = 8
29    // CHECK: size = 8
30    "test.data_layout_query"() : () -> !llvm.ptr<i8, 3>
31    // CHECK: alignment = 8
32    // CHECK: bitsize = 64
33    // CHECK: preferred = 8
34    // CHECK: size = 8
35    "test.data_layout_query"() : () -> !llvm.ptr<i8, 5>
36    // CHECK: alignment = 8
37	// CHECK: bitsize = 64
38    // CHECK: preferred = 8
39    // CHECK: size = 8
40    "test.data_layout_query"() : () -> !llvm.ptr<5>
41    return
42  }
43}
44
45// -----
46
47module attributes { dlti.dl_spec = #dlti.dl_spec<
48  #dlti.dl_entry<!llvm.ptr<i8>, dense<[32, 32, 64]> : vector<3xi32>>,
49  #dlti.dl_entry<!llvm.ptr<i8, 5>, dense<[64, 64, 64]> : vector<3xi32>>,
50  #dlti.dl_entry<!llvm.ptr<4>, dense<[32, 64, 64]> : vector<3xi32>>
51>} {
52  // CHECK: @spec
53  func.func @spec() {
54    // CHECK: alignment = 4
55    // CHECK: bitsize = 32
56    // CHECK: preferred = 8
57    // CHECK: size = 4
58    "test.data_layout_query"() : () -> !llvm.ptr<i8>
59    // CHECK: alignment = 4
60    // CHECK: bitsize = 32
61    // CHECK: preferred = 8
62    // CHECK: size = 4
63    "test.data_layout_query"() : () -> !llvm.ptr<i32>
64    // CHECK: alignment = 4
65    // CHECK: bitsize = 32
66    // CHECK: preferred = 8
67    // CHECK: size = 4
68    "test.data_layout_query"() : () -> !llvm.ptr<bf16>
69    // CHECK: alignment = 4
70    // CHECK: bitsize = 32
71    // CHECK: preferred = 8
72    // CHECK: size = 4
73    "test.data_layout_query"() : () -> !llvm.ptr<!llvm.ptr<i8>>
74    // CHECK: alignment = 4
75    // CHECK: bitsize = 32
76    // CHECK: preferred = 8
77    // CHECK: size = 4
78    "test.data_layout_query"() : () -> !llvm.ptr<i8, 3>
79    // CHECK: alignment = 8
80    // CHECK: bitsize = 64
81    // CHECK: preferred = 8
82    // CHECK: size = 8
83    "test.data_layout_query"() : () -> !llvm.ptr<i8, 5>
84    // CHECK: alignment = 4
85	// CHECK: bitsize = 32
86    // CHECK: preferred = 8
87    // CHECK: size = 4
88    "test.data_layout_query"() : () -> !llvm.ptr<3>
89    // CHECK: alignment = 8
90	// CHECK: bitsize = 32
91    // CHECK: preferred = 8
92    // CHECK: size = 4
93	"test.data_layout_query"() : () -> !llvm.ptr<4>
94    return
95  }
96}
97
98// -----
99
100// expected-error@below {{unexpected layout attribute for pointer to 'i32'}}
101module attributes { dlti.dl_spec = #dlti.dl_spec<
102  #dlti.dl_entry<!llvm.ptr<i32>, dense<[64, 64, 64]> : vector<3xi32>>
103>} {
104  func.func @pointer() {
105    return
106  }
107}
108
109// -----
110
111// expected-error@below {{expected layout attribute for '!llvm.ptr<i8>' to be a dense integer elements attribute with 3 or 4 elements}}
112module attributes { dlti.dl_spec = #dlti.dl_spec<
113  #dlti.dl_entry<!llvm.ptr<i8>, dense<[64.0, 64.0, 64.0]> : vector<3xf32>>
114>} {
115  func.func @pointer() {
116    return
117  }
118}
119
120// -----
121
122// expected-error@below {{preferred alignment is expected to be at least as large as ABI alignment}}
123module attributes { dlti.dl_spec = #dlti.dl_spec<
124  #dlti.dl_entry<!llvm.ptr<i8>, dense<[64, 64, 32]> : vector<3xi32>>
125>} {
126  func.func @pointer() {
127    return
128  }
129}
130
131// -----
132
133module {
134    // CHECK: @no_spec
135    func.func @no_spec() {
136        // simple case
137        // CHECK: alignment = 4
138        // CHECK: bitsize = 32
139        // CHECK: preferred = 4
140        // CHECK: size = 4
141        "test.data_layout_query"() : () -> !llvm.struct<(i32)>
142
143        // padding inbetween
144        // CHECK: alignment = 8
145        // CHECK: bitsize = 128
146        // CHECK: preferred = 8
147        // CHECK: size = 16
148        "test.data_layout_query"() : () -> !llvm.struct<(i32, f64)>
149
150        // padding at end of struct
151        // CHECK: alignment = 8
152        // CHECK: bitsize = 128
153        // CHECK: preferred = 8
154        // CHECK: size = 16
155        "test.data_layout_query"() : () -> !llvm.struct<(f64, i32)>
156
157         // packed
158         // CHECK: alignment = 1
159         // CHECK: bitsize = 96
160         // CHECK: preferred = 8
161         // CHECK: size = 12
162         "test.data_layout_query"() : () -> !llvm.struct<packed (f64, i32)>
163
164         // empty
165         // CHECK: alignment = 1
166         // CHECK: bitsize = 0
167         // CHECK: preferred = 1
168         // CHECK: size = 0
169         "test.data_layout_query"() : () -> !llvm.struct<()>
170         return
171    }
172}
173
174// -----
175
176module attributes { dlti.dl_spec = #dlti.dl_spec<
177  #dlti.dl_entry<!llvm.struct<()>, dense<[32, 32]> : vector<2xi32>>
178>} {
179    // CHECK: @spec
180    func.func @spec() {
181        // Strict alignment is applied
182        // CHECK: alignment = 4
183        // CHECK: bitsize = 16
184        // CHECK: preferred = 4
185        // CHECK: size = 2
186        "test.data_layout_query"() : () -> !llvm.struct<(i16)>
187
188        // No impact on structs that have stricter requirements
189        // CHECK: alignment = 8
190        // CHECK: bitsize = 128
191        // CHECK: preferred = 8
192        // CHECK: size = 16
193        "test.data_layout_query"() : () -> !llvm.struct<(i32, f64)>
194
195         // Only the preferred alignment of structs is affected
196         // CHECK: alignment = 1
197         // CHECK: bitsize = 32
198         // CHECK: preferred = 4
199         // CHECK: size = 4
200         "test.data_layout_query"() : () -> !llvm.struct<packed (i16, i16)>
201
202         // empty
203         // CHECK: alignment = 4
204         // CHECK: bitsize = 0
205         // CHECK: preferred = 4
206         // CHECK: size = 0
207         "test.data_layout_query"() : () -> !llvm.struct<()>
208         return
209    }
210}
211
212// -----
213
214module attributes { dlti.dl_spec = #dlti.dl_spec<
215  #dlti.dl_entry<!llvm.struct<()>, dense<[32]> : vector<1xi32>>
216>} {
217    // CHECK: @spec_without_preferred
218    func.func @spec_without_preferred() {
219        // abi alignment is applied to both preferred and abi
220        // CHECK: alignment = 4
221        // CHECK: bitsize = 16
222        // CHECK: preferred = 4
223        // CHECK: size = 2
224        "test.data_layout_query"() : () -> !llvm.struct<(i16)>
225        return
226    }
227}
228
229// -----
230
231// expected-error@below {{unexpected layout attribute for struct '!llvm.struct<(i8)>'}}
232module attributes { dlti.dl_spec = #dlti.dl_spec<
233  #dlti.dl_entry<!llvm.struct<(i8)>, dense<[64, 64]> : vector<2xi32>>
234>} {
235  func.func @struct() {
236    return
237  }
238}
239
240// -----
241
242// expected-error@below {{expected layout attribute for '!llvm.struct<()>' to be a dense integer elements attribute of 1 or 2 elements}}
243module attributes { dlti.dl_spec = #dlti.dl_spec<
244  #dlti.dl_entry<!llvm.struct<()>, dense<[64, 64, 64]> : vector<3xi32>>
245>} {
246  func.func @struct() {
247    return
248  }
249}
250
251// -----
252
253// expected-error@below {{preferred alignment is expected to be at least as large as ABI alignment}}
254module attributes { dlti.dl_spec = #dlti.dl_spec<
255  #dlti.dl_entry<!llvm.struct<()>, dense<[64, 32]> : vector<2xi32>>
256>} {
257  func.func @struct() {
258    return
259  }
260}
261
262// -----
263
264module {
265    // CHECK: @arrays
266    func.func @arrays() {
267        // simple case
268        // CHECK: alignment = 4
269        // CHECK: bitsize = 64
270        // CHECK: preferred = 4
271        // CHECK: size = 8
272        "test.data_layout_query"() : () -> !llvm.array<2 x i32>
273
274        // size 0
275        // CHECK: alignment = 8
276        // CHECK: bitsize = 0
277        // CHECK: preferred = 8
278        // CHECK: size = 0
279        "test.data_layout_query"() : () -> !llvm.array<0 x f64>
280
281        // alignment info matches element type
282        // CHECK: alignment = 4
283        // CHECK: bitsize = 64
284        // CHECK: preferred = 8
285        // CHECK: size = 8
286        "test.data_layout_query"() : () -> !llvm.array<1 x i64>
287        return
288    }
289}
290
291// -----
292
293module attributes { dlti.dl_spec = #dlti.dl_spec<
294  #dlti.dl_entry<!llvm.struct<()>, dense<[64]> : vector<1xi32>>
295>} {
296    // CHECK: @overaligned
297    func.func @overaligned() {
298        // Over aligned element types are respected
299        // CHECK: alignment = 8
300        // CHECK: bitsize = 128
301        // CHECK: preferred = 8
302        // CHECK: size = 16
303        "test.data_layout_query"() : () -> !llvm.array<2 x struct<(i8)>>
304         return
305    }
306}
307