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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
// RUN: mlir-opt -test-convert-to-spirv="run-signature-conversion=false run-vector-unrolling=false" -split-input-file %s | FileCheck %s
// CHECK-LABEL: @extract
// CHECK-SAME: %[[ARG:.+]]: vector<2xf32>
// CHECK: spirv.CompositeExtract %[[ARG]][0 : i32] : vector<2xf32>
// CHECK: spirv.CompositeExtract %[[ARG]][1 : i32] : vector<2xf32>
func.func @extract(%arg0 : vector<2xf32>) -> (vector<1xf32>, f32) {
%0 = "vector.extract"(%arg0) <{static_position = array<i64: 0>}> : (vector<2xf32>) -> vector<1xf32>
%1 = "vector.extract"(%arg0) <{static_position = array<i64: 1>}> : (vector<2xf32>) -> f32
return %0, %1: vector<1xf32>, f32
}
// -----
// CHECK-LABEL: @extract_size1_vector
// CHECK-SAME: %[[ARG0:.+]]: f32
// CHECK: spirv.ReturnValue %[[ARG0]] : f32
func.func @extract_size1_vector(%arg0 : vector<1xf32>) -> f32 {
%0 = vector.extract %arg0[0] : f32 from vector<1xf32>
return %0: f32
}
// -----
// CHECK-LABEL: @insert
// CHECK-SAME: %[[V:.*]]: vector<4xf32>, %[[S:.*]]: f32
// CHECK: spirv.CompositeInsert %[[S]], %[[V]][2 : i32] : f32 into vector<4xf32>
func.func @insert(%arg0 : vector<4xf32>, %arg1: f32) -> vector<4xf32> {
%1 = vector.insert %arg1, %arg0[2] : f32 into vector<4xf32>
return %1: vector<4xf32>
}
// -----
// CHECK-LABEL: @insert_index_vector
// CHECK: spirv.CompositeInsert %{{.+}}, %{{.+}}[2 : i32] : i32 into vector<4xi32>
func.func @insert_index_vector(%arg0 : vector<4xindex>, %arg1: index) -> vector<4xindex> {
%1 = vector.insert %arg1, %arg0[2] : index into vector<4xindex>
return %1: vector<4xindex>
}
// -----
// CHECK-LABEL: @insert_size1_vector
// CHECK-SAME: %[[V:.*]]: f32, %[[S:.*]]: f32
// CHECK: spirv.ReturnValue %[[S]] : f32
func.func @insert_size1_vector(%arg0 : vector<1xf32>, %arg1: f32) -> vector<1xf32> {
%1 = vector.insert %arg1, %arg0[0] : f32 into vector<1xf32>
return %1 : vector<1xf32>
}
// -----
// CHECK-LABEL: @insert_size1_vector
// CHECK-SAME: %[[SUB:.*]]: f32, %[[FULL:.*]]: vector<3xf32>
// CHECK: %[[RET:.*]] = spirv.CompositeInsert %[[SUB]], %[[FULL]][2 : i32] : f32 into vector<3xf32>
// CHECK: spirv.ReturnValue %[[RET]] : vector<3xf32>
func.func @insert_size1_vector(%arg0 : vector<1xf32>, %arg1: vector<3xf32>) -> vector<3xf32> {
%1 = vector.insert_strided_slice %arg0, %arg1 {offsets = [2], strides = [1]} : vector<1xf32> into vector<3xf32>
return %1 : vector<3xf32>
}
// -----
// CHECK-LABEL: @fma
// CHECK-SAME: %[[A:.*]]: vector<4xf32>, %[[B:.*]]: vector<4xf32>, %[[C:.*]]: vector<4xf32>
// CHECK: spirv.GL.Fma %[[A]], %[[B]], %[[C]] : vector<4xf32>
func.func @fma(%a: vector<4xf32>, %b: vector<4xf32>, %c: vector<4xf32>) -> vector<4xf32> {
%0 = vector.fma %a, %b, %c: vector<4xf32>
return %0 : vector<4xf32>
}
// -----
// CHECK-LABEL: @fma_size1_vector
// CHECK: spirv.GL.Fma %{{.+}} : f32
func.func @fma_size1_vector(%a: vector<1xf32>, %b: vector<1xf32>, %c: vector<1xf32>) -> vector<1xf32> {
%0 = vector.fma %a, %b, %c: vector<1xf32>
return %0 : vector<1xf32>
}
// -----
// CHECK-LABEL: func @splat
// CHECK-SAME: (%[[A:.+]]: f32)
// CHECK: %[[VAL:.+]] = spirv.CompositeConstruct %[[A]], %[[A]], %[[A]], %[[A]]
// CHECK: spirv.ReturnValue %[[VAL]] : vector<4xf32>
func.func @splat(%f : f32) -> vector<4xf32> {
%splat = vector.broadcast %f : f32 to vector<4xf32>
return %splat : vector<4xf32>
}
// -----
// CHECK-LABEL: func @splat_size1_vector
// CHECK-SAME: (%[[A:.+]]: f32)
// CHECK: spirv.ReturnValue %[[A]] : f32
func.func @splat_size1_vector(%f : f32) -> vector<1xf32> {
%bc = vector.broadcast %f : f32 to vector<1xf32>
return %bc : vector<1xf32>
}
// -----
// CHECK-LABEL: func @scalar_broadcast
// CHECK-SAME: (%[[A:.+]]: f32)
// CHECK: %[[VAL:.+]] = spirv.CompositeConstruct %[[A]], %[[A]], %[[A]], %[[A]]
// CHECK: spirv.ReturnValue %[[VAL]] : vector<4xf32>
func.func @scalar_broadcast(%f : f32) -> vector<4xf32> {
%bc = vector.broadcast %f : f32 to vector<4xf32>
return %bc : vector<4xf32>
}
// -----
// CHECK-LABEL: func @scalar_broadcast_size1_vector
// CHECK-SAME: (%[[A:.+]]: f32)
// CHECK: spirv.ReturnValue %[[A]] : f32
func.func @scalar_broadcast_size1_vector(%f : f32) -> vector<1xf32> {
%splat = vector.broadcast %f : f32 to vector<1xf32>
return %splat : vector<1xf32>
}
// -----
// CHECK-LABEL: func @shuffle
// CHECK-SAME: %[[ARG0:.+]]: f32, %[[ARG1:.+]]: f32
// CHECK: spirv.CompositeConstruct %[[ARG0]], %[[ARG1]], %[[ARG1]], %[[ARG0]] : (f32, f32, f32, f32) -> vector<4xf32>
func.func @shuffle(%v0 : vector<1xf32>, %v1: vector<1xf32>) -> vector<4xf32> {
%shuffle = vector.shuffle %v0, %v1 [0, 1, 1, 0] : vector<1xf32>, vector<1xf32>
return %shuffle : vector<4xf32>
}
// -----
// CHECK-LABEL: func @shuffle
// CHECK-SAME: %[[V0:.+]]: vector<3xf32>, %[[V1:.+]]: vector<3xf32>
// CHECK: spirv.VectorShuffle [3 : i32, 2 : i32, 5 : i32, 1 : i32] %[[V0]], %[[V1]] : vector<3xf32>, vector<3xf32> -> vector<4xf32>
func.func @shuffle(%v0 : vector<3xf32>, %v1: vector<3xf32>) -> vector<4xf32> {
%shuffle = vector.shuffle %v0, %v1 [3, 2, 5, 1] : vector<3xf32>, vector<3xf32>
return %shuffle : vector<4xf32>
}
// -----
// CHECK-LABEL: func @shuffle
// CHECK-SAME: %[[ARG0:.+]]: i32, %[[ARG1:.+]]: vector<3xi32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[ARG1]][1 : i32] : vector<3xi32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[ARG1]][2 : i32] : vector<3xi32>
// CHECK: %[[RES:.+]] = spirv.CompositeConstruct %[[ARG0]], %[[S1]], %[[S2]] : (i32, i32, i32) -> vector<3xi32>
// CHECK: spirv.ReturnValue %[[RES]]
func.func @shuffle(%v0 : vector<1xi32>, %v1: vector<3xi32>) -> vector<3xi32> {
%shuffle = vector.shuffle %v0, %v1 [0, 2, 3] : vector<1xi32>, vector<3xi32>
return %shuffle : vector<3xi32>
}
// -----
// CHECK-LABEL: func @shuffle
// CHECK-SAME: %[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32
// CHECK: %[[RES:.+]] = spirv.CompositeConstruct %[[ARG0]], %[[ARG1]] : (i32, i32) -> vector<2xi32>
// CHECK: spirv.ReturnValue %[[RES]]
func.func @shuffle(%v0 : vector<1xi32>, %v1: vector<1xi32>) -> vector<2xi32> {
%shuffle = vector.shuffle %v0, %v1 [0, 1] : vector<1xi32>, vector<1xi32>
return %shuffle : vector<2xi32>
}
// -----
// CHECK-LABEL: func @interleave
// CHECK-SAME: (%[[ARG0:.+]]: vector<2xf32>, %[[ARG1:.+]]: vector<2xf32>)
// CHECK: %[[SHUFFLE:.*]] = spirv.VectorShuffle [0 : i32, 2 : i32, 1 : i32, 3 : i32] %[[ARG0]], %[[ARG1]] : vector<2xf32>, vector<2xf32> -> vector<4xf32>
// CHECK: spirv.ReturnValue %[[SHUFFLE]]
func.func @interleave(%a: vector<2xf32>, %b: vector<2xf32>) -> vector<4xf32> {
%0 = vector.interleave %a, %b : vector<2xf32> -> vector<4xf32>
return %0 : vector<4xf32>
}
// -----
// CHECK-LABEL: func @interleave_size1
// CHECK-SAME: (%[[ARG0:.+]]: f32, %[[ARG1:.+]]: f32)
// CHECK: %[[RES:.*]] = spirv.CompositeConstruct %[[ARG0]], %[[ARG1]] : (f32, f32) -> vector<2xf32>
// CHECK: spirv.ReturnValue %[[RES]]
func.func @interleave_size1(%a: vector<1xf32>, %b: vector<1xf32>) -> vector<2xf32> {
%0 = vector.interleave %a, %b : vector<1xf32> -> vector<2xf32>
return %0 : vector<2xf32>
}
// -----
// CHECK-LABEL: func @reduction_add
// CHECK-SAME: (%[[V:.+]]: vector<4xi32>)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<4xi32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<4xi32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<4xi32>
// CHECK: %[[S3:.+]] = spirv.CompositeExtract %[[V]][3 : i32] : vector<4xi32>
// CHECK: %[[ADD0:.+]] = spirv.IAdd %[[S0]], %[[S1]]
// CHECK: %[[ADD1:.+]] = spirv.IAdd %[[ADD0]], %[[S2]]
// CHECK: %[[ADD2:.+]] = spirv.IAdd %[[ADD1]], %[[S3]]
// CHECK: spirv.ReturnValue %[[ADD2]]
func.func @reduction_add(%v : vector<4xi32>) -> i32 {
%reduce = vector.reduction <add>, %v : vector<4xi32> into i32
return %reduce : i32
}
// -----
// CHECK-LABEL: func @reduction_addf_one_elem
// CHECK-SAME: (%[[ARG0:.+]]: f32)
// CHECK: spirv.ReturnValue %[[ARG0]] : f32
func.func @reduction_addf_one_elem(%arg0: vector<1xf32>) -> f32 {
%red = vector.reduction <add>, %arg0 : vector<1xf32> into f32
return %red : f32
}
// -----
// CHECK-LABEL: func @reduction_addf_one_elem_acc
// CHECK-SAME: (%[[ARG0:.+]]: f32, %[[ACC:.+]]: f32)
// CHECK: %[[RES:.+]] = spirv.FAdd %[[ACC]], %[[ARG0]] : f32
// CHECK: spirv.ReturnValue %[[RES]] : f32
func.func @reduction_addf_one_elem_acc(%arg0: vector<1xf32>, %acc: f32) -> f32 {
%red = vector.reduction <add>, %arg0, %acc : vector<1xf32> into f32
return %red : f32
}
// -----
// CHECK-LABEL: func @reduction_mul
// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>
// CHECK: %[[MUL0:.+]] = spirv.FMul %[[S0]], %[[S1]]
// CHECK: %[[MUL1:.+]] = spirv.FMul %[[MUL0]], %[[S2]]
// CHECK: %[[MUL2:.+]] = spirv.FMul %[[MUL1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MUL2]]
func.func @reduction_mul(%v : vector<3xf32>, %s: f32) -> f32 {
%reduce = vector.reduction <mul>, %v, %s : vector<3xf32> into f32
return %reduce : f32
}
// -----
// CHECK-LABEL: func @reduction_maximumf
// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>
// CHECK: %[[MAX0:.+]] = spirv.GL.FMax %[[S0]], %[[S1]]
// CHECK: %[[MAX1:.+]] = spirv.GL.FMax %[[MAX0]], %[[S2]]
// CHECK: %[[MAX2:.+]] = spirv.GL.FMax %[[MAX1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MAX2]]
func.func @reduction_maximumf(%v : vector<3xf32>, %s: f32) -> f32 {
%reduce = vector.reduction <maximumf>, %v, %s : vector<3xf32> into f32
return %reduce : f32
}
// -----
// CHECK-LABEL: func @reduction_minimumf
// CHECK-SAME: (%[[V:.+]]: vector<3xf32>, %[[S:.+]]: f32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xf32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xf32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xf32>
// CHECK: %[[MIN0:.+]] = spirv.GL.FMin %[[S0]], %[[S1]]
// CHECK: %[[MIN1:.+]] = spirv.GL.FMin %[[MIN0]], %[[S2]]
// CHECK: %[[MIN2:.+]] = spirv.GL.FMin %[[MIN1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MIN2]]
func.func @reduction_minimumf(%v : vector<3xf32>, %s: f32) -> f32 {
%reduce = vector.reduction <minimumf>, %v, %s : vector<3xf32> into f32
return %reduce : f32
}
// -----
// CHECK-LABEL: func @reduction_maxsi
// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>
// CHECK: %[[MAX0:.+]] = spirv.GL.SMax %[[S0]], %[[S1]]
// CHECK: %[[MAX1:.+]] = spirv.GL.SMax %[[MAX0]], %[[S2]]
// CHECK: %[[MAX2:.+]] = spirv.GL.SMax %[[MAX1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MAX2]]
func.func @reduction_maxsi(%v : vector<3xi32>, %s: i32) -> i32 {
%reduce = vector.reduction <maxsi>, %v, %s : vector<3xi32> into i32
return %reduce : i32
}
// -----
// CHECK-LABEL: func @reduction_minsi
// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>
// CHECK: %[[MIN0:.+]] = spirv.GL.SMin %[[S0]], %[[S1]]
// CHECK: %[[MIN1:.+]] = spirv.GL.SMin %[[MIN0]], %[[S2]]
// CHECK: %[[MIN2:.+]] = spirv.GL.SMin %[[MIN1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MIN2]]
func.func @reduction_minsi(%v : vector<3xi32>, %s: i32) -> i32 {
%reduce = vector.reduction <minsi>, %v, %s : vector<3xi32> into i32
return %reduce : i32
}
// -----
// CHECK-LABEL: func @reduction_maxui
// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>
// CHECK: %[[MAX0:.+]] = spirv.GL.UMax %[[S0]], %[[S1]]
// CHECK: %[[MAX1:.+]] = spirv.GL.UMax %[[MAX0]], %[[S2]]
// CHECK: %[[MAX2:.+]] = spirv.GL.UMax %[[MAX1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MAX2]]
func.func @reduction_maxui(%v : vector<3xi32>, %s: i32) -> i32 {
%reduce = vector.reduction <maxui>, %v, %s : vector<3xi32> into i32
return %reduce : i32
}
// -----
// CHECK-LABEL: func @reduction_minui
// CHECK-SAME: (%[[V:.+]]: vector<3xi32>, %[[S:.+]]: i32)
// CHECK: %[[S0:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<3xi32>
// CHECK: %[[S1:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<3xi32>
// CHECK: %[[S2:.+]] = spirv.CompositeExtract %[[V]][2 : i32] : vector<3xi32>
// CHECK: %[[MIN0:.+]] = spirv.GL.UMin %[[S0]], %[[S1]]
// CHECK: %[[MIN1:.+]] = spirv.GL.UMin %[[MIN0]], %[[S2]]
// CHECK: %[[MIN2:.+]] = spirv.GL.UMin %[[MIN1]], %[[S]]
// CHECK: spirv.ReturnValue %[[MIN2]]
func.func @reduction_minui(%v : vector<3xi32>, %s: i32) -> i32 {
%reduce = vector.reduction <minui>, %v, %s : vector<3xi32> into i32
return %reduce : i32
}
// -----
// CHECK-LABEL: @shape_cast_same_type
// CHECK-SAME: (%[[ARG0:.*]]: vector<2xf32>)
// CHECK: spirv.ReturnValue %[[ARG0]]
func.func @shape_cast_same_type(%arg0 : vector<2xf32>) -> vector<2xf32> {
%1 = vector.shape_cast %arg0 : vector<2xf32> to vector<2xf32>
return %arg0 : vector<2xf32>
}
// -----
// CHECK-LABEL: @shape_cast_size1_vector
// CHECK-SAME: (%[[ARG0:.*]]: f32)
// CHECK: spirv.ReturnValue %[[ARG0]]
func.func @shape_cast_size1_vector(%arg0 : vector<f32>) -> vector<1xf32> {
%1 = vector.shape_cast %arg0 : vector<f32> to vector<1xf32>
return %1 : vector<1xf32>
}
|