[llvm] [SPIRV] Emit NonSemantic DebugValue (PR #224158)

Diego Novillo via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 06:15:09 PDT 2026


================
@@ -259,6 +260,100 @@ unsigned SPIRVNonSemanticDebugHandler::toNSDISrcLang(unsigned DwarfSrcLang) {
   }
 }
 
+// Whether \p BT is a SPIR-V OpTypeBool.
+static bool isBooleanType(const DIBasicType *BT) {
+  return BT->getEncoding() == dwarf::DW_ATE_boolean;
+}
+
+// \p Value truncated to the width of \p BT, or 0 or 1 for a boolean.
+static uint64_t constantBits(uint64_t Value, const DIBasicType *BT) {
+  // A boolean is one of two values and a DIBasicType may give it no size, so
+  // masking to its width would turn every true into a false.
+  if (isBooleanType(BT))
+    return Value != 0;
+  unsigned Width = BT->getSizeInBits();
+  return Width >= 64 ? Value : Value & ((uint64_t(1) << Width) - 1);
+}
+
+// \p Value truncated to the width of \p BT. APInt::getZExtValue() asserts
+// above 64 bits, so the truncation comes first.
+static uint64_t constantBits(const APInt &Value, const DIBasicType *BT) {
+  unsigned Width = isBooleanType(BT) ? 1 : BT->getSizeInBits();
+  return constantBits(Value.getActiveBits() > 64
+                          ? Value.trunc(std::min(Width, 64u)).getZExtValue()
+                          : Value.getZExtValue(),
+                      BT);
+}
+
+// \p CI as a 64-bit value, truncated to the width of \p BT. A one-bit constant
+// is zero extended, widths 2 through 64 are sign extended, and anything wider
+// is truncated.
+static uint64_t constantBits(const ConstantInt *CI, const DIBasicType *BT) {
+  const APInt &Value = CI->getValue();
+  if (Value.getBitWidth() > 64)
+    return constantBits(Value, BT);
+  if (Value.getBitWidth() == 1)
+    return constantBits(Value.getZExtValue(), BT);
+  return constantBits(static_cast<uint64_t>(Value.getSExtValue()), BT);
+}
+
+// The DIBasicType that \p Ty resolves to through any typedefs, or null.
+//
+// This accepts: a boolean of any size, and a 16, 32 or 64-bit integer or float.
+// Anything else gives null, including a type reached through a cv-qualifier.
+static const DIBasicType *stripToScalarType(const DIType *Ty) {
+  // Only a typedef is looked through. A cv-qualified type is not emitted as a
+  // DebugType, so emitDebugLocalVariable() cannot name it and the variable
+  // gets no DebugLocalVariable.
+  while (const auto *DT = dyn_cast_or_null<DIDerivedType>(Ty)) {
----------------
dnovillo wrote:

Good catch. Yes. It reproduces on hand-written or fuzzed IR. Added a guard and a test.

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


More information about the llvm-commits mailing list