Skip to content

Commit 8e958fc

Browse files
authored
Add SPV_NV_shader_atomic_fp16_vector extension (#3772)
It allowed fp16 atomics translation. Spec: https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/NV/SPV_NV_shader_atomic_fp16_vector.asciidoc
1 parent bd15d75 commit 8e958fc

5 files changed

Lines changed: 72 additions & 0 deletions

File tree

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,4 @@ EXT(SPV_INTEL_float4)
9696
EXT(SPV_INTEL_fp_conversions)
9797
EXT(SPV_KHR_float_controls2)
9898
EXT(SPV_AMD_weak_linkage)
99+
EXT(SPV_NV_shader_atomic_fp16_vector)

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3135,6 +3135,9 @@ class SPIRVAtomicFAddEXTInst : public SPIRVAtomicInstBase {
31353135
public:
31363136
std::optional<ExtensionID> getRequiredExtension() const override {
31373137
assert(hasType());
3138+
if (getType()->isTypeVector() &&
3139+
getType()->getVectorComponentType()->isTypeFloat(16))
3140+
return ExtensionID::SPV_NV_shader_atomic_fp16_vector;
31383141
if (getType()->isTypeFloat(16, FPEncodingBFloat16KHR))
31393142
Module->addExtension(ExtensionID::SPV_INTEL_16bit_atomics);
31403143
if (getType()->isTypeFloat(16))
@@ -3144,6 +3147,9 @@ class SPIRVAtomicFAddEXTInst : public SPIRVAtomicInstBase {
31443147

31453148
SPIRVCapVec getRequiredCapability() const override {
31463149
assert(hasType());
3150+
if (getType()->isTypeVector() &&
3151+
getType()->getVectorComponentType()->isTypeFloat(16))
3152+
return {CapabilityAtomicFloat16VectorNV};
31473153
if (getType()->isTypeFloat(16, FPEncodingBFloat16KHR))
31483154
return {internal::CapabilityAtomicBFloat16AddINTEL};
31493155
if (getType()->isTypeFloat(16))
@@ -3160,13 +3166,19 @@ class SPIRVAtomicFAddEXTInst : public SPIRVAtomicInstBase {
31603166
class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
31613167
public:
31623168
std::optional<ExtensionID> getRequiredExtension() const override {
3169+
if (getType()->isTypeVector() &&
3170+
getType()->getVectorComponentType()->isTypeFloat(16))
3171+
return ExtensionID::SPV_NV_shader_atomic_fp16_vector;
31633172
if (getType()->isTypeFloat(16, FPEncodingBFloat16KHR))
31643173
Module->addExtension(ExtensionID::SPV_INTEL_16bit_atomics);
31653174
return ExtensionID::SPV_EXT_shader_atomic_float_min_max;
31663175
}
31673176

31683177
SPIRVCapVec getRequiredCapability() const override {
31693178
assert(hasType());
3179+
if (getType()->isTypeVector() &&
3180+
getType()->getVectorComponentType()->isTypeFloat(16))
3181+
return {CapabilityAtomicFloat16VectorNV};
31703182
if (getType()->isTypeFloat(16, FPEncodingBFloat16KHR))
31713183
return {internal::CapabilityAtomicBFloat16MinMaxINTEL};
31723184
if (getType()->isTypeFloat(16))

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
630630
add(CapabilityLongCompositesINTEL, "LongCompositesINTEL");
631631
add(CapabilityOptNoneEXT, "OptNoneEXT");
632632
add(CapabilityAtomicFloat16AddEXT, "AtomicFloat16AddEXT");
633+
add(CapabilityAtomicFloat16VectorNV, "AtomicFloat16VectorNV");
633634
add(internal::CapabilityAtomicBFloat16AddINTEL, "AtomicBFloat16AddINTEL");
634635
add(internal::CapabilityAtomicBFloat16MinMaxINTEL,
635636
"AtomicBFloat16MinMaxINTEL");
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_NV_shader_atomic_fp16_vector -o %t.spv
3+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
4+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
5+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
6+
7+
; SPV_NV_shader_atomic_fp16_vector lets OpAtomicFAddEXT, OpAtomicFMinEXT and
8+
; OpAtomicFMaxEXT operate on a 2- or 4-component vector of fp16. fsub has no
9+
; atomic opcode, so it is emitted as OpFNegate followed by OpAtomicFAddEXT.
10+
11+
; CHECK-SPIRV-DAG: Capability AtomicFloat16VectorNV
12+
; CHECK-SPIRV-DAG: Extension "SPV_NV_shader_atomic_fp16_vector"
13+
; CHECK-SPIRV: TypeFloat [[#Half:]] 16
14+
; CHECK-SPIRV: TypeVector [[#V2:]] [[#Half]] 2
15+
; CHECK-SPIRV: TypeVector [[#V4:]] [[#Half]] 4
16+
; CHECK-SPIRV: AtomicFAddEXT [[#V2]]
17+
; CHECK-SPIRV: FNegate [[#V2]] [[#Neg:]]
18+
; CHECK-SPIRV: AtomicFAddEXT [[#V2]] [[#]] [[#]] [[#]] [[#]] [[#Neg]]
19+
; CHECK-SPIRV: AtomicFMinEXT [[#V2]]
20+
; CHECK-SPIRV: AtomicFMaxEXT [[#V2]]
21+
; CHECK-SPIRV: AtomicFAddEXT [[#V4]]
22+
23+
; CHECK-LLVM: call spir_func <2 x half> @{{.*}}atomic_add{{.*}}(ptr addrspace(1) %p, <2 x half> %v2)
24+
; CHECK-LLVM: fneg <2 x half> %v2
25+
; CHECK-LLVM: call spir_func <2 x half> @{{.*}}atomic_add
26+
; CHECK-LLVM: call spir_func <2 x half> @{{.*}}atomic_min
27+
; CHECK-LLVM: call spir_func <2 x half> @{{.*}}atomic_max
28+
; CHECK-LLVM: call spir_func <4 x half> @{{.*}}atomic_add
29+
30+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
31+
target triple = "spir64"
32+
33+
define spir_func void @test(ptr addrspace(1) %p, <2 x half> %v2, <4 x half> %v4) {
34+
entry:
35+
%a = atomicrmw fadd ptr addrspace(1) %p, <2 x half> %v2 seq_cst
36+
%s = atomicrmw fsub ptr addrspace(1) %p, <2 x half> %v2 seq_cst
37+
%mn = atomicrmw fmin ptr addrspace(1) %p, <2 x half> %v2 seq_cst
38+
%mx = atomicrmw fmax ptr addrspace(1) %p, <2 x half> %v2 seq_cst
39+
%a4 = atomicrmw fadd ptr addrspace(1) %p, <4 x half> %v4 seq_cst
40+
ret void
41+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: llvm-as < %s -o %t.bc
2+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s
3+
4+
; Without SPV_NV_shader_atomic_fp16_vector an fp16 vector atomic cannot be
5+
; translated.
6+
7+
; CHECK: RequiresExtension: Feature requires the following SPIR-V extension:
8+
; CHECK-NEXT: SPV_NV_shader_atomic_fp16_vector
9+
10+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
11+
target triple = "spir64"
12+
13+
define spir_func void @test(ptr addrspace(1) %p, <2 x half> %v2) {
14+
entry:
15+
%a = atomicrmw fadd ptr addrspace(1) %p, <2 x half> %v2 seq_cst
16+
ret void
17+
}

0 commit comments

Comments
 (0)