Fix GCC build problem with 288f05f related to SmallVector. (#116958)
[llvm-project.git] / mlir / test / Conversion / FuncToSPIRV / types-to-spirv.mlir
blob82d750755ffe2e83a3a797db66f1dc4e3da9bc57
1 // RUN: mlir-opt -split-input-file -convert-func-to-spirv %s -o - | FileCheck %s
2 // RUN: mlir-opt -split-input-file -convert-func-to-spirv="emulate-lt-32-bit-scalar-types=false" %s | \
3 // RUN:   FileCheck %s --check-prefix=NOEMU
5 //===----------------------------------------------------------------------===//
6 // Integer types
7 //===----------------------------------------------------------------------===//
9 // Check that non-32-bit integer types are converted to 32-bit types if the
10 // corresponding capabilities are not available.
11 module attributes {
12   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
13 } {
15 // CHECK-LABEL: spirv.func @integer8
16 // CHECK-SAME: i32
17 // CHECK-SAME: si32
18 // CHECK-SAME: ui32
19 // NOEMU-LABEL: func.func @integer8
20 // NOEMU-SAME: i8
21 // NOEMU-SAME: si8
22 // NOEMU-SAME: ui8
23 func.func @integer8(%arg0: i8, %arg1: si8, %arg2: ui8) { return }
25 // CHECK-LABEL: spirv.func @integer16
26 // CHECK-SAME: i32
27 // CHECK-SAME: si32
28 // CHECK-SAME: ui32
29 // NOEMU-LABEL: func.func @integer16
30 // NOEMU-SAME: i16
31 // NOEMU-SAME: si16
32 // NOEMU-SAME: ui16
33 func.func @integer16(%arg0: i16, %arg1: si16, %arg2: ui16) { return }
35 // We do not truncate 64-bit types to 32-bit ones.
36 // CHECK-LABEL: func.func @integer64
37 // CHECK-SAME: i64
38 // CHECK-SAME: si64
39 // CHECK-SAME: ui64
40 // NOEMU-LABEL: func.func @integer64
41 // NOEMU-SAME: i64
42 // NOEMU-SAME: si64
43 // NOEMU-SAME: ui64
44 func.func @integer64(%arg0: i64, %arg1: si64, %arg2: ui64) { return }
46 // i128 is not supported by SPIR-V.
47 // CHECK-LABEL: func.func @integer128
48 // CHECK-SAME: i128
49 // NOEMU-LABEL: func.func @integer128
50 // NOEMU-SAME: i128
51 func.func @integer128(%arg0: i128) { return }
53 } // end module
55 // -----
57 // Check that non-32-bit integer types are kept untouched if the corresponding
58 // capabilities are available.
59 module attributes {
60   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Int8, Int16, Int64], []>, #spirv.resource_limits<>>
61 } {
63 // CHECK-LABEL: spirv.func @integer8
64 // CHECK-SAME: i8
65 // CHECK-SAME: si8
66 // CHECK-SAME: ui8
67 // NOEMU-LABEL: spirv.func @integer8
68 // NOEMU-SAME: i8
69 // NOEMU-SAME: si8
70 // NOEMU-SAME: ui8
71 func.func @integer8(%arg0: i8, %arg1: si8, %arg2: ui8) { return }
73 // CHECK-LABEL: spirv.func @integer16
74 // CHECK-SAME: i16
75 // CHECK-SAME: si16
76 // CHECK-SAME: ui16
77 // NOEMU-LABEL: spirv.func @integer16
78 // NOEMU-SAME: i16
79 // NOEMU-SAME: si16
80 // NOEMU-SAME: ui16
81 func.func @integer16(%arg0: i16, %arg1: si16, %arg2: ui16) { return }
83 // CHECK-LABEL: spirv.func @integer64
84 // CHECK-SAME: i64
85 // CHECK-SAME: si64
86 // CHECK-SAME: ui64
87 // NOEMU-LABEL: spirv.func @integer64
88 // NOEMU-SAME: i64
89 // NOEMU-SAME: si64
90 // NOEMU-SAME: ui64
91 func.func @integer64(%arg0: i64, %arg1: si64, %arg2: ui64) { return }
93 } // end module
95 // -----
97 // Check that power-of-two sub-byte bitwidths are converted to i32.
98 module attributes {
99   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
100 } {
102 // CHECK: spirv.func @integer2(%{{.+}}: i32)
103 func.func @integer2(%arg0: i8) { return }
105 // CHECK: spirv.func @integer4(%{{.+}}: i32)
106 func.func @integer4(%arg0: i4) { return }
108 // CHECK: spirv.func @v3i4(%{{.+}}: vector<3xi32>)
109 func.func @v3i4(%arg0: vector<3xi4>) { return }
111 } // end module
113 // -----
115 // Check that other bitwidths are not supported.
116 module attributes {
117   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
118 } {
120 // CHECK-NOT: spirv.func @integer3
121 func.func @integer3(%arg0: i3) { return }
123 // CHECK-NOT: spirv.func @integer13
124 func.func @integer4(%arg0: i13) { return }
126 // CHECK-NOT: spirv.func @integer128
127 func.func @integer128(%arg0: i128) { return }
129 // CHECK-NOT: spirv.func @integer42
130 func.func @integer42(%arg0: i42) { return }
132 } // end module
134 // -----
136 //===----------------------------------------------------------------------===//
137 // Index type
138 //===----------------------------------------------------------------------===//
140 // The index type is always converted into i32 or i64, with i32 being the
141 // default.
142 module attributes {
143   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
144 } {
146 // CHECK-LABEL: spirv.func @index_type
147 // CHECK-SAME: %{{.*}}: i32
148 func.func @index_type(%arg0: index) { return }
150 } // end module
152 // -----
154 //===----------------------------------------------------------------------===//
155 // Float types
156 //===----------------------------------------------------------------------===//
158 // Check that non-32-bit float types are converted to 32-bit types if the
159 // corresponding capabilities are not available.
160 module attributes {
161   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
162 } {
164 // CHECK-LABEL: spirv.func @float16
165 // CHECK-SAME: f32
166 // NOEMU-LABEL: func.func @float16
167 // NOEMU-SAME: f16
168 func.func @float16(%arg0: f16) { return }
170 // CHECK-LABEL: func.func @float64
171 // CHECK-SAME: f64
172 // NOEMU-LABEL: func.func @float64
173 // NOEMU-SAME: f64
174 func.func @float64(%arg0: f64) { return }
176 // f80 is not supported by SPIR-V.
177 // CHECK-LABEL: func.func @float80
178 // CHECK-SAME: f80
179 // NOEMU-LABEL: func.func @float80
180 // NOEMU-SAME: f80
181 func.func @float80(%arg0: f80) { return }
183 } // end module
185 // -----
187 // Check that non-32-bit float types are kept untouched if the corresponding
188 // capabilities are available.
189 module attributes {
190   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Float16, Float64], []>, #spirv.resource_limits<>>
191 } {
193 // CHECK-LABEL: spirv.func @float16
194 // CHECK-SAME: f16
195 // NOEMU-LABEL: spirv.func @float16
196 // NOEMU-SAME: f16
197 func.func @float16(%arg0: f16) { return }
199 // CHECK-LABEL: spirv.func @float64
200 // CHECK-SAME: f64
201 // NOEMU-LABEL: spirv.func @float64
202 // NOEMU-SAME: f64
203 func.func @float64(%arg0: f64) { return }
205 } // end module
207 // -----
209 // Check that bf16 is not supported.
210 module attributes {
211   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
212 } {
214 // CHECK-NOT: spirv.func @bf16_type
215 func.func @bf16_type(%arg0: bf16) { return }
217 } // end module
219 // -----
221 //===----------------------------------------------------------------------===//
222 // Complex types
223 //===----------------------------------------------------------------------===//
225 // Check that capabilities for scalar types affects complex types too: having
226 // special capabilities means keep vector types untouched.
227 module attributes {
228   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,
229     [Float64, StorageUniform16, StorageBuffer16BitAccess],
230     [SPV_KHR_16bit_storage, SPV_KHR_8bit_storage]>, #spirv.resource_limits<>>
231 } {
233 // CHECK-LABEL: func @complex_types
234 // CHECK-SAME: vector<2xf32>
235 // CHECK-SAME: vector<2xf64>
236 func.func @complex_types(
237     %arg0: complex<f32>,
238     %arg2: complex<f64>
239 ) { return }
241 // CHECK-LABEL: func @memref_complex_types_with_cap
242 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x vector<2xf16>, stride=4> [0])>, StorageBuffer>
243 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x vector<2xf16>, stride=4> [0])>, Uniform>
244 func.func @memref_complex_types_with_cap(
245     %arg0: memref<4xcomplex<f16>, #spirv.storage_class<StorageBuffer>>,
246     %arg1: memref<2x8xcomplex<f16>, #spirv.storage_class<Uniform>>
247 ) { return }
249 } // end module
251 // -----
253 // Check that capabilities for scalar types affects complex types too: no special
254 // capabilities available means widening element types to 32-bit.
256 module attributes {
257   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
258 } {
260 // Emulation is unimplemented right now.
261 // CHECK-LABEL: func @memref_complex_types_no_cap
262 // CHECK-SAME: memref<4xcomplex<f16>, #spirv.storage_class<StorageBuffer>>
263 // CHECK-SAME: memref<2x8xcomplex<f16>, #spirv.storage_class<Uniform>>
264 // NOEMU-LABEL: func @memref_complex_types_no_cap
265 // NOEMU-SAME: memref<4xcomplex<f16>, #spirv.storage_class<StorageBuffer>>
266 // NOEMU-SAME: memref<2x8xcomplex<f16>, #spirv.storage_class<Uniform>>
267 func.func @memref_complex_types_no_cap(
268     %arg0: memref<4xcomplex<f16>, #spirv.storage_class<StorageBuffer>>,
269     %arg1: memref<2x8xcomplex<f16>, #spirv.storage_class<Uniform>>
270 ) { return }
272 } // end module
274 // -----
276 //===----------------------------------------------------------------------===//
277 // Vector types
278 //===----------------------------------------------------------------------===//
280 // Check that capabilities for scalar types affects vector types too: no special
281 // capabilities available means widening element types to 32-bit.
282 module attributes {
283   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
284 } {
286 // CHECK-LABEL: spirv.func @int_vector
287 // CHECK-SAME: vector<2xi32>
288 // CHECK-SAME: vector<3xsi32>
289 func.func @int_vector(
290   %arg0: vector<2xi8>,
291   %arg1: vector<3xsi16>
292 ) { return }
294 // CHECK-LABEL: spirv.func @float_vector
295 // CHECK-SAME: vector<2xf32>
296 func.func @float_vector(
297   %arg0: vector<2xf16>
298 ) { return }
300 // CHECK-LABEL: spirv.func @one_element_vector
301 // CHECK-SAME: %{{.+}}: i32
302 func.func @one_element_vector(%arg0: vector<1xi8>) { return }
304 // CHECK-LABEL: spirv.func @index_vector
305 // CHECK-SAME: %{{.*}}: vector<4xi32>
306 func.func @index_vector(%arg0: vector<4xindex>) { return }
308 } // end module
310 // -----
312 // Check that capabilities for scalar types affects vector types too: having
313 // special capabilities means keep vector types untouched.
314 module attributes {
315   spirv.target_env = #spirv.target_env<
316     #spirv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64], []>, #spirv.resource_limits<>>
317 } {
319 // CHECK-LABEL: spirv.func @int_vector
320 // CHECK-SAME: vector<2xi8>
321 // CHECK-SAME: vector<3xsi16>
322 // CHECK-SAME: vector<4xui64>
323 func.func @int_vector(
324   %arg0: vector<2xi8>,
325   %arg1: vector<3xsi16>,
326   %arg2: vector<4xui64>
327 ) { return }
329 // CHECK-LABEL: spirv.func @float_vector
330 // CHECK-SAME: vector<2xf16>
331 // CHECK-SAME: vector<3xf64>
332 func.func @float_vector(
333   %arg0: vector<2xf16>,
334   %arg1: vector<3xf64>
335 ) { return }
337 // CHECK-LABEL: spirv.func @one_element_vector
338 // CHECK-SAME: %{{.+}}: i32
339 func.func @one_element_vector(%arg0: vector<1xi32>) { return }
341 // CHECK-LABEL: spirv.func @zerod_vector
342 //  CHECK-SAME: %{{.+}}: f32
343 func.func @zerod_vector(%arg0: vector<f32>) { return }
345 } // end module
347 // -----
349 // Check that > 4-element vectors are not supported.
350 module attributes {
351   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
352 } {
354 // CHECK-NOT: spirv.func @large_vector
355 func.func @large_vector(%arg0: vector<1024xi32>) { return }
357 } // end module
359 // -----
361 //===----------------------------------------------------------------------===//
362 // MemRef types
363 //===----------------------------------------------------------------------===//
365 // Check memory spaces.
366 module attributes {
367   spirv.target_env = #spirv.target_env<
368     #spirv.vce<v1.0, [], [SPV_KHR_storage_buffer_storage_class]>, #spirv.resource_limits<>>
369 } {
371 // CHECK-LABEL: func @memref_mem_space
372 // CHECK-SAME: StorageBuffer
373 // CHECK-SAME: Uniform
374 // CHECK-SAME: Workgroup
375 // CHECK-SAME: PushConstant
376 // CHECK-SAME: Private
377 // CHECK-SAME: Function
378 func.func @memref_mem_space(
379     %arg0: memref<4xf32, #spirv.storage_class<StorageBuffer>>,
380     %arg1: memref<4xf32, #spirv.storage_class<Uniform>>,
381     %arg2: memref<4xf32, #spirv.storage_class<Workgroup>>,
382     %arg3: memref<4xf32, #spirv.storage_class<PushConstant>>,
383     %arg4: memref<4xf32, #spirv.storage_class<Private>>,
384     %arg5: memref<4xf32, #spirv.storage_class<Function>>
385 ) { return }
387 // CHECK-LABEL: func @memref_1bit_type
388 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x i32, stride=4> [0])>, StorageBuffer>
389 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x i32>)>, Function>
390 // NOEMU-LABEL: func @memref_1bit_type
391 // NOEMU-SAME: memref<4x8xi1, #spirv.storage_class<StorageBuffer>>
392 // NOEMU-SAME: memref<4x8xi1, #spirv.storage_class<Function>>
393 func.func @memref_1bit_type(
394     %arg0: memref<4x8xi1, #spirv.storage_class<StorageBuffer>>,
395     %arg1: memref<4x8xi1, #spirv.storage_class<Function>>
396 ) { return }
398 // CHECK-LABEL: func @memref_index_type
399 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x i32, stride=4> [0])>, StorageBuffer>
400 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x i32>)>, Function>
401 func.func @memref_index_type(
402     %arg0: memref<4xindex, #spirv.storage_class<StorageBuffer>>,
403     %arg1: memref<4xindex, #spirv.storage_class<Function>>
404 ) { return }
406 } // end module
408 // -----
410 // Reject memory spaces.
411 module attributes {
412   spirv.target_env = #spirv.target_env<
413     #spirv.vce<v1.0, [], [SPV_KHR_storage_buffer_storage_class]>, #spirv.resource_limits<>>
414 } {
416 // CHECK-LABEL: func @numeric_memref_mem_space1
417 // CHECK-SAME: memref<4xf32>
418 // NOEMU-LABEL: func @numeric_memref_mem_space1
419 // NOEMU-SAME: memref<4xf32>
420 func.func @numeric_memref_mem_space1(%arg0: memref<4xf32>) { return }
422 // CHECK-LABEL: func @numeric_memref_mem_space2
423 // CHECK-SAME: memref<4xf32, 3>
424 // NOEMU-LABEL: func @numeric_memref_mem_space2
425 // NOEMU-SAME: memref<4xf32, 3>
426 func.func @numeric_memref_mem_space2(%arg0: memref<4xf32, 3>) { return }
428 } // end module
430 // -----
432 // Check that using non-32-bit scalar types in interface storage classes
433 // requires special capability and extension: convert them to 32-bit if not
434 // satisfied.
435 module attributes {
436   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
437 } {
439 // An i1 is store in 8-bit, so 5xi1 has 40 bits, which is stored in 2xi32.
440 // CHECK-LABEL: spirv.func @memref_1bit_type
441 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<2 x i32, stride=4> [0])>, StorageBuffer>
442 // NOEMU-LABEL: func @memref_1bit_type
443 // NOEMU-SAME: memref<5xi1, #spirv.storage_class<StorageBuffer>>
444 func.func @memref_1bit_type(%arg0: memref<5xi1, #spirv.storage_class<StorageBuffer>>) { return }
446 // 16 i2 values are tightly packed into one i32 value; so 33 i2 values takes 3 i32 value.
447 // CHECK-LABEL: spirv.func @memref_2bit_type
448 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<3 x i32, stride=4> [0])>, StorageBuffer>
449 func.func @memref_2bit_type(%arg0: memref<33xi2, #spirv.storage_class<StorageBuffer>>) { return }
451 // 8 i4 values are tightly packed into one i32 value; so 16 i4 values takes 2 i32 value.
452 // CHECK-LABEL: spirv.func @memref_4bit_type
453 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<2 x i32, stride=4> [0])>, StorageBuffer>
454 func.func @memref_4bit_type(%arg0: memref<16xi4, #spirv.storage_class<StorageBuffer>>) { return }
456 // CHECK-LABEL: spirv.func @memref_8bit_StorageBuffer
457 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x i32, stride=4> [0])>, StorageBuffer>
458 // NOEMU-LABEL: func @memref_8bit_StorageBuffer
459 // NOEMU-SAME: memref<16xi8, #spirv.storage_class<StorageBuffer>>
460 func.func @memref_8bit_StorageBuffer(%arg0: memref<16xi8, #spirv.storage_class<StorageBuffer>>) { return }
462 // CHECK-LABEL: spirv.func @memref_8bit_Uniform
463 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x si32, stride=4> [0])>, Uniform>
464 // NOEMU-LABEL: func @memref_8bit_Uniform
465 // NOEMU-SAME: memref<16xsi8, #spirv.storage_class<Uniform>>
466 func.func @memref_8bit_Uniform(%arg0: memref<16xsi8, #spirv.storage_class<Uniform>>) { return }
468 // CHECK-LABEL: spirv.func @memref_8bit_PushConstant
469 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x ui32, stride=4> [0])>, PushConstant>
470 // NOEMU-LABEL: func @memref_8bit_PushConstant
471 // NOEMU-SAME: memref<16xui8, #spirv.storage_class<PushConstant>>
472 func.func @memref_8bit_PushConstant(%arg0: memref<16xui8, #spirv.storage_class<PushConstant>>) { return }
474 // CHECK-LABEL: spirv.func @memref_16bit_StorageBuffer
475 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x i32, stride=4> [0])>, StorageBuffer>
476 // NOEMU-LABEL: func @memref_16bit_StorageBuffer
477 // NOEMU-SAME: memref<16xi16, #spirv.storage_class<StorageBuffer>>
478 func.func @memref_16bit_StorageBuffer(%arg0: memref<16xi16, #spirv.storage_class<StorageBuffer>>) { return }
480 // CHECK-LABEL: spirv.func @memref_16bit_Uniform
481 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x si32, stride=4> [0])>, Uniform>
482 // NOEMU-LABEL: func @memref_16bit_Uniform
483 // NOEMU-SAME: memref<16xsi16, #spirv.storage_class<Uniform>>
484 func.func @memref_16bit_Uniform(%arg0: memref<16xsi16, #spirv.storage_class<Uniform>>) { return }
486 // CHECK-LABEL: spirv.func @memref_16bit_PushConstant
487 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x ui32, stride=4> [0])>, PushConstant>
488 // NOEMU-LABEL: func @memref_16bit_PushConstant
489 // NOEMU-SAME: memref<16xui16, #spirv.storage_class<PushConstant>>
490 func.func @memref_16bit_PushConstant(%arg0: memref<16xui16, #spirv.storage_class<PushConstant>>) { return }
492 // CHECK-LABEL: spirv.func @memref_16bit_Input
493 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x f32>)>, Input>
494 // NOEMU-LABEL: func @memref_16bit_Input
495 // NOEMU-SAME: memref<16xf16, #spirv.storage_class<Input>>
496 func.func @memref_16bit_Input(%arg3: memref<16xf16, #spirv.storage_class<Input>>) { return }
498 // CHECK-LABEL: spirv.func @memref_16bit_Output
499 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<8 x f32>)>, Output>
500 // NOEMU-LABEL: func @memref_16bit_Output
501 // NOEMU-SAME: memref<16xf16, #spirv.storage_class<Output>>
502 func.func @memref_16bit_Output(%arg4: memref<16xf16, #spirv.storage_class<Output>>) { return }
504 // We do not truncate i64 to i32.
506 // CHECK-LABEL: func.func @memref_64bit_StorageBuffer
507 // CHECK-SAME: memref<16xi64, #spirv.storage_class<StorageBuffer>>
508 // NOEMU-LABEL: func.func @memref_64bit_StorageBuffer
509 // NOEMU-SAME: memref<16xi64, #spirv.storage_class<StorageBuffer>>
510 func.func @memref_64bit_StorageBuffer(%arg0: memref<16xi64, #spirv.storage_class<StorageBuffer>>) { return }
512 // CHECK-LABEL: func.func @memref_64bit_Uniform
513 // CHECK-SAME: memref<16xsi64, #spirv.storage_class<Uniform>>
514 // NOEMU-LABEL: func.func @memref_64bit_Uniform
515 // NOEMU-SAME: memref<16xsi64, #spirv.storage_class<Uniform>>
516 func.func @memref_64bit_Uniform(%arg0: memref<16xsi64, #spirv.storage_class<Uniform>>) { return }
518 // CHECK-LABEL: func.func @memref_64bit_PushConstant
519 // CHECK-SAME: memref<16xui64, #spirv.storage_class<PushConstant>>
520 // NOEMU-LABEL: func.func @memref_64bit_PushConstant
521 // NOEMU-SAME: memref<16xui64, #spirv.storage_class<PushConstant>>
522 func.func @memref_64bit_PushConstant(%arg0: memref<16xui64, #spirv.storage_class<PushConstant>>) { return }
524 // CHECK-LABEL: func.func @memref_64bit_Input
525 // CHECK-SAME: memref<16xf64, #spirv.storage_class<Input>>
526 // NOEMU-LABEL: func.func @memref_64bit_Input
527 // NOEMU-SAME: memref<16xf64, #spirv.storage_class<Input>>
528 func.func @memref_64bit_Input(%arg3: memref<16xf64, #spirv.storage_class<Input>>) { return }
530 // CHECK-LABEL: func.func @memref_64bit_Output
531 // CHECK-SAME: memref<16xf64, #spirv.storage_class<Output>>
532 // NOEMU-LABEL: func.func @memref_64bit_Output
533 // NOEMU-SAME: memref<16xf64, #spirv.storage_class<Output>>
534 func.func @memref_64bit_Output(%arg4: memref<16xf64, #spirv.storage_class<Output>>) { return }
536 } // end module
538 // -----
540 // Check that using non-32-bit scalar types in interface storage classes
541 // requires special capability and extension: keep as-is when the capability
542 // and extension is available.
543 module attributes {
544   spirv.target_env = #spirv.target_env<
545     #spirv.vce<v1.0, [StoragePushConstant8, StoragePushConstant16, Int64, Float64],
546              [SPV_KHR_8bit_storage, SPV_KHR_16bit_storage]>, #spirv.resource_limits<>>
547 } {
549 // CHECK-LABEL: spirv.func @memref_8bit_PushConstant
550 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i8, stride=1> [0])>, PushConstant>
551 // NOEMU-LABEL: spirv.func @memref_8bit_PushConstant
552 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i8, stride=1> [0])>, PushConstant>
553 func.func @memref_8bit_PushConstant(%arg0: memref<16xi8, #spirv.storage_class<PushConstant>>) { return }
555 // CHECK-LABEL: spirv.func @memref_16bit_PushConstant
556 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16, stride=2> [0])>, PushConstant>
557 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16, stride=2> [0])>, PushConstant>
558 // NOEMU-LABEL: spirv.func @memref_16bit_PushConstant
559 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16, stride=2> [0])>, PushConstant>
560 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16, stride=2> [0])>, PushConstant>
561 func.func @memref_16bit_PushConstant(
562   %arg0: memref<16xi16, #spirv.storage_class<PushConstant>>,
563   %arg1: memref<16xf16, #spirv.storage_class<PushConstant>>
564 ) { return }
566 // CHECK-LABEL: spirv.func @memref_64bit_PushConstant
567 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64, stride=8> [0])>, PushConstant>
568 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64, stride=8> [0])>, PushConstant>
569 // NOEMU-LABEL: spirv.func @memref_64bit_PushConstant
570 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64, stride=8> [0])>, PushConstant>
571 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64, stride=8> [0])>, PushConstant>
572 func.func @memref_64bit_PushConstant(
573   %arg0: memref<16xi64, #spirv.storage_class<PushConstant>>,
574   %arg1: memref<16xf64, #spirv.storage_class<PushConstant>>
575 ) { return }
577 } // end module
579 // -----
581 // Check that using non-32-bit scalar types in interface storage classes
582 // requires special capability and extension: keep as-is when the capability
583 // and extension is available.
584 module attributes {
585   spirv.target_env = #spirv.target_env<
586     #spirv.vce<v1.0, [StorageBuffer8BitAccess, StorageBuffer16BitAccess, Int64, Float64],
587              [SPV_KHR_8bit_storage, SPV_KHR_16bit_storage]>, #spirv.resource_limits<>>
588 } {
590 // CHECK-LABEL: spirv.func @memref_8bit_StorageBuffer
591 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i8, stride=1> [0])>, StorageBuffer>
592 // NOEMU-LABEL: spirv.func @memref_8bit_StorageBuffer
593 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i8, stride=1> [0])>, StorageBuffer>
594 func.func @memref_8bit_StorageBuffer(%arg0: memref<16xi8, #spirv.storage_class<StorageBuffer>>) { return }
596 // CHECK-LABEL: spirv.func @memref_16bit_StorageBuffer
597 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16, stride=2> [0])>, StorageBuffer>
598 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16, stride=2> [0])>, StorageBuffer>
599 // NOEMU-LABEL: spirv.func @memref_16bit_StorageBuffer
600 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16, stride=2> [0])>, StorageBuffer>
601 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16, stride=2> [0])>, StorageBuffer>
602 func.func @memref_16bit_StorageBuffer(
603   %arg0: memref<16xi16, #spirv.storage_class<StorageBuffer>>,
604   %arg1: memref<16xf16, #spirv.storage_class<StorageBuffer>>
605 ) { return }
607 // CHECK-LABEL: spirv.func @memref_64bit_StorageBuffer
608 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64, stride=8> [0])>, StorageBuffer>
609 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64, stride=8> [0])>, StorageBuffer>
610 // NOEMU-LABEL: spirv.func @memref_64bit_StorageBuffer
611 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64, stride=8> [0])>, StorageBuffer>
612 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64, stride=8> [0])>, StorageBuffer>
613 func.func @memref_64bit_StorageBuffer(
614   %arg0: memref<16xi64, #spirv.storage_class<StorageBuffer>>,
615   %arg1: memref<16xf64, #spirv.storage_class<StorageBuffer>>
616 ) { return }
618 } // end module
620 // -----
622 // Check that using non-32-bit scalar types in interface storage classes
623 // requires special capability and extension: keep as-is when the capability
624 // and extension is available.
625 module attributes {
626   spirv.target_env = #spirv.target_env<
627     #spirv.vce<v1.0, [UniformAndStorageBuffer8BitAccess, StorageUniform16, Int64, Float64],
628              [SPV_KHR_8bit_storage, SPV_KHR_16bit_storage]>, #spirv.resource_limits<>>
629 } {
631 // CHECK-LABEL: spirv.func @memref_8bit_Uniform
632 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i8, stride=1> [0])>, Uniform>
633 // NOEMU-LABEL: spirv.func @memref_8bit_Uniform
634 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i8, stride=1> [0])>, Uniform>
635 func.func @memref_8bit_Uniform(%arg0: memref<16xi8, #spirv.storage_class<Uniform>>) { return }
637 // CHECK-LABEL: spirv.func @memref_16bit_Uniform
638 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16, stride=2> [0])>, Uniform>
639 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16, stride=2> [0])>, Uniform>
640 // NOEMU-LABEL: spirv.func @memref_16bit_Uniform
641 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16, stride=2> [0])>, Uniform>
642 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16, stride=2> [0])>, Uniform>
643 func.func @memref_16bit_Uniform(
644   %arg0: memref<16xi16, #spirv.storage_class<Uniform>>,
645   %arg1: memref<16xf16, #spirv.storage_class<Uniform>>
646 ) { return }
648 // CHECK-LABEL: spirv.func @memref_64bit_Uniform
649 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64, stride=8> [0])>, Uniform>
650 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64, stride=8> [0])>, Uniform>
651 // NOEMU-LABEL: spirv.func @memref_64bit_Uniform
652 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64, stride=8> [0])>, Uniform>
653 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64, stride=8> [0])>, Uniform>
654 func.func @memref_64bit_Uniform(
655   %arg0: memref<16xi64, #spirv.storage_class<Uniform>>,
656   %arg1: memref<16xf64, #spirv.storage_class<Uniform>>
657 ) { return }
659 } // end module
661 // -----
663 // Check that using non-32-bit scalar types in interface storage classes
664 // requires special capability and extension: keep as-is when the capability
665 // and extension is available.
666 module attributes {
667   spirv.target_env = #spirv.target_env<
668     #spirv.vce<v1.0, [StorageInputOutput16, Int64, Float64], [SPV_KHR_16bit_storage]>, #spirv.resource_limits<>>
669 } {
671 // CHECK-LABEL: spirv.func @memref_16bit_Input
672 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16>)>, Input>
673 // NOEMU-LABEL: spirv.func @memref_16bit_Input
674 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f16>)>, Input>
675 func.func @memref_16bit_Input(%arg3: memref<16xf16, #spirv.storage_class<Input>>) { return }
677 // CHECK-LABEL: spirv.func @memref_16bit_Output
678 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16>)>, Output>
679 // NOEMU-LABEL: spirv.func @memref_16bit_Output
680 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i16>)>, Output>
681 func.func @memref_16bit_Output(%arg4: memref<16xi16, #spirv.storage_class<Output>>) { return }
683 // CHECK-LABEL: spirv.func @memref_64bit_Input
684 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64>)>, Input>
685 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64>)>, Input>
686 // NOEMU-LABEL: spirv.func @memref_64bit_Input
687 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64>)>, Input>
688 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64>)>, Input>
689 func.func @memref_64bit_Input(
690   %arg0: memref<16xi64, #spirv.storage_class<Input>>,
691   %arg1: memref<16xf64, #spirv.storage_class<Input>>
692 ) { return }
694 // CHECK-LABEL: spirv.func @memref_64bit_Output
695 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64>)>, Output>
696 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64>)>, Output>
697 // NOEMU-LABEL: spirv.func @memref_64bit_Output
698 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x i64>)>, Output>
699 // NOEMU-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<16 x f64>)>, Output>
700 func.func @memref_64bit_Output(
701   %arg0: memref<16xi64, #spirv.storage_class<Output>>,
702   %arg1: memref<16xf64, #spirv.storage_class<Output>>
703 ) { return }
705 } // end module
707 // -----
709 // Check that memref offset and strides affect the array size.
710 module attributes {
711   spirv.target_env = #spirv.target_env<
712     #spirv.vce<v1.0, [StorageBuffer16BitAccess], [SPV_KHR_16bit_storage]>, #spirv.resource_limits<>>
713 } {
715 // CHECK-LABEL: spirv.func @memref_offset_strides
716 func.func @memref_offset_strides(
717 // CHECK-SAME: !spirv.array<64 x f32, stride=4> [0])>, StorageBuffer>
718 // CHECK-SAME: !spirv.array<72 x f32, stride=4> [0])>, StorageBuffer>
719 // CHECK-SAME: !spirv.array<256 x f32, stride=4> [0])>, StorageBuffer>
720 // CHECK-SAME: !spirv.array<64 x f32, stride=4> [0])>, StorageBuffer>
721 // CHECK-SAME: !spirv.array<88 x f32, stride=4> [0])>, StorageBuffer>
722   %arg0: memref<16x4xf32, strided<[4, 1], offset: 0>, #spirv.storage_class<StorageBuffer>>,  // tightly packed; row major
723   %arg1: memref<16x4xf32, strided<[4, 1], offset: 8>, #spirv.storage_class<StorageBuffer>>,  // offset 8
724   %arg2: memref<16x4xf32, strided<[16, 1], offset: 0>, #spirv.storage_class<StorageBuffer>>, // pad 12 after each row
725   %arg3: memref<16x4xf32, strided<[1, 16], offset: 0>, #spirv.storage_class<StorageBuffer>>, // tightly packed; col major
726   %arg4: memref<16x4xf32, strided<[1, 22], offset: 0>, #spirv.storage_class<StorageBuffer>>, // pad 4 after each col
728 // CHECK-SAME: !spirv.array<64 x f16, stride=2> [0])>, StorageBuffer>
729 // CHECK-SAME: !spirv.array<72 x f16, stride=2> [0])>, StorageBuffer>
730 // CHECK-SAME: !spirv.array<256 x f16, stride=2> [0])>, StorageBuffer>
731 // CHECK-SAME: !spirv.array<64 x f16, stride=2> [0])>, StorageBuffer>
732 // CHECK-SAME: !spirv.array<88 x f16, stride=2> [0])>, StorageBuffer>
733   %arg5: memref<16x4xf16, strided<[4, 1], offset: 0>, #spirv.storage_class<StorageBuffer>>,
734   %arg6: memref<16x4xf16, strided<[4, 1], offset: 8>, #spirv.storage_class<StorageBuffer>>,
735   %arg7: memref<16x4xf16, strided<[16, 1], offset: 0>, #spirv.storage_class<StorageBuffer>>,
736   %arg8: memref<16x4xf16, strided<[1, 16], offset: 0>, #spirv.storage_class<StorageBuffer>>,
737   %arg9: memref<16x4xf16, strided<[1, 22], offset: 0>, #spirv.storage_class<StorageBuffer>>
738 ) { return }
740 } // end module
742 // -----
744 // Dynamic shapes
745 module attributes {
746   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
747 } {
749 // Check that unranked shapes are not supported.
750 // CHECK-LABEL: func @unranked_memref
751 // CHECK-SAME: memref<*xi32>
752 func.func @unranked_memref(%arg0: memref<*xi32>) { return }
754 // CHECK-LABEL: func @memref_1bit_type
755 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>
756 // NOEMU-LABEL: func @memref_1bit_type
757 // NOEMU-SAME: memref<?xi1, #spirv.storage_class<StorageBuffer>>
758 func.func @memref_1bit_type(%arg0: memref<?xi1, #spirv.storage_class<StorageBuffer>>) { return }
760 // CHECK-LABEL: spirv.func @memref_2bit_type
761 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>
762 func.func @memref_2bit_type(%arg0: memref<?xi2, #spirv.storage_class<StorageBuffer>>) { return }
764 // CHECK-LABEL: spirv.func @memref_4bit_type
765 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>
766 func.func @memref_4bit_type(%arg0: memref<?xi4, #spirv.storage_class<StorageBuffer>>) { return }
768 // CHECK-LABEL: func @dynamic_dim_memref
769 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>
770 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>
771 func.func @dynamic_dim_memref(
772     %arg0: memref<8x?xi32, #spirv.storage_class<StorageBuffer>>,
773     %arg1: memref<?x?xf32, #spirv.storage_class<StorageBuffer>>) { return }
775 // Check that using non-32-bit scalar types in interface storage classes
776 // requires special capability and extension: convert them to 32-bit if not
777 // satisfied.
779 // CHECK-LABEL: spirv.func @memref_8bit_StorageBuffer
780 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>
781 // NOEMU-LABEL: func @memref_8bit_StorageBuffer
782 // NOEMU-SAME: memref<?xi8, #spirv.storage_class<StorageBuffer>>
783 func.func @memref_8bit_StorageBuffer(%arg0: memref<?xi8, #spirv.storage_class<StorageBuffer>>) { return }
785 // CHECK-LABEL: spirv.func @memref_8bit_Uniform
786 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<si32, stride=4> [0])>, Uniform>
787 // NOEMU-LABEL: func @memref_8bit_Uniform
788 // NOEMU-SAME: memref<?xsi8, #spirv.storage_class<Uniform>>
789 func.func @memref_8bit_Uniform(%arg0: memref<?xsi8, #spirv.storage_class<Uniform>>) { return }
791 // CHECK-LABEL: spirv.func @memref_8bit_PushConstant
792 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<ui32, stride=4> [0])>, PushConstant>
793 // NOEMU-LABEL: func @memref_8bit_PushConstant
794 // NOEMU-SAME: memref<?xui8, #spirv.storage_class<PushConstant>>
795 func.func @memref_8bit_PushConstant(%arg0: memref<?xui8, #spirv.storage_class<PushConstant>>) { return }
797 // CHECK-LABEL: spirv.func @memref_16bit_StorageBuffer
798 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>
799 // NOEMU-LABEL: func @memref_16bit_StorageBuffer
800 // NOEMU-SAME: memref<?xi16, #spirv.storage_class<StorageBuffer>>
801 func.func @memref_16bit_StorageBuffer(%arg0: memref<?xi16, #spirv.storage_class<StorageBuffer>>) { return }
803 // CHECK-LABEL: spirv.func @memref_16bit_Uniform
804 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<si32, stride=4> [0])>, Uniform>
805 // NOEMU-LABEL: func @memref_16bit_Uniform
806 // NOEMU-SAME: memref<?xsi16, #spirv.storage_class<Uniform>>
807 func.func @memref_16bit_Uniform(%arg0: memref<?xsi16, #spirv.storage_class<Uniform>>) { return }
809 // CHECK-LABEL: spirv.func @memref_16bit_PushConstant
810 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<ui32, stride=4> [0])>, PushConstant>
811 // NOEMU-LABEL: func @memref_16bit_PushConstant
812 // NOEMU-SAME: memref<?xui16, #spirv.storage_class<PushConstant>>
813 func.func @memref_16bit_PushConstant(%arg0: memref<?xui16, #spirv.storage_class<PushConstant>>) { return }
815 // CHECK-LABEL: spirv.func @memref_16bit_Input
816 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32>)>, Input>
817 // NOEMU-LABEL: func @memref_16bit_Input
818 // NOEMU-SAME: memref<?xf16, #spirv.storage_class<Input>>
819 func.func @memref_16bit_Input(%arg3: memref<?xf16, #spirv.storage_class<Input>>) { return }
821 // CHECK-LABEL: spirv.func @memref_16bit_Output
822 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32>)>, Output>
823 // NOEMU-LABEL: func @memref_16bit_Output
824 // NOEMU-SAME: memref<?xf16, #spirv.storage_class<Output>>
825 func.func @memref_16bit_Output(%arg4: memref<?xf16, #spirv.storage_class<Output>>) { return }
827 } // end module
829 // -----
831 // Vector types
832 module attributes {
833   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
834 } {
836 // CHECK-LABEL: func @memref_vector
837 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x vector<2xf32>, stride=8> [0])>, StorageBuffer>
838 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.array<4 x vector<4xf32>, stride=16> [0])>, Uniform>
839 func.func @memref_vector(
840     %arg0: memref<4xvector<2xf32>, #spirv.storage_class<StorageBuffer>>,
841     %arg1: memref<4xvector<4xf32>, #spirv.storage_class<Uniform>>)
842 { return }
844 // CHECK-LABEL: func @dynamic_dim_memref_vector
845 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xi32>, stride=16> [0])>, StorageBuffer>
846 // CHECK-SAME: !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer>
847 func.func @dynamic_dim_memref_vector(
848     %arg0: memref<8x?xvector<4xi32>, #spirv.storage_class<StorageBuffer>>,
849     %arg1: memref<?x?xvector<2xf32>, #spirv.storage_class<StorageBuffer>>)
850 { return }
852 } // end module
854 // -----
856 // Vector types, check that sizes not available in SPIR-V are not transformed.
857 module attributes {
858   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
859 } {
861 // CHECK-LABEL: func @memref_vector_wrong_size
862 // CHECK-SAME: memref<4xvector<5xf32>, #spirv.storage_class<StorageBuffer>>
863 func.func @memref_vector_wrong_size(
864     %arg0: memref<4xvector<5xf32>, #spirv.storage_class<StorageBuffer>>)
865 { return }
867 } // end module
869 // -----
871 //===----------------------------------------------------------------------===//
872 // Tensor types
873 //===----------------------------------------------------------------------===//
875 // Check that tensor element types are kept untouched with proper capabilities.
876 module attributes {
877   spirv.target_env = #spirv.target_env<
878     #spirv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64], []>, #spirv.resource_limits<>>
879 } {
881 // CHECK-LABEL: spirv.func @int_tensor_types
882 // CHECK-SAME: !spirv.array<32 x i64>
883 // CHECK-SAME: !spirv.array<32 x i32>
884 // CHECK-SAME: !spirv.array<32 x i16>
885 // CHECK-SAME: !spirv.array<32 x i8>
886 func.func @int_tensor_types(
887   %arg0: tensor<8x4xi64>,
888   %arg1: tensor<8x4xi32>,
889   %arg2: tensor<8x4xi16>,
890   %arg3: tensor<8x4xi8>
891 ) { return }
893 // CHECK-LABEL: spirv.func @float_tensor_types
894 // CHECK-SAME: !spirv.array<32 x f64>
895 // CHECK-SAME: !spirv.array<32 x f32>
896 // CHECK-SAME: !spirv.array<32 x f16>
897 func.func @float_tensor_types(
898   %arg0: tensor<8x4xf64>,
899   %arg1: tensor<8x4xf32>,
900   %arg2: tensor<8x4xf16>
901 ) { return }
903 } // end module
905 // -----
907 // Check that tensor element types are changed to 32-bit without capabilities.
908 module attributes {
909   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
910 } {
912 // CHECK-LABEL: spirv.func @int_tensor_types
913 // CHECK-SAME: !spirv.array<32 x i32>
914 // CHECK-SAME: !spirv.array<32 x i32>
915 // CHECK-SAME: !spirv.array<32 x i32>
916 func.func @int_tensor_types(
917   %arg1: tensor<8x4xi32>,
918   %arg2: tensor<8x4xi16>,
919   %arg3: tensor<8x4xi8>
920 ) { return }
922 // CHECK-LABEL: spirv.func @float_tensor_types
923 // CHECK-SAME: !spirv.array<32 x f32>
924 // CHECK-SAME: !spirv.array<32 x f32>
925 func.func @float_tensor_types(
926   %arg1: tensor<8x4xf32>,
927   %arg2: tensor<8x4xf16>
928 ) { return }
931 // CHECK-LABEL: spirv.func @index_tensor_type
932 // CHECK-SAME: %{{.*}}: !spirv.array<20 x i32>
933 func.func @index_tensor_type(%arg0: tensor<4x5xindex>) { return }
935 } // end module
937 // -----
939 // Check that dynamic shapes are not supported.
940 module attributes {
941   spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [], []>, #spirv.resource_limits<>>
942 } {
944 // CHECK-LABEL: func @unranked_tensor
945 // CHECK-SAME: tensor<*xi32>
946 func.func @unranked_tensor(%arg0: tensor<*xi32>) { return }
948 // CHECK-LABEL: func @dynamic_dim_tensor
949 // CHECK-SAME: tensor<8x?xi32>
950 func.func @dynamic_dim_tensor(%arg0: tensor<8x?xi32>) { return }
952 } // end module