1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
2
3//===----------------------------------------------------------------------===//
4// spv.FAdd
5//===----------------------------------------------------------------------===//
6
7func.func @fadd_scalar(%arg: f32) -> f32 {
8  // CHECK: spv.FAdd
9  %0 = spv.FAdd %arg, %arg : f32
10  return %0 : f32
11}
12
13// -----
14
15//===----------------------------------------------------------------------===//
16// spv.FDiv
17//===----------------------------------------------------------------------===//
18
19func.func @fdiv_scalar(%arg: f32) -> f32 {
20  // CHECK: spv.FDiv
21  %0 = spv.FDiv %arg, %arg : f32
22  return %0 : f32
23}
24
25// -----
26
27//===----------------------------------------------------------------------===//
28// spv.FMod
29//===----------------------------------------------------------------------===//
30
31func.func @fmod_scalar(%arg: f32) -> f32 {
32  // CHECK: spv.FMod
33  %0 = spv.FMod %arg, %arg : f32
34  return %0 : f32
35}
36
37// -----
38
39//===----------------------------------------------------------------------===//
40// spv.FMul
41//===----------------------------------------------------------------------===//
42
43func.func @fmul_scalar(%arg: f32) -> f32 {
44  // CHECK: spv.FMul
45  %0 = spv.FMul %arg, %arg : f32
46  return %0 : f32
47}
48
49func.func @fmul_vector(%arg: vector<4xf32>) -> vector<4xf32> {
50  // CHECK: spv.FMul
51  %0 = spv.FMul %arg, %arg : vector<4xf32>
52  return %0 : vector<4xf32>
53}
54
55// -----
56
57func.func @fmul_i32(%arg: i32) -> i32 {
58  // expected-error @+1 {{operand #0 must be 16/32/64-bit float or vector of 16/32/64-bit float values}}
59  %0 = spv.FMul %arg, %arg : i32
60  return %0 : i32
61}
62
63// -----
64
65func.func @fmul_bf16(%arg: bf16) -> bf16 {
66  // expected-error @+1 {{operand #0 must be 16/32/64-bit float or vector of 16/32/64-bit float values}}
67  %0 = spv.FMul %arg, %arg : bf16
68  return %0 : bf16
69}
70
71// -----
72
73func.func @fmul_tensor(%arg: tensor<4xf32>) -> tensor<4xf32> {
74  // expected-error @+1 {{operand #0 must be 16/32/64-bit float or vector of 16/32/64-bit float values}}
75  %0 = spv.FMul %arg, %arg : tensor<4xf32>
76  return %0 : tensor<4xf32>
77}
78
79// -----
80
81//===----------------------------------------------------------------------===//
82// spv.FNegate
83//===----------------------------------------------------------------------===//
84
85func.func @fnegate_scalar(%arg: f32) -> f32 {
86  // CHECK: spv.FNegate
87  %0 = spv.FNegate %arg : f32
88  return %0 : f32
89}
90
91// -----
92
93//===----------------------------------------------------------------------===//
94// spv.FRem
95//===----------------------------------------------------------------------===//
96
97func.func @frem_scalar(%arg: f32) -> f32 {
98  // CHECK: spv.FRem
99  %0 = spv.FRem %arg, %arg : f32
100  return %0 : f32
101}
102
103// -----
104
105//===----------------------------------------------------------------------===//
106// spv.FSub
107//===----------------------------------------------------------------------===//
108
109func.func @fsub_scalar(%arg: f32) -> f32 {
110  // CHECK: spv.FSub
111  %0 = spv.FSub %arg, %arg : f32
112  return %0 : f32
113}
114
115// -----
116
117//===----------------------------------------------------------------------===//
118// spv.IAdd
119//===----------------------------------------------------------------------===//
120
121func.func @iadd_scalar(%arg: i32) -> i32 {
122  // CHECK: spv.IAdd
123  %0 = spv.IAdd %arg, %arg : i32
124  return %0 : i32
125}
126
127// -----
128
129//===----------------------------------------------------------------------===//
130// spv.IMul
131//===----------------------------------------------------------------------===//
132
133func.func @imul_scalar(%arg: i32) -> i32 {
134  // CHECK: spv.IMul
135  %0 = spv.IMul %arg, %arg : i32
136  return %0 : i32
137}
138
139// -----
140
141//===----------------------------------------------------------------------===//
142// spv.ISub
143//===----------------------------------------------------------------------===//
144
145func.func @isub_scalar(%arg: i32) -> i32 {
146  // CHECK: spv.ISub
147  %0 = spv.ISub %arg, %arg : i32
148  return %0 : i32
149}
150
151// -----
152
153//===----------------------------------------------------------------------===//
154// spv.ISubBorrow
155//===----------------------------------------------------------------------===//
156
157// CHECK-LABEL: @isub_borrow_scalar
158func.func @isub_borrow_scalar(%arg: i32) -> !spv.struct<(i32, i32)> {
159  // CHECK: spv.ISubBorrow %{{.+}}, %{{.+}} : !spv.struct<(i32, i32)>
160  %0 = spv.ISubBorrow %arg, %arg : !spv.struct<(i32, i32)>
161  return %0 : !spv.struct<(i32, i32)>
162}
163
164// CHECK-LABEL: @isub_borrow_vector
165func.func @isub_borrow_vector(%arg: vector<3xi32>) -> !spv.struct<(vector<3xi32>, vector<3xi32>)> {
166  // CHECK: spv.ISubBorrow %{{.+}}, %{{.+}} : !spv.struct<(vector<3xi32>, vector<3xi32>)>
167  %0 = spv.ISubBorrow %arg, %arg : !spv.struct<(vector<3xi32>, vector<3xi32>)>
168  return %0 : !spv.struct<(vector<3xi32>, vector<3xi32>)>
169}
170
171// -----
172
173func.func @isub_borrow(%arg: i32) -> !spv.struct<(i32, i32, i32)> {
174  // expected-error @+1 {{expected spv.struct type with two members}}
175  %0 = spv.ISubBorrow %arg, %arg : !spv.struct<(i32, i32, i32)>
176  return %0 : !spv.struct<(i32, i32, i32)>
177}
178
179// -----
180
181func.func @isub_borrow(%arg: i32) -> !spv.struct<(i32)> {
182  // expected-error @+1 {{expected result struct type containing two members}}
183  %0 = "spv.ISubBorrow"(%arg, %arg): (i32, i32) -> !spv.struct<(i32)>
184  return %0 : !spv.struct<(i32)>
185}
186
187// -----
188
189func.func @isub_borrow(%arg: i32) -> !spv.struct<(i32, i64)> {
190  // expected-error @+1 {{expected all operand types and struct member types are the same}}
191  %0 = "spv.ISubBorrow"(%arg, %arg): (i32, i32) -> !spv.struct<(i32, i64)>
192  return %0 : !spv.struct<(i32, i64)>
193}
194
195// -----
196
197func.func @isub_borrow(%arg: i64) -> !spv.struct<(i32, i32)> {
198  // expected-error @+1 {{expected all operand types and struct member types are the same}}
199  %0 = "spv.ISubBorrow"(%arg, %arg): (i64, i64) -> !spv.struct<(i32, i32)>
200  return %0 : !spv.struct<(i32, i32)>
201}
202
203// -----
204
205//===----------------------------------------------------------------------===//
206// spv.SDiv
207//===----------------------------------------------------------------------===//
208
209func.func @sdiv_scalar(%arg: i32) -> i32 {
210  // CHECK: spv.SDiv
211  %0 = spv.SDiv %arg, %arg : i32
212  return %0 : i32
213}
214
215// -----
216
217//===----------------------------------------------------------------------===//
218// spv.SMod
219//===----------------------------------------------------------------------===//
220
221func.func @smod_scalar(%arg: i32) -> i32 {
222  // CHECK: spv.SMod
223  %0 = spv.SMod %arg, %arg : i32
224  return %0 : i32
225}
226
227// -----
228
229//===----------------------------------------------------------------------===//
230// spv.SNegate
231//===----------------------------------------------------------------------===//
232
233func.func @snegate_scalar(%arg: i32) -> i32 {
234  // CHECK: spv.SNegate
235  %0 = spv.SNegate %arg : i32
236  return %0 : i32
237}
238
239// -----
240//===----------------------------------------------------------------------===//
241// spv.SRem
242//===----------------------------------------------------------------------===//
243
244func.func @srem_scalar(%arg: i32) -> i32 {
245  // CHECK: spv.SRem
246  %0 = spv.SRem %arg, %arg : i32
247  return %0 : i32
248}
249
250// -----
251
252//===----------------------------------------------------------------------===//
253// spv.UDiv
254//===----------------------------------------------------------------------===//
255
256func.func @udiv_scalar(%arg: i32) -> i32 {
257  // CHECK: spv.UDiv
258  %0 = spv.UDiv %arg, %arg : i32
259  return %0 : i32
260}
261
262// -----
263
264//===----------------------------------------------------------------------===//
265// spv.UMod
266//===----------------------------------------------------------------------===//
267
268func.func @umod_scalar(%arg: i32) -> i32 {
269  // CHECK: spv.UMod
270  %0 = spv.UMod %arg, %arg : i32
271  return %0 : i32
272}
273
274// -----
275//===----------------------------------------------------------------------===//
276// spv.VectorTimesScalar
277//===----------------------------------------------------------------------===//
278
279func.func @vector_times_scalar(%vector: vector<4xf32>, %scalar: f32) -> vector<4xf32> {
280  // CHECK: spv.VectorTimesScalar %{{.+}}, %{{.+}} : (vector<4xf32>, f32) -> vector<4xf32>
281  %0 = spv.VectorTimesScalar %vector, %scalar : (vector<4xf32>, f32) -> vector<4xf32>
282  return %0 : vector<4xf32>
283}
284
285// -----
286
287func.func @vector_times_scalar(%vector: vector<4xf32>, %scalar: f16) -> vector<4xf32> {
288  // expected-error @+1 {{scalar operand and result element type match}}
289  %0 = spv.VectorTimesScalar %vector, %scalar : (vector<4xf32>, f16) -> vector<4xf32>
290  return %0 : vector<4xf32>
291}
292
293// -----
294
295func.func @vector_times_scalar(%vector: vector<4xf32>, %scalar: f32) -> vector<3xf32> {
296  // expected-error @+1 {{vector operand and result type mismatch}}
297  %0 = spv.VectorTimesScalar %vector, %scalar : (vector<4xf32>, f32) -> vector<3xf32>
298  return %0 : vector<3xf32>
299}
300