[llvm] [SPIRV] Let atomic store store pointers (PR #201251)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 11:06:49 PDT 2026


https://github.com/fineg74 updated https://github.com/llvm/llvm-project/pull/201251

>From 7b3468282ea87580ddca788ca77f87ba3708cd08 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 2 Jun 2026 18:51:17 -0700
Subject: [PATCH 1/6] Let atomic store store pointers

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 51 ++++++++++++++++---
 llvm/lib/Target/SPIRV/SPIRVTypeInst.cpp       |  4 ++
 llvm/lib/Target/SPIRV/SPIRVTypeInst.h         |  2 +
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index c575932cd8709..480f83ea0e610 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2051,7 +2051,7 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
 
   SPIRVTypeInst PtrType = GR.getSPIRVTypeForVReg(Ptr);
   SPIRVTypeInst PointeeType = GR.getPointeeType(PtrType);
-  if (!PointeeType.isTypeIntOrFloat())
+  if (!PointeeType.isTypeIntOrFloat() && !PointeeType.isTypePtr())
     return diagnoseUnsupported(I,
                                "Lowering to SPIR-V of atomic store is only "
                                "allowed for integer or floating point types");
@@ -2073,12 +2073,49 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
   Register MemSemReg = buildI32Constant(MemSem | StorageClass, I);
 
   MachineIRBuilder MIRBuilder(I);
-  auto AtomicStore = MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
-                         .addUse(Ptr)
-                         .addUse(ScopeReg)
-                         .addUse(MemSemReg)
-                         .addUse(StoreVal);
-  AtomicStore.constrainAllUses(TII, TRI, RBI);
+
+  if (PointeeType.isTypePtr()) {
+    auto PtrSize = GR.getPointerSize();
+    SPIRVTypeInst SpirvType = GR.getOrCreateSPIRVIntegerType(PtrSize, I, TII);
+
+    Register NewVRegVal =
+        MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
+    MRI->setRegClass(NewVRegVal, MRI->getRegClassOrNull(StoreVal));
+    GR.assignSPIRVTypeToVReg(SpirvType, NewVRegVal, MIRBuilder.getMF());
+    MIRBuilder.buildInstr(SPIRV::OpConvertPtrToU)
+        .addDef(NewVRegVal)
+        .addUse(GR.getSPIRVTypeID(SpirvType)) // Result type
+        .addUse(StoreVal)                     // Pointer operand
+        .constrainAllUses(TII, TRI, RBI);
+
+    Register NewVRegPtr =
+        MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
+    MRI->setRegClass(NewVRegPtr, MRI->getRegClassOrNull(Ptr));
+    SPIRVTypeInst PtrType = GR.getOrCreateSPIRVPointerType(
+        SpirvType, MIRBuilder,
+        addressSpaceToStorageClass(MemOp.getAddrSpace(), STI));
+    GR.assignSPIRVTypeToVReg(PtrType, NewVRegPtr, MIRBuilder.getMF());
+
+    MIRBuilder.buildInstr(SPIRV::OpBitcast)
+        .addDef(NewVRegPtr)
+        .addUse(GR.getSPIRVTypeID(PtrType))
+        .addUse(Ptr)
+        .constrainAllUses(TII, TRI, RBI);
+
+    MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
+        .addUse(NewVRegPtr)
+        .addUse(ScopeReg)
+        .addUse(MemSemReg)
+        .addUse(NewVRegVal)
+        .constrainAllUses(TII, TRI, RBI);
+  } else {
+    auto AtomicStore = MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
+                           .addUse(Ptr)
+                           .addUse(ScopeReg)
+                           .addUse(MemSemReg)
+                           .addUse(StoreVal);
+    AtomicStore.constrainAllUses(TII, TRI, RBI);
+  }
   return true;
 }
 
diff --git a/llvm/lib/Target/SPIRV/SPIRVTypeInst.cpp b/llvm/lib/Target/SPIRV/SPIRVTypeInst.cpp
index 7a7d62f9297f5..58857b6a3eac2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTypeInst.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTypeInst.cpp
@@ -38,4 +38,8 @@ bool SPIRVTypeInst::isTypeIntN(unsigned N) const {
 bool SPIRVTypeInst::isAnyTypeFloat() const {
   return MI->getOpcode() == SPIRV::OpTypeFloat;
 }
+
+bool SPIRVTypeInst::isTypePtr() const {
+  return MI->getOpcode() == SPIRV::OpTypePointer;
+}
 } // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVTypeInst.h b/llvm/lib/Target/SPIRV/SPIRVTypeInst.h
index 39648ef622d3e..0d371f441cf9e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTypeInst.h
+++ b/llvm/lib/Target/SPIRV/SPIRVTypeInst.h
@@ -55,6 +55,8 @@ class SPIRVTypeInst {
   bool isAnyTypeFloat() const;
   // Returns true if this is an OpTypeInt or OpTypeFloat instruction.
   bool isTypeIntOrFloat() const { return isTypeIntN() || isAnyTypeFloat(); }
+  // Returns true if this is an OpTypePointer instruction.
+  bool isTypePtr() const;
 
   friend struct DenseMapInfo<SPIRVTypeInst>;
 };

>From 36f669fc7f1b544fdc2055a1c49258a844dbc76a Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 3 Jun 2026 17:16:37 -0700
Subject: [PATCH 2/6] Address PR comments

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  9 ++++----
 .../atomic-load-store-unsupported.ll          |  2 +-
 .../SPIRV/transcoding/store-atomic-ptr-64.ll  | 23 +++++++++++++++++++
 .../SPIRV/transcoding/store-atomic-ptr.ll     | 23 +++++++++++++++++++
 4 files changed, 52 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 480f83ea0e610..a791e92517ece 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2052,9 +2052,9 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
   SPIRVTypeInst PtrType = GR.getSPIRVTypeForVReg(Ptr);
   SPIRVTypeInst PointeeType = GR.getPointeeType(PtrType);
   if (!PointeeType.isTypeIntOrFloat() && !PointeeType.isTypePtr())
-    return diagnoseUnsupported(I,
-                               "Lowering to SPIR-V of atomic store is only "
-                               "allowed for integer or floating point types");
+    return diagnoseUnsupported(
+        I, "Lowering to SPIR-V of atomic store is only "
+           "allowed for integer, floating point or pointer types");
 
   assert(I.getNumMemOperands());
   const MachineMemOperand &MemOp = **I.memoperands_begin();
@@ -2076,7 +2076,8 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
 
   if (PointeeType.isTypePtr()) {
     auto PtrSize = GR.getPointerSize();
-    SPIRVTypeInst SpirvType = GR.getOrCreateSPIRVIntegerType(PtrSize, I, TII);
+    SPIRVTypeInst SpirvType =
+        GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
 
     Register NewVRegVal =
         MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
index b6c055ff3b7de..18848af7cd995 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
@@ -7,7 +7,7 @@
 ; RUN: not llc -O0 -mtriple=spirv64-- %t/store-vector.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-VEC %s
 
 ; FAIL-LOAD-VEC: error:{{.*}}atomic load is only allowed for integer or floating point types
-; FAIL-STORE-VEC: error:{{.*}}atomic store is only allowed for integer or floating point types
+; FAIL-STORE-VEC: error:{{.*}}atomic store is only allowed for integer, floating point or pointer types
 
 ;--- load-vector.ll
 define <2 x i32> @load_vector_acquire(ptr addrspace(1) %ptr) {
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
new file mode 100644
index 0000000000000..ff3b3100fd501
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
@@ -0,0 +1,23 @@
+; RUN: llc -O0 -mtriple=spirv64-- %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-- %s -o - -filetype=obj | spirv-val %}
+
+; Check that 'store atomic' LLVM IR instructions are lowered correctly to
+; OpAtomicStore when a pointer is passed as value
+
+; CHECK-DAG: %[[#Int64:]] = OpTypeInt 64 0
+; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
+; CHECK-DAG: %[[#Int64Ptr:]] = OpTypePointer Generic %[[#Int64]]
+; CHECK-DAG: %[[#Int8Ptr:]] = OpTypePointer Generic %[[#Int8]]
+; CHECK-DAG: %[[#PtrInt8Ptr:]] = OpTypePointer Generic %[[#Int8Ptr]]
+
+define void @store_ptr(ptr addrspace(4) %ptr, ptr addrspace(4) %val) {
+; CHECK-LABEL: OpFunction %[[#]]
+; CHECK:       %[[#ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
+; CHECK:       %[[#val:]] = OpFunctionParameter %[[#Int8Ptr]]
+; CHECK:       %[[#convertVal:]] = OpConvertPtrToU %[[#Int64:]] %[[#val:]]
+; CHECK:       %[[#convertPtr:]] = OpBitcast %[[#Int64Ptr:]] %[[#ptr:]]
+; CHECK:       OpAtomicStore %[[#convertPtr]] %[[#]] %[[#]] %[[#convertVal]]
+; CHECK:       OpReturn
+  store atomic ptr addrspace(4) %val, ptr addrspace(4) %ptr monotonic, align 8
+  ret void
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
new file mode 100644
index 0000000000000..f940553b33128
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
@@ -0,0 +1,23 @@
+; RUN: llc -O0 -mtriple=spirv32-- %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-- %s -o - -filetype=obj | spirv-val %}
+
+; Check that 'store atomic' LLVM IR instructions are lowered correctly to
+; OpAtomicStore when a pointer is passed as value
+
+; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
+; CHECK-DAG: %[[#Int32Ptr:]] = OpTypePointer Generic %[[#Int32]]
+; CHECK-DAG: %[[#Int8Ptr:]] = OpTypePointer Generic %[[#Int8]]
+; CHECK-DAG: %[[#PtrInt8Ptr:]] = OpTypePointer Generic %[[#Int8Ptr]]
+
+define void @store_ptr(ptr addrspace(4) %ptr, ptr addrspace(4) %val) {
+; CHECK-LABEL: OpFunction %[[#]]
+; CHECK:       %[[#ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
+; CHECK:       %[[#val:]] = OpFunctionParameter %[[#Int8Ptr]]
+; CHECK:       %[[#convertVal:]] = OpConvertPtrToU %[[#Int32:]] %[[#val:]]
+; CHECK:       %[[#convertPtr:]] = OpBitcast %[[#Int32Ptr:]] %[[#ptr:]]
+; CHECK:       OpAtomicStore %[[#convertPtr]] %[[#]] %[[#]] %[[#convertVal]]
+; CHECK:       OpReturn
+  store atomic ptr addrspace(4) %val, ptr addrspace(4) %ptr monotonic, align 8
+  ret void
+}
\ No newline at end of file

>From d998484d93342bc5d2e9dc21ee39d79df27b1e3a Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Thu, 4 Jun 2026 11:41:33 -0700
Subject: [PATCH 3/6] Address PR comments

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 32 +++++++++++--------
 .../SPIRV/transcoding/store-atomic-ptr-64.ll  | 16 +++++-----
 .../SPIRV/transcoding/store-atomic-ptr.ll     | 16 +++++-----
 3 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index a791e92517ece..5bc8ce60b423e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2075,39 +2075,43 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
   MachineIRBuilder MIRBuilder(I);
 
   if (PointeeType.isTypePtr()) {
+    // If data to store is a pointer type we cast it to an integer type of the
+    // same size as the pointer size using OpConvertPtrToU and then generate
+    // OpAtomicStore with casted values as required by spec.
     auto PtrSize = GR.getPointerSize();
-    SPIRVTypeInst SpirvType =
+    SPIRVTypeInst PtrAsIntSpirvType =
         GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
 
-    Register NewVRegVal =
+    Register PtrToUVal =
         MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
-    MRI->setRegClass(NewVRegVal, MRI->getRegClassOrNull(StoreVal));
-    GR.assignSPIRVTypeToVReg(SpirvType, NewVRegVal, MIRBuilder.getMF());
+    MRI->setRegClass(PtrToUVal, MRI->getRegClassOrNull(StoreVal));
+    GR.assignSPIRVTypeToVReg(PtrAsIntSpirvType, PtrToUVal, MIRBuilder.getMF());
     MIRBuilder.buildInstr(SPIRV::OpConvertPtrToU)
-        .addDef(NewVRegVal)
-        .addUse(GR.getSPIRVTypeID(SpirvType)) // Result type
-        .addUse(StoreVal)                     // Pointer operand
+        .addDef(PtrToUVal)
+        .addUse(GR.getSPIRVTypeID(PtrAsIntSpirvType)) // Result type
+        .addUse(StoreVal)                             // Pointer operand
         .constrainAllUses(TII, TRI, RBI);
 
-    Register NewVRegPtr =
+    Register PtrCastedToMatchValReg =
         MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
-    MRI->setRegClass(NewVRegPtr, MRI->getRegClassOrNull(Ptr));
+    MRI->setRegClass(PtrCastedToMatchValReg, MRI->getRegClassOrNull(Ptr));
     SPIRVTypeInst PtrType = GR.getOrCreateSPIRVPointerType(
-        SpirvType, MIRBuilder,
+        PtrAsIntSpirvType, MIRBuilder,
         addressSpaceToStorageClass(MemOp.getAddrSpace(), STI));
-    GR.assignSPIRVTypeToVReg(PtrType, NewVRegPtr, MIRBuilder.getMF());
+    GR.assignSPIRVTypeToVReg(PtrType, PtrCastedToMatchValReg,
+                             MIRBuilder.getMF());
 
     MIRBuilder.buildInstr(SPIRV::OpBitcast)
-        .addDef(NewVRegPtr)
+        .addDef(PtrCastedToMatchValReg)
         .addUse(GR.getSPIRVTypeID(PtrType))
         .addUse(Ptr)
         .constrainAllUses(TII, TRI, RBI);
 
     MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
-        .addUse(NewVRegPtr)
+        .addUse(PtrCastedToMatchValReg)
         .addUse(ScopeReg)
         .addUse(MemSemReg)
-        .addUse(NewVRegVal)
+        .addUse(PtrToUVal)
         .constrainAllUses(TII, TRI, RBI);
   } else {
     auto AtomicStore = MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
index ff3b3100fd501..45cdc73153f1a 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
@@ -1,8 +1,8 @@
-; RUN: llc -O0 -mtriple=spirv64-- %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64 %s -o - | FileCheck %s
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-- %s -o - -filetype=obj | spirv-val %}
 
 ; Check that 'store atomic' LLVM IR instructions are lowered correctly to
-; OpAtomicStore when a pointer is passed as value
+; OpAtomicStore when a pointer is passed as value.
 
 ; CHECK-DAG: %[[#Int64:]] = OpTypeInt 64 0
 ; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
@@ -12,12 +12,12 @@
 
 define void @store_ptr(ptr addrspace(4) %ptr, ptr addrspace(4) %val) {
 ; CHECK-LABEL: OpFunction %[[#]]
-; CHECK:       %[[#ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
-; CHECK:       %[[#val:]] = OpFunctionParameter %[[#Int8Ptr]]
-; CHECK:       %[[#convertVal:]] = OpConvertPtrToU %[[#Int64:]] %[[#val:]]
-; CHECK:       %[[#convertPtr:]] = OpBitcast %[[#Int64Ptr:]] %[[#ptr:]]
-; CHECK:       OpAtomicStore %[[#convertPtr]] %[[#]] %[[#]] %[[#convertVal]]
+; CHECK:       %[[#Ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
+; CHECK:       %[[#Val:]] = OpFunctionParameter %[[#Int8Ptr]]
+; CHECK:       %[[#ConvertVal:]] = OpConvertPtrToU %[[#Int64]] %[[#Val]]
+; CHECK:       %[[#ConvertPtr:]] = OpBitcast %[[#Int64Ptr]] %[[#Ptr]]
+; CHECK:       OpAtomicStore %[[#ConvertPtr]] %[[#]] %[[#]] %[[#ConvertVal]]
 ; CHECK:       OpReturn
   store atomic ptr addrspace(4) %val, ptr addrspace(4) %ptr monotonic, align 8
   ret void
-}
\ No newline at end of file
+}
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
index f940553b33128..66df7c0809b17 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
@@ -1,8 +1,8 @@
-; RUN: llc -O0 -mtriple=spirv32-- %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv32 %s -o - | FileCheck %s
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-- %s -o - -filetype=obj | spirv-val %}
 
 ; Check that 'store atomic' LLVM IR instructions are lowered correctly to
-; OpAtomicStore when a pointer is passed as value
+; OpAtomicStore when a pointer is passed as value.
 
 ; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0
 ; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
@@ -12,12 +12,12 @@
 
 define void @store_ptr(ptr addrspace(4) %ptr, ptr addrspace(4) %val) {
 ; CHECK-LABEL: OpFunction %[[#]]
-; CHECK:       %[[#ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
-; CHECK:       %[[#val:]] = OpFunctionParameter %[[#Int8Ptr]]
-; CHECK:       %[[#convertVal:]] = OpConvertPtrToU %[[#Int32:]] %[[#val:]]
-; CHECK:       %[[#convertPtr:]] = OpBitcast %[[#Int32Ptr:]] %[[#ptr:]]
-; CHECK:       OpAtomicStore %[[#convertPtr]] %[[#]] %[[#]] %[[#convertVal]]
+; CHECK:       %[[#Ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
+; CHECK:       %[[#Val:]] = OpFunctionParameter %[[#Int8Ptr]]
+; CHECK:       %[[#ConvertVal:]] = OpConvertPtrToU %[[#Int32]] %[[#Val]]
+; CHECK:       %[[#ConvertPtr:]] = OpBitcast %[[#Int32Ptr]] %[[#Ptr]]
+; CHECK:       OpAtomicStore %[[#ConvertPtr]] %[[#]] %[[#]] %[[#ConvertVal]]
 ; CHECK:       OpReturn
   store atomic ptr addrspace(4) %val, ptr addrspace(4) %ptr monotonic, align 8
   ret void
-}
\ No newline at end of file
+}

>From 376c3828e4cd932d46f88154e7ee31e63a8a9bdd Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Thu, 4 Jun 2026 20:11:55 -0700
Subject: [PATCH 4/6] Address PR comments. Limit the functionality to physical
 addressing model. Add a test case  for logical addressing mode

---
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp     | 10 ++++++----
 .../SPIRV/transcoding/atomic-load-store-unsupported.ll |  8 ++++++++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 5bc8ce60b423e..8f5b84f412b87 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2051,7 +2051,8 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
 
   SPIRVTypeInst PtrType = GR.getSPIRVTypeForVReg(Ptr);
   SPIRVTypeInst PointeeType = GR.getPointeeType(PtrType);
-  if (!PointeeType.isTypeIntOrFloat() && !PointeeType.isTypePtr())
+  if (!(PointeeType.isTypeIntOrFloat() ||
+        (STI.isPhysicalSPIRV() && PointeeType.isTypePtr())))
     return diagnoseUnsupported(
         I, "Lowering to SPIR-V of atomic store is only "
            "allowed for integer, floating point or pointer types");
@@ -2076,9 +2077,10 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
 
   if (PointeeType.isTypePtr()) {
     // If data to store is a pointer type we cast it to an integer type of the
-    // same size as the pointer size using OpConvertPtrToU and then generate
-    // OpAtomicStore with casted values as required by spec.
-    auto PtrSize = GR.getPointerSize();
+    // same size as the pointer size using OpConvertPtrToU, bitcast Ptr
+    // parameter to pointer to integer type and then generate OpAtomicStore with
+    // casted values as required by spec.
+    unsigned PtrSize = GR.getPointerSize();
     SPIRVTypeInst PtrAsIntSpirvType =
         GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
 
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
index 18848af7cd995..d8baa77520163 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
@@ -6,6 +6,8 @@
 
 ; RUN: not llc -O0 -mtriple=spirv64-- %t/store-vector.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-VEC %s
 
+; RUN: not llc -O0 -mtriple=spirv %t/store-ptr-vulkan.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-VEC %s
+
 ; FAIL-LOAD-VEC: error:{{.*}}atomic load is only allowed for integer or floating point types
 ; FAIL-STORE-VEC: error:{{.*}}atomic store is only allowed for integer, floating point or pointer types
 
@@ -20,3 +22,9 @@ define void @store_vector_release(ptr addrspace(1) %ptr, <2 x i32> %val) {
   store atomic <2 x i32> %val, ptr addrspace(1) %ptr release, align 8
   ret void
 }
+
+;--- store-ptr-vulkan.ll
+define void @store_vector_release(ptr addrspace(1) %ptr, ptr addrspace(1) %val) {
+  store atomic ptr addrspace(1) %val, ptr addrspace(1) %ptr monotonic, align 8
+  ret void
+}

>From 6399c481f2487a632067863e28e73b53ba1ab2ac Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Fri, 5 Jun 2026 09:33:01 -0700
Subject: [PATCH 5/6] Address PR comments

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 100 +++++++++---------
 .../atomic-load-store-unsupported.ll          |   2 +-
 .../SPIRV/transcoding/store-atomic-ptr-64.ll  |  23 ----
 .../SPIRV/transcoding/store-atomic-ptr.ll     |  18 +++-
 4 files changed, 64 insertions(+), 79 deletions(-)
 delete mode 100644 llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 8f5b84f412b87..4cc103469edca 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2051,11 +2051,6 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
 
   SPIRVTypeInst PtrType = GR.getSPIRVTypeForVReg(Ptr);
   SPIRVTypeInst PointeeType = GR.getPointeeType(PtrType);
-  if (!(PointeeType.isTypeIntOrFloat() ||
-        (STI.isPhysicalSPIRV() && PointeeType.isTypePtr())))
-    return diagnoseUnsupported(
-        I, "Lowering to SPIR-V of atomic store is only "
-           "allowed for integer, floating point or pointer types");
 
   assert(I.getNumMemOperands());
   const MachineMemOperand &MemOp = **I.memoperands_begin();
@@ -2072,57 +2067,62 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
   if (MemOp.isVolatile() && STI.getTargetTriple().isVulkanOS())
     MemSem |= static_cast<uint32_t>(SPIRV::MemorySemantics::Volatile);
   Register MemSemReg = buildI32Constant(MemSem | StorageClass, I);
-
   MachineIRBuilder MIRBuilder(I);
 
   if (PointeeType.isTypePtr()) {
-    // If data to store is a pointer type we cast it to an integer type of the
-    // same size as the pointer size using OpConvertPtrToU, bitcast Ptr
-    // parameter to pointer to integer type and then generate OpAtomicStore with
-    // casted values as required by spec.
-    unsigned PtrSize = GR.getPointerSize();
-    SPIRVTypeInst PtrAsIntSpirvType =
-        GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
-
-    Register PtrToUVal =
-        MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
-    MRI->setRegClass(PtrToUVal, MRI->getRegClassOrNull(StoreVal));
-    GR.assignSPIRVTypeToVReg(PtrAsIntSpirvType, PtrToUVal, MIRBuilder.getMF());
-    MIRBuilder.buildInstr(SPIRV::OpConvertPtrToU)
-        .addDef(PtrToUVal)
-        .addUse(GR.getSPIRVTypeID(PtrAsIntSpirvType)) // Result type
-        .addUse(StoreVal)                             // Pointer operand
-        .constrainAllUses(TII, TRI, RBI);
+    if (STI.isPhysicalSPIRV()) {
+      // If data to store is a pointer type we cast it to an integer type of the
+      // same size as the pointer size using OpConvertPtrToU, bitcast Ptr
+      // parameter to pointer to integer type and then generate OpAtomicStore
+      // with casted values as required by spec.
+      unsigned PtrSize = GR.getPointerSize();
+      SPIRVTypeInst PtrAsIntSpirvType =
+          GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
+
+      Register PtrToUVal =
+          MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
+      MRI->setRegClass(PtrToUVal, MRI->getRegClassOrNull(StoreVal));
+      GR.assignSPIRVTypeToVReg(PtrAsIntSpirvType, PtrToUVal,
+                               MIRBuilder.getMF());
+      MIRBuilder.buildInstr(SPIRV::OpConvertPtrToU)
+          .addDef(PtrToUVal)
+          .addUse(GR.getSPIRVTypeID(PtrAsIntSpirvType)) // Result type
+          .addUse(StoreVal)                             // Pointer operand
+          .constrainAllUses(TII, TRI, RBI);
 
-    Register PtrCastedToMatchValReg =
-        MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
-    MRI->setRegClass(PtrCastedToMatchValReg, MRI->getRegClassOrNull(Ptr));
-    SPIRVTypeInst PtrType = GR.getOrCreateSPIRVPointerType(
-        PtrAsIntSpirvType, MIRBuilder,
-        addressSpaceToStorageClass(MemOp.getAddrSpace(), STI));
-    GR.assignSPIRVTypeToVReg(PtrType, PtrCastedToMatchValReg,
-                             MIRBuilder.getMF());
-
-    MIRBuilder.buildInstr(SPIRV::OpBitcast)
-        .addDef(PtrCastedToMatchValReg)
-        .addUse(GR.getSPIRVTypeID(PtrType))
-        .addUse(Ptr)
-        .constrainAllUses(TII, TRI, RBI);
+      Register PtrCastedToMatchValReg =
+          MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
+      MRI->setRegClass(PtrCastedToMatchValReg, MRI->getRegClassOrNull(Ptr));
+      SPIRVTypeInst PtrType = GR.getOrCreateSPIRVPointerType(
+          PtrAsIntSpirvType, MIRBuilder,
+          addressSpaceToStorageClass(MemOp.getAddrSpace(), STI));
+      GR.assignSPIRVTypeToVReg(PtrType, PtrCastedToMatchValReg,
+                               MIRBuilder.getMF());
+
+      MIRBuilder.buildInstr(SPIRV::OpBitcast)
+          .addDef(PtrCastedToMatchValReg)
+          .addUse(GR.getSPIRVTypeID(PtrType))
+          .addUse(Ptr)
+          .constrainAllUses(TII, TRI, RBI);
 
-    MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
-        .addUse(PtrCastedToMatchValReg)
-        .addUse(ScopeReg)
-        .addUse(MemSemReg)
-        .addUse(PtrToUVal)
-        .constrainAllUses(TII, TRI, RBI);
-  } else {
-    auto AtomicStore = MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
-                           .addUse(Ptr)
-                           .addUse(ScopeReg)
-                           .addUse(MemSemReg)
-                           .addUse(StoreVal);
-    AtomicStore.constrainAllUses(TII, TRI, RBI);
+      StoreVal = PtrToUVal;
+      Ptr = PtrCastedToMatchValReg;
+      PointeeType = PtrAsIntSpirvType;
+    }
   }
+
+  if (!PointeeType.isTypeIntOrFloat())
+    return diagnoseUnsupported(I,
+                               "Lowering to SPIR-V of atomic store is only "
+                               "allowed for integer or floating point types");
+
+  auto AtomicStore = MIRBuilder.buildInstr(SPIRV::OpAtomicStore)
+                         .addUse(Ptr)
+                         .addUse(ScopeReg)
+                         .addUse(MemSemReg)
+                         .addUse(StoreVal);
+  AtomicStore.constrainAllUses(TII, TRI, RBI);
+
   return true;
 }
 
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
index d8baa77520163..a21e9ba5645b7 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
@@ -9,7 +9,7 @@
 ; RUN: not llc -O0 -mtriple=spirv %t/store-ptr-vulkan.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-VEC %s
 
 ; FAIL-LOAD-VEC: error:{{.*}}atomic load is only allowed for integer or floating point types
-; FAIL-STORE-VEC: error:{{.*}}atomic store is only allowed for integer, floating point or pointer types
+; FAIL-STORE-VEC: error:{{.*}}atomic store is only allowed for integer or floating point types
 
 ;--- load-vector.ll
 define <2 x i32> @load_vector_acquire(ptr addrspace(1) %ptr) {
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
deleted file mode 100644
index 45cdc73153f1a..0000000000000
--- a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr-64.ll
+++ /dev/null
@@ -1,23 +0,0 @@
-; RUN: llc -O0 -mtriple=spirv64 %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-- %s -o - -filetype=obj | spirv-val %}
-
-; Check that 'store atomic' LLVM IR instructions are lowered correctly to
-; OpAtomicStore when a pointer is passed as value.
-
-; CHECK-DAG: %[[#Int64:]] = OpTypeInt 64 0
-; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
-; CHECK-DAG: %[[#Int64Ptr:]] = OpTypePointer Generic %[[#Int64]]
-; CHECK-DAG: %[[#Int8Ptr:]] = OpTypePointer Generic %[[#Int8]]
-; CHECK-DAG: %[[#PtrInt8Ptr:]] = OpTypePointer Generic %[[#Int8Ptr]]
-
-define void @store_ptr(ptr addrspace(4) %ptr, ptr addrspace(4) %val) {
-; CHECK-LABEL: OpFunction %[[#]]
-; CHECK:       %[[#Ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
-; CHECK:       %[[#Val:]] = OpFunctionParameter %[[#Int8Ptr]]
-; CHECK:       %[[#ConvertVal:]] = OpConvertPtrToU %[[#Int64]] %[[#Val]]
-; CHECK:       %[[#ConvertPtr:]] = OpBitcast %[[#Int64Ptr]] %[[#Ptr]]
-; CHECK:       OpAtomicStore %[[#ConvertPtr]] %[[#]] %[[#]] %[[#ConvertVal]]
-; CHECK:       OpReturn
-  store atomic ptr addrspace(4) %val, ptr addrspace(4) %ptr monotonic, align 8
-  ret void
-}
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
index 66df7c0809b17..223b59da2797f 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/store-atomic-ptr.ll
@@ -1,21 +1,29 @@
-; RUN: llc -O0 -mtriple=spirv32 %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv32 %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV32
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-- %s -o - -filetype=obj | spirv-val %}
 
+; RUN: llc -O0 -mtriple=spirv64 %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV64
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-- %s -o - -filetype=obj | spirv-val %}
+
+
 ; Check that 'store atomic' LLVM IR instructions are lowered correctly to
 ; OpAtomicStore when a pointer is passed as value.
 
-; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0
+; SPIRV32-DAG: %[[#Int32:]] = OpTypeInt 32 0
 ; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
-; CHECK-DAG: %[[#Int32Ptr:]] = OpTypePointer Generic %[[#Int32]]
+; SPIRV32-DAG: %[[#Int32Ptr:]] = OpTypePointer Generic %[[#Int32]]
 ; CHECK-DAG: %[[#Int8Ptr:]] = OpTypePointer Generic %[[#Int8]]
 ; CHECK-DAG: %[[#PtrInt8Ptr:]] = OpTypePointer Generic %[[#Int8Ptr]]
+; SPIRV64-DAG: %[[#Int64:]] = OpTypeInt 64 0
+; SPIRV64-DAG: %[[#Int64Ptr:]] = OpTypePointer Generic %[[#Int64]]
 
 define void @store_ptr(ptr addrspace(4) %ptr, ptr addrspace(4) %val) {
 ; CHECK-LABEL: OpFunction %[[#]]
 ; CHECK:       %[[#Ptr:]] = OpFunctionParameter %[[#PtrInt8Ptr]]
 ; CHECK:       %[[#Val:]] = OpFunctionParameter %[[#Int8Ptr]]
-; CHECK:       %[[#ConvertVal:]] = OpConvertPtrToU %[[#Int32]] %[[#Val]]
-; CHECK:       %[[#ConvertPtr:]] = OpBitcast %[[#Int32Ptr]] %[[#Ptr]]
+; SPIRV32:       %[[#ConvertVal:]] = OpConvertPtrToU %[[#Int32]] %[[#Val]]
+; SPIRV32:       %[[#ConvertPtr:]] = OpBitcast %[[#Int32Ptr]] %[[#Ptr]]
+; SPIRV64:       %[[#ConvertVal:]] = OpConvertPtrToU %[[#Int64]] %[[#Val]]
+; SPIRV64:       %[[#ConvertPtr:]] = OpBitcast %[[#Int64Ptr]] %[[#Ptr]]
 ; CHECK:       OpAtomicStore %[[#ConvertPtr]] %[[#]] %[[#]] %[[#ConvertVal]]
 ; CHECK:       OpReturn
   store atomic ptr addrspace(4) %val, ptr addrspace(4) %ptr monotonic, align 8

>From 4739a56aa9459597b7e500265c7de2f17932ae4a Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Mon, 8 Jun 2026 11:06:06 -0700
Subject: [PATCH 6/6] Report an error when pointer type is used with logical
 address mode

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 75 ++++++++++---------
 .../atomic-load-store-unsupported.ll          |  3 +-
 2 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 4cc103469edca..c23ddae2acd7a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2070,45 +2070,46 @@ bool SPIRVInstructionSelector::selectAtomicStore(MachineInstr &I) const {
   MachineIRBuilder MIRBuilder(I);
 
   if (PointeeType.isTypePtr()) {
-    if (STI.isPhysicalSPIRV()) {
-      // If data to store is a pointer type we cast it to an integer type of the
-      // same size as the pointer size using OpConvertPtrToU, bitcast Ptr
-      // parameter to pointer to integer type and then generate OpAtomicStore
-      // with casted values as required by spec.
-      unsigned PtrSize = GR.getPointerSize();
-      SPIRVTypeInst PtrAsIntSpirvType =
-          GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
-
-      Register PtrToUVal =
-          MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
-      MRI->setRegClass(PtrToUVal, MRI->getRegClassOrNull(StoreVal));
-      GR.assignSPIRVTypeToVReg(PtrAsIntSpirvType, PtrToUVal,
-                               MIRBuilder.getMF());
-      MIRBuilder.buildInstr(SPIRV::OpConvertPtrToU)
-          .addDef(PtrToUVal)
-          .addUse(GR.getSPIRVTypeID(PtrAsIntSpirvType)) // Result type
-          .addUse(StoreVal)                             // Pointer operand
-          .constrainAllUses(TII, TRI, RBI);
+    if (!STI.isPhysicalSPIRV())
+      return diagnoseUnsupported(
+          I, "Lowering to SPIR-V of atomic store is only "
+             "allowed for pointer types for physical addressing model");
+    // If data to store is a pointer type we cast it to an integer type of the
+    // same size as the pointer size using OpConvertPtrToU, bitcast Ptr
+    // parameter to pointer to integer type and then generate OpAtomicStore
+    // with casted values as required by spec.
+    unsigned PtrSize = GR.getPointerSize();
+    SPIRVTypeInst PtrAsIntSpirvType =
+        GR.getOrCreateSPIRVIntegerType(PtrSize, MIRBuilder);
+
+    Register PtrToUVal =
+        MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
+    MRI->setRegClass(PtrToUVal, MRI->getRegClassOrNull(StoreVal));
+    GR.assignSPIRVTypeToVReg(PtrAsIntSpirvType, PtrToUVal, MIRBuilder.getMF());
+    MIRBuilder.buildInstr(SPIRV::OpConvertPtrToU)
+        .addDef(PtrToUVal)
+        .addUse(GR.getSPIRVTypeID(PtrAsIntSpirvType)) // Result type
+        .addUse(StoreVal)                             // Pointer operand
+        .constrainAllUses(TII, TRI, RBI);
 
-      Register PtrCastedToMatchValReg =
-          MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
-      MRI->setRegClass(PtrCastedToMatchValReg, MRI->getRegClassOrNull(Ptr));
-      SPIRVTypeInst PtrType = GR.getOrCreateSPIRVPointerType(
-          PtrAsIntSpirvType, MIRBuilder,
-          addressSpaceToStorageClass(MemOp.getAddrSpace(), STI));
-      GR.assignSPIRVTypeToVReg(PtrType, PtrCastedToMatchValReg,
-                               MIRBuilder.getMF());
-
-      MIRBuilder.buildInstr(SPIRV::OpBitcast)
-          .addDef(PtrCastedToMatchValReg)
-          .addUse(GR.getSPIRVTypeID(PtrType))
-          .addUse(Ptr)
-          .constrainAllUses(TII, TRI, RBI);
+    Register PtrCastedToMatchValReg =
+        MRI->createGenericVirtualRegister(LLT::scalar(PtrSize));
+    MRI->setRegClass(PtrCastedToMatchValReg, MRI->getRegClassOrNull(Ptr));
+    SPIRVTypeInst PtrType = GR.getOrCreateSPIRVPointerType(
+        PtrAsIntSpirvType, MIRBuilder,
+        addressSpaceToStorageClass(MemOp.getAddrSpace(), STI));
+    GR.assignSPIRVTypeToVReg(PtrType, PtrCastedToMatchValReg,
+                             MIRBuilder.getMF());
+
+    MIRBuilder.buildInstr(SPIRV::OpBitcast)
+        .addDef(PtrCastedToMatchValReg)
+        .addUse(GR.getSPIRVTypeID(PtrType))
+        .addUse(Ptr)
+        .constrainAllUses(TII, TRI, RBI);
 
-      StoreVal = PtrToUVal;
-      Ptr = PtrCastedToMatchValReg;
-      PointeeType = PtrAsIntSpirvType;
-    }
+    StoreVal = PtrToUVal;
+    Ptr = PtrCastedToMatchValReg;
+    PointeeType = PtrAsIntSpirvType;
   }
 
   if (!PointeeType.isTypeIntOrFloat())
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
index a21e9ba5645b7..b5ed65c829f7b 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/atomic-load-store-unsupported.ll
@@ -6,10 +6,11 @@
 
 ; RUN: not llc -O0 -mtriple=spirv64-- %t/store-vector.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-VEC %s
 
-; RUN: not llc -O0 -mtriple=spirv %t/store-ptr-vulkan.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-VEC %s
+; RUN: not llc -O0 -mtriple=spirv %t/store-ptr-vulkan.ll -o /dev/null 2>&1 | FileCheck --check-prefix=FAIL-STORE-PTR %s
 
 ; FAIL-LOAD-VEC: error:{{.*}}atomic load is only allowed for integer or floating point types
 ; FAIL-STORE-VEC: error:{{.*}}atomic store is only allowed for integer or floating point types
+; FAIL-STORE-PTR: error:{{.*}}atomic store is only allowed for pointer types for physical addressing model
 
 ;--- load-vector.ll
 define <2 x i32> @load_vector_acquire(ptr addrspace(1) %ptr) {



More information about the llvm-commits mailing list