diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp index 7c007de315589..7fc779587f4f1 100644 --- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp +++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp @@ -16,6 +16,7 @@ #include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h" #include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h" #include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h" +#include "mlir/Dialect/SPIRV/IR/TargetAndABI.h" #include "mlir/Target/SPIRV/SPIRVBinaryUtils.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" @@ -112,7 +113,9 @@ LogicalResult Serializer::serialize() { // TODO: handle the other sections processCapability(); - processExtension(); + if (failed(processExtension())) { + return failure(); + } processMemoryModel(); processDebugInfo(); @@ -204,13 +207,24 @@ void Serializer::processDebugInfo() { // TODO: Encode more debug instructions. } -void Serializer::processExtension() { +LogicalResult Serializer::processExtension() { llvm::SmallVector extName; - for (spirv::Extension ext : module.getVceTriple()->getExtensions()) { + llvm::SmallSet deducedExts( + llvm::from_range, module.getVceTriple()->getExtensions()); + auto nonSemanticInfoExt = spirv::Extension::SPV_KHR_non_semantic_info; + if (options.emitDebugInfo && !deducedExts.contains(nonSemanticInfoExt)) { + TargetEnvAttr targetEnvAttr = lookupTargetEnvOrDefault(module); + if (!is_contained(targetEnvAttr.getExtensions(), nonSemanticInfoExt)) + return module.emitError( + "SPV_KHR_non_semantic_info extension not available"); + deducedExts.insert(nonSemanticInfoExt); + } + for (spirv::Extension ext : deducedExts) { extName.clear(); spirv::encodeStringLiteralInto(extName, spirv::stringifyExtension(ext)); encodeInstructionInto(extensions, spirv::Opcode::OpExtension, extName); } + return success(); } void Serializer::processMemoryModel() { diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.h b/mlir/lib/Target/SPIRV/Serialization/Serializer.h index 7047869bca4cd..fb2cecdff8e43 100644 --- a/mlir/lib/Target/SPIRV/Serialization/Serializer.h +++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.h @@ -102,7 +102,7 @@ class Serializer { void processDebugInfo(); - void processExtension(); + LogicalResult processExtension(); void processMemoryModel(); diff --git a/mlir/test/Target/SPIRV/debug-negative.mlir b/mlir/test/Target/SPIRV/debug-negative.mlir new file mode 100644 index 0000000000000..2c826870b5f02 --- /dev/null +++ b/mlir/test/Target/SPIRV/debug-negative.mlir @@ -0,0 +1,5 @@ +// RUN: mlir-translate %s --test-spirv-roundtrip-debug --no-implicit-module --verify-diagnostics + +// expected-error@below {{SPV_KHR_non_semantic_info extension not available}} +spirv.module Logical GLSL450 requires #spirv.vce attributes {spirv.target_env = #spirv.target_env<#spirv.vce, #spirv.resource_limits<>>} { +} diff --git a/mlir/test/Target/SPIRV/debug.mlir b/mlir/test/Target/SPIRV/debug.mlir index 58bf364593fc9..5a7ed19d22c11 100644 --- a/mlir/test/Target/SPIRV/debug.mlir +++ b/mlir/test/Target/SPIRV/debug.mlir @@ -1,69 +1,70 @@ // RUN: mlir-translate -no-implicit-module -test-spirv-roundtrip-debug -mlir-print-debuginfo -mlir-print-local-scope %s | FileCheck %s +// RUN: %if spirv-tools %{ mlir-translate --no-implicit-module --serialize-spirv %s | spirv-val %} -spirv.module Logical GLSL450 requires #spirv.vce { - // CHECK: loc({{".*debug.mlir"}}:5:3) +spirv.module Logical GLSL450 requires #spirv.vce attributes {spirv.target_env = #spirv.target_env<#spirv.vce, #spirv.resource_limits<>>} { + // CHECK: loc({{".*debug.mlir"}}:6:3) spirv.GlobalVariable @var0 bind(0, 1) : !spirv.ptr spirv.func @arithmetic(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) "None" { - // CHECK: loc({{".*debug.mlir"}}:8:10) + // CHECK: loc({{".*debug.mlir"}}:9:10) %0 = spirv.FAdd %arg0, %arg1 : vector<4xf32> - // CHECK: loc({{".*debug.mlir"}}:10:10) + // CHECK: loc({{".*debug.mlir"}}:11:10) %1 = spirv.FNegate %arg0 : vector<4xf32> spirv.Return } spirv.func @atomic(%ptr: !spirv.ptr, %value: i32, %comparator: i32) "None" { - // CHECK: loc({{".*debug.mlir"}}:16:10) + // CHECK: loc({{".*debug.mlir"}}:17:10) %1 = spirv.AtomicAnd %ptr, %value : !spirv.ptr spirv.Return } spirv.func @bitwiser(%arg0 : i32, %arg1 : i32) "None" { - // CHECK: loc({{".*debug.mlir"}}:22:10) + // CHECK: loc({{".*debug.mlir"}}:23:10) %0 = spirv.BitwiseAnd %arg0, %arg1 : i32 spirv.Return } spirv.func @convert(%arg0 : f32) "None" { - // CHECK: loc({{".*debug.mlir"}}:28:10) + // CHECK: loc({{".*debug.mlir"}}:29:10) %0 = spirv.ConvertFToU %arg0 : f32 to i32 spirv.Return } spirv.func @composite(%arg0 : !spirv.struct<(f32, !spirv.struct<(!spirv.array<4xf32>, f32)>)>, %arg1: !spirv.array<4xf32>, %arg2 : f32, %arg3 : f32) "None" { - // CHECK: loc({{".*debug.mlir"}}:34:10) + // CHECK: loc({{".*debug.mlir"}}:35:10) %0 = spirv.CompositeInsert %arg1, %arg0[1 : i32, 0 : i32] : !spirv.array<4xf32> into !spirv.struct<(f32, !spirv.struct<(!spirv.array<4xf32>, f32)>)> - // CHECK: loc({{".*debug.mlir"}}:36:10) + // CHECK: loc({{".*debug.mlir"}}:37:10) %1 = spirv.CompositeConstruct %arg2, %arg3 : (f32, f32) -> vector<2xf32> spirv.Return } spirv.func @group_non_uniform(%val: f32) "None" { - // CHECK: loc({{".*debug.mlir"}}:42:10) + // CHECK: loc({{".*debug.mlir"}}:43:10) %0 = spirv.GroupNonUniformFAdd %val : f32 -> f32 spirv.Return } spirv.func @local_var() "None" { %zero = spirv.Constant 0: i32 - // CHECK: loc({{".*debug.mlir"}}:49:12) + // CHECK: loc({{".*debug.mlir"}}:50:12) %var = spirv.Variable init(%zero) : !spirv.ptr spirv.Return } spirv.func @logical(%arg0: i32, %arg1: i32) "None" { - // CHECK: loc({{".*debug.mlir"}}:55:10) + // CHECK: loc({{".*debug.mlir"}}:56:10) %0 = spirv.IEqual %arg0, %arg1 : i32 spirv.Return } spirv.func @memory_accesses(%arg0 : !spirv.ptr>, StorageBuffer>, %arg1 : i32, %arg2 : i32) "None" { - // CHECK: loc({{".*debug.mlir"}}:61:10) + // CHECK: loc({{".*debug.mlir"}}:62:10) %2 = spirv.AccessChain %arg0[%arg1, %arg2] : !spirv.ptr>, StorageBuffer>, i32, i32 -> !spirv.ptr - // CHECK: loc({{".*debug.mlir"}}:63:10) + // CHECK: loc({{".*debug.mlir"}}:64:10) %3 = spirv.Load "StorageBuffer" %2 : f32 - // CHECK: loc({{.*debug.mlir"}}:65:5) + // CHECK: loc({{.*debug.mlir"}}:66:5) spirv.Store "StorageBuffer" %2, %3 : f32 - // CHECK: loc({{".*debug.mlir"}}:67:5) + // CHECK: loc({{".*debug.mlir"}}:68:5) spirv.Return } @@ -73,49 +74,49 @@ spirv.module Logical GLSL450 requires #spirv.vce { %ivar = spirv.Variable init(%zero) : !spirv.ptr %jvar = spirv.Variable init(%zero) : !spirv.ptr spirv.mlir.loop { - // CHECK: loc({{".*debug.mlir"}}:75:5) + // CHECK: loc({{".*debug.mlir"}}:76:5) spirv.Branch ^header ^header: %ival0 = spirv.Load "Function" %ivar : i32 %icmp = spirv.SLessThan %ival0, %count : i32 - // CHECK: loc({{".*debug.mlir"}}:75:5) + // CHECK: loc({{".*debug.mlir"}}:76:5) spirv.BranchConditional %icmp, ^body, ^merge ^body: spirv.Store "Function" %jvar, %zero : i32 spirv.mlir.loop { - // CHECK: loc({{".*debug.mlir"}}:85:7) + // CHECK: loc({{".*debug.mlir"}}:86:7) spirv.Branch ^header ^header: %jval0 = spirv.Load "Function" %jvar : i32 %jcmp = spirv.SLessThan %jval0, %count : i32 - // CHECK: loc({{".*debug.mlir"}}:85:7) + // CHECK: loc({{".*debug.mlir"}}:86:7) spirv.BranchConditional %jcmp, ^body, ^merge ^body: - // CHECK: loc({{".*debug.mlir"}}:95:9) + // CHECK: loc({{".*debug.mlir"}}:96:9) spirv.Branch ^continue ^continue: %jval1 = spirv.Load "Function" %jvar : i32 %add = spirv.IAdd %jval1, %one : i32 spirv.Store "Function" %jvar, %add : i32 - // CHECK: loc({{".*debug.mlir"}}:101:9) + // CHECK: loc({{".*debug.mlir"}}:102:9) spirv.Branch ^header ^merge: - // CHECK: loc({{".*debug.mlir"}}:85:7) + // CHECK: loc({{".*debug.mlir"}}:86:7) spirv.mlir.merge - // CHECK: loc({{".*debug.mlir"}}:85:7) + // CHECK: loc({{".*debug.mlir"}}:86:7) } - // CHECK: loc({{".*debug.mlir"}}:108:7) + // CHECK: loc({{".*debug.mlir"}}:109:7) spirv.Branch ^continue ^continue: %ival1 = spirv.Load "Function" %ivar : i32 %add = spirv.IAdd %ival1, %one : i32 spirv.Store "Function" %ivar, %add : i32 - // CHECK: loc({{".*debug.mlir"}}:114:7) + // CHECK: loc({{".*debug.mlir"}}:115:7) spirv.Branch ^header ^merge: - // CHECK: loc({{".*debug.mlir"}}:75:5) + // CHECK: loc({{".*debug.mlir"}}:76:5) spirv.mlir.merge - // CHECK: loc({{".*debug.mlir"}}:75:5) + // CHECK: loc({{".*debug.mlir"}}:76:5) } spirv.Return } @@ -126,21 +127,23 @@ spirv.module Logical GLSL450 requires #spirv.vce { %two = spirv.Constant 2: i32 %var = spirv.Variable init(%zero) : !spirv.ptr spirv.mlir.selection { - // CHECK: loc({{".*debug.mlir"}}:128:5) + // CHECK: loc({{".*debug.mlir"}}:129:5) spirv.BranchConditional %cond [5, 10], ^then, ^else ^then: spirv.Store "Function" %var, %one : i32 - // CHECK: loc({{".*debug.mlir"}}:134:7) + // CHECK: loc({{".*debug.mlir"}}:135:7) spirv.Branch ^merge ^else: spirv.Store "Function" %var, %two : i32 - // CHECK: loc({{".*debug.mlir"}}:138:7) + // CHECK: loc({{".*debug.mlir"}}:139:7) spirv.Branch ^merge ^merge: - // CHECK: loc({{".*debug.mlir"}}:128:5) + // CHECK: loc({{".*debug.mlir"}}:129:5) spirv.mlir.merge - // CHECK: loc({{".*debug.mlir"}}:128:5) + // CHECK: loc({{".*debug.mlir"}}:129:5) } spirv.Return } + + spirv.EntryPoint "GLCompute" @local_var }