Skip to content

Commit f9bbc0c

Browse files
vmaksimojsji
authored andcommitted
Add SPV_INTEL_16bit_atomics extension (#3424)
This continues #3343 and reflects specification update, including extension renaming. Specification: #20009 Original commit: KhronosGroup/SPIRV-LLVM-Translator@2f2a95e686e72ec
1 parent 20a1be0 commit f9bbc0c

File tree

13 files changed

+170
-22
lines changed

13 files changed

+170
-22
lines changed

llvm-spirv/include/LLVMSPIRVExtensions.inc

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

llvm-spirv/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() {

llvm-spirv/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)

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,11 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
714714
add(internal::CapabilityFloat4E2M1CooperativeMatrixINTEL,
715715
"Float4E2M1CooperativeMatrixINTEL");
716716
add(internal::CapabilityFloatConversionsINTEL, "FloatConversionsINTEL");
717+
add(internal::CapabilityAtomicInt16CompareExchangeINTEL,
718+
"AtomicInt16CompareExchangeINTEL");
719+
add(internal::CapabilityInt16AtomicsINTEL, "Int16AtomicsINTEL");
720+
add(internal::CapabilityAtomicBFloat16LoadStoreINTEL,
721+
"AtomicBFloat16LoadStoreINTEL");
717722
}
718723
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
719724

llvm-spirv/lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ enum InternalCapability {
124124
ICapabilityAtomicBFloat16AddINTEL = 6255,
125125
ICapabilityAtomicBFloat16MinMaxINTEL = 6256,
126126
ICapabilityPredicatedIOINTEL = 6257,
127+
ICapabilityAtomicInt16CompareExchangeINTEL = 6260,
128+
ICapabilityInt16AtomicsINTEL = 6261,
129+
ICapabilityAtomicBFloat16LoadStoreINTEL = 6262,
127130
ICapabilityCooperativeMatrixPrefetchINTEL = 6411,
128131
ICapabilityMaskedGatherScatterINTEL = 6427,
129132
ICapabilityJointMatrixWIInstructionsINTEL = 6435,
@@ -317,6 +320,13 @@ constexpr FunctionControlMask FunctionControlOptNoneINTELMask =
317320
constexpr ExecutionMode ExecutionModeNamedSubgroupSizeINTEL =
318321
static_cast<ExecutionMode>(IExecModeNamedSubgroupSizeINTEL);
319322

323+
constexpr Capability CapabilityAtomicInt16CompareExchangeINTEL =
324+
static_cast<Capability>(ICapabilityAtomicInt16CompareExchangeINTEL);
325+
constexpr Capability CapabilityInt16AtomicsINTEL =
326+
static_cast<Capability>(ICapabilityInt16AtomicsINTEL);
327+
constexpr Capability CapabilityAtomicBFloat16LoadStoreINTEL =
328+
static_cast<Capability>(ICapabilityAtomicBFloat16LoadStoreINTEL);
329+
320330
} // namespace internal
321331
} // namespace spv
322332

llvm-spirv/test/extensions/INTEL/SPV_INTEL_shader_atomic_bfloat16/AtomicFAddEXT.ll renamed to llvm-spirv/test/extensions/INTEL/SPV_INTEL_16bit_atomics/AtomicFAddEXT.ll

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

@@ -10,7 +10,7 @@ target triple = "spir64-unknown-unknown"
1010

1111
; CHECK-SPIRV-DAG: Capability AtomicBFloat16AddINTEL
1212
; CHECK-SPIRV-DAG: Capability BFloat16TypeKHR
13-
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_shader_atomic_bfloat16"
13+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_16bit_atomics"
1414
; CHECK-SPIRV-DAG: Extension "SPV_KHR_bfloat16"
1515

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

llvm-spirv/test/extensions/INTEL/SPV_INTEL_shader_atomic_bfloat16/AtomicFMaxEXT.ll renamed to llvm-spirv/test/extensions/INTEL/SPV_INTEL_16bit_atomics/AtomicFMaxEXT.ll

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

@@ -10,7 +10,7 @@ target triple = "spir64-unknown-unknown"
1010

1111
; CHECK-SPIRV-DAG: Capability AtomicBFloat16MinMaxINTEL
1212
; CHECK-SPIRV-DAG: Capability BFloat16TypeKHR
13-
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_shader_atomic_bfloat16"
13+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_16bit_atomics"
1414
; CHECK-SPIRV-DAG: Extension "SPV_KHR_bfloat16"
1515

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

llvm-spirv/test/extensions/INTEL/SPV_INTEL_shader_atomic_bfloat16/AtomicFMinEXT.ll renamed to llvm-spirv/test/extensions/INTEL/SPV_INTEL_16bit_atomics/AtomicFMinEXT.ll

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

@@ -10,7 +10,7 @@ target triple = "spir64-unknown-unknown"
1010

1111
; CHECK-SPIRV-DAG: Capability AtomicBFloat16MinMaxINTEL
1212
; CHECK-SPIRV-DAG: Capability BFloat16TypeKHR
13-
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_shader_atomic_bfloat16"
13+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_16bit_atomics"
1414
; CHECK-SPIRV-DAG: Extension "SPV_KHR_bfloat16"
1515

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

0 commit comments

Comments
 (0)