Skip to content

Conversation

YixingZhang007
Copy link
Contributor

@YixingZhang007 YixingZhang007 commented Sep 4, 2025

This PR introduces support for FPEncoding operand for SPIR-V instruction OpTypeFloat, with the following main changes:

  1. Introduces FPEncoding enum class to represent floating-point encodings, such as BFloat16KHR, in SPIR-V.
  2. Updates SPIR-V instruction OpTypeFloat to accept FPEncoding as its second input operand.
  3. Updates SPIR-V type creation to handle new encoding requirements.

This PR enables support for the BFloat floating-point type in SPIR-V.

@YixingZhang007 YixingZhang007 marked this pull request as draft September 4, 2025 12:15
@llvmbot
Copy link
Member

llvmbot commented Sep 4, 2025

@llvm/pr-subscribers-backend-spir-v

Author: None (YixingZhang007)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/156871.diff

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp (+25-1)
  • (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h (+13)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index cfe24c84941a9..0f258e03b23c8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -1122,7 +1122,19 @@ SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
   SPIRVType *SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
                                          ExplicitLayoutRequired, EmitIR);
   TypesInProcessing.erase(Ty);
-  VRegToTypeMap[&MIRBuilder.getMF()][getSPIRVTypeID(SpirvType)] = SpirvType;
+
+  // Record the FPVariant of the floating-point registers in the
+  // VRegFPVariantMap.
+  MachineFunction *MF = &MIRBuilder.getMF();
+  Register TypeReg = getSPIRVTypeID(SpirvType);
+  if (Ty->isFloatingPointTy()) {
+    if (Ty->isBFloatTy()) {
+      VRegFPVariantMap[MF][TypeReg] = FPVariant::BRAIN_FLOAT;
+    } else {
+      VRegFPVariantMap[MF][TypeReg] = FPVariant::IEEE_FLOAT;
+    }
+  }
+  VRegToTypeMap[MF][TypeReg] = SpirvType;
 
   // TODO: We could end up with two SPIR-V types pointing to the same llvm type.
   // Is that a problem?
@@ -2088,3 +2100,15 @@ bool SPIRVGlobalRegistry::hasBlockDecoration(SPIRVType *Type) const {
   }
   return false;
 }
+
+SPIRVGlobalRegistry::FPVariant
+SPIRVGlobalRegistry::getFPVariantForVReg(Register VReg,
+                                         const MachineFunction *MF) {
+  auto t = VRegFPVariantMap.find(MF ? MF : CurMF);
+  if (t != VRegFPVariantMap.end()) {
+    auto tt = t->second.find(VReg);
+    if (tt != t->second.end())
+      return tt->second;
+  }
+  return FPVariant::NONE;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 7ef812828b7cc..1f8c30dc01f7f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -29,6 +29,10 @@ using SPIRVType = const MachineInstr;
 using StructOffsetDecorator = std::function<void(Register)>;
 
 class SPIRVGlobalRegistry : public SPIRVIRMapping {
+public:
+  enum class FPVariant { NONE, IEEE_FLOAT, BRAIN_FLOAT };
+
+private:
   // Registers holding values which have types associated with them.
   // Initialized upon VReg definition in IRTranslator.
   // Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
@@ -88,6 +92,11 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
   // map of aliasing decorations to aliasing metadata
   std::unordered_map<const MDNode *, MachineInstr *> AliasInstMDMap;
 
+  // Maps floating point Registers to their FPVariant (float type kind), given
+  // the MachineFunction.
+  DenseMap<const MachineFunction *, DenseMap<Register, FPVariant>>
+      VRegFPVariantMap;
+
   // Add a new OpTypeXXX instruction without checking for duplicates.
   SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
                              SPIRV::AccessQualifier::AccessQualifier AQ,
@@ -422,6 +431,10 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
   // structures referring this instruction.
   void invalidateMachineInstr(MachineInstr *MI);
 
+  // Return the FPVariant of to the given floating-point regiester.
+  FPVariant getFPVariantForVReg(Register VReg,
+                                const MachineFunction *MF = nullptr);
+
 private:
   SPIRVType *getOpTypeBool(MachineIRBuilder &MIRBuilder);
 

@YixingZhang007 YixingZhang007 changed the title add the support for bfloat in SPIRV [SPIRV] Add FPVariant tracking for floating-point registers in SPIR-V Sep 4, 2025
@YixingZhang007
Copy link
Contributor Author

This PR is a prerequisite for adding support for the SPIR-V extension SPV_KHR_bfloat16 in PR #155645

Copy link
Contributor

@maarquitos14 maarquitos14 left a comment

Choose a reason for hiding this comment

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

A couple of nits, but looks good to me otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto t = VRegFPVariantMap.find(MF ? MF : CurMF);
auto T = VRegFPVariantMap.find(MF ? MF : CurMF);

Also, can we have the explicit type if it's not too complicated? Makes the code easier to read. I wouldn't mind a more descriptive variable name either :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I have made the change :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto tt = t->second.find(VReg);
auto tt = t->second.find(VReg);

Same than before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For sure! I have fixed it. Thanks!

Copy link

github-actions bot commented Sep 5, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@YixingZhang007 YixingZhang007 force-pushed the add_spirv_bfloat_support branch 2 times, most recently from 7459a65 to a67050e Compare September 5, 2025 19:22
Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't realize it was such a nasty type. You can go back to auto if you wish.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I agree auto might be a better choice here. I’ve updated both iterator types to use auto. Thanks for the suggestion :)

@YixingZhang007
Copy link
Contributor Author

The current CI failure in SPIRV-V Tests / Test SPIR-V is due to the test failure in CodeGen/SPIRV/instructions/integer-casts.ll. I think this failure is not related to the changes introduced in this PR. I had temporarily commented out all modifications, and this test still failed. The commit reverting all changes can be found at a67050e, and its corresponding SPIRV-V Tests / Test SPIR-V failure can be found at https://github.com/llvm/llvm-project/actions/runs/17502517326/job/49718552664.

Copy link
Contributor

Choose a reason for hiding this comment

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

should we make it unreachable instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

This could happen if the register is not a floating pointer register right? I think we still want want.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I’ve updated the approach for representing floating-point types in the PR, and FPVariant is no longer used. Please let me know if there’s anything I can improve with the current approach. Thank you! :)

Copy link
Contributor

@MrSidims MrSidims Sep 8, 2025

Choose a reason for hiding this comment

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

Why it's not enough to use VRegToTypeMap? Object that holds OpTypeFloat 16 should be different from OpTypeFloat 16 0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry that there was a mistake in my initial thinking. I thought OpTypeFloat was a non-variadic SPIR-V operation, so all floating points would be represented with instruction OpTypeFloat 16. I have updated OpTypeFloat to now be a variadic operation. Thanks :)

Copy link
Contributor

@s-perron s-perron left a comment

Choose a reason for hiding this comment

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

I don't have any problems with this.

Copy link
Contributor

Choose a reason for hiding this comment

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

This could happen if the register is not a floating pointer register right? I think we still want want.

Copy link
Contributor

@Keenuts Keenuts left a comment

Choose a reason for hiding this comment

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

No issues with this, but seconding the question about the reuse of the existing VRegToTypeMap. Is there a performance need to store the FPVariant in a map, or can getFPVariantForVreg do a lookup in the generic map and then do the isBFloatTy/isFloatTy every time?

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Return the FPVariant of to the given floating-point regiester.
// Return the FPVariant of to the given floating-point register.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I’ve updated the approach for representing floating-point types in the PR. FPVariant and VRegFPVariantMap are no longer used. Instead, we introduced an FPEncoding enum class, which is now placed as the second operand of OpTypeFloat SPIR-V instruction. Please feel free to let me know if there’s anything I can improve with the current approach. Thank you! :)

@YixingZhang007 YixingZhang007 changed the title [SPIRV] Add FPVariant tracking for floating-point registers in SPIR-V [SPIRV] Add FPEncoding operand support for SPIR-V OpTypeFloat Sep 10, 2025
@YixingZhang007 YixingZhang007 changed the title [SPIRV] Add FPEncoding operand support for SPIR-V OpTypeFloat [SPIRV] Add FPEncoding operand support for OpTypeFloat Sep 10, 2025
@YixingZhang007
Copy link
Contributor Author

I’ve updated this PR by changing the approach for tracking the type of floating-point registers (IEEE 754 vs. Bfloat).
Previously, we used an FPVariant class along with a VRegFPVariantMap to map registers to their floating-point type. Now, I’ve replaced these with an FPEncoding enum class and modified the SPIR-V instruction format for floating point registers from OpTypeFloat $bitwidth to OpTypeFloat $bitwidth $FPEncoding. This way, the floating-point type can be directly distinguished from the second operand of the OpTypeFloat instruction.

Copy link
Contributor

@maarquitos14 maarquitos14 left a comment

Choose a reason for hiding this comment

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

LGTM. Should we add any test to see if we can properly generate bfloat16 type?

Copy link
Contributor

@Keenuts Keenuts left a comment

Choose a reason for hiding this comment

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

Thanks!

@YixingZhang007
Copy link
Contributor Author

YixingZhang007 commented Sep 12, 2025

LGTM. Should we add any test to see if we can properly generate bfloat16 type?

Thanks for the suggestion! I have added test case for bfloat in the SPIR-V test basic_float_types.ll.

@YixingZhang007 YixingZhang007 force-pushed the add_spirv_bfloat_support branch from ac5fc5d to 68c8bbd Compare September 15, 2025 11:59
@YixingZhang007 YixingZhang007 force-pushed the add_spirv_bfloat_support branch from 4a8d961 to 5b8b92d Compare September 15, 2025 16:42
Copy link
Contributor

@MrSidims MrSidims left a comment

Choose a reason for hiding this comment

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

Test failure is unrelated and will be handled separately.

@MrSidims MrSidims merged commit 3a5cc95 into llvm:main Sep 16, 2025
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants