409 lines · plain
1// RUN: mlir-opt --split-input-file --verify-diagnostics --mlir-disable-threading \2// RUN: --test-spirv-target-env %s | FileCheck %s3 4// Note: The following tests check that a spirv.target_env can properly control5// the conversion target and filter unavailable ops during the conversion.6// We don't care about the op argument consistency too much; so certain enum7// values for enum attributes may not make much sense for the test op.8 9// spirv.AtomicCompareExchangeWeak is available from SPIR-V 1.0 to 1.3 under10// Kernel capability.11// spirv.AtomicCompareExchangeWeak has two memory semantics enum attribute,12// whose value, if containing AtomicCounterMemory bit, additionally requires13// AtomicStorage capability.14 15// spirv.BitReverse is available in all SPIR-V versions under Shader capability.16 17// spirv.GroupNonUniformBallot is available starting from SPIR-V 1.3 under18// GroupNonUniform capability.19 20// spirv.KHR.SubgroupBallot is available under in all SPIR-V versions under21// SubgroupBallotKHR capability and SPV_KHR_shader_ballot extension.22 23// Integer Dot Product ops (spirv.*Dot*) require the24// SPV_KHR_integer_dot_product extension and a number of related capabilities.25 26// The GeometryPointSize capability implies the Geometry capability, which27// implies the Shader capability.28 29// PhysicalStorageBuffer64 addressing model is available via extension30// SPV_EXT_physical_storage_buffer or SPV_KHR_physical_storage_buffer;31// both extensions are incorporated into SPIR-V 1.5.32 33// Vulkan memory model is available via extension SPV_KHR_vulkan_memory_model,34// which extensions are incorporated into SPIR-V 1.5.35 36 37// expected-error @+1 {{missing 'spirv.target_env' attribute}}38func.func @main() {39 return40}41 42// -----43 44//===----------------------------------------------------------------------===//45// MaxVersion46//===----------------------------------------------------------------------===//47 48// CHECK-LABEL: @cmp_exchange_weak_suitable_version_capabilities49func.func @cmp_exchange_weak_suitable_version_capabilities(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 attributes {50 spirv.target_env = #spirv.target_env<#spirv.vce<v1.1, [Kernel, AtomicStorage], []>, #spirv.resource_limits<>>51} {52 // CHECK: spirv.AtomicCompareExchangeWeak <Workgroup> <AcquireRelease|AtomicCounterMemory> <Acquire>53 %0 = "test.convert_to_atomic_compare_exchange_weak_op"(%ptr, %value, %comparator): (!spirv.ptr<i32, Workgroup>, i32, i32) -> (i32)54 return %0: i3255}56 57// CHECK-LABEL: @cmp_exchange_weak_unsupported_version58func.func @cmp_exchange_weak_unsupported_version(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 attributes {59 spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [Kernel, AtomicStorage], []>, #spirv.resource_limits<>>60} {61 // CHECK: test.convert_to_atomic_compare_exchange_weak_op62 %0 = "test.convert_to_atomic_compare_exchange_weak_op"(%ptr, %value, %comparator): (!spirv.ptr<i32, Workgroup>, i32, i32) -> (i32)63 return %0: i3264}65 66//===----------------------------------------------------------------------===//67// MinVersion68//===----------------------------------------------------------------------===//69 70// CHECK-LABEL: @group_non_uniform_ballot_suitable_version71func.func @group_non_uniform_ballot_suitable_version(%predicate: i1) -> vector<4xi32> attributes {72 spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [GroupNonUniformBallot], []>, #spirv.resource_limits<>>73} {74 // CHECK: spirv.GroupNonUniformBallot <Workgroup>75 %0 = "test.convert_to_group_non_uniform_ballot_op"(%predicate): (i1) -> (vector<4xi32>)76 return %0: vector<4xi32>77}78 79// CHECK-LABEL: @group_non_uniform_ballot_unsupported_version80func.func @group_non_uniform_ballot_unsupported_version(%predicate: i1) -> vector<4xi32> attributes {81 spirv.target_env = #spirv.target_env<#spirv.vce<v1.1, [GroupNonUniformBallot], []>, #spirv.resource_limits<>>82} {83 // CHECK: test.convert_to_group_non_uniform_ballot_op84 %0 = "test.convert_to_group_non_uniform_ballot_op"(%predicate): (i1) -> (vector<4xi32>)85 return %0: vector<4xi32>86}87 88//===----------------------------------------------------------------------===//89// Capability90//===----------------------------------------------------------------------===//91 92// CHECK-LABEL: @cmp_exchange_weak_missing_capability_kernel93func.func @cmp_exchange_weak_missing_capability_kernel(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 attributes {94 spirv.target_env = #spirv.target_env<#spirv.vce<v1.3, [AtomicStorage], []>, #spirv.resource_limits<>>95} {96 // CHECK: test.convert_to_atomic_compare_exchange_weak_op97 %0 = "test.convert_to_atomic_compare_exchange_weak_op"(%ptr, %value, %comparator): (!spirv.ptr<i32, Workgroup>, i32, i32) -> (i32)98 return %0: i3299}100 101// CHECK-LABEL: @cmp_exchange_weak_missing_capability_atomic_storage102func.func @cmp_exchange_weak_missing_capability_atomic_storage(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 attributes {103 spirv.target_env = #spirv.target_env<#spirv.vce<v1.3, [Kernel], []>, #spirv.resource_limits<>>104} {105 // CHECK: test.convert_to_atomic_compare_exchange_weak_op106 %0 = "test.convert_to_atomic_compare_exchange_weak_op"(%ptr, %value, %comparator): (!spirv.ptr<i32, Workgroup>, i32, i32) -> (i32)107 return %0: i32108}109 110// CHECK-LABEL: @subgroup_ballot_missing_capability111func.func @subgroup_ballot_missing_capability(%predicate: i1) -> vector<4xi32> attributes {112 spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [], [SPV_KHR_shader_ballot]>, #spirv.resource_limits<>>113} {114 // CHECK: test.convert_to_subgroup_ballot_op115 %0 = "test.convert_to_subgroup_ballot_op"(%predicate): (i1) -> (vector<4xi32>)116 return %0: vector<4xi32>117}118 119// CHECK-LABEL: @bit_reverse_directly_implied_capability120func.func @bit_reverse_directly_implied_capability(%operand: i32) -> i32 attributes {121 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Geometry], []>, #spirv.resource_limits<>>122} {123 // CHECK: spirv.BitReverse124 %0 = "test.convert_to_bit_reverse_op"(%operand): (i32) -> (i32)125 return %0: i32126}127 128// CHECK-LABEL: @bit_reverse_recursively_implied_capability129func.func @bit_reverse_recursively_implied_capability(%operand: i32) -> i32 attributes {130 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [GeometryPointSize], []>, #spirv.resource_limits<>>131} {132 // CHECK: spirv.BitReverse133 %0 = "test.convert_to_bit_reverse_op"(%operand): (i32) -> (i32)134 return %0: i32135}136 137// CHECK-LABEL: @sdot_scalar_i32_i32_capabilities138func.func @sdot_scalar_i32_i32_capabilities(%operand: i32) -> i32 attributes {139 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,140 [DotProduct, DotProductInput4x8BitPacked], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>141} {142 // CHECK: spirv.SDot143 %0 = "test.convert_to_sdot_op"(%operand, %operand) {format = #spirv.packed_vector_format<PackedVectorFormat4x8Bit>}: (i32, i32) -> (i32)144 return %0: i32145}146 147// CHECK-LABEL: @sdot_scalar_i32_i32_missing_capability1148func.func @sdot_scalar_i32_i32_missing_capability1(%operand: i32) -> i32 attributes {149 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,150 [DotProduct], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>151} {152 // CHECK: test.convert_to_sdot_op153 %0 = "test.convert_to_sdot_op"(%operand, %operand) {format = #spirv.packed_vector_format<PackedVectorFormat4x8Bit>}: (i32, i32) -> (i32)154 return %0: i32155}156 157// CHECK-LABEL: @sdot_scalar_i32_i32_missing_capability2158func.func @sdot_scalar_i32_i32_missing_capability2(%operand: i32) -> i32 attributes {159 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,160 [DotProductInput4x8BitPacked], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>161} {162 // CHECK: test.convert_to_sdot_op163 %0 = "test.convert_to_sdot_op"(%operand, %operand) {format = #spirv.packed_vector_format<PackedVectorFormat4x8Bit>}: (i32, i32) -> (i32)164 return %0: i32165}166 167// CHECK-LABEL: @sudot_vector_4xi8_i32_capabilities168func.func @sudot_vector_4xi8_i32_capabilities(%operand: vector<4xi8>) -> i32 attributes {169 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,170 [DotProduct, DotProductInput4x8Bit], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>171} {172 // CHECK: spirv.SUDot173 %0 = "test.convert_to_sudot_op"(%operand, %operand): (vector<4xi8>, vector<4xi8>) -> (i32)174 return %0: i32175}176 177// CHECK-LABEL: @sudot_vector_4xi8_i32_missing_capability1178func.func @sudot_vector_4xi8_i32_missing_capability1(%operand: vector<4xi8>) -> i32 attributes {179 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,180 [DotProduct], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>181} {182 // CHECK: test.convert_to_sudot_op183 %0 = "test.convert_to_sudot_op"(%operand, %operand): (vector<4xi8>, vector<4xi8>) -> (i32)184 return %0: i32185}186 187// CHECK-LABEL: @sudot_vector_4xi8_i32_missing_capability2188func.func @sudot_vector_4xi8_i32_missing_capability2(%operand: vector<4xi8>) -> i32 attributes {189 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,190 [DotProductInput4x8Bit], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>191} {192 // CHECK: test.convert_to_sudot_op193 %0 = "test.convert_to_sudot_op"(%operand, %operand): (vector<4xi8>, vector<4xi8>) -> (i32)194 return %0: i32195}196 197// CHECK-LABEL: @udot_vector_4xi16_i64_capabilities198func.func @udot_vector_4xi16_i64_capabilities(%operand: vector<4xi16>) -> i64 attributes {199 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,200 [DotProduct, DotProductInputAll, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>201} {202 // CHECK: spirv.UDot203 %0 = "test.convert_to_udot_op"(%operand, %operand): (vector<4xi16>, vector<4xi16>) -> (i64)204 return %0: i64205}206 207// CHECK-LABEL: @udot_vector_4xi16_i64_missing_capability1208func.func @udot_vector_4xi16_i64_missing_capability1(%operand: vector<4xi16>) -> i64 attributes {209 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,210 [DotProduct, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>211} {212 // CHECK: test.convert_to_udot_op213 %0 = "test.convert_to_udot_op"(%operand, %operand): (vector<4xi16>, vector<4xi16>) -> (i64)214 return %0: i64215}216 217// CHECK-LABEL: @udot_vector_4xi16_i64_missing_capability2218func.func @udot_vector_4xi16_i64_missing_capability2(%operand: vector<4xi16>) -> i64 attributes {219 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,220 [DotProductInputAll, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>221} {222 // CHECK: test.convert_to_udot_op223 %0 = "test.convert_to_udot_op"(%operand, %operand): (vector<4xi16>, vector<4xi16>) -> (i64)224 return %0 : i64225}226 227// CHECK-LABEL: @sdot_acc_sat_scalar_i32_i32_capabilities228func.func @sdot_acc_sat_scalar_i32_i32_capabilities(%operand: i32) -> i32 attributes {229 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,230 [DotProduct, DotProductInput4x8BitPacked], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>231} {232 // CHECK: spirv.SDotAccSat233 %0 = "test.convert_to_sdot_acc_sat_op"(%operand, %operand, %operand)234 {format = #spirv.packed_vector_format<PackedVectorFormat4x8Bit>}: (i32, i32, i32) -> (i32)235 return %0: i32236}237 238// CHECK-LABEL: @sudot_acc_sat_vector_4xi8_i32_capabilities239func.func @sudot_acc_sat_vector_4xi8_i32_capabilities(%operand: vector<4xi8>, %acc: i32) -> i32 attributes {240 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,241 [DotProduct, DotProductInput4x8Bit], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>242} {243 // CHECK: spirv.SUDotAccSat244 %0 = "test.convert_to_sudot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi8>, vector<4xi8>, i32) -> (i32)245 return %0: i32246}247 248// CHECK-LABEL: @udot_acc_sat_vector_4xi8_i32_missing_capability1249func.func @udot_acc_sat_vector_4xi8_i32_missing_capability1(%operand: vector<4xi8>, %acc: i32) -> i32 attributes {250 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,251 [DotProduct, DotProductInputAll, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>252} {253 // CHECK: test.convert_to_udot_acc_sat_op254 %0 = "test.convert_to_udot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi8>, vector<4xi8>, i32) -> (i32)255 return %0: i32256}257 258// CHECK-LABEL: @udot_acc_sat_vector_4xi8_i32_missing_capability2259func.func @udot_acc_sat_vector_4xi8_i32_missing_capability2(%operand: vector<4xi8>, %acc: i32) -> i32 attributes {260 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,261 [DotProductInputAll, DotProductInput4x8Bit, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>262} {263 // CHECK: test.convert_to_udot_acc_sat_op264 %0 = "test.convert_to_udot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi8>, vector<4xi8>, i32) -> (i32)265 return %0: i32266}267 268// CHECK-LABEL: @udot_acc_sat_vector_4xi16_i64_capabilities269func.func @udot_acc_sat_vector_4xi16_i64_capabilities(%operand: vector<4xi16>, %acc: i64) -> i64 attributes {270 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,271 [DotProduct, DotProductInputAll, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>272} {273 // CHECK: spirv.UDotAccSat274 %0 = "test.convert_to_udot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi16>, vector<4xi16>, i64) -> (i64)275 return %0: i64276}277 278// CHECK-LABEL: @udot_acc_sat_vector_4xi16_i64_missing_capability1279func.func @udot_acc_sat_vector_4xi16_i64_missing_capability1(%operand: vector<4xi16>, %acc: i64) -> i64 attributes {280 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,281 [DotProductInputAll, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>282} {283 // CHECK: test.convert_to_udot_acc_sat_op284 %0 = "test.convert_to_udot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi16>, vector<4xi16>, i64) -> (i64)285 return %0: i64286}287 288// CHECK-LABEL: @udot_acc_sat_vector_4xi16_i64_missing_capability2289func.func @udot_acc_sat_vector_4xi16_i64_missing_capability2(%operand: vector<4xi16>, %acc: i64) -> i64 attributes {290 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0,291 [DotProduct, Int16, Int64], [SPV_KHR_integer_dot_product]>, #spirv.resource_limits<>>292} {293 // CHECK: test.convert_to_udot_acc_sat_op294 %0 = "test.convert_to_udot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi16>, vector<4xi16>, i64) -> (i64)295 return %0: i64296}297 298//===----------------------------------------------------------------------===//299// Extension300//===----------------------------------------------------------------------===//301 302// CHECK-LABEL: @subgroup_ballot_suitable_extension303func.func @subgroup_ballot_suitable_extension(%predicate: i1) -> vector<4xi32> attributes {304 spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [SubgroupBallotKHR], [SPV_KHR_shader_ballot]>, #spirv.resource_limits<>>305} {306 // CHECK: spirv.KHR.SubgroupBallot307 %0 = "test.convert_to_subgroup_ballot_op"(%predicate): (i1) -> (vector<4xi32>)308 return %0: vector<4xi32>309}310 311// CHECK-LABEL: @subgroup_ballot_missing_extension312func.func @subgroup_ballot_missing_extension(%predicate: i1) -> vector<4xi32> attributes {313 spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [SubgroupBallotKHR], []>, #spirv.resource_limits<>>314} {315 // CHECK: test.convert_to_subgroup_ballot_op316 %0 = "test.convert_to_subgroup_ballot_op"(%predicate): (i1) -> (vector<4xi32>)317 return %0: vector<4xi32>318}319 320// CHECK-LABEL: @module_suitable_extension1321func.func @module_suitable_extension1() attributes {322 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [VulkanMemoryModel, PhysicalStorageBufferAddresses], [SPV_KHR_vulkan_memory_model, SPV_EXT_physical_storage_buffer]>, #spirv.resource_limits<>>323} {324 // CHECK: spirv.module PhysicalStorageBuffer64 Vulkan325 "test.convert_to_module_op"() : () ->()326 return327}328 329// CHECK-LABEL: @module_suitable_extension2330func.func @module_suitable_extension2() attributes {331 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [VulkanMemoryModel, PhysicalStorageBufferAddresses], [SPV_KHR_vulkan_memory_model, SPV_KHR_physical_storage_buffer]>, #spirv.resource_limits<>>332} {333 // CHECK: spirv.module PhysicalStorageBuffer64 Vulkan334 "test.convert_to_module_op"() : () -> ()335 return336}337 338// CHECK-LABEL: @module_missing_extension_mm339func.func @module_missing_extension_mm() attributes {340 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [VulkanMemoryModel, PhysicalStorageBufferAddresses], [SPV_KHR_physical_storage_buffer]>, #spirv.resource_limits<>>341} {342 // CHECK: test.convert_to_module_op343 "test.convert_to_module_op"() : () -> ()344 return345}346 347// CHECK-LABEL: @module_missing_extension_am348func.func @module_missing_extension_am() attributes {349 spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [VulkanMemoryModel, PhysicalStorageBufferAddresses], [SPV_KHR_vulkan_memory_model]>, #spirv.resource_limits<>>350} {351 // CHECK: test.convert_to_module_op352 "test.convert_to_module_op"() : () -> ()353 return354}355 356// CHECK-LABEL: @module_implied_extension357func.func @module_implied_extension() attributes {358 // Version 1.5 implies SPV_KHR_vulkan_memory_model and SPV_KHR_physical_storage_buffer.359 spirv.target_env = #spirv.target_env<#spirv.vce<v1.5, [VulkanMemoryModel, PhysicalStorageBufferAddresses], []>, #spirv.resource_limits<>>360} {361 // CHECK: spirv.module PhysicalStorageBuffer64 Vulkan362 "test.convert_to_module_op"() : () -> ()363 return364}365 366// CHECK-LABEL: @udot_vector_4xi16_i64_implied_extension367func.func @udot_vector_4xi16_i64_implied_extension(%operand: vector<4xi16>) -> i64 attributes {368 // Version 1.6 implies SPV_KHR_integer_to_product.369 spirv.target_env = #spirv.target_env<#spirv.vce<v1.6,370 [DotProduct, DotProductInputAll, Int16, Int64], []>, #spirv.resource_limits<>>371} {372 // CHECK: spirv.UDot373 %0 = "test.convert_to_udot_op"(%operand, %operand): (vector<4xi16>, vector<4xi16>) -> (i64)374 return %0: i64375}376 377// CHECK-LABEL: @udot_vector_4xi16_i64_missing_extension378func.func @udot_vector_4xi16_i64_missing_extension(%operand: vector<4xi16>) -> i64 attributes {379 // Version 1.5 does not imply SPV_KHR_integer_to_product.380 spirv.target_env = #spirv.target_env<#spirv.vce<v1.5,381 [DotProduct, DotProductInputAll, Int16, Int64], []>, #spirv.resource_limits<>>382} {383 // CHECK: test.convert_to_udot_op384 %0 = "test.convert_to_udot_op"(%operand, %operand): (vector<4xi16>, vector<4xi16>) -> (i64)385 return %0: i64386}387 388// CHECK-LABEL: @sdot_acc_sat_vector_4xi16_i64_implied_extension389func.func @sdot_acc_sat_vector_4xi16_i64_implied_extension(%operand: vector<4xi16>, %acc: i64) -> i64 attributes {390 // Version 1.6 implies SPV_KHR_integer_to_product.391 spirv.target_env = #spirv.target_env<#spirv.vce<v1.6,392 [DotProduct, DotProductInputAll, Int16, Int64], []>, #spirv.resource_limits<>>393} {394 // CHECK: spirv.SDotAccSat395 %0 = "test.convert_to_sdot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi16>, vector<4xi16>, i64) -> (i64)396 return %0: i64397}398 399// CHECK-LABEL: @sdot_acc_sat_vector_4xi16_i64_missing_extension400func.func @sdot_acc_sat_vector_4xi16_i64_missing_extension(%operand: vector<4xi16>, %acc: i64) -> i64 attributes {401 // Version 1.5 does not imply SPV_KHR_integer_to_product.402 spirv.target_env = #spirv.target_env<#spirv.vce<v1.5,403 [DotProduct, DotProductInputAll, Int16, Int64], []>, #spirv.resource_limits<>>404} {405 // CHECK: test.convert_to_sdot_acc_sat_op406 %0 = "test.convert_to_sdot_acc_sat_op"(%operand, %operand, %acc): (vector<4xi16>, vector<4xi16>, i64) -> (i64)407 return %0: i64408}409