[llvm] [SPIR-V] Drop storage-class MemorySemantics bit for relaxed Vulkan atomics (PR #215802)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 06:28:51 PDT 2026


https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/215802

VUID-StandaloneSpirv-MemorySemantics-10871 forbids combining a storage class semantics bit with a relaxed memory order

The backend unconditionally OR'd the two together, which was untested until #215634 moved this test under the SPIR-V backend where spirv-val actually runs

>From 5aebb657cc4c005c41f876d894559ff5cb47f372 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 12 Aug 2026 15:27:27 +0200
Subject: [PATCH] [SPIR-V] Drop storage-class MemorySemantics bit for relaxed
 Vulkan atomics

VUID-StandaloneSpirv-MemorySemantics-10871 forbids combining a storage class semantics bit with a relaxed memory order

The backend unconditionally OR'd the two together, which was untested until #215634 moved this test under the SPIR-V backend where spirv-val actually runs
---
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 14 ++++++++++----
 llvm/lib/Target/SPIRV/SPIRVUtils.cpp               |  8 ++++++++
 llvm/lib/Target/SPIRV/SPIRVUtils.h                 |  3 +++
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index a13775f9d02ad..7fe41d6c1fa1e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2141,7 +2141,9 @@ bool SPIRVInstructionSelector::selectAtomicLoad(Register ResVReg,
   uint32_t MemSem = static_cast<uint32_t>(getMemSemantics(AO));
   if (MemOp.isVolatile() && STI.getTargetTriple().isVulkanOS())
     MemSem |= static_cast<uint32_t>(SPIRV::MemorySemantics::Volatile);
-  Register MemSemReg = buildI32Constant(MemSem | StorageClass, I);
+  uint32_t Sem = getMemSemanticsWithStorageClass(STI.getTargetTriple(), MemSem,
+                                                 StorageClass);
+  Register MemSemReg = buildI32Constant(Sem, I);
 
   MachineIRBuilder MIRBuilder(I);
 
@@ -2298,7 +2300,9 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
   uint32_t MemSem = static_cast<uint32_t>(getMemSemantics(AO));
   if (MemOp.isVolatile() && STI.getTargetTriple().isVulkanOS())
     MemSem |= static_cast<uint32_t>(SPIRV::MemorySemantics::Volatile);
-  Register MemSemReg = buildI32Constant(MemSem | StorageClass, I);
+  uint32_t Sem = getMemSemanticsWithStorageClass(STI.getTargetTriple(), MemSem,
+                                                 StorageClass);
+  Register MemSemReg = buildI32Constant(Sem, I);
   MachineIRBuilder MIRBuilder(I);
 
   if (PointeeType.isTypePtr()) {
@@ -2581,8 +2585,10 @@ bool SPIRVInstructionSelector::selectAtomicRMW(Register ResVReg,
   uint32_t ScSem = static_cast<uint32_t>(
       getMemSemanticsForStorageClass(GR.getPointerStorageClass(Ptr)));
   AtomicOrdering AO = MemOp->getSuccessOrdering();
-  uint32_t MemSem = static_cast<uint32_t>(getMemSemantics(AO)) | ScSem;
-  Register MemSemReg = buildI32Constant(MemSem, I);
+  uint32_t OrderSem = static_cast<uint32_t>(getMemSemantics(AO));
+  Register MemSemReg = buildI32Constant(
+      getMemSemanticsWithStorageClass(STI.getTargetTriple(), OrderSem, ScSem),
+      I);
 
   Register ValueReg = I.getOperand(2).getReg();
   if (NegateOpcode != 0) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index ce993299096ad..75fb210a19244 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -449,6 +449,14 @@ SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord) {
   llvm_unreachable(nullptr);
 }
 
+uint32_t getMemSemanticsWithStorageClass(const Triple &TT, uint32_t OrderSem,
+                                         uint32_t StorageClassSem) {
+  bool DropStorageClass =
+      TT.isVulkanOS() &&
+      OrderSem == static_cast<uint32_t>(SPIRV::MemorySemantics::None);
+  return OrderSem | (DropStorageClass ? 0 : StorageClassSem);
+}
+
 SPIRV::Scope::Scope getMemScope(const Triple &TT, LLVMContext &Ctx,
                                 SyncScope::ID Id) {
   // Named by
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index b95f09eba95f1..abae9cc3da23a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -286,6 +286,9 @@ getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC);
 
 SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord);
 
+uint32_t getMemSemanticsWithStorageClass(const Triple &TT, uint32_t OrderSem,
+                                         uint32_t StorageClassSem);
+
 SPIRV::Scope::Scope getMemScope(const Triple &TT, LLVMContext &Ctx,
                                 SyncScope::ID Id);
 



More information about the llvm-commits mailing list