1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s 2 3//===----------------------------------------------------------------------===// 4// spirv.Bitcast 5//===----------------------------------------------------------------------===// 6 7func.func @cast1(%arg0 : f32) { 8 // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : f32 to i32 9 %0 = spirv.Bitcast %arg0 : f32 to i32 10 return 11} 12 13func.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 17} 18 19func.func @cast3(%arg0 : vector<2xf32>) { 20 // CHECK: {{%.*}} = spirv.Bitcast {{%.*}} : vector<2xf32> to i64 21 %0 = spirv.Bitcast %arg0 : vector<2xf32> to i64 22 return 23} 24 25func.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 29} 30 31func.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 35} 36 37func.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 41} 42 43// ----- 44 45func.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 49} 50 51// ----- 52 53func.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 57} 58 59// ----- 60 61func.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 65} 66 67// ----- 68 69func.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 73} 74 75// ----- 76 77func.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 81} 82 83// ----- 84 85//===----------------------------------------------------------------------===// 86// spirv.ConvertFToS 87//===----------------------------------------------------------------------===// 88 89func.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 93} 94 95// ----- 96 97func.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 101} 102 103// ----- 104 105func.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> 109} 110 111// ----- 112 113//===----------------------------------------------------------------------===// 114// spirv.ConvertFToU 115//===----------------------------------------------------------------------===// 116 117func.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 121} 122 123// ----- 124 125func.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 129} 130 131// ----- 132 133func.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> 137} 138 139// ----- 140 141func.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 145} 146 147// ----- 148 149//===----------------------------------------------------------------------===// 150// spirv.ConvertSToF 151//===----------------------------------------------------------------------===// 152 153func.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 157} 158 159// ----- 160 161func.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 165} 166 167// ----- 168 169func.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> 173} 174 175// ----- 176 177//===----------------------------------------------------------------------===// 178// spirv.ConvertUToF 179//===----------------------------------------------------------------------===// 180 181func.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 185} 186 187// ----- 188 189func.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 193} 194 195// ----- 196 197func.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> 201} 202 203// ----- 204 205//===----------------------------------------------------------------------===// 206// spirv.FConvert 207//===----------------------------------------------------------------------===// 208 209func.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 213} 214 215// ----- 216 217func.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> 221} 222 223// ----- 224 225func.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 229} 230 231// ----- 232 233func.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 237} 238 239// ----- 240 241//===----------------------------------------------------------------------===// 242// spirv.SConvert 243//===----------------------------------------------------------------------===// 244 245func.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 249} 250 251// ----- 252 253//===----------------------------------------------------------------------===// 254// spirv.UConvert 255//===----------------------------------------------------------------------===// 256 257func.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 261} 262 263// ----- 264 265//===----------------------------------------------------------------------===// 266// spirv.PtrCastToGeneric 267//===----------------------------------------------------------------------===// 268 269func.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 273} 274// ----- 275 276func.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 280} 281 282// ----- 283 284func.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 288} 289 290// ----- 291 292func.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 296} 297 298// ----- 299 300//===----------------------------------------------------------------------===// 301// spirv.GenericCastToPtr 302//===----------------------------------------------------------------------===// 303 304func.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 308} 309// ----- 310 311func.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 315} 316 317// ----- 318 319func.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 323} 324 325// ----- 326 327func.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 331} 332// ----- 333 334//===----------------------------------------------------------------------===// 335// spirv.GenericCastToPtrExplicit 336//===----------------------------------------------------------------------===// 337 338func.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 342} 343// ----- 344 345func.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 349} 350 351// ----- 352 353func.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 357} 358 359// ----- 360 361func.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 365} 366 367// ----- 368 369//===----------------------------------------------------------------------===// 370// spirv.ConvertPtrToU 371//===----------------------------------------------------------------------===// 372spirv.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 } 388} 389 390// ----- 391 392spirv.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 } 398} 399 400// ----- 401 402spirv.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 } 408} 409 410// ----- 411 412spirv.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 } 418} 419 420// ----- 421 422//===----------------------------------------------------------------------===// 423// spirv.ConvertUToPtr 424//===----------------------------------------------------------------------===// 425spirv.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 } 441} 442 443// ----- 444 445spirv.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 } 451} 452 453// ----- 454 455spirv.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 } 461} 462 463// ----- 464 465spirv.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 } 471} 472