[Mlir-commits] [mlir] [mlir][spirv] Conditionally add SPV_KHR_non_semantic_info extension u… (PR #152686)

Mohammadreza Ameri Mahabadian llvmlistbot at llvm.org
Mon Aug 11 04:26:58 PDT 2025


https://github.com/mahabadm updated https://github.com/llvm/llvm-project/pull/152686

>From 7bc82e5ccd906615b69e80f41ef69f40d2b91be2 Mon Sep 17 00:00:00 2001
From: Mohammadreza Ameri Mahabadian <mohammadreza.amerimahabadian at arm.com>
Date: Fri, 8 Aug 2025 09:54:24 +0100
Subject: [PATCH 1/2] [mlir][spirv] Conditionally add SPV_KHR_non_semantic_info
 extension upon serialization

If serialization option `emitDebugInfo` is enabled, then it is required to serialize `SPV_KHR_non_semantic_info` extension provided that it is available in the target environment.

Signed-off-by: Mohammadreza Ameri Mahabadian <mohammadreza.amerimahabadian at arm.com>
---
 .../Target/SPIRV/Serialization/Serializer.cpp | 20 ++++++++++++++++---
 .../Target/SPIRV/Serialization/Serializer.h   |  2 +-
 mlir/test/Target/SPIRV/debug.mlir             |  2 +-
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
index c049574fbc9e3..16ebc2274c95f 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<uint32_t, 16> extName;
-  for (spirv::Extension ext : module.getVceTriple()->getExtensions()) {
+  llvm::SmallSet<Extension, 4> deducedExts;
+  deducedExts.insert_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.mlir b/mlir/test/Target/SPIRV/debug.mlir
index 58bf364593fc9..eba64e24c60d9 100644
--- a/mlir/test/Target/SPIRV/debug.mlir
+++ b/mlir/test/Target/SPIRV/debug.mlir
@@ -1,6 +1,6 @@
 // RUN: mlir-translate -no-implicit-module -test-spirv-roundtrip-debug -mlir-print-debuginfo -mlir-print-local-scope %s | FileCheck %s
 
-spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
+spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], [SPV_KHR_non_semantic_info]> attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Shader], [SPV_KHR_non_semantic_info]>, #spirv.resource_limits<>>} {
   // CHECK: loc({{".*debug.mlir"}}:5:3)
   spirv.GlobalVariable @var0 bind(0, 1) : !spirv.ptr<f32, Input>
   spirv.func @arithmetic(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) "None" {

>From 6926cd387807217fe90d29fbd6bf4e52ce37e299 Mon Sep 17 00:00:00 2001
From: Mohammadreza Ameri Mahabadian <mohammadreza.amerimahabadian at arm.com>
Date: Mon, 11 Aug 2025 11:47:01 +0100
Subject: [PATCH 2/2] Addressing code review comment

Signed-off-by: Mohammadreza Ameri Mahabadian <mohammadreza.amerimahabadian at arm.com>
---
 .../Target/SPIRV/Serialization/Serializer.cpp |  4 +-
 mlir/test/Target/SPIRV/debug.mlir             | 69 ++++++++++---------
 2 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
index 16ebc2274c95f..7f10138624942 100644
--- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
@@ -209,8 +209,8 @@ void Serializer::processDebugInfo() {
 
 LogicalResult Serializer::processExtension() {
   llvm::SmallVector<uint32_t, 16> extName;
-  llvm::SmallSet<Extension, 4> deducedExts;
-  deducedExts.insert_range(module.getVceTriple()->getExtensions());
+  llvm::SmallSet<Extension, 4> 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);
diff --git a/mlir/test/Target/SPIRV/debug.mlir b/mlir/test/Target/SPIRV/debug.mlir
index eba64e24c60d9..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<v1.0, [Shader], [SPV_KHR_non_semantic_info]> attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Shader], [SPV_KHR_non_semantic_info]>, #spirv.resource_limits<>>} {
-  // CHECK: loc({{".*debug.mlir"}}:5:3)
+spirv.module Logical GLSL450 requires #spirv.vce<v1.3, [Shader, GroupNonUniformArithmetic], [SPV_KHR_non_semantic_info, SPV_KHR_storage_buffer_storage_class]> attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.3, [Shader, GroupNonUniformArithmetic], [SPV_KHR_non_semantic_info, SPV_KHR_storage_buffer_storage_class]>, #spirv.resource_limits<>>} {
+  // CHECK: loc({{".*debug.mlir"}}:6:3)
   spirv.GlobalVariable @var0 bind(0, 1) : !spirv.ptr<f32, Input>
   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<i32, Workgroup>, %value: i32, %comparator: i32) "None" {
-    // CHECK: loc({{".*debug.mlir"}}:16:10)
+    // CHECK: loc({{".*debug.mlir"}}:17:10)
     %1 = spirv.AtomicAnd <Device> <None> %ptr, %value : !spirv.ptr<i32, Workgroup>
     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 <Workgroup> <Reduce> %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<i32, Function>
     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<!spirv.array<4x!spirv.array<4xf32>>, 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<!spirv.array<4x!spirv.array<4xf32>>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer>
-    // 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<v1.0, [Shader], [SPV_KHR_non_se
     %ivar = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
     %jvar = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
     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<v1.0, [Shader], [SPV_KHR_non_se
     %two = spirv.Constant 2: i32
     %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
     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
 }



More information about the Mlir-commits mailing list