[llvm] [SPIR-V] Handle spirv.MemoryModel metadata (PR #186138)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 12 08:23:45 PDT 2026


https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/186138

>From dde8548bcb15f33c4a707a005a91a999114d0f44 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 12 Mar 2026 16:09:58 +0100
Subject: [PATCH] [SPIR-V] Handle Shader attr info from spirv.MemoryModel
 metadata

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp |  8 +++++-
 llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp      | 25 +++++++++++++++++++
 .../CodeGen/SPIRV/memory-model-md-glsl450.ll  | 14 +++++++++++
 .../CodeGen/SPIRV/memory-model-md-shader.ll   | 14 +++++++++++
 .../CodeGen/SPIRV/memory-model-md-vulkan.ll   | 14 +++++++++++
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/memory-model-md-glsl450.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/memory-model-md-shader.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/memory-model-md-vulkan.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 38bc72ff154fa..091249c7f62d3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -215,6 +215,10 @@ void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
   MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
                                  MAI.Addr, *ST);
 
+  if (MAI.Mem == SPIRV::MemoryModel::VulkanKHR)
+    MAI.Reqs.addExtension(
+        SPIRV::Extension::SPV_KHR_vulkan_memory_model);
+
   if (!ST->isShader()) {
     // TODO: check if it's required by default.
     MAI.ExtInstSetMap[static_cast<unsigned>(
@@ -940,7 +944,9 @@ void RequirementHandler::initAvailableCapabilitiesForVulkan(
                     Capability::StorageBufferArrayDynamicIndexing,
                     Capability::StorageImageArrayDynamicIndexing,
                     Capability::DerivativeControl, Capability::MinLod,
-                    Capability::ImageGatherExtended});
+                    Capability::ImageGatherExtended,
+                    Capability::Addresses,
+                    Capability::VulkanMemoryModelKHR});
 
   // Became core in Vulkan 1.2
   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
index d65d8ec53c6d0..cb014002c1f23 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SPIRVSubtarget.h"
+#include "MCTargetDesc/SPIRVBaseInfo.h"
 #include "SPIRV.h"
 #include "SPIRVCommandLine.h"
 #include "SPIRVGlobalRegistry.h"
@@ -207,6 +208,30 @@ void SPIRVSubtarget::resolveEnvFromModule(const Module &M) {
     }
   }
 
+  if (!HasShaderAttr) {
+    if (auto *MemModel = M.getNamedMetadata("spirv.MemoryModel")) {
+      assert(MemModel->getNumOperands() > 0 && "Invalid spirv.MemoryModel");
+      auto *MemMD = MemModel->getOperand(0);
+      assert(MemMD->getNumOperands() > 1 &&
+             "Invalid spirv.MemoryModel operand");
+      unsigned MemModelVal =
+          mdconst::extract<ConstantInt>(MemMD->getOperand(1))->getZExtValue();
+      switch (MemModelVal) {
+      case SPIRV::MemoryModel::Simple:
+      case SPIRV::MemoryModel::GLSL450:
+        HasShaderAttr = true;
+        break;
+      case SPIRV::MemoryModel::VulkanKHR:
+        HasShaderAttr = true;
+        AvailableExtensions.insert(
+            SPIRV::Extension::SPV_KHR_vulkan_memory_model);
+        break;
+      case SPIRV::MemoryModel::OpenCL:
+        break;
+      }
+    }
+  }
+
   setEnv(HasShaderAttr ? Shader : Kernel);
 }
 
diff --git a/llvm/test/CodeGen/SPIRV/memory-model-md-glsl450.ll b/llvm/test/CodeGen/SPIRV/memory-model-md-glsl450.ll
new file mode 100644
index 0000000000000..9d2ce1128a43c
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/memory-model-md-glsl450.ll
@@ -0,0 +1,14 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpMemoryModel Logical GLSL450
+define void @main() {
+entry:
+  ret void
+}
+
+; AddressingModel=Logical (0), MemoryModel=GLSL450 (1)
+!spirv.MemoryModel = !{!0}
+!0 = !{i32 0, i32 1}
diff --git a/llvm/test/CodeGen/SPIRV/memory-model-md-shader.ll b/llvm/test/CodeGen/SPIRV/memory-model-md-shader.ll
new file mode 100644
index 0000000000000..d40fba3acd382
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/memory-model-md-shader.ll
@@ -0,0 +1,14 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpMemoryModel Physical32 Simple
+define void @main() {
+entry:
+  ret void
+}
+
+; AddressingModel=Physical32 (1), MemoryModel=Simple (0)
+!spirv.MemoryModel = !{!0}
+!0 = !{i32 1, i32 0}
diff --git a/llvm/test/CodeGen/SPIRV/memory-model-md-vulkan.ll b/llvm/test/CodeGen/SPIRV/memory-model-md-vulkan.ll
new file mode 100644
index 0000000000000..cbee31481ea42
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/memory-model-md-vulkan.ll
@@ -0,0 +1,14 @@
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpMemoryModel Logical Vulkan
+define void @main() {
+entry:
+  ret void
+}
+
+; AddressingModel=Logical (0), MemoryModel=VulkanKHR (3)
+!spirv.MemoryModel = !{!0}
+!0 = !{i32 0, i32 3}



More information about the llvm-commits mailing list