[RISCV] Fix the code alignment for GroupFloatVectors. NFC
[llvm-project.git] / mlir / test / Conversion / ArithmeticToSPIRV / arithmetic-to-spirv.mlir
blob18b7680e8e1b8e4965fa835a5664e54539a655ee
1 // RUN: mlir-opt -split-input-file -convert-std-to-spirv -verify-diagnostics %s | FileCheck %s
3 //===----------------------------------------------------------------------===//
4 // arithmetic ops
5 //===----------------------------------------------------------------------===//
7 module attributes {
8   spv.target_env = #spv.target_env<
9     #spv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64, Shader], []>, {}>
10 } {
12 // Check integer operation conversions.
13 // CHECK-LABEL: @int32_scalar
14 func @int32_scalar(%lhs: i32, %rhs: i32) {
15   // CHECK: spv.IAdd %{{.*}}, %{{.*}}: i32
16   %0 = arith.addi %lhs, %rhs: i32
17   // CHECK: spv.ISub %{{.*}}, %{{.*}}: i32
18   %1 = arith.subi %lhs, %rhs: i32
19   // CHECK: spv.IMul %{{.*}}, %{{.*}}: i32
20   %2 = arith.muli %lhs, %rhs: i32
21   // CHECK: spv.SDiv %{{.*}}, %{{.*}}: i32
22   %3 = arith.divsi %lhs, %rhs: i32
23   // CHECK: spv.UDiv %{{.*}}, %{{.*}}: i32
24   %4 = arith.divui %lhs, %rhs: i32
25   // CHECK: spv.UMod %{{.*}}, %{{.*}}: i32
26   %5 = arith.remui %lhs, %rhs: i32
27   return
30 // CHECK-LABEL: @scalar_srem
31 // CHECK-SAME: (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32)
32 func @scalar_srem(%lhs: i32, %rhs: i32) {
33   // CHECK: %[[LABS:.+]] = spv.GLSL.SAbs %[[LHS]] : i32
34   // CHECK: %[[RABS:.+]] = spv.GLSL.SAbs %[[RHS]] : i32
35   // CHECK:  %[[ABS:.+]] = spv.UMod %[[LABS]], %[[RABS]] : i32
36   // CHECK:  %[[POS:.+]] = spv.IEqual %[[LHS]], %[[LABS]] : i32
37   // CHECK:  %[[NEG:.+]] = spv.SNegate %[[ABS]] : i32
38   // CHECK:      %{{.+}} = spv.Select %[[POS]], %[[ABS]], %[[NEG]] : i1, i32
39   %0 = arith.remsi %lhs, %rhs: i32
40   return
43 // Check float unary operation conversions.
44 // CHECK-LABEL: @float32_unary_scalar
45 func @float32_unary_scalar(%arg0: f32) {
46   // CHECK: spv.FNegate %{{.*}}: f32
47   %0 = arith.negf %arg0 : f32
48   return
51 // Check float binary operation conversions.
52 // CHECK-LABEL: @float32_binary_scalar
53 func @float32_binary_scalar(%lhs: f32, %rhs: f32) {
54   // CHECK: spv.FAdd %{{.*}}, %{{.*}}: f32
55   %0 = arith.addf %lhs, %rhs: f32
56   // CHECK: spv.FSub %{{.*}}, %{{.*}}: f32
57   %1 = arith.subf %lhs, %rhs: f32
58   // CHECK: spv.FMul %{{.*}}, %{{.*}}: f32
59   %2 = arith.mulf %lhs, %rhs: f32
60   // CHECK: spv.FDiv %{{.*}}, %{{.*}}: f32
61   %3 = arith.divf %lhs, %rhs: f32
62   // CHECK: spv.FRem %{{.*}}, %{{.*}}: f32
63   %4 = arith.remf %lhs, %rhs: f32
64   return
67 // Check int vector types.
68 // CHECK-LABEL: @int_vector234
69 func @int_vector234(%arg0: vector<2xi8>, %arg1: vector<4xi64>) {
70   // CHECK: spv.SDiv %{{.*}}, %{{.*}}: vector<2xi8>
71   %0 = arith.divsi %arg0, %arg0: vector<2xi8>
72   // CHECK: spv.UDiv %{{.*}}, %{{.*}}: vector<4xi64>
73   %1 = arith.divui %arg1, %arg1: vector<4xi64>
74   return
77 // CHECK-LABEL: @vector_srem
78 // CHECK-SAME: (%[[LHS:.+]]: vector<3xi16>, %[[RHS:.+]]: vector<3xi16>)
79 func @vector_srem(%arg0: vector<3xi16>, %arg1: vector<3xi16>) {
80   // CHECK: %[[LABS:.+]] = spv.GLSL.SAbs %[[LHS]] : vector<3xi16>
81   // CHECK: %[[RABS:.+]] = spv.GLSL.SAbs %[[RHS]] : vector<3xi16>
82   // CHECK:  %[[ABS:.+]] = spv.UMod %[[LABS]], %[[RABS]] : vector<3xi16>
83   // CHECK:  %[[POS:.+]] = spv.IEqual %[[LHS]], %[[LABS]] : vector<3xi16>
84   // CHECK:  %[[NEG:.+]] = spv.SNegate %[[ABS]] : vector<3xi16>
85   // CHECK:      %{{.+}} = spv.Select %[[POS]], %[[ABS]], %[[NEG]] : vector<3xi1>, vector<3xi16>
86   %0 = arith.remsi %arg0, %arg1: vector<3xi16>
87   return
90 // Check float vector types.
91 // CHECK-LABEL: @float_vector234
92 func @float_vector234(%arg0: vector<2xf16>, %arg1: vector<3xf64>) {
93   // CHECK: spv.FAdd %{{.*}}, %{{.*}}: vector<2xf16>
94   %0 = arith.addf %arg0, %arg0: vector<2xf16>
95   // CHECK: spv.FMul %{{.*}}, %{{.*}}: vector<3xf64>
96   %1 = arith.mulf %arg1, %arg1: vector<3xf64>
97   return
100 // CHECK-LABEL: @one_elem_vector
101 func @one_elem_vector(%arg0: vector<1xi32>) {
102   // CHECK: spv.IAdd %{{.+}}, %{{.+}}: i32
103   %0 = arith.addi %arg0, %arg0: vector<1xi32>
104   return
107 // CHECK-LABEL: @unsupported_5elem_vector
108 func @unsupported_5elem_vector(%arg0: vector<5xi32>) {
109   // CHECK: arith.subi
110   %1 = arith.subi %arg0, %arg0: vector<5xi32>
111   return
114 // CHECK-LABEL: @unsupported_2x2elem_vector
115 func @unsupported_2x2elem_vector(%arg0: vector<2x2xi32>) {
116   // CHECK: arith.muli
117   %2 = arith.muli %arg0, %arg0: vector<2x2xi32>
118   return
121 } // end module
123 // -----
125 // Check that types are converted to 32-bit when no special capabilities.
126 module attributes {
127   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
128 } {
130 // CHECK-LABEL: @int_vector23
131 func @int_vector23(%arg0: vector<2xi8>, %arg1: vector<3xi16>) {
132   // CHECK: spv.SDiv %{{.*}}, %{{.*}}: vector<2xi32>
133   %0 = arith.divsi %arg0, %arg0: vector<2xi8>
134   // CHECK: spv.SDiv %{{.*}}, %{{.*}}: vector<3xi32>
135   %1 = arith.divsi %arg1, %arg1: vector<3xi16>
136   return
139 // CHECK-LABEL: @float_scalar
140 func @float_scalar(%arg0: f16, %arg1: f64) {
141   // CHECK: spv.FAdd %{{.*}}, %{{.*}}: f32
142   %0 = arith.addf %arg0, %arg0: f16
143   // CHECK: spv.FMul %{{.*}}, %{{.*}}: f32
144   %1 = arith.mulf %arg1, %arg1: f64
145   return
148 } // end module
150 // -----
152 // Check that types are converted to 32-bit when no special capabilities that
153 // are not supported.
154 module attributes {
155   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
156 } {
158 // expected-error @+1 {{failed to materialize conversion for block argument #0 that remained live after conversion, type was 'vector<4xi64>', with target type 'vector<4xi32>'}}
159 func @int_vector4_invalid(%arg0: vector<4xi64>) {
160   // expected-error @+2 {{bitwidth emulation is not implemented yet on unsigned op}}
161   // expected-note @+1 {{see existing live user here}}
162   %0 = arith.divui %arg0, %arg0: vector<4xi64>
163   return
166 } // end module
168 // -----
170 //===----------------------------------------------------------------------===//
171 // std bit ops
172 //===----------------------------------------------------------------------===//
174 module attributes {
175   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
176 } {
178 // CHECK-LABEL: @bitwise_scalar
179 func @bitwise_scalar(%arg0 : i32, %arg1 : i32) {
180   // CHECK: spv.BitwiseAnd
181   %0 = arith.andi %arg0, %arg1 : i32
182   // CHECK: spv.BitwiseOr
183   %1 = arith.ori %arg0, %arg1 : i32
184   // CHECK: spv.BitwiseXor
185   %2 = arith.xori %arg0, %arg1 : i32
186   return
189 // CHECK-LABEL: @bitwise_vector
190 func @bitwise_vector(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
191   // CHECK: spv.BitwiseAnd
192   %0 = arith.andi %arg0, %arg1 : vector<4xi32>
193   // CHECK: spv.BitwiseOr
194   %1 = arith.ori %arg0, %arg1 : vector<4xi32>
195   // CHECK: spv.BitwiseXor
196   %2 = arith.xori %arg0, %arg1 : vector<4xi32>
197   return
200 // CHECK-LABEL: @logical_scalar
201 func @logical_scalar(%arg0 : i1, %arg1 : i1) {
202   // CHECK: spv.LogicalAnd
203   %0 = arith.andi %arg0, %arg1 : i1
204   // CHECK: spv.LogicalOr
205   %1 = arith.ori %arg0, %arg1 : i1
206   // CHECK: spv.LogicalNotEqual
207   %2 = arith.xori %arg0, %arg1 : i1
208   return
211 // CHECK-LABEL: @logical_vector
212 func @logical_vector(%arg0 : vector<4xi1>, %arg1 : vector<4xi1>) {
213   // CHECK: spv.LogicalAnd
214   %0 = arith.andi %arg0, %arg1 : vector<4xi1>
215   // CHECK: spv.LogicalOr
216   %1 = arith.ori %arg0, %arg1 : vector<4xi1>
217   // CHECK: spv.LogicalNotEqual
218   %2 = arith.xori %arg0, %arg1 : vector<4xi1>
219   return
222 // CHECK-LABEL: @shift_scalar
223 func @shift_scalar(%arg0 : i32, %arg1 : i32) {
224   // CHECK: spv.ShiftLeftLogical
225   %0 = arith.shli %arg0, %arg1 : i32
226   // CHECK: spv.ShiftRightArithmetic
227   %1 = arith.shrsi %arg0, %arg1 : i32
228   // CHECK: spv.ShiftRightLogical
229   %2 = arith.shrui %arg0, %arg1 : i32
230   return
233 // CHECK-LABEL: @shift_vector
234 func @shift_vector(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
235   // CHECK: spv.ShiftLeftLogical
236   %0 = arith.shli %arg0, %arg1 : vector<4xi32>
237   // CHECK: spv.ShiftRightArithmetic
238   %1 = arith.shrsi %arg0, %arg1 : vector<4xi32>
239   // CHECK: spv.ShiftRightLogical
240   %2 = arith.shrui %arg0, %arg1 : vector<4xi32>
241   return
244 } // end module
246 // -----
248 //===----------------------------------------------------------------------===//
249 // arith.cmpf
250 //===----------------------------------------------------------------------===//
252 module attributes {
253   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
254 } {
256 // CHECK-LABEL: @cmpf
257 func @cmpf(%arg0 : f32, %arg1 : f32) {
258   // CHECK: spv.FOrdEqual
259   %1 = arith.cmpf oeq, %arg0, %arg1 : f32
260   // CHECK: spv.FOrdGreaterThan
261   %2 = arith.cmpf ogt, %arg0, %arg1 : f32
262   // CHECK: spv.FOrdGreaterThanEqual
263   %3 = arith.cmpf oge, %arg0, %arg1 : f32
264   // CHECK: spv.FOrdLessThan
265   %4 = arith.cmpf olt, %arg0, %arg1 : f32
266   // CHECK: spv.FOrdLessThanEqual
267   %5 = arith.cmpf ole, %arg0, %arg1 : f32
268   // CHECK: spv.FOrdNotEqual
269   %6 = arith.cmpf one, %arg0, %arg1 : f32
270   // CHECK: spv.FUnordEqual
271   %7 = arith.cmpf ueq, %arg0, %arg1 : f32
272   // CHECK: spv.FUnordGreaterThan
273   %8 = arith.cmpf ugt, %arg0, %arg1 : f32
274   // CHECK: spv.FUnordGreaterThanEqual
275   %9 = arith.cmpf uge, %arg0, %arg1 : f32
276   // CHECK: spv.FUnordLessThan
277   %10 = arith.cmpf ult, %arg0, %arg1 : f32
278   // CHECK: FUnordLessThanEqual
279   %11 = arith.cmpf ule, %arg0, %arg1 : f32
280   // CHECK: spv.FUnordNotEqual
281   %12 = arith.cmpf une, %arg0, %arg1 : f32
282   return
285 } // end module
287 // -----
289 // With Kernel capability, we can convert NaN check to spv.Ordered/spv.Unordered.
290 module attributes {
291   spv.target_env = #spv.target_env<#spv.vce<v1.0, [Kernel], []>, {}>
292 } {
294 // CHECK-LABEL: @cmpf
295 func @cmpf(%arg0 : f32, %arg1 : f32) {
296   // CHECK: spv.Ordered
297   %0 = arith.cmpf ord, %arg0, %arg1 : f32
298   // CHECK: spv.Unordered
299   %1 = arith.cmpf uno, %arg0, %arg1 : f32
300   return
303 } // end module
305 // -----
307 // Without Kernel capability, we need to convert NaN check to spv.IsNan.
308 module attributes {
309   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
310 } {
312 // CHECK-LABEL: @cmpf
313 // CHECK-SAME: %[[LHS:.+]]: f32, %[[RHS:.+]]: f32
314 func @cmpf(%arg0 : f32, %arg1 : f32) {
315   // CHECK:      %[[LHS_NAN:.+]] = spv.IsNan %[[LHS]] : f32
316   // CHECK-NEXT: %[[RHS_NAN:.+]] = spv.IsNan %[[RHS]] : f32
317   // CHECK-NEXT: %[[OR:.+]] = spv.LogicalOr %[[LHS_NAN]], %[[RHS_NAN]] : i1
318   // CHECK-NEXT: %{{.+}} = spv.LogicalNot %[[OR]] : i1
319   %0 = arith.cmpf ord, %arg0, %arg1 : f32
321   // CHECK-NEXT: %[[LHS_NAN:.+]] = spv.IsNan %[[LHS]] : f32
322   // CHECK-NEXT: %[[RHS_NAN:.+]] = spv.IsNan %[[RHS]] : f32
323   // CHECK-NEXT: %{{.+}} = spv.LogicalOr %[[LHS_NAN]], %[[RHS_NAN]] : i1
324   %1 = arith.cmpf uno, %arg0, %arg1 : f32
325   return
328 } // end module
330 // -----
332 //===----------------------------------------------------------------------===//
333 // arith.cmpi
334 //===----------------------------------------------------------------------===//
336 module attributes {
337   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
338 } {
340 // CHECK-LABEL: @cmpi
341 func @cmpi(%arg0 : i32, %arg1 : i32) {
342   // CHECK: spv.IEqual
343   %0 = arith.cmpi eq, %arg0, %arg1 : i32
344   // CHECK: spv.INotEqual
345   %1 = arith.cmpi ne, %arg0, %arg1 : i32
346   // CHECK: spv.SLessThan
347   %2 = arith.cmpi slt, %arg0, %arg1 : i32
348   // CHECK: spv.SLessThanEqual
349   %3 = arith.cmpi sle, %arg0, %arg1 : i32
350   // CHECK: spv.SGreaterThan
351   %4 = arith.cmpi sgt, %arg0, %arg1 : i32
352   // CHECK: spv.SGreaterThanEqual
353   %5 = arith.cmpi sge, %arg0, %arg1 : i32
354   // CHECK: spv.ULessThan
355   %6 = arith.cmpi ult, %arg0, %arg1 : i32
356   // CHECK: spv.ULessThanEqual
357   %7 = arith.cmpi ule, %arg0, %arg1 : i32
358   // CHECK: spv.UGreaterThan
359   %8 = arith.cmpi ugt, %arg0, %arg1 : i32
360   // CHECK: spv.UGreaterThanEqual
361   %9 = arith.cmpi uge, %arg0, %arg1 : i32
362   return
365 // CHECK-LABEL: @boolcmpi
366 func @boolcmpi(%arg0 : i1, %arg1 : i1) {
367   // CHECK: spv.LogicalEqual
368   %0 = arith.cmpi eq, %arg0, %arg1 : i1
369   // CHECK: spv.LogicalNotEqual
370   %1 = arith.cmpi ne, %arg0, %arg1 : i1
371   return
374 // CHECK-LABEL: @vecboolcmpi
375 func @vecboolcmpi(%arg0 : vector<4xi1>, %arg1 : vector<4xi1>) {
376   // CHECK: spv.LogicalEqual
377   %0 = arith.cmpi eq, %arg0, %arg1 : vector<4xi1>
378   // CHECK: spv.LogicalNotEqual
379   %1 = arith.cmpi ne, %arg0, %arg1 : vector<4xi1>
380   return
383 } // end module
385 // -----
387 //===----------------------------------------------------------------------===//
388 // arith.constant
389 //===----------------------------------------------------------------------===//
391 module attributes {
392   spv.target_env = #spv.target_env<
393     #spv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64], []>, {}>
394 } {
396 // CHECK-LABEL: @constant
397 func @constant() {
398   // CHECK: spv.Constant true
399   %0 = arith.constant true
400   // CHECK: spv.Constant 42 : i32
401   %1 = arith.constant 42 : i32
402   // CHECK: spv.Constant 5.000000e-01 : f32
403   %2 = arith.constant 0.5 : f32
404   // CHECK: spv.Constant dense<[2, 3]> : vector<2xi32>
405   %3 = arith.constant dense<[2, 3]> : vector<2xi32>
406   // CHECK: spv.Constant 1 : i32
407   %4 = arith.constant 1 : index
408   // CHECK: spv.Constant dense<1> : tensor<6xi32> : !spv.array<6 x i32, stride=4>
409   %5 = arith.constant dense<1> : tensor<2x3xi32>
410   // CHECK: spv.Constant dense<1.000000e+00> : tensor<6xf32> : !spv.array<6 x f32, stride=4>
411   %6 = arith.constant dense<1.0> : tensor<2x3xf32>
412   // CHECK: spv.Constant dense<{{\[}}1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf32> : !spv.array<6 x f32, stride=4>
413   %7 = arith.constant dense<[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]> : tensor<2x3xf32>
414   // CHECK: spv.Constant dense<{{\[}}1, 2, 3, 4, 5, 6]> : tensor<6xi32> : !spv.array<6 x i32, stride=4>
415   %8 = arith.constant dense<[[1, 2, 3], [4, 5, 6]]> : tensor<2x3xi32>
416   // CHECK: spv.Constant dense<{{\[}}1, 2, 3, 4, 5, 6]> : tensor<6xi32> : !spv.array<6 x i32, stride=4>
417   %9 =  arith.constant dense<[[1, 2], [3, 4], [5, 6]]> : tensor<3x2xi32>
418   // CHECK: spv.Constant dense<{{\[}}1, 2, 3, 4, 5, 6]> : tensor<6xi32> : !spv.array<6 x i32, stride=4>
419   %10 =  arith.constant dense<[1, 2, 3, 4, 5, 6]> : tensor<6xi32>
420   return
423 // CHECK-LABEL: @constant_16bit
424 func @constant_16bit() {
425   // CHECK: spv.Constant 4 : i16
426   %0 = arith.constant 4 : i16
427   // CHECK: spv.Constant 5.000000e+00 : f16
428   %1 = arith.constant 5.0 : f16
429   // CHECK: spv.Constant dense<[2, 3]> : vector<2xi16>
430   %2 = arith.constant dense<[2, 3]> : vector<2xi16>
431   // CHECK: spv.Constant dense<4.000000e+00> : tensor<5xf16> : !spv.array<5 x f16, stride=2>
432   %3 = arith.constant dense<4.0> : tensor<5xf16>
433   return
436 // CHECK-LABEL: @constant_64bit
437 func @constant_64bit() {
438   // CHECK: spv.Constant 4 : i64
439   %0 = arith.constant 4 : i64
440   // CHECK: spv.Constant 5.000000e+00 : f64
441   %1 = arith.constant 5.0 : f64
442   // CHECK: spv.Constant dense<[2, 3]> : vector<2xi64>
443   %2 = arith.constant dense<[2, 3]> : vector<2xi64>
444   // CHECK: spv.Constant dense<4.000000e+00> : tensor<5xf64> : !spv.array<5 x f64, stride=8>
445   %3 = arith.constant dense<4.0> : tensor<5xf64>
446   return
449 // CHECK-LABEL: @constant_size1
450 func @constant_size1() {
451   // CHECK: spv.Constant true
452   %0 = arith.constant dense<true> : tensor<1xi1>
453   // CHECK: spv.Constant 4 : i64
454   %1 = arith.constant dense<4> : vector<1xi64>
455   // CHECK: spv.Constant 5.000000e+00 : f64
456   %2 = arith.constant dense<5.0> : tensor<1xf64>
457   return
460 } // end module
462 // -----
464 // Check that constants are converted to 32-bit when no special capability.
465 module attributes {
466   spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, {}>
467 } {
469 // CHECK-LABEL: @constant_16bit
470 func @constant_16bit() {
471   // CHECK: spv.Constant 4 : i32
472   %0 = arith.constant 4 : i16
473   // CHECK: spv.Constant 5.000000e+00 : f32
474   %1 = arith.constant 5.0 : f16
475   // CHECK: spv.Constant dense<[2, 3]> : vector<2xi32>
476   %2 = arith.constant dense<[2, 3]> : vector<2xi16>
477   // CHECK: spv.Constant dense<4.000000e+00> : tensor<5xf32> : !spv.array<5 x f32, stride=4>
478   %3 = arith.constant dense<4.0> : tensor<5xf16>
479   // CHECK: spv.Constant dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf32> : !spv.array<4 x f32, stride=4>
480   %4 = arith.constant dense<[[1.0, 2.0], [3.0, 4.0]]> : tensor<2x2xf16>
481   return
484 // CHECK-LABEL: @constant_64bit
485 func @constant_64bit() {
486   // CHECK: spv.Constant 4 : i32
487   %0 = arith.constant 4 : i64
488   // CHECK: spv.Constant 5.000000e+00 : f32
489   %1 = arith.constant 5.0 : f64
490   // CHECK: spv.Constant dense<[2, 3]> : vector<2xi32>
491   %2 = arith.constant dense<[2, 3]> : vector<2xi64>
492   // CHECK: spv.Constant dense<4.000000e+00> : tensor<5xf32> : !spv.array<5 x f32, stride=4>
493   %3 = arith.constant dense<4.0> : tensor<5xf64>
494   // CHECK: spv.Constant dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf32> : !spv.array<4 x f32, stride=4>
495   %4 = arith.constant dense<[[1.0, 2.0], [3.0, 4.0]]> : tensor<2x2xf16>
496   return
499 // CHECK-LABEL: @constant_size1
500 func @constant_size1() {
501   // CHECK: spv.Constant 4 : i32
502   %0 = arith.constant dense<4> : vector<1xi64>
503   // CHECK: spv.Constant 5.000000e+00 : f32
504   %1 = arith.constant dense<5.0> : tensor<1xf64>
505   return
508 // CHECK-LABEL: @corner_cases
509 func @corner_cases() {
510   // CHECK: %{{.*}} = spv.Constant -1 : i32
511   %0 = arith.constant 4294967295  : i64 // 2^32 - 1
512   // CHECK: %{{.*}} = spv.Constant 2147483647 : i32
513   %1 = arith.constant 2147483647  : i64 // 2^31 - 1
514   // CHECK: %{{.*}} = spv.Constant -2147483648 : i32
515   %2 = arith.constant 2147483648  : i64 // 2^31
516   // CHECK: %{{.*}} = spv.Constant -2147483648 : i32
517   %3 = arith.constant -2147483648 : i64 // -2^31
519   // CHECK: %{{.*}} = spv.Constant -1 : i32
520   %5 = arith.constant -1 : i64
521   // CHECK: %{{.*}} = spv.Constant -2 : i32
522   %6 = arith.constant -2 : i64
523   // CHECK: %{{.*}} = spv.Constant -1 : i32
524   %7 = arith.constant -1 : index
525   // CHECK: %{{.*}} = spv.Constant -2 : i32
526   %8 = arith.constant -2 : index
529   // CHECK: spv.Constant false
530   %9 = arith.constant false
531   // CHECK: spv.Constant true
532   %10 = arith.constant true
534   return
537 // CHECK-LABEL: @unsupported_cases
538 func @unsupported_cases() {
539   // CHECK: %{{.*}} = arith.constant 4294967296 : i64
540   %0 = arith.constant 4294967296 : i64 // 2^32
541   // CHECK: %{{.*}} = arith.constant -2147483649 : i64
542   %1 = arith.constant -2147483649 : i64 // -2^31 - 1
543   // CHECK: %{{.*}} = arith.constant 1.0000000000000002 : f64
544   %2 = arith.constant 0x3FF0000000000001 : f64 // smallest number > 1
545   return
548 } // end module
550 // -----
552 //===----------------------------------------------------------------------===//
553 // std cast ops
554 //===----------------------------------------------------------------------===//
556 module attributes {
557   spv.target_env = #spv.target_env<
558     #spv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64], []>, {}>
559 } {
561 // CHECK-LABEL: index_cast1
562 func @index_cast1(%arg0: i16) {
563   // CHECK: spv.SConvert %{{.+}} : i16 to i32
564   %0 = arith.index_cast %arg0 : i16 to index
565   return
568 // CHECK-LABEL: index_cast2
569 func @index_cast2(%arg0: index) {
570   // CHECK: spv.SConvert %{{.+}} : i32 to i16
571   %0 = arith.index_cast %arg0 : index to i16
572   return
575 // CHECK-LABEL: index_cast3
576 func @index_cast3(%arg0: i32) {
577   // CHECK-NOT: spv.SConvert
578   %0 = arith.index_cast %arg0 : i32 to index
579   return
582 // CHECK-LABEL: index_cast4
583 func @index_cast4(%arg0: index) {
584   // CHECK-NOT: spv.SConvert
585   %0 = arith.index_cast %arg0 : index to i32
586   return
589 // CHECK-LABEL: @bit_cast
590 func @bit_cast(%arg0: vector<2xf32>, %arg1: i64) {
591   // CHECK: spv.Bitcast %{{.+}} : vector<2xf32> to vector<2xi32>
592   %0 = arith.bitcast %arg0 : vector<2xf32> to vector<2xi32>
593   // CHECK: spv.Bitcast %{{.+}} : i64 to f64
594   %1 = arith.bitcast %arg1 : i64 to f64
595   return
598 // CHECK-LABEL: @fpext1
599 func @fpext1(%arg0: f16) -> f64 {
600   // CHECK: spv.FConvert %{{.*}} : f16 to f64
601   %0 = arith.extf %arg0 : f16 to f64
602   return %0 : f64
605 // CHECK-LABEL: @fpext2
606 func @fpext2(%arg0 : f32) -> f64 {
607   // CHECK: spv.FConvert %{{.*}} : f32 to f64
608   %0 = arith.extf %arg0 : f32 to f64
609   return %0 : f64
612 // CHECK-LABEL: @fptrunc1
613 func @fptrunc1(%arg0 : f64) -> f16 {
614   // CHECK: spv.FConvert %{{.*}} : f64 to f16
615   %0 = arith.truncf %arg0 : f64 to f16
616   return %0 : f16
619 // CHECK-LABEL: @fptrunc2
620 func @fptrunc2(%arg0: f32) -> f16 {
621   // CHECK: spv.FConvert %{{.*}} : f32 to f16
622   %0 = arith.truncf %arg0 : f32 to f16
623   return %0 : f16
626 // CHECK-LABEL: @sitofp1
627 func @sitofp1(%arg0 : i32) -> f32 {
628   // CHECK: spv.ConvertSToF %{{.*}} : i32 to f32
629   %0 = arith.sitofp %arg0 : i32 to f32
630   return %0 : f32
633 // CHECK-LABEL: @sitofp2
634 func @sitofp2(%arg0 : i64) -> f64 {
635   // CHECK: spv.ConvertSToF %{{.*}} : i64 to f64
636   %0 = arith.sitofp %arg0 : i64 to f64
637   return %0 : f64
640 // CHECK-LABEL: @uitofp_i16_f32
641 func @uitofp_i16_f32(%arg0: i16) -> f32 {
642   // CHECK: spv.ConvertUToF %{{.*}} : i16 to f32
643   %0 = arith.uitofp %arg0 : i16 to f32
644   return %0 : f32
647 // CHECK-LABEL: @uitofp_i32_f32
648 func @uitofp_i32_f32(%arg0 : i32) -> f32 {
649   // CHECK: spv.ConvertUToF %{{.*}} : i32 to f32
650   %0 = arith.uitofp %arg0 : i32 to f32
651   return %0 : f32
654 // CHECK-LABEL: @uitofp_i1_f32
655 func @uitofp_i1_f32(%arg0 : i1) -> f32 {
656   // CHECK: %[[ZERO:.+]] = spv.Constant 0.000000e+00 : f32
657   // CHECK: %[[ONE:.+]] = spv.Constant 1.000000e+00 : f32
658   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : i1, f32
659   %0 = arith.uitofp %arg0 : i1 to f32
660   return %0 : f32
663 // CHECK-LABEL: @uitofp_i1_f64
664 func @uitofp_i1_f64(%arg0 : i1) -> f64 {
665   // CHECK: %[[ZERO:.+]] = spv.Constant 0.000000e+00 : f64
666   // CHECK: %[[ONE:.+]] = spv.Constant 1.000000e+00 : f64
667   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : i1, f64
668   %0 = arith.uitofp %arg0 : i1 to f64
669   return %0 : f64
672 // CHECK-LABEL: @uitofp_vec_i1_f32
673 func @uitofp_vec_i1_f32(%arg0 : vector<4xi1>) -> vector<4xf32> {
674   // CHECK: %[[ZERO:.+]] = spv.Constant dense<0.000000e+00> : vector<4xf32>
675   // CHECK: %[[ONE:.+]] = spv.Constant dense<1.000000e+00> : vector<4xf32>
676   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : vector<4xi1>, vector<4xf32>
677   %0 = arith.uitofp %arg0 : vector<4xi1> to vector<4xf32>
678   return %0 : vector<4xf32>
681 // CHECK-LABEL: @uitofp_vec_i1_f64
682 spv.func @uitofp_vec_i1_f64(%arg0: vector<4xi1>) -> vector<4xf64> "None" {
683   // CHECK: %[[ZERO:.+]] = spv.Constant dense<0.000000e+00> : vector<4xf64>
684   // CHECK: %[[ONE:.+]] = spv.Constant dense<1.000000e+00> : vector<4xf64>
685   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : vector<4xi1>, vector<4xf64>
686   %0 = spv.Constant dense<0.000000e+00> : vector<4xf64>
687   %1 = spv.Constant dense<1.000000e+00> : vector<4xf64>
688   %2 = spv.Select %arg0, %1, %0 : vector<4xi1>, vector<4xf64>
689   spv.ReturnValue %2 : vector<4xf64>
692 // CHECK-LABEL: @sexti1
693 func @sexti1(%arg0: i16) -> i64 {
694   // CHECK: spv.SConvert %{{.*}} : i16 to i64
695   %0 = arith.extsi %arg0 : i16 to i64
696   return %0 : i64
699 // CHECK-LABEL: @sexti2
700 func @sexti2(%arg0 : i32) -> i64 {
701   // CHECK: spv.SConvert %{{.*}} : i32 to i64
702   %0 = arith.extsi %arg0 : i32 to i64
703   return %0 : i64
706 // CHECK-LABEL: @zexti1
707 func @zexti1(%arg0: i16) -> i64 {
708   // CHECK: spv.UConvert %{{.*}} : i16 to i64
709   %0 = arith.extui %arg0 : i16 to i64
710   return %0 : i64
713 // CHECK-LABEL: @zexti2
714 func @zexti2(%arg0 : i32) -> i64 {
715   // CHECK: spv.UConvert %{{.*}} : i32 to i64
716   %0 = arith.extui %arg0 : i32 to i64
717   return %0 : i64
720 // CHECK-LABEL: @zexti3
721 func @zexti3(%arg0 : i1) -> i32 {
722   // CHECK: %[[ZERO:.+]] = spv.Constant 0 : i32
723   // CHECK: %[[ONE:.+]] = spv.Constant 1 : i32
724   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : i1, i32
725   %0 = arith.extui %arg0 : i1 to i32
726   return %0 : i32
729 // CHECK-LABEL: @zexti4
730 func @zexti4(%arg0 : vector<4xi1>) -> vector<4xi32> {
731   // CHECK: %[[ZERO:.+]] = spv.Constant dense<0> : vector<4xi32>
732   // CHECK: %[[ONE:.+]] = spv.Constant dense<1> : vector<4xi32>
733   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : vector<4xi1>, vector<4xi32>
734   %0 = arith.extui %arg0 : vector<4xi1> to vector<4xi32>
735   return %0 : vector<4xi32>
738 // CHECK-LABEL: @zexti5
739 func @zexti5(%arg0 : vector<4xi1>) -> vector<4xi64> {
740   // CHECK: %[[ZERO:.+]] = spv.Constant dense<0> : vector<4xi64>
741   // CHECK: %[[ONE:.+]] = spv.Constant dense<1> : vector<4xi64>
742   // CHECK: spv.Select %{{.*}}, %[[ONE]], %[[ZERO]] : vector<4xi1>, vector<4xi64>
743   %0 = arith.extui %arg0 : vector<4xi1> to vector<4xi64>
744   return %0 : vector<4xi64>
747 // CHECK-LABEL: @trunci1
748 func @trunci1(%arg0 : i64) -> i16 {
749   // CHECK: spv.SConvert %{{.*}} : i64 to i16
750   %0 = arith.trunci %arg0 : i64 to i16
751   return %0 : i16
754 // CHECK-LABEL: @trunci2
755 func @trunci2(%arg0: i32) -> i16 {
756   // CHECK: spv.SConvert %{{.*}} : i32 to i16
757   %0 = arith.trunci %arg0 : i32 to i16
758   return %0 : i16
761 // CHECK-LABEL: @trunc_to_i1
762 func @trunc_to_i1(%arg0: i32) -> i1 {
763   // CHECK: %[[MASK:.*]] = spv.Constant 1 : i32
764   // CHECK: %[[MASKED_SRC:.*]] = spv.BitwiseAnd %{{.*}}, %[[MASK]] : i32
765   // CHECK: %[[IS_ONE:.*]] = spv.IEqual %[[MASKED_SRC]], %[[MASK]] : i32
766   // CHECK-DAG: %[[TRUE:.*]] = spv.Constant true
767   // CHECK-DAG: %[[FALSE:.*]] = spv.Constant false
768   // CHECK: spv.Select %[[IS_ONE]], %[[TRUE]], %[[FALSE]] : i1, i1
769   %0 = arith.trunci %arg0 : i32 to i1
770   return %0 : i1
773 // CHECK-LABEL: @trunc_to_veci1
774 func @trunc_to_veci1(%arg0: vector<4xi32>) -> vector<4xi1> {
775   // CHECK: %[[MASK:.*]] = spv.Constant dense<1> : vector<4xi32>
776   // CHECK: %[[MASKED_SRC:.*]] = spv.BitwiseAnd %{{.*}}, %[[MASK]] : vector<4xi32>
777   // CHECK: %[[IS_ONE:.*]] = spv.IEqual %[[MASKED_SRC]], %[[MASK]] : vector<4xi32>
778   // CHECK-DAG: %[[TRUE:.*]] = spv.Constant dense<true> : vector<4xi1>
779   // CHECK-DAG: %[[FALSE:.*]] = spv.Constant dense<false> : vector<4xi1>
780   // CHECK: spv.Select %[[IS_ONE]], %[[TRUE]], %[[FALSE]] : vector<4xi1>, vector<4xi1>
781   %0 = arith.trunci %arg0 : vector<4xi32> to vector<4xi1>
782   return %0 : vector<4xi1>
785 // CHECK-LABEL: @fptosi1
786 func @fptosi1(%arg0 : f32) -> i32 {
787   // CHECK: spv.ConvertFToS %{{.*}} : f32 to i32
788   %0 = arith.fptosi %arg0 : f32 to i32
789   return %0 : i32
792 // CHECK-LABEL: @fptosi2
793 func @fptosi2(%arg0 : f16) -> i16 {
794   // CHECK: spv.ConvertFToS %{{.*}} : f16 to i16
795   %0 = arith.fptosi %arg0 : f16 to i16
796   return %0 : i16
799 } // end module
801 // -----
803 // Checks that cast types will be adjusted when missing special capabilities for
804 // certain non-32-bit scalar types.
805 module attributes {
806   spv.target_env = #spv.target_env<#spv.vce<v1.0, [Float64], []>, {}>
807 } {
809 // CHECK-LABEL: @fpext1
810 // CHECK-SAME: %[[ARG:.*]]: f32
811 func @fpext1(%arg0: f16) -> f64 {
812   // CHECK-NEXT: spv.FConvert %[[ARG]] : f32 to f64
813   %0 = arith.extf %arg0 : f16 to f64
814   return %0: f64
817 // CHECK-LABEL: @fpext2
818 // CHECK-SAME: %[[ARG:.*]]: f32
819 func @fpext2(%arg0 : f32) -> f64 {
820   // CHECK-NEXT: spv.FConvert %[[ARG]] : f32 to f64
821   %0 = arith.extf %arg0 : f32 to f64
822   return %0: f64
825 } // end module
827 // -----
829 // Checks that cast types will be adjusted when missing special capabilities for
830 // certain non-32-bit scalar types.
831 module attributes {
832   spv.target_env = #spv.target_env<#spv.vce<v1.0, [Float16], []>, {}>
833 } {
835 // CHECK-LABEL: @fptrunc1
836 // CHECK-SAME: %[[ARG:.*]]: f32
837 func @fptrunc1(%arg0 : f64) -> f16 {
838   // CHECK-NEXT: spv.FConvert %[[ARG]] : f32 to f16
839   %0 = arith.truncf %arg0 : f64 to f16
840   return %0: f16
843 // CHECK-LABEL: @fptrunc2
844 // CHECK-SAME: %[[ARG:.*]]: f32
845 func @fptrunc2(%arg0: f32) -> f16 {
846   // CHECK-NEXT: spv.FConvert %[[ARG]] : f32 to f16
847   %0 = arith.truncf %arg0 : f32 to f16
848   return %0: f16
851 // CHECK-LABEL: @sitofp
852 func @sitofp(%arg0 : i64) -> f64 {
853   // CHECK: spv.ConvertSToF %{{.*}} : i32 to f32
854   %0 = arith.sitofp %arg0 : i64 to f64
855   return %0: f64
858 } // end module
860 // -----
862 // Check OpenCL lowering of arith.remsi
863 module attributes {
864   spv.target_env = #spv.target_env<
865     #spv.vce<v1.0, [Int16, Kernel], []>, {}>
866 } {
868 // CHECK-LABEL: @scalar_srem
869 // CHECK-SAME: (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32)
870 func @scalar_srem(%lhs: i32, %rhs: i32) {
871   // CHECK: %[[LABS:.+]] = spv.OCL.s_abs %[[LHS]] : i32
872   // CHECK: %[[RABS:.+]] = spv.OCL.s_abs %[[RHS]] : i32
873   // CHECK:  %[[ABS:.+]] = spv.UMod %[[LABS]], %[[RABS]] : i32
874   // CHECK:  %[[POS:.+]] = spv.IEqual %[[LHS]], %[[LABS]] : i32
875   // CHECK:  %[[NEG:.+]] = spv.SNegate %[[ABS]] : i32
876   // CHECK:      %{{.+}} = spv.Select %[[POS]], %[[ABS]], %[[NEG]] : i1, i32
877   %0 = arith.remsi %lhs, %rhs: i32
878   return
881 // CHECK-LABEL: @vector_srem
882 // CHECK-SAME: (%[[LHS:.+]]: vector<3xi16>, %[[RHS:.+]]: vector<3xi16>)
883 func @vector_srem(%arg0: vector<3xi16>, %arg1: vector<3xi16>) {
884   // CHECK: %[[LABS:.+]] = spv.OCL.s_abs %[[LHS]] : vector<3xi16>
885   // CHECK: %[[RABS:.+]] = spv.OCL.s_abs %[[RHS]] : vector<3xi16>
886   // CHECK:  %[[ABS:.+]] = spv.UMod %[[LABS]], %[[RABS]] : vector<3xi16>
887   // CHECK:  %[[POS:.+]] = spv.IEqual %[[LHS]], %[[LABS]] : vector<3xi16>
888   // CHECK:  %[[NEG:.+]] = spv.SNegate %[[ABS]] : vector<3xi16>
889   // CHECK:      %{{.+}} = spv.Select %[[POS]], %[[ABS]], %[[NEG]] : vector<3xi1>, vector<3xi16>
890   %0 = arith.remsi %arg0, %arg1: vector<3xi16>
891   return
894 } // end module