[llvm] [SPIRV] Fix `SPIRVTypeInst` `DenseMapInfo` implementation (PR #181667)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 16 06:03:22 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Juan Manuel Martinez CaamaƱo (jmmartinez)

<details>
<summary>Changes</summary>

The previous `DenseMapInfo` implementation was wrong.

The new implementation relies completely on `DenseMapInfo<MachineInst*>`'s. To do this, we use "tag dispatch" to call a special constructor only accessible by `DenseMapInfo` that bypasses the assertion when building the empty/tombstone keys.

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


1 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h (+17-7) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 0dd0bbaf36bc0..54f5ce3ed1127 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -36,12 +36,17 @@ using StructOffsetDecorator = std::function<void(Register)>;
 class SPIRVTypeInst {
   const MachineInstr *MI;
 
-public:
   static bool definesATypeRegister(const MachineInstr &MI) {
     const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
     return MRI.getRegClass(MI.getOperand(0).getReg()) == &SPIRV::TYPERegClass;
   }
 
+  // Used by DenseMapInfo to bypass the assertion. The thombstone and empty keys
+  // are not null. They are -1 and -2 aligned to the appropiate pointer size.
+  struct BypassAssertion {};
+  SPIRVTypeInst(const MachineInstr *MI, BypassAssertion) : MI(MI) {};
+
+public:
   SPIRVTypeInst(const MachineInstr &MI) : SPIRVTypeInst(&MI) {}
   SPIRVTypeInst(const MachineInstr *MI) : MI(MI) {
     // A SPIRV Type whose result is not a type is invalid.
@@ -69,15 +74,20 @@ class SPIRVTypeInst {
 
   operator bool() const { return MI; }
 
-  unsigned getHashValue() const {
-    return DenseMapInfo<const MachineInstr *>::getHashValue(MI);
-  }
+  friend struct DenseMapInfo<SPIRVTypeInst>;
 };
 
 template <> struct DenseMapInfo<SPIRVTypeInst> {
-  static SPIRVTypeInst getEmptyKey() { return SPIRVTypeInst(nullptr); }
-  static SPIRVTypeInst getTombstoneKey() { return SPIRVTypeInst(nullptr); }
-  static unsigned getHashValue(SPIRVTypeInst Ty) { return Ty.getHashValue(); }
+  using MIInfo = DenseMapInfo<MachineInstr *>;
+  static SPIRVTypeInst getEmptyKey() {
+    return {MIInfo::getEmptyKey(), SPIRVTypeInst::BypassAssertion()};
+  }
+  static SPIRVTypeInst getTombstoneKey() {
+    return {MIInfo::getTombstoneKey(), SPIRVTypeInst::BypassAssertion()};
+  }
+  static unsigned getHashValue(SPIRVTypeInst Ty) {
+    return MIInfo::getHashValue(Ty.MI);
+  }
   static bool isEqual(SPIRVTypeInst Ty1, SPIRVTypeInst Ty2) {
     return Ty1 == Ty2;
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/181667


More information about the llvm-commits mailing list