Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/docs/SPIRVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ Below is a list of supported SPIR-V extensions, sorted alphabetically by their e
- Adds atomic add instruction on floating-point numbers.
* - ``SPV_EXT_shader_atomic_float_min_max``
- Adds atomic min and max instruction on floating-point numbers.
* - ``SPV_INTEL_16bit_atomics``
- Extends the SPV_EXT_shader_atomic_float_add and SPV_EXT_shader_atomic_float_min_max to support addition, minimum and maximum on 16-bit `bfloat16` floating-point numbers in memory.
* - ``SPV_INTEL_2d_block_io``
- Adds additional subgroup block prefetch, load, load transposed, load transformed and store instructions to read two-dimensional blocks of data from a two-dimensional region of memory, or to write two-dimensional blocks of data to a two dimensional region of memory.
* - ``SPV_INTEL_arbitrary_precision_integers``
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3482,7 +3482,7 @@ bool IRTranslator::translateAtomicCmpXchg(const User &U,

bool IRTranslator::translateAtomicRMW(const User &U,
MachineIRBuilder &MIRBuilder) {
if (containsBF16Type(U))
if (!MF->getTarget().getTargetTriple().isSPIRV() && containsBF16Type(U))
return false;

const AtomicRMWInst &I = cast<AtomicRMWInst>(U);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float16_add},
{"SPV_EXT_shader_atomic_float_min_max",
SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_min_max},
{"SPV_INTEL_16bit_atomics",
SPIRV::Extension::Extension::SPV_INTEL_16bit_atomics},
{"SPV_EXT_arithmetic_fence",
SPIRV::Extension::Extension::SPV_EXT_arithmetic_fence},
{"SPV_EXT_demote_to_helper_invocation",
Expand Down
46 changes: 33 additions & 13 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,13 @@ static void addOpTypeImageReqs(const MachineInstr &MI,
}
}

static bool isBFloat16Type(const SPIRVType *TypeDef) {
return TypeDef && TypeDef->getNumOperands() == 3 &&
TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
TypeDef->getOperand(1).getImm() == 16 &&
TypeDef->getOperand(2).getImm() == SPIRV::FPEncoding::BFloat16KHR;
}

// Add requirements for handling atomic float instructions
#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
"The atomic float instruction requires the following SPIR-V " \
Expand All @@ -1081,11 +1088,21 @@ static void AddAtomicFloatRequirements(const MachineInstr &MI,
Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
switch (BitWidth) {
case 16:
if (!ST.canUseExtension(
SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
report_fatal_error(ATOM_FLT_REQ_EXT_MSG("16_add"), false);
Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
Reqs.addCapability(SPIRV::Capability::AtomicFloat16AddEXT);
if (isBFloat16Type(TypeDef)) {
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pass should probably not be using fatal errors for anything

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC there is a later mechanism which checks which extension is allowed for the current target and raises an "SPIR-V module cannot be satisfied" error if an extension/capability is showing but is not allowed.

report_fatal_error(
"The atomic bfloat16 instruction requires the following SPIR-V "
"extension: SPV_INTEL_16bit_atomics",
false);
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
Reqs.addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
} else {
if (!ST.canUseExtension(
SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
report_fatal_error(ATOM_FLT_REQ_EXT_MSG("16_add"), false);
Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
Reqs.addCapability(SPIRV::Capability::AtomicFloat16AddEXT);
}
break;
case 32:
Reqs.addCapability(SPIRV::Capability::AtomicFloat32AddEXT);
Expand All @@ -1104,7 +1121,17 @@ static void AddAtomicFloatRequirements(const MachineInstr &MI,
Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
switch (BitWidth) {
case 16:
Reqs.addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
if (isBFloat16Type(TypeDef)) {
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
report_fatal_error(
"The atomic bfloat16 instruction requires the following SPIR-V "
"extension: SPV_INTEL_16bit_atomics",
false);
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
Reqs.addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
} else {
Reqs.addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
}
break;
case 32:
Reqs.addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
Expand Down Expand Up @@ -1328,13 +1355,6 @@ void addPrintfRequirements(const MachineInstr &MI,
}
}

static bool isBFloat16Type(const SPIRVType *TypeDef) {
return TypeDef && TypeDef->getNumOperands() == 3 &&
TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
TypeDef->getOperand(1).getImm() == 16 &&
TypeDef->getOperand(2).getImm() == SPIRV::FPEncoding::BFloat16KHR;
}

void addInstrRequirements(const MachineInstr &MI,
SPIRV::ModuleAnalysisInfo &MAI,
const SPIRVSubtarget &ST) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ defm SPV_INTEL_predicated_io : ExtensionOperand<127, [EnvOpenCL]>;
defm SPV_KHR_maximal_reconvergence : ExtensionOperand<128, [EnvVulkan]>;
defm SPV_INTEL_bfloat16_arithmetic
: ExtensionOperand<129, [EnvVulkan, EnvOpenCL]>;
defm SPV_INTEL_16bit_atomics : ExtensionOperand<130, [EnvVulkan, EnvOpenCL]>;

//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
Expand Down Expand Up @@ -566,9 +567,11 @@ defm FloatControls2
defm AtomicFloat32AddEXT : CapabilityOperand<6033, 0, 0, [SPV_EXT_shader_atomic_float_add], []>;
defm AtomicFloat64AddEXT : CapabilityOperand<6034, 0, 0, [SPV_EXT_shader_atomic_float_add], []>;
defm AtomicFloat16AddEXT : CapabilityOperand<6095, 0, 0, [SPV_EXT_shader_atomic_float16_add], []>;
defm AtomicBFloat16AddINTEL : CapabilityOperand<6255, 0, 0, [SPV_INTEL_16bit_atomics], []>;
defm AtomicFloat16MinMaxEXT : CapabilityOperand<5616, 0, 0, [SPV_EXT_shader_atomic_float_min_max], []>;
defm AtomicFloat32MinMaxEXT : CapabilityOperand<5612, 0, 0, [SPV_EXT_shader_atomic_float_min_max], []>;
defm AtomicFloat64MinMaxEXT : CapabilityOperand<5613, 0, 0, [SPV_EXT_shader_atomic_float_min_max], []>;
defm AtomicBFloat16MinMaxINTEL : CapabilityOperand<6256, 0, 0, [SPV_INTEL_16bit_atomics], []>;
defm VariableLengthArrayINTEL : CapabilityOperand<5817, 0, 0, [SPV_INTEL_variable_length_array], []>;
defm GroupUniformArithmeticKHR : CapabilityOperand<6400, 0, 0, [SPV_KHR_uniform_group_instructions], []>;
defm USMStorageClassesINTEL : CapabilityOperand<5935, 0, 0, [SPV_INTEL_usm_storage_classes], [Kernel]>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR1
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_shader_atomic_float_add,+SPV_KHR_bfloat16 %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR2

; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_shader_atomic_float_add,+SPV_INTEL_16bit_atomics,+SPV_KHR_bfloat16,+SPV_INTEL_bfloat16_arithmetic %s -o - | FileCheck %s

; CHECK-ERROR1: LLVM ERROR: The atomic float instruction requires the following SPIR-V extension: SPV_EXT_shader_atomic_float_add
; CHECK-ERROR2: LLVM ERROR: The atomic bfloat16 instruction requires the following SPIR-V extension: SPV_INTEL_16bit_atomics
Comment on lines +6 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not available it should go through the AtomicExpand legalization

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this pass enabled by default for all the pipelines?
At least if it's not for SPIR-V BE, then the reported error seems more legit in this case.


; CHECK: Capability BFloat16TypeKHR
; CHECK: Capability AtomicBFloat16AddINTEL
; CHECK: Extension "SPV_KHR_bfloat16"
; CHECK: Extension "SPV_EXT_shader_atomic_float_add"
; CHECK: Extension "SPV_INTEL_16bit_atomics"
; CHECK-DAG: %[[TyBF16:[0-9]+]] = OpTypeFloat 16 0
; CHECK-DAG: %[[TyBF16Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyBF16]]
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
; CHECK-DAG: %[[ConstBF16:[0-9]+]] = OpConstant %[[TyBF16]] 16936{{$}}
; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyBF16]]
; CHECK-DAG: %[[BF16Ptr:[0-9]+]] = OpVariable %[[TyBF16Ptr]] CrossWorkgroup %[[Const0]]
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
; CHECK: OpAtomicFAddEXT %[[TyBF16]] %[[BF16Ptr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[ConstBF16]]
; CHECK: %[[NegatedConstBF16:[0-9]+]] = OpFNegate %[[TyBF16]] %[[ConstBF16]]
; CHECK: OpAtomicFAddEXT %[[TyBF16]] %[[BF16Ptr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[NegatedConstBF16]]


@f = common dso_local local_unnamed_addr addrspace(1) global bfloat 0.000000e+00, align 8

define dso_local spir_func void @test1() local_unnamed_addr {
entry:
%addval = atomicrmw fadd ptr addrspace(1) @f, bfloat 42.000000e+00 seq_cst
%subval = atomicrmw fsub ptr addrspace(1) @f, bfloat 42.000000e+00 seq_cst
ret void
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_shader_atomic_float_min_max,+SPV_KHR_bfloat16 %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_shader_atomic_float_min_max,+SPV_INTEL_16bit_atomics,+SPV_KHR_bfloat16 %s -o - | FileCheck %s

; CHECK-ERROR: LLVM ERROR: The atomic bfloat16 instruction requires the following SPIR-V extension: SPV_INTEL_16bit_atomics

; CHECK: Capability AtomicBFloat16MinMaxINTEL
; CHECK: Extension "SPV_KHR_bfloat16"
; CHECK: Extension "SPV_EXT_shader_atomic_float_min_max"
; CHECK: Extension "SPV_INTEL_16bit_atomics"
; CHECK-DAG: %[[TyBF16:[0-9]+]] = OpTypeFloat 16 0
; CHECK-DAG: %[[TyBF16Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyBF16]]
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
; CHECK-DAG: %[[ConstBF16:[0-9]+]] = OpConstant %[[TyBF16]] 16936{{$}}
; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyBF16]]
; CHECK-DAG: %[[BF16Ptr:[0-9]+]] = OpVariable %[[TyBF16Ptr]] CrossWorkgroup %[[Const0]]
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
; CHECK: OpAtomicFMinEXT %[[TyBF16]] %[[BF16Ptr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[ConstBF16]]
; CHECK: OpAtomicFMaxEXT %[[TyBF16]] %[[BF16Ptr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[ConstBF16]]

@f = common dso_local local_unnamed_addr addrspace(1) global bfloat 0.000000e+00, align 8

define spir_func void @test1() {
entry:
%minval = atomicrmw fmin ptr addrspace(1) @f, bfloat 42.0e+00 seq_cst
%maxval = atomicrmw fmax ptr addrspace(1) @f, bfloat 42.0e+00 seq_cst
ret void
}