Skip to content

Commit a79c852

Browse files
authored
[Backport to 21] Add SPV_INTEL_16bit_atomics extension (#3424)
This continues #3343 and reflects specification update, including extension renaming. Specification: intel/llvm#20009
1 parent 3c0231e commit a79c852

File tree

13 files changed

+172
-22
lines changed

13 files changed

+172
-22
lines changed

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ EXT(SPV_INTEL_bfloat16_arithmetic)
8181
EXT(SPV_INTEL_ternary_bitwise_function)
8282
EXT(SPV_INTEL_int4)
8383
EXT(SPV_INTEL_function_variants)
84-
EXT(SPV_INTEL_shader_atomic_bfloat16)
84+
EXT(SPV_INTEL_16bit_atomics)
8585
EXT(SPV_EXT_float8)
8686
EXT(SPV_INTEL_predicated_io)
8787
EXT(SPV_INTEL_sigmoid)

lib/SPIRV/libSPIRV/SPIRVEnum.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ template <> inline void SPIRVMap<SPIRVCapabilityKind, SPIRVCapVec>::init() {
230230
{CapabilityInt4TypeINTEL, CapabilityCooperativeMatrixKHR});
231231
ADD_VEC_INIT(internal::CapabilityBFloat16ArithmeticINTEL,
232232
{CapabilityBFloat16TypeKHR});
233+
ADD_VEC_INIT(internal::CapabilityAtomicInt16CompareExchangeINTEL,
234+
{CapabilityInt16});
235+
ADD_VEC_INIT(internal::CapabilityInt16AtomicsINTEL,
236+
{internal::CapabilityAtomicInt16CompareExchangeINTEL});
237+
ADD_VEC_INIT(internal::CapabilityAtomicBFloat16LoadStoreINTEL,
238+
{CapabilityBFloat16TypeKHR});
239+
ADD_VEC_INIT(internal::CapabilityAtomicBFloat16AddINTEL,
240+
{CapabilityBFloat16TypeKHR});
241+
ADD_VEC_INIT(internal::CapabilityAtomicBFloat16MinMaxINTEL,
242+
{CapabilityBFloat16TypeKHR});
233243
}
234244

235245
template <> inline void SPIRVMap<SPIRVExecutionModelKind, SPIRVCapVec>::init() {

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,8 +2964,16 @@ class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
29642964
// Besides, OpAtomicCompareExchangeWeak, OpAtomicFlagTestAndSet and
29652965
// OpAtomicFlagClear instructions require the "kernel" capability. But this
29662966
// capability should be added by setting the OpenCL memory model.
2967-
if (hasType() && getType()->isTypeInt(64))
2968-
return {CapabilityInt64Atomics};
2967+
if (hasType()) {
2968+
if (getType()->isTypeInt(64))
2969+
return {CapabilityInt64Atomics};
2970+
if (getType()->isTypeInt(16) &&
2971+
Module->isAllowedToUseExtension(
2972+
ExtensionID::SPV_INTEL_16bit_atomics)) {
2973+
Module->addExtension(ExtensionID::SPV_INTEL_16bit_atomics);
2974+
return {internal::CapabilityInt16AtomicsINTEL};
2975+
}
2976+
}
29692977
return {};
29702978
}
29712979

@@ -3003,7 +3011,24 @@ class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
30033011
}
30043012
};
30053013

3006-
class SPIRVAtomicStoreInst : public SPIRVAtomicInstBase {
3014+
// This specialization will handle smaller set of compare-and-swap instructions
3015+
// that require only one capability. The instructions are: OpAtomicLoad,
3016+
// OpAtomicStore, OpAtomicExchange, OpAtomicCompareExchange and
3017+
// OpAtomicCompareExchangeWeak.
3018+
class SPIRVAtomicCompareExchangeInstructions : public SPIRVAtomicInstBase {
3019+
public:
3020+
SPIRVCapVec getRequiredCapability() const override {
3021+
if (hasType() && getType()->isTypeInt(16) &&
3022+
this->getModule()->isAllowedToUseExtension(
3023+
ExtensionID::SPV_INTEL_16bit_atomics)) {
3024+
Module->addExtension(ExtensionID::SPV_INTEL_16bit_atomics);
3025+
return {internal::CapabilityAtomicInt16CompareExchangeINTEL};
3026+
}
3027+
return SPIRVAtomicInstBase::getRequiredCapability();
3028+
}
3029+
};
3030+
3031+
class SPIRVAtomicStoreInst : public SPIRVAtomicCompareExchangeInstructions {
30073032
public:
30083033
// Overriding the following method because of 'const'-related
30093034
// issues with overriding getRequiredCapability(). TODO: Resolve.
@@ -3020,7 +3045,7 @@ class SPIRVAtomicFAddEXTInst : public SPIRVAtomicInstBase {
30203045
std::optional<ExtensionID> getRequiredExtension() const override {
30213046
assert(hasType());
30223047
if (getType()->isTypeFloat(16, FPEncodingBFloat16KHR))
3023-
return ExtensionID::SPV_INTEL_shader_atomic_bfloat16;
3048+
Module->addExtension(ExtensionID::SPV_INTEL_16bit_atomics);
30243049
if (getType()->isTypeFloat(16))
30253050
return ExtensionID::SPV_EXT_shader_atomic_float16_add;
30263051
return ExtensionID::SPV_EXT_shader_atomic_float_add;
@@ -3045,7 +3070,7 @@ class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
30453070
public:
30463071
std::optional<ExtensionID> getRequiredExtension() const override {
30473072
if (getType()->isTypeFloat(16, FPEncodingBFloat16KHR))
3048-
return ExtensionID::SPV_INTEL_shader_atomic_bfloat16;
3073+
Module->addExtension(ExtensionID::SPV_INTEL_16bit_atomics);
30493074
return ExtensionID::SPV_EXT_shader_atomic_float_min_max;
30503075
}
30513076

@@ -3069,10 +3094,6 @@ class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
30693094
// Atomic builtins
30703095
_SPIRV_OP(AtomicFlagTestAndSet, true, 6)
30713096
_SPIRV_OP(AtomicFlagClear, false, 4)
3072-
_SPIRV_OP(AtomicLoad, true, 6)
3073-
_SPIRV_OP(AtomicExchange, true, 7)
3074-
_SPIRV_OP(AtomicCompareExchange, true, 9)
3075-
_SPIRV_OP(AtomicCompareExchangeWeak, true, 9)
30763097
_SPIRV_OP(AtomicIIncrement, true, 6)
30773098
_SPIRV_OP(AtomicIDecrement, true, 6)
30783099
_SPIRV_OP(AtomicIAdd, true, 7)
@@ -3089,7 +3110,11 @@ _SPIRV_OP(MemoryBarrier, false, 3)
30893110
#define _SPIRV_OP(x, BaseClass, ...) \
30903111
typedef SPIRVInstTemplate<SPIRV##BaseClass, Op##x, __VA_ARGS__> SPIRV##x;
30913112
// Specialized atomic builtins
3113+
_SPIRV_OP(AtomicLoad, AtomicCompareExchangeInstructions, true, 6)
30923114
_SPIRV_OP(AtomicStore, AtomicStoreInst, false, 5)
3115+
_SPIRV_OP(AtomicExchange, AtomicCompareExchangeInstructions, true, 7)
3116+
_SPIRV_OP(AtomicCompareExchange, AtomicCompareExchangeInstructions, true, 9)
3117+
_SPIRV_OP(AtomicCompareExchangeWeak, AtomicCompareExchangeInstructions, true, 9)
30933118
_SPIRV_OP(AtomicFAddEXT, AtomicFAddEXTInst, true, 7)
30943119
_SPIRV_OP(AtomicFMinEXT, AtomicFMinMaxEXTBase, true, 7)
30953120
_SPIRV_OP(AtomicFMaxEXT, AtomicFMinMaxEXTBase, true, 7)

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,11 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
699699
add(internal::CapabilityFloat4E2M1CooperativeMatrixINTEL,
700700
"Float4E2M1CooperativeMatrixINTEL");
701701
add(internal::CapabilityFloatConversionsINTEL, "FloatConversionsINTEL");
702+
add(internal::CapabilityAtomicInt16CompareExchangeINTEL,
703+
"AtomicInt16CompareExchangeINTEL");
704+
add(internal::CapabilityInt16AtomicsINTEL, "Int16AtomicsINTEL");
705+
add(internal::CapabilityAtomicBFloat16LoadStoreINTEL,
706+
"AtomicBFloat16LoadStoreINTEL");
702707
}
703708
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
704709

lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ enum InternalCapability {
123123
ICapabilityAtomicBFloat16AddINTEL = 6255,
124124
ICapabilityAtomicBFloat16MinMaxINTEL = 6256,
125125
ICapabilityPredicatedIOINTEL = 6257,
126+
ICapabilityAtomicInt16CompareExchangeINTEL = 6260,
127+
ICapabilityInt16AtomicsINTEL = 6261,
128+
ICapabilityAtomicBFloat16LoadStoreINTEL = 6262,
126129
ICapabilityCooperativeMatrixPrefetchINTEL = 6411,
127130
ICapabilityMaskedGatherScatterINTEL = 6427,
128131
ICapabilityJointMatrixWIInstructionsINTEL = 6435,
@@ -309,6 +312,13 @@ constexpr Capability CapabilityBFloat16ArithmeticINTEL =
309312
constexpr ExecutionMode ExecutionModeNamedSubgroupSizeINTEL =
310313
static_cast<ExecutionMode>(IExecModeNamedSubgroupSizeINTEL);
311314

315+
constexpr Capability CapabilityAtomicInt16CompareExchangeINTEL =
316+
static_cast<Capability>(ICapabilityAtomicInt16CompareExchangeINTEL);
317+
constexpr Capability CapabilityInt16AtomicsINTEL =
318+
static_cast<Capability>(ICapabilityInt16AtomicsINTEL);
319+
constexpr Capability CapabilityAtomicBFloat16LoadStoreINTEL =
320+
static_cast<Capability>(ICapabilityAtomicBFloat16LoadStoreINTEL);
321+
312322
} // namespace internal
313323
} // namespace spv
314324

test/extensions/INTEL/SPV_INTEL_shader_atomic_bfloat16/AtomicFAddEXT.ll renamed to test/extensions/INTEL/SPV_INTEL_16bit_atomics/AtomicFAddEXT.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: llvm-as %s -o %t.bc
2-
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_shader_atomic_bfloat16,+SPV_KHR_bfloat16 -o %t.spv
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_16bit_atomics,+SPV_KHR_bfloat16,+SPV_EXT_shader_atomic_float_add -o %t.spv
33
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
44
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
55

@@ -11,7 +11,7 @@ target triple = "spir64-unknown-unknown"
1111

1212
; CHECK-SPIRV-DAG: Capability AtomicBFloat16AddINTEL
1313
; CHECK-SPIRV-DAG: Capability BFloat16TypeKHR
14-
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_shader_atomic_bfloat16"
14+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_16bit_atomics"
1515
; CHECK-SPIRV-DAG: Extension "SPV_KHR_bfloat16"
1616

1717
; CHECK-SPIRV: TypeFloat [[BFLOAT:[0-9]+]] 16 0

test/extensions/INTEL/SPV_INTEL_shader_atomic_bfloat16/AtomicFMaxEXT.ll renamed to test/extensions/INTEL/SPV_INTEL_16bit_atomics/AtomicFMaxEXT.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: llvm-as %s -o %t.bc
2-
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_shader_atomic_bfloat16,+SPV_KHR_bfloat16 -o %t.spv
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_16bit_atomics,+SPV_KHR_bfloat16,+SPV_EXT_shader_atomic_float_min_max -o %t.spv
33
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
44
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
55

@@ -11,7 +11,7 @@ target triple = "spir64-unknown-unknown"
1111

1212
; CHECK-SPIRV-DAG: Capability AtomicBFloat16MinMaxINTEL
1313
; CHECK-SPIRV-DAG: Capability BFloat16TypeKHR
14-
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_shader_atomic_bfloat16"
14+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_16bit_atomics"
1515
; CHECK-SPIRV-DAG: Extension "SPV_KHR_bfloat16"
1616

1717
; CHECK-SPIRV: TypeFloat [[BFLOAT:[0-9]+]] 16 0

test/extensions/INTEL/SPV_INTEL_shader_atomic_bfloat16/AtomicFMinEXT.ll renamed to test/extensions/INTEL/SPV_INTEL_16bit_atomics/AtomicFMinEXT.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: llvm-as %s -o %t.bc
2-
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_shader_atomic_bfloat16,+SPV_KHR_bfloat16 -o %t.spv
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_16bit_atomics,+SPV_KHR_bfloat16,+SPV_EXT_shader_atomic_float_min_max -o %t.spv
33
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
44
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
55

@@ -11,7 +11,7 @@ target triple = "spir64-unknown-unknown"
1111

1212
; CHECK-SPIRV-DAG: Capability AtomicBFloat16MinMaxINTEL
1313
; CHECK-SPIRV-DAG: Capability BFloat16TypeKHR
14-
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_shader_atomic_bfloat16"
14+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_16bit_atomics"
1515
; CHECK-SPIRV-DAG: Extension "SPV_KHR_bfloat16"
1616

1717
; CHECK-SPIRV: TypeFloat [[BFLOAT:[0-9]+]] 16 0
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_16bit_atomics
3+
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
4+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
5+
6+
; RUN: llvm-spirv -r --spirv-target-env=CL2.0 %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis %t.rev.bc
8+
; RUN: FileCheck < %t.rev.ll %s --check-prefixes=CHECK-LLVM
9+
10+
; Check that without extension we don't use its capabilities - there is no
11+
; limitation on using i16 with atomic instruction in the core specification.
12+
; RUN: llvm-spirv %t.bc -o %t.noext.spv
13+
; RUN: spirv-val %t.noext.spv
14+
; RUN: llvm-spirv -to-text %t.noext.spv -o %t.noext.spt
15+
; RUN: FileCheck < %t.noext.spt %s --check-prefix=CHECK-SPIRV-NOEXT
16+
17+
; CHECK-SPIRV: Capability Int16
18+
; CHECK-SPIRV: Capability AtomicInt16CompareExchangeINTEL
19+
; CHECK-SPIRV-NOT: Capability Int16AtomicsINTEL
20+
; CHECK-SPIRV: Extension "SPV_INTEL_16bit_atomics"
21+
22+
; CHECK-SPIRV-NOEXT: Capability Int16
23+
; CHECK-SPIRV-NOEXT-NOT: Capability AtomicInt16CompareExchangeINTEL
24+
; CHECK-SPIRV-NOEXT-NOT: Capability Int16AtomicsINTEL
25+
; CHECK-SPIRV-NOEXT-NOT: Extension "SPV_INTEL_16bit_atomics"
26+
27+
; CHECK-SPIRV-DAG: Constant [[#]] [[#CrossDeviceScope:]] 0
28+
; CHECK-SPIRV-DAG: Constant [[#]] [[#Release:]] 4
29+
; CHECK-SPIRV-DAG: Constant [[#]] [[#SequentiallyConsistent:]] 16
30+
; CHECK-SPIRV-DAG: Constant [[#]] [[#Acquire:]] 2
31+
32+
; CHECK-LLVM: call spir_func void @_Z21atomic_store_explicitPU3AS4VU7_Atomicss12memory_order12memory_scope
33+
; CHECK-LLVM: call spir_func i16 @_Z20atomic_load_explicitPU3AS4VU7_Atomics12memory_order12memory_scope
34+
; CHECK-LLVM: call spir_func i16 @_Z24atomic_exchange_explicitPU3AS4VU7_Atomicss12memory_order12memory_scope
35+
; CHECK-LLVM: call spir_func i1 @_Z39atomic_compare_exchange_strong_explicitPU3AS4VU7_AtomicsPU3AS4ss12memory_orderS4_12memory_scope
36+
37+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
38+
target triple = "spir64"
39+
40+
@ui = common dso_local addrspace(1) global i16 0, align 4
41+
; Function Attrs: nounwind
42+
define dso_local spir_func void @test() {
43+
entry:
44+
; CHECK-SPIRV: {{(Variable|UntypedVariableKHR)}} [[#]] [[#PTR:]] 7
45+
%0 = alloca i16
46+
; CHECK-SPIRV: AtomicStore [[#PTR]] [[#CrossDeviceScope]] [[#Release]] [[#]]
47+
store atomic i16 0, ptr %0 release, align 4
48+
; CHECK-SPIRV: AtomicLoad [[#]] [[#]] [[#PTR]] [[#CrossDeviceScope]] [[#Acquire]]
49+
%2 = load atomic i16, ptr %0 acquire, align 4
50+
; CHECK-SPIRV: AtomicExchange [[#]] [[#]] [[#]] [[#CrossDeviceScope]] [[#]] {{.+}}
51+
%4 = atomicrmw xchg ptr addrspace(1) @ui, i16 42 acq_rel
52+
; CHECK-SPIRV: AtomicCompareExchange [[#]] [[#]] [[#]] [[#CrossDeviceScope]] [[#SequentiallyConsistent]] [[#Acquire]] {{.+}}
53+
%5 = cmpxchg ptr %0, i16 128, i16 456 seq_cst acquire
54+
55+
ret void
56+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_16bit_atomics
3+
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
4+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
5+
6+
; RUN: llvm-spirv -r --spirv-target-env=CL2.0 %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis %t.rev.bc
8+
; RUN: FileCheck < %t.rev.ll %s --check-prefixes=CHECK-LLVM
9+
10+
; RUN: llvm-spirv -r --spirv-target-env="SPV-IR" %t.spv -o %t.rev.bc
11+
; RUN: llvm-dis %t.rev.bc
12+
; RUN: FileCheck < %t.rev.ll %s --check-prefixes=CHECK-LLVM-SPV-IR
13+
14+
; Check that without extension we don't use its capabilities - there is no
15+
; limitation on using i16 with atomic instruction in the core specification.
16+
; RUN: llvm-spirv %t.bc -o %t.noext.spv
17+
; RUN: spirv-val %t.noext.spv
18+
; RUN: llvm-spirv -to-text %t.noext.spv -o %t.noext.spt
19+
; RUN: FileCheck < %t.noext.spt %s --check-prefix=CHECK-SPIRV-NOEXT
20+
21+
; CHECK-SPIRV: Capability Int16
22+
; CHECK-SPIRV: Capability AtomicInt16CompareExchangeINTEL
23+
; CHECK-SPIRV: Capability Int16AtomicsINTEL
24+
; CHECK-SPIRV: Extension "SPV_INTEL_16bit_atomics"
25+
; CHECK-SPIRV: AtomicOr
26+
27+
; CHECK-SPIRV-NOEXT: Capability Int16
28+
; CHECK-SPIRV-NOEXT-NOT: Capability AtomicInt16CompareExchangeINTEL
29+
; CHECK-SPIRV-NOEXT-NOT: Capability Int16AtomicsINTEL
30+
; CHECK-SPIRV-NOEXT-NOT: Extension "SPV_INTEL_16bit_atomics"
31+
32+
; CHECK-LLVM: call spir_func i16 @_Z24atomic_fetch_or_explicitPU3AS4VU7_Atomicss12memory_order12memory_scope
33+
; CHECK-LLVM-SPV-IR: call spir_func i16 @_Z16__spirv_AtomicOrPU3AS1siis
34+
35+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
36+
target triple = "spir64"
37+
38+
@ui = common dso_local addrspace(1) global i16 0, align 4
39+
40+
define dso_local spir_func void @test() {
41+
entry:
42+
%0 = atomicrmw or ptr addrspace(1) @ui, i16 42 release
43+
ret void
44+
}

0 commit comments

Comments
 (0)