[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