[AArch64] Add fpext and fpround costs (#119292)
[llvm-project.git] / mlir / test / Dialect / SPIRV / IR / cast-ops.mlir
blob34d0109e6bb440355650109a4380fe7e2eeebf8a
1 // RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
3 //===----------------------------------------------------------------------===//
4 // spirv.Bitcast
5 //===----------------------------------------------------------------------===//
7 func.func @cast1(%arg0 : f32) {
8   // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : f32 to i32
9   %0 = spirv.Bitcast %arg0 : f32 to i32
10   return
13 func.func @cast2(%arg0 : vector<2xf32>) {
14   // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : vector<2xf32> to vector<2xi32>
15   %0 = spirv.Bitcast %arg0 : vector<2xf32> to vector<2xi32>
16   return
19 func.func @cast3(%arg0 : vector<2xf32>) {
20   // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : vector<2xf32> to i64
21   %0 = spirv.Bitcast %arg0 : vector<2xf32> to i64
22   return
25 func.func @cast4(%arg0 : !spirv.ptr<f32, Function>) {
26   // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : !spirv.ptr<f32, Function> to !spirv.ptr<i32, Function>
27   %0 = spirv.Bitcast %arg0 : !spirv.ptr<f32, Function> to !spirv.ptr<i32, Function>
28   return
31 func.func @cast5(%arg0 : !spirv.ptr<f32, Function>) {
32   // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : !spirv.ptr<f32, Function> to !spirv.ptr<vector<2xi32>, Function>
33   %0 = spirv.Bitcast %arg0 : !spirv.ptr<f32, Function> to !spirv.ptr<vector<2xi32>, Function>
34   return
37 func.func @cast6(%arg0 : vector<4xf32>) {
38   // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : vector<4xf32> to vector<2xi64>
39   %0 = spirv.Bitcast %arg0 : vector<4xf32> to vector<2xi64>
40   return
43 // -----
45 func.func @cast1(%arg0 : f32) {
46   // expected-error @+1 {{result type must be different from operand type}}
47   %0 = spirv.Bitcast %arg0 : f32 to f32
48   return
51 // -----
53 func.func @cast1(%arg0 : f32) {
54   // expected-error @+1 {{mismatch in result type bitwidth 64 and operand type bitwidth 32}}
55   %0 = spirv.Bitcast %arg0 : f32 to i64
56   return
59 // -----
61 func.func @cast1(%arg0 : vector<2xf32>) {
62   // expected-error @+1 {{mismatch in result type bitwidth 96 and operand type bitwidth 64}}
63   %0 = spirv.Bitcast %arg0 : vector<2xf32> to vector<3xf32>
64   return
67 // -----
69 func.func @cast3(%arg0 : !spirv.ptr<f32, Function>) {
70   // expected-error @+1 {{unhandled bit cast conversion from pointer type to non-pointer type}}
71   %0 = spirv.Bitcast %arg0 : !spirv.ptr<f32, Function> to i64
72   return
75 // -----
77 func.func @cast3(%arg0 : i64) {
78   // expected-error @+1 {{unhandled bit cast conversion from non-pointer type to pointer type}}
79   %0 = spirv.Bitcast %arg0 : i64 to !spirv.ptr<f32, Function>
80   return
83 // -----
85 //===----------------------------------------------------------------------===//
86 // spirv.ConvertFToS
87 //===----------------------------------------------------------------------===//
89 func.func @convert_f_to_s_scalar(%arg0 : f32) -> i32 {
90   // CHECK: {{%.*}} = spirv.ConvertFToS {{%.*}} : f32 to i32
91   %0 = spirv.ConvertFToS %arg0 : f32 to i32
92   spirv.ReturnValue %0 : i32
95 // -----
97 func.func @convert_f64_to_s32_scalar(%arg0 : f64) -> i32 {
98   // CHECK: {{%.*}} = spirv.ConvertFToS {{%.*}} : f64 to i32
99   %0 = spirv.ConvertFToS %arg0 : f64 to i32
100   spirv.ReturnValue %0 : i32
103 // -----
105 func.func @convert_f_to_s_vector(%arg0 : vector<3xf32>) -> vector<3xi32> {
106   // CHECK: {{%.*}} = spirv.ConvertFToS {{%.*}} : vector<3xf32> to vector<3xi32>
107   %0 = spirv.ConvertFToS %arg0 : vector<3xf32> to vector<3xi32>
108   spirv.ReturnValue %0 : vector<3xi32>
111 // -----
113 //===----------------------------------------------------------------------===//
114 // spirv.ConvertFToU
115 //===----------------------------------------------------------------------===//
117 func.func @convert_f_to_u_scalar(%arg0 : f32) -> i32 {
118   // CHECK: {{%.*}} = spirv.ConvertFToU {{%.*}} : f32 to i32
119   %0 = spirv.ConvertFToU %arg0 : f32 to i32
120   spirv.ReturnValue %0 : i32
123 // -----
125 func.func @convert_f64_to_u32_scalar(%arg0 : f64) -> i32 {
126   // CHECK: {{%.*}} = spirv.ConvertFToU {{%.*}} : f64 to i32
127   %0 = spirv.ConvertFToU %arg0 : f64 to i32
128   spirv.ReturnValue %0 : i32
131 // -----
133 func.func @convert_f_to_u_vector(%arg0 : vector<3xf32>) -> vector<3xi32> {
134   // CHECK: {{%.*}} = spirv.ConvertFToU {{%.*}} : vector<3xf32> to vector<3xi32>
135   %0 = spirv.ConvertFToU %arg0 : vector<3xf32> to vector<3xi32>
136   spirv.ReturnValue %0 : vector<3xi32>
139 // -----
141 func.func @convert_f_to_u.coopmatrix(%arg0 : !spirv.coopmatrix<8x16xf32, Subgroup, MatrixB>) {
142   // CHECK: {{%.*}} = spirv.ConvertFToU {{%.*}} : !spirv.coopmatrix<8x16xf32, Subgroup, MatrixB> to !spirv.coopmatrix<8x16xi32, Subgroup, MatrixB>
143   %0 = spirv.ConvertFToU %arg0 : !spirv.coopmatrix<8x16xf32, Subgroup, MatrixB> to !spirv.coopmatrix<8x16xi32, Subgroup, MatrixB>
144   spirv.Return
147 // -----
149 //===----------------------------------------------------------------------===//
150 // spirv.ConvertSToF
151 //===----------------------------------------------------------------------===//
153 func.func @convert_s_to_f_scalar(%arg0 : i32) -> f32 {
154   // CHECK: {{%.*}} = spirv.ConvertSToF {{%.*}} : i32 to f32
155   %0 = spirv.ConvertSToF %arg0 : i32 to f32
156   spirv.ReturnValue %0 : f32
159 // -----
161 func.func @convert_s64_to_f32_scalar(%arg0 : i64) -> f32 {
162   // CHECK: {{%.*}} = spirv.ConvertSToF {{%.*}} : i64 to f32
163   %0 = spirv.ConvertSToF %arg0 : i64 to f32
164   spirv.ReturnValue %0 : f32
167 // -----
169 func.func @convert_s_to_f_vector(%arg0 : vector<3xi32>) -> vector<3xf32> {
170   // CHECK: {{%.*}} = spirv.ConvertSToF {{%.*}} : vector<3xi32> to vector<3xf32>
171   %0 = spirv.ConvertSToF %arg0 : vector<3xi32> to vector<3xf32>
172   spirv.ReturnValue %0 : vector<3xf32>
175 // -----
177 //===----------------------------------------------------------------------===//
178 // spirv.ConvertUToF
179 //===----------------------------------------------------------------------===//
181 func.func @convert_u_to_f_scalar(%arg0 : i32) -> f32 {
182   // CHECK: {{%.*}} = spirv.ConvertUToF {{%.*}} : i32 to f32
183   %0 = spirv.ConvertUToF %arg0 : i32 to f32
184   spirv.ReturnValue %0 : f32
187 // -----
189 func.func @convert_u64_to_f32_scalar(%arg0 : i64) -> f32 {
190   // CHECK: {{%.*}} = spirv.ConvertUToF {{%.*}} : i64 to f32
191   %0 = spirv.ConvertUToF %arg0 : i64 to f32
192   spirv.ReturnValue %0 : f32
195 // -----
197 func.func @convert_u_to_f_vector(%arg0 : vector<3xi32>) -> vector<3xf32> {
198   // CHECK: {{%.*}} = spirv.ConvertUToF {{%.*}} : vector<3xi32> to vector<3xf32>
199   %0 = spirv.ConvertUToF %arg0 : vector<3xi32> to vector<3xf32>
200   spirv.ReturnValue %0 : vector<3xf32>
203 // -----
205 //===----------------------------------------------------------------------===//
206 // spirv.FConvert
207 //===----------------------------------------------------------------------===//
209 func.func @f_convert_scalar(%arg0 : f32) -> f64 {
210   // CHECK: {{%.*}} = spirv.FConvert {{%.*}} : f32 to f64
211   %0 = spirv.FConvert %arg0 : f32 to f64
212   spirv.ReturnValue %0 : f64
215 // -----
217 func.func @f_convert_vector(%arg0 : vector<3xf32>) -> vector<3xf64> {
218   // CHECK: {{%.*}} = spirv.FConvert {{%.*}} : vector<3xf32> to vector<3xf64>
219   %0 = spirv.FConvert %arg0 : vector<3xf32> to vector<3xf64>
220   spirv.ReturnValue %0 : vector<3xf64>
223 // -----
225 func.func @f_convert_coop_matrix(%arg0 : !spirv.coopmatrix<8x16xf32, Subgroup, MatrixA>) {
226   // CHECK: {{%.*}} = spirv.FConvert {{%.*}} : !spirv.coopmatrix<8x16xf32, Subgroup, MatrixA> to !spirv.coopmatrix<8x16xf64, Subgroup, MatrixA>
227   %0 = spirv.FConvert %arg0 : !spirv.coopmatrix<8x16xf32, Subgroup, MatrixA> to !spirv.coopmatrix<8x16xf64, Subgroup, MatrixA>
228   spirv.Return
231 // -----
233 func.func @f_convert_vector(%arg0 : f32) -> f32 {
234   // expected-error @+1 {{expected the different bit widths for operand type and result type, but provided 'f32' and 'f32'}}
235   %0 = spirv.FConvert %arg0 : f32 to f32
236   spirv.ReturnValue %0 : f32
239 // -----
241 //===----------------------------------------------------------------------===//
242 // spirv.SConvert
243 //===----------------------------------------------------------------------===//
245 func.func @s_convert_scalar(%arg0 : i32) -> i64 {
246   // CHECK: {{%.*}} = spirv.SConvert {{%.*}} : i32 to i64
247   %0 = spirv.SConvert %arg0 : i32 to i64
248   spirv.ReturnValue %0 : i64
251 // -----
253 //===----------------------------------------------------------------------===//
254 // spirv.UConvert
255 //===----------------------------------------------------------------------===//
257 func.func @u_convert_scalar(%arg0 : i32) -> i64 {
258   // CHECK: {{%.*}} = spirv.UConvert {{%.*}} : i32 to i64
259   %0 = spirv.UConvert %arg0 : i32 to i64
260   spirv.ReturnValue %0 : i64
263 // -----
265 //===----------------------------------------------------------------------===//
266 // spirv.PtrCastToGeneric
267 //===----------------------------------------------------------------------===//
269 func.func @ptrcasttogeneric1(%arg0 : !spirv.ptr<f32, CrossWorkgroup>) {
270   // CHECK: {{%.*}} = spirv.PtrCastToGeneric {{%.*}} : !spirv.ptr<f32, CrossWorkgroup> to !spirv.ptr<f32, Generic>
271   %0 = spirv.PtrCastToGeneric %arg0 : !spirv.ptr<f32, CrossWorkgroup> to !spirv.ptr<f32, Generic>
272   return
274 // -----
276 func.func @ptrcasttogeneric2(%arg0 : !spirv.ptr<f32, StorageBuffer>) {
277   // expected-error @+1 {{pointer must point to the Workgroup, CrossWorkgroup, or Function Storage Class}}
278   %0 = spirv.PtrCastToGeneric %arg0 : !spirv.ptr<f32, StorageBuffer> to !spirv.ptr<f32, Generic>
279   return
282 // -----
284 func.func @ptrcasttogeneric3(%arg0 : !spirv.ptr<f32, CrossWorkgroup>) {
285   // expected-error @+1 {{result type must be of storage class Generic}}
286   %0 = spirv.PtrCastToGeneric %arg0 : !spirv.ptr<f32, CrossWorkgroup> to !spirv.ptr<f32, Uniform>
287   return
290 // -----
292 func.func @ptrcasttogeneric4(%arg0 : !spirv.ptr<f32, CrossWorkgroup>) {
293   // expected-error @+1 {{pointee type must have the same as the op result type}}
294   %0 = spirv.PtrCastToGeneric %arg0 : !spirv.ptr<f32, CrossWorkgroup> to !spirv.ptr<vector<2xi32>, Generic>
295   return
298 // -----
300 //===----------------------------------------------------------------------===//
301 // spirv.GenericCastToPtr
302 //===----------------------------------------------------------------------===//
304 func.func @genericcasttoptr1(%arg0 : !spirv.ptr<vector<2xi32>, Generic>) {
305   // CHECK: {{%.*}} = spirv.GenericCastToPtr {{%.*}} : !spirv.ptr<vector<2xi32>, Generic> to !spirv.ptr<vector<2xi32>, CrossWorkgroup>
306   %0 = spirv.GenericCastToPtr %arg0 : !spirv.ptr<vector<2xi32>, Generic> to !spirv.ptr<vector<2xi32>, CrossWorkgroup>
307   return
309 // -----
311 func.func @genericcasttoptr2(%arg0 : !spirv.ptr<f32, Uniform>) {
312   // expected-error @+1 {{pointer type must be of storage class Generic}}
313   %0 = spirv.GenericCastToPtr %arg0 : !spirv.ptr<f32, Uniform> to !spirv.ptr<f32, Workgroup>
314   return
317 // -----
319 func.func @genericcasttoptr3(%arg0 : !spirv.ptr<f32, Generic>) {
320   // expected-error @+1 {{result must point to the Workgroup, CrossWorkgroup, or Function Storage Class}}
321   %0 = spirv.GenericCastToPtr %arg0 : !spirv.ptr<f32, Generic> to !spirv.ptr<f32, Uniform>
322   return
325 // -----
327 func.func @genericcasttoptr4(%arg0 : !spirv.ptr<f32, Generic>) {
328   // expected-error @+1 {{pointee type must have the same as the op result type}}
329   %0 = spirv.GenericCastToPtr %arg0 : !spirv.ptr<f32, Generic> to !spirv.ptr<vector<2xi32>, Workgroup>
330   return
332 // -----
334 //===----------------------------------------------------------------------===//
335 // spirv.GenericCastToPtrExplicit
336 //===----------------------------------------------------------------------===//
338 func.func @genericcasttoptrexplicit1(%arg0 : !spirv.ptr<vector<2xi32>, Generic>) {
339   // CHECK: {{%.*}} = spirv.GenericCastToPtrExplicit {{%.*}} : !spirv.ptr<vector<2xi32>, Generic> to !spirv.ptr<vector<2xi32>, CrossWorkgroup>
340   %0 = spirv.GenericCastToPtrExplicit %arg0 : !spirv.ptr<vector<2xi32>, Generic> to !spirv.ptr<vector<2xi32>, CrossWorkgroup>
341   return
343 // -----
345 func.func @genericcasttoptrexplicit2(%arg0 : !spirv.ptr<f32, Uniform>) {
346   // expected-error @+1 {{pointer type must be of storage class Generic}}
347   %0 = spirv.GenericCastToPtrExplicit %arg0 : !spirv.ptr<f32, Uniform> to !spirv.ptr<f32, Workgroup>
348   return
351 // -----
353 func.func @genericcasttoptrexplicit3(%arg0 : !spirv.ptr<f32, Generic>) {
354   // expected-error @+1 {{result must point to the Workgroup, CrossWorkgroup, or Function Storage Class}}
355   %0 = spirv.GenericCastToPtrExplicit %arg0 : !spirv.ptr<f32, Generic> to !spirv.ptr<f32, Uniform>
356   return
359 // -----
361 func.func @genericcasttoptrexplicit4(%arg0 : !spirv.ptr<f32, Generic>) {
362   // expected-error @+1 {{pointee type must have the same as the op result type}}
363   %0 = spirv.GenericCastToPtrExplicit %arg0 : !spirv.ptr<f32, Generic> to !spirv.ptr<vector<2xi32>, Workgroup>
364   return
367 // -----
369 //===----------------------------------------------------------------------===//
370 // spirv.ConvertPtrToU
371 //===----------------------------------------------------------------------===//
372 spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses], []> {
373   spirv.func @covert_ptr_to_u(%arg0 : !spirv.ptr<i32, Generic>) "None" {
374     // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, Generic> to i32
375     %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
376     spirv.Return
377   }
378   spirv.func @covert_ptr_to_u_truncate(%arg0 : !spirv.ptr<i64, Generic>) "None" {
379     // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i64, Generic> to i32
380     %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i64, Generic> to i32
381     spirv.Return
382   }
383   spirv.func @covert_ptr_to_u_extend(%arg0 : !spirv.ptr<i32, Generic>) "None" {
384     // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, Generic> to i64
385     %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i64
386     spirv.Return
387   }
390 // -----
392 spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
393   spirv.func @covert_ptr_to_u_PhysicalStorageBuffer(%arg0 : !spirv.ptr<i32, PhysicalStorageBuffer> { spirv.decoration = #spirv.decoration<Aliased> }) "None" {
394     // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, PhysicalStorageBuffer> to i32
395     %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, PhysicalStorageBuffer> to i32
396     spirv.Return
397   }
400 // -----
402 spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
403   spirv.func @covert_ptr_to_u_fail(%arg0 : !spirv.ptr<i32, Generic>) "None" {
404     // expected-error @+1 {{operand must be a physical pointer}}
405     %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
406     spirv.Return
407   }
410 // -----
412 spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
413   spirv.func @covert_ptr_to_u_fail_2(%arg0 : !spirv.ptr<i32, Generic>) "None" {
414     // expected-error @+1 {{operand must be a physical pointer}}
415     %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
416     spirv.Return
417   }
420 // -----
422 //===----------------------------------------------------------------------===//
423 // spirv.ConvertUToPtr
424 //===----------------------------------------------------------------------===//
425 spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses], []> {
426   spirv.func @covert_u_to_ptr(%arg0 : i32) "None" {
427     // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i32, Generic> 
428     %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
429     spirv.Return
430   }
431   spirv.func @covert_u_to_ptr_truncate(%arg0 : i64) "None" {
432     // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i64 to !spirv.ptr<i32, Generic> 
433     %0 = spirv.ConvertUToPtr %arg0 : i64 to !spirv.ptr<i32, Generic>
434     spirv.Return
435   }
436   spirv.func @covert_u_to_ptr_extend(%arg0 : i32) "None" {
437     // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i64, Generic> 
438     %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i64, Generic>
439     spirv.Return
440   }
443 // -----
445 spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
446   spirv.func @covert_u_to_ptr_PhysicalStorageBuffer(%arg0 : i32) "None" {
447     // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i32, PhysicalStorageBuffer>
448     %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, PhysicalStorageBuffer>
449     spirv.Return
450   }
453 // -----
455 spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
456   spirv.func @covert_u_to_ptr_fail(%arg0 : i32) "None" {
457     // expected-error @+1 {{result must be a physical pointer}}
458     %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
459     spirv.Return
460   }
463 // -----
465 spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
466   spirv.func @covert_u_to_ptr_fail_2(%arg0 : i32) "None" {
467     // expected-error @+1 {{result must be a physical pointer}}
468     %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
469     spirv.Return
470   }