diff options
| author | YixingZhang007 <yixing.zhang@intel.com> | 2025-09-22 08:52:57 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-22 14:52:57 +0200 |
| commit | f91e0bf16098decbee75233f67109751f2a2e79b (patch) | |
| tree | 2631d8aa5babde1854b5d272aa353e8c2f90469b /llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | |
| parent | ac69f9d9bba407e26bf744fcfd44b062fc76511a (diff) | |
[SPIRV] Add support for the SPIR-V extension SPV_KHR_bfloat16 (#155645)
This PR introduces the support for the SPIR-V extension
`SPV_KHR_bfloat16`. This extension extends the `OpTypeFloat` instruction
to enable the use of bfloat16 types with cooperative matrices and dot
products.
TODO:
Per the `SPV_KHR_bfloat16` extension, there are a limited number of
instructions that can use the bfloat16 type. For example, arithmetic
instructions like `FAdd` or `FMul` can't operate on `bfloat16` values.
Therefore, a future patch should be added to either emit an error or
fall back to FP32 for arithmetic in cases where bfloat16 must not be
used.
Reference Specification:
https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_bfloat16.asciidoc
Diffstat (limited to 'llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp')
| -rw-r--r-- | llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index b7e371d19086..a95f393b7560 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -1222,6 +1222,13 @@ static void AddDotProductRequirements(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::RequirementHandler &Reqs, const SPIRVSubtarget &ST) { @@ -1261,12 +1268,29 @@ void addInstrRequirements(const MachineInstr &MI, Reqs.addCapability(SPIRV::Capability::Int8); break; } + case SPIRV::OpDot: { + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); + SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(1).getReg()); + if (isBFloat16Type(TypeDef)) + Reqs.addCapability(SPIRV::Capability::BFloat16DotProductKHR); + break; + } case SPIRV::OpTypeFloat: { unsigned BitWidth = MI.getOperand(1).getImm(); if (BitWidth == 64) Reqs.addCapability(SPIRV::Capability::Float64); - else if (BitWidth == 16) - Reqs.addCapability(SPIRV::Capability::Float16); + else if (BitWidth == 16) { + if (isBFloat16Type(&MI)) { + if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16)) + report_fatal_error("OpTypeFloat type with bfloat requires the " + "following SPIR-V extension: SPV_KHR_bfloat16", + false); + Reqs.addExtension(SPIRV::Extension::SPV_KHR_bfloat16); + Reqs.addCapability(SPIRV::Capability::BFloat16TypeKHR); + } else { + Reqs.addCapability(SPIRV::Capability::Float16); + } + } break; } case SPIRV::OpTypeVector: { @@ -1286,8 +1310,9 @@ void addInstrRequirements(const MachineInstr &MI, assert(MI.getOperand(2).isReg()); const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(2).getReg()); - if (TypeDef->getOpcode() == SPIRV::OpTypeFloat && - TypeDef->getOperand(1).getImm() == 16) + if ((TypeDef->getNumOperands() == 2) && + (TypeDef->getOpcode() == SPIRV::OpTypeFloat) && + (TypeDef->getOperand(1).getImm() == 16)) Reqs.addCapability(SPIRV::Capability::Float16Buffer); break; } @@ -1593,7 +1618,7 @@ void addInstrRequirements(const MachineInstr &MI, Reqs.addCapability(SPIRV::Capability::AsmINTEL); } break; - case SPIRV::OpTypeCooperativeMatrixKHR: + case SPIRV::OpTypeCooperativeMatrixKHR: { if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix)) report_fatal_error( "OpTypeCooperativeMatrixKHR type requires the " @@ -1601,7 +1626,12 @@ void addInstrRequirements(const MachineInstr &MI, false); Reqs.addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix); Reqs.addCapability(SPIRV::Capability::CooperativeMatrixKHR); + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); + SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(1).getReg()); + if (isBFloat16Type(TypeDef)) + Reqs.addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR); break; + } case SPIRV::OpArithmeticFenceEXT: if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence)) report_fatal_error("OpArithmeticFenceEXT requires the " |
