1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
2
3//===----------------------------------------------------------------------===//
4// spv.CompositeConstruct
5//===----------------------------------------------------------------------===//
6
7func @composite_construct_vector(%arg0: f32, %arg1: f32, %arg2 : f32) -> vector<3xf32> {
8  // CHECK: spv.CompositeConstruct {{%.*}}, {{%.*}}, {{%.*}} : vector<3xf32>
9  %0 = spv.CompositeConstruct %arg0, %arg1, %arg2 : vector<3xf32>
10  return %0: vector<3xf32>
11}
12
13// -----
14
15func @composite_construct_struct(%arg0: vector<3xf32>, %arg1: !spv.array<4xf32>, %arg2 : !spv.struct<(f32)>) -> !spv.struct<(vector<3xf32>, !spv.array<4xf32>, !spv.struct<(f32)>)> {
16  // CHECK: spv.CompositeConstruct %arg0, %arg1, %arg2 : !spv.struct<(vector<3xf32>, !spv.array<4 x f32>, !spv.struct<(f32)>)>
17  %0 = spv.CompositeConstruct %arg0, %arg1, %arg2 : !spv.struct<(vector<3xf32>, !spv.array<4xf32>, !spv.struct<(f32)>)>
18  return %0: !spv.struct<(vector<3xf32>, !spv.array<4xf32>, !spv.struct<(f32)>)>
19}
20
21// -----
22
23func @composite_construct_coopmatrix(%arg0 : f32) -> !spv.coopmatrix<8x16xf32, Subgroup> {
24  // CHECK: spv.CompositeConstruct {{%.*}} : !spv.coopmatrix<8x16xf32, Subgroup>
25  %0 = spv.CompositeConstruct %arg0 : !spv.coopmatrix<8x16xf32, Subgroup>
26  return %0: !spv.coopmatrix<8x16xf32, Subgroup>
27}
28
29// -----
30
31func @composite_construct_empty_struct() -> !spv.struct<()> {
32  // CHECK: spv.CompositeConstruct : !spv.struct<()>
33  %0 = spv.CompositeConstruct : !spv.struct<()>
34  return %0: !spv.struct<()>
35}
36
37// -----
38
39func @composite_construct_invalid_num_of_elements(%arg0: f32) -> f32 {
40  // expected-error @+1 {{result type must be a composite type, but provided 'f32'}}
41  %0 = spv.CompositeConstruct %arg0 : f32
42  return %0: f32
43}
44
45// -----
46
47func @composite_construct_invalid_result_type(%arg0: f32, %arg1: f32, %arg2 : f32) -> vector<3xf32> {
48  // expected-error @+1 {{has incorrect number of operands: expected 3, but provided 2}}
49  %0 = spv.CompositeConstruct %arg0, %arg2 : vector<3xf32>
50  return %0: vector<3xf32>
51}
52
53// -----
54
55func @composite_construct_invalid_operand_type(%arg0: f32, %arg1: f32, %arg2 : f32) -> vector<3xi32> {
56  // expected-error @+1 {{operand type mismatch: expected operand type 'i32', but provided 'f32'}}
57  %0 = "spv.CompositeConstruct" (%arg0, %arg1, %arg2) : (f32, f32, f32) -> vector<3xi32>
58  return %0: vector<3xi32>
59}
60
61// -----
62
63func @composite_construct_coopmatrix(%arg0 : f32, %arg1 : f32) -> !spv.coopmatrix<8x16xf32, Subgroup> {
64  // expected-error @+1 {{has incorrect number of operands: expected 1, but provided 2}}
65  %0 = spv.CompositeConstruct %arg0, %arg1 : !spv.coopmatrix<8x16xf32, Subgroup>
66  return %0: !spv.coopmatrix<8x16xf32, Subgroup>
67}
68
69// -----
70
71//===----------------------------------------------------------------------===//
72// spv.CompositeExtractOp
73//===----------------------------------------------------------------------===//
74
75func @composite_extract_array(%arg0: !spv.array<4xf32>) -> f32 {
76  // CHECK: {{%.*}} = spv.CompositeExtract {{%.*}}[1 : i32] : !spv.array<4 x f32>
77  %0 = spv.CompositeExtract %arg0[1 : i32] : !spv.array<4xf32>
78  return %0: f32
79}
80
81// -----
82
83func @composite_extract_struct(%arg0 : !spv.struct<(f32, !spv.array<4xf32>)>) -> f32 {
84  // CHECK: {{%.*}} = spv.CompositeExtract {{%.*}}[1 : i32, 2 : i32] : !spv.struct<(f32, !spv.array<4 x f32>)>
85  %0 = spv.CompositeExtract %arg0[1 : i32, 2 : i32] : !spv.struct<(f32, !spv.array<4xf32>)>
86  return %0 : f32
87}
88
89// -----
90
91func @composite_extract_vector(%arg0 : vector<4xf32>) -> f32 {
92  // CHECK: {{%.*}} = spv.CompositeExtract {{%.*}}[1 : i32] : vector<4xf32>
93  %0 = spv.CompositeExtract %arg0[1 : i32] : vector<4xf32>
94  return %0 : f32
95}
96
97// -----
98
99func @composite_extract_coopmatrix(%arg0 : !spv.coopmatrix<8x16xf32, Subgroup>) -> f32 {
100  // CHECK: {{%.*}} = spv.CompositeExtract {{%.*}}[2 : i32] : !spv.coopmatrix<8x16xf32, Subgroup>
101  %0 = spv.CompositeExtract %arg0[2 : i32] : !spv.coopmatrix<8x16xf32, Subgroup>
102  return %0 : f32
103}
104
105// -----
106
107func @composite_extract_no_ssa_operand() -> () {
108  // expected-error @+1 {{expected SSA operand}}
109  %0 = spv.CompositeExtract [4 : i32, 1 : i32] : !spv.array<4x!spv.array<4xf32>>
110  return
111}
112
113// -----
114
115func @composite_extract_invalid_index_type_1() -> () {
116  %0 = spv.Constant 10 : i32
117  %1 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>
118  %2 = spv.Load "Function" %1 ["Volatile"] : !spv.array<4x!spv.array<4xf32>>
119  // expected-error @+1 {{expected non-function type}}
120  %3 = spv.CompositeExtract %2[%0] : !spv.array<4x!spv.array<4xf32>>
121  return
122}
123
124// -----
125
126func @composite_extract_invalid_index_type_2(%arg0 : !spv.array<4x!spv.array<4xf32>>) -> () {
127  // expected-error @+1 {{attribute 'indices' failed to satisfy constraint: 32-bit integer array attribute}}
128  %0 = spv.CompositeExtract %arg0[1] : !spv.array<4x!spv.array<4xf32>>
129  return
130}
131
132// -----
133
134func @composite_extract_invalid_index_identifier(%arg0 : !spv.array<4x!spv.array<4xf32>>) -> () {
135  // expected-error @+1 {{expected non-function type}}
136  %0 = spv.CompositeExtract %arg0 ]1 : i32) : !spv.array<4x!spv.array<4xf32>>
137  return
138}
139
140// -----
141
142func @composite_extract_2D_array_out_of_bounds_access_1(%arg0: !spv.array<4x!spv.array<4xf32>>) -> () {
143  // expected-error @+1 {{index 4 out of bounds for '!spv.array<4 x !spv.array<4 x f32>>'}}
144  %0 = spv.CompositeExtract %arg0[4 : i32, 1 : i32] : !spv.array<4x!spv.array<4xf32>>
145  return
146}
147
148// -----
149
150func @composite_extract_2D_array_out_of_bounds_access_2(%arg0: !spv.array<4x!spv.array<4xf32>>
151) -> () {
152  // expected-error @+1 {{index 4 out of bounds for '!spv.array<4 x f32>'}}
153  %0 = spv.CompositeExtract %arg0[1 : i32, 4 : i32] : !spv.array<4x!spv.array<4xf32>>
154  return
155}
156
157// -----
158
159func @composite_extract_struct_element_out_of_bounds_access(%arg0 : !spv.struct<(f32, !spv.array<4xf32>)>) -> () {
160  // expected-error @+1 {{index 2 out of bounds for '!spv.struct<(f32, !spv.array<4 x f32>)>'}}
161  %0 = spv.CompositeExtract %arg0[2 : i32, 0 : i32] : !spv.struct<(f32, !spv.array<4xf32>)>
162  return
163}
164
165// -----
166
167func @composite_extract_vector_out_of_bounds_access(%arg0: vector<4xf32>) -> () {
168  // expected-error @+1 {{index 4 out of bounds for 'vector<4xf32>'}}
169  %0 = spv.CompositeExtract %arg0[4 : i32] : vector<4xf32>
170  return
171}
172
173// -----
174
175func @composite_extract_invalid_types_1(%arg0: !spv.array<4x!spv.array<4xf32>>) -> () {
176  // expected-error @+1 {{cannot extract from non-composite type 'f32' with index 3}}
177  %0 = spv.CompositeExtract %arg0[1 : i32, 2 : i32, 3 : i32] : !spv.array<4x!spv.array<4xf32>>
178  return
179}
180
181// -----
182
183func @composite_extract_invalid_types_2(%arg0: f32) -> () {
184  // expected-error @+1 {{cannot extract from non-composite type 'f32' with index 1}}
185  %0 = spv.CompositeExtract %arg0[1 : i32] : f32
186  return
187}
188
189// -----
190
191func @composite_extract_invalid_extracted_type(%arg0: !spv.array<4x!spv.array<4xf32>>) -> () {
192  // expected-error @+1 {{expected at least one index for spv.CompositeExtract}}
193  %0 = spv.CompositeExtract %arg0[] : !spv.array<4x!spv.array<4xf32>>
194  return
195}
196
197// -----
198
199func @composite_extract_result_type_mismatch(%arg0: !spv.array<4xf32>) -> i32 {
200  // expected-error @+1 {{invalid result type: expected 'f32' but provided 'i32'}}
201  %0 = "spv.CompositeExtract"(%arg0) {indices = [2: i32]} : (!spv.array<4xf32>) -> (i32)
202  return %0: i32
203}
204
205// -----
206
207//===----------------------------------------------------------------------===//
208// spv.CompositeInsert
209//===----------------------------------------------------------------------===//
210
211func @composite_insert_array(%arg0: !spv.array<4xf32>, %arg1: f32) -> !spv.array<4xf32> {
212  // CHECK: {{%.*}} = spv.CompositeInsert {{%.*}}, {{%.*}}[1 : i32] : f32 into !spv.array<4 x f32>
213  %0 = spv.CompositeInsert %arg1, %arg0[1 : i32] : f32 into !spv.array<4xf32>
214  return %0: !spv.array<4xf32>
215}
216
217// -----
218
219func @composite_insert_struct(%arg0: !spv.struct<(!spv.array<4xf32>, f32)>, %arg1: !spv.array<4xf32>) -> !spv.struct<(!spv.array<4xf32>, f32)> {
220  // CHECK: {{%.*}} = spv.CompositeInsert {{%.*}}, {{%.*}}[0 : i32] : !spv.array<4 x f32> into !spv.struct<(!spv.array<4 x f32>, f32)>
221  %0 = spv.CompositeInsert %arg1, %arg0[0 : i32] : !spv.array<4xf32> into !spv.struct<(!spv.array<4xf32>, f32)>
222  return %0: !spv.struct<(!spv.array<4xf32>, f32)>
223}
224
225// -----
226
227func @composite_insert_coopmatrix(%arg0: !spv.coopmatrix<8x16xi32, Subgroup>, %arg1: i32) -> !spv.coopmatrix<8x16xi32, Subgroup> {
228  // CHECK: {{%.*}} = spv.CompositeInsert {{%.*}}, {{%.*}}[5 : i32] : i32 into !spv.coopmatrix<8x16xi32, Subgroup>
229  %0 = spv.CompositeInsert %arg1, %arg0[5 : i32] : i32 into !spv.coopmatrix<8x16xi32, Subgroup>
230  return %0: !spv.coopmatrix<8x16xi32, Subgroup>
231}
232
233// -----
234
235func @composite_insert_no_indices(%arg0: !spv.array<4xf32>, %arg1: f32) -> !spv.array<4xf32> {
236  // expected-error @+1 {{expected at least one index}}
237  %0 = spv.CompositeInsert %arg1, %arg0[] : f32 into !spv.array<4xf32>
238  return %0: !spv.array<4xf32>
239}
240
241// -----
242
243func @composite_insert_out_of_bounds(%arg0: !spv.array<4xf32>, %arg1: f32) -> !spv.array<4xf32> {
244  // expected-error @+1 {{index 4 out of bounds}}
245  %0 = spv.CompositeInsert %arg1, %arg0[4 : i32] : f32 into !spv.array<4xf32>
246  return %0: !spv.array<4xf32>
247}
248
249// -----
250
251func @composite_insert_invalid_object_type(%arg0: !spv.array<4xf32>, %arg1: f64) -> !spv.array<4xf32> {
252  // expected-error @+1 {{object operand type should be 'f32', but found 'f64'}}
253  %0 = spv.CompositeInsert %arg1, %arg0[3 : i32] : f64 into !spv.array<4xf32>
254  return %0: !spv.array<4xf32>
255}
256
257// -----
258
259func @composite_insert_invalid_result_type(%arg0: !spv.array<4xf32>, %arg1 : f32) -> !spv.array<4xf64> {
260  // expected-error @+1 {{result type should be the same as the composite type, but found '!spv.array<4 x f32>' vs '!spv.array<4 x f64>'}}
261  %0 = "spv.CompositeInsert"(%arg1, %arg0) {indices = [0: i32]} : (f32, !spv.array<4xf32>) -> !spv.array<4xf64>
262  return %0: !spv.array<4xf64>
263}
264
265// -----
266
267//===----------------------------------------------------------------------===//
268// spv.VectorExtractDynamic
269//===----------------------------------------------------------------------===//
270
271func @vector_dynamic_extract(%vec: vector<4xf32>, %id : i32) -> f32 {
272  // CHECK: spv.VectorExtractDynamic %{{.*}}[%{{.*}}] : vector<4xf32>, i32
273  %0 = spv.VectorExtractDynamic %vec[%id] : vector<4xf32>, i32
274  return %0 : f32
275}
276
277//===----------------------------------------------------------------------===//
278// spv.VectorInsertDynamic
279//===----------------------------------------------------------------------===//
280
281func @vector_dynamic_insert(%val: f32, %vec: vector<4xf32>, %id : i32) -> vector<4xf32> {
282  // CHECK: spv.VectorInsertDynamic %{{.*}}, %{{.*}}[%{{.*}}] : vector<4xf32>, i32
283  %0 = spv.VectorInsertDynamic %val, %vec[%id] : vector<4xf32>, i32
284  return %0 : vector<4xf32>
285}
286
287// -----
288
289//===----------------------------------------------------------------------===//
290// spv.VectorShuffle
291//===----------------------------------------------------------------------===//
292
293func @vector_shuffle(%vector1: vector<4xf32>, %vector2: vector<2xf32>) -> vector<3xf32> {
294  // CHECK: %{{.+}} = spv.VectorShuffle [1 : i32, 3 : i32, -1 : i32] %{{.+}} : vector<4xf32>, %arg1 : vector<2xf32> -> vector<3xf32>
295  %0 = spv.VectorShuffle [1: i32, 3: i32, 0xffffffff: i32] %vector1: vector<4xf32>, %vector2: vector<2xf32> -> vector<3xf32>
296  return %0: vector<3xf32>
297}
298
299// -----
300
301func @vector_shuffle_extra_selector(%vector1: vector<4xf32>, %vector2: vector<2xf32>) -> vector<3xf32> {
302  // expected-error @+1 {{result type element count (3) mismatch with the number of component selectors (4)}}
303  %0 = spv.VectorShuffle [1: i32, 3: i32, 5: i32, 2: i32] %vector1: vector<4xf32>, %vector2: vector<2xf32> -> vector<3xf32>
304  return %0: vector<3xf32>
305}
306
307// -----
308
309func @vector_shuffle_extra_selector(%vector1: vector<4xf32>, %vector2: vector<2xf32>) -> vector<3xf32> {
310  // expected-error @+1 {{component selector 7 out of range: expected to be in [0, 6) or 0xffffffff}}
311  %0 = spv.VectorShuffle [1: i32, 7: i32, 5: i32] %vector1: vector<4xf32>, %vector2: vector<2xf32> -> vector<3xf32>
312  return %0: vector<3xf32>
313}
314