[llvm] [DWARF] Emit 0/1 for constant boolean values (PR #151225)

Laxman Sole via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 20 19:01:57 PDT 2025


https://github.com/laxmansole updated https://github.com/llvm/llvm-project/pull/151225

>From b43c85898c1d899ff8aeda73adef9d54d45a5a0d Mon Sep 17 00:00:00 2001
From: Laxman Sole <lsole at nvidia.com>
Date: Fri, 25 Jul 2025 10:11:18 -0700
Subject: [PATCH 1/2] [DWARF] Emit 0/1 for constant boolean values

---
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   | 34 ++++++++++++-
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp    |  6 ++-
 .../CodeGen/AsmPrinter/DwarfExpression.cpp    |  9 ++++
 llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h |  3 ++
 .../NVPTX/debug-bool-const-location.ll        | 51 +++++++++++++++++++
 .../DebugInfo/NVPTX/debug-bool-const-value.ll | 37 ++++++++++++++
 6 files changed, 136 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll
 create mode 100644 llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 67f526fe91464..5167d9be4d3fb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -247,6 +247,13 @@ void DwarfCompileUnit::addLocationAttribute(
   DIELoc *Loc = nullptr;
   std::optional<unsigned> NVPTXAddressSpace;
   std::unique_ptr<DIEDwarfExpression> DwarfExpr;
+
+  // Check if this variable is of boolean type
+  bool isBoolean = false;
+  if (GV && GV->getType())
+    if (auto *BasicType = dyn_cast<DIBasicType>(GV->getType()))
+      isBoolean = BasicType->getEncoding() == dwarf::DW_ATE_boolean;
+
   for (const auto &GE : GlobalExprs) {
     const GlobalVariable *Global = GE.Var;
     const DIExpression *Expr = GE.Expr;
@@ -257,11 +264,17 @@ void DwarfCompileUnit::addLocationAttribute(
     // DW_AT_const_value(X).
     if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
       addToAccelTable = true;
+
+      // Determine the value to use, normalizing booleans to 0 or 1
+      int64_t valueToUse = Expr->getElement(1);
+      if (isBoolean)
+        valueToUse = valueToUse ? 1 : 0;
+
       addConstantValue(
           *VariableDIE,
           DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==
               *Expr->isConstant(),
-          Expr->getElement(1));
+          valueToUse);
       break;
     }
 
@@ -821,6 +834,22 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
   }
   if (!DVal->isVariadic()) {
     const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
+
+    // Helper function to handle boolean constant values with type safety
+    auto addConstantValueWithBooleanNormalization =
+        [&](DIE &VariableDie, uint64_t intValue, const DIType *Type) {
+          if (auto *BasicType = dyn_cast_or_null<DIBasicType>(Type)) {
+            if (BasicType->getEncoding() == dwarf::DW_ATE_boolean) {
+              // Normalize boolean values: any non-zero becomes 1, zero stays 0
+              uint64_t normalizedBoolValue = (intValue) ? 1 : 0;
+              addConstantValue(VariableDie, normalizedBoolValue, Type);
+              return;
+            }
+          }
+          // For non-boolean types, use the original constant value
+          addConstantValue(VariableDie, intValue, Type);
+        };
+
     if (Entry->isLocation()) {
       addVariableAddress(DV, VariableDie, Entry->getLoc());
     } else if (Entry->isInt()) {
@@ -837,7 +866,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
           addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,
                   dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
       } else
-        addConstantValue(VariableDie, Entry->getInt(), DV.getType());
+        addConstantValueWithBooleanNormalization(VariableDie, Entry->getInt(),
+                                                 DV.getType());
     } else if (Entry->isConstantFP()) {
       addConstantFPValue(VariableDie, Entry->getConstantFP());
     } else if (Entry->isConstantInt()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index c27f100775625..2090157a1a91c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -3111,8 +3111,10 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
                             &AP](const DbgValueLocEntry &Entry,
                                  DIExpressionCursor &Cursor) -> bool {
     if (Entry.isInt()) {
-      if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
-                 BT->getEncoding() == dwarf::DW_ATE_signed_char))
+      if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean))
+        DwarfExpr.addBooleanConstant(Entry.getInt());
+      else if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
+                      BT->getEncoding() == dwarf::DW_ATE_signed_char))
         DwarfExpr.addSignedConstant(Entry.getInt());
       else
         DwarfExpr.addUnsignedConstant(Entry.getInt());
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index e684054ffa3e4..8a30714db2fdf 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -194,6 +194,15 @@ void DwarfExpression::addStackValue() {
     emitOp(dwarf::DW_OP_stack_value);
 }
 
+void DwarfExpression::addBooleanConstant(int64_t Value) {
+  assert(isImplicitLocation() || isUnknownLocation());
+  LocationKind = Implicit;
+  if (Value == 0)
+    emitOp(dwarf::DW_OP_lit0);
+  else
+    emitOp(dwarf::DW_OP_lit1);
+}
+
 void DwarfExpression::addSignedConstant(int64_t Value) {
   assert(isImplicitLocation() || isUnknownLocation());
   LocationKind = Implicit;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 06809ab263875..700e0ec5813ee 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -229,6 +229,9 @@ class DwarfExpression {
   /// This needs to be called last to commit any pending changes.
   void finalize();
 
+  /// Emit a boolean constant.
+  void addBooleanConstant(int64_t Value);
+
   /// Emit a signed constant.
   void addSignedConstant(int64_t Value);
 
diff --git a/llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll b/llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll
new file mode 100644
index 0000000000000..f073d51e7ef99
--- /dev/null
+++ b/llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll
@@ -0,0 +1,51 @@
+; RUN: llc < %s -asm-verbose -mattr=+ptx76  -O0| FileCheck %s
+; RUN: %if ptxas %{ llc < %s -asm-verbose -mattr=+ptx76  -O0 | %ptxas-verify %}
+
+target triple = "nvptx64-nvidia-cuda"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"
+
+; CHECK: {{.*}}section {{.*}}debug_loc
+; CHECK: .b8 48{{.*}} DW_OP_lit0
+; CHECK: .b8 49{{.*}} DW_OP_lit1
+; CHECK: .b8 144{{.*}} DW_OP_regx
+
+define void @foo(i8 %"arg.arg") !dbg !5
+{
+entry:
+  %".4" = alloca i1
+  %".5" = icmp eq i8 %"arg.arg", 0
+  %arg = alloca i1
+  br i1 %".5", label %"entry.if", label %"entry.else"
+entry.if:
+  store i1 false, i1* %arg
+  call void @"llvm.dbg.value"(metadata i1 false , metadata !9, metadata !10), !dbg !6
+  br label %"entry.endif"
+entry.else:
+  store i1 true, i1* %arg
+  call void @"llvm.dbg.value"(metadata i1 true , metadata !9, metadata !10), !dbg !7
+  br label %"entry.endif"
+entry.endif:
+  %".11" = load i1, i1* %arg
+  store i1 %".11", i1* %".4", !dbg !8
+  call void @"llvm.dbg.value"(metadata i1 %".11" , metadata !9, metadata !10), !dbg !8
+  ret void, !dbg !8
+}
+
+declare void @"llvm.dbg.value"(metadata %".1", metadata %".2", metadata %".3")
+
+!llvm.dbg.cu = !{ !2 }
+!llvm.module.flags = !{ !11, !12 }
+!nvvm.annotations = !{}
+
+!1 = !DIFile(directory: "/source/dir", filename: "test.cu")
+!2 = distinct !DICompileUnit(emissionKind: FullDebug, file: !1, isOptimized: false, language: DW_LANG_C_plus_plus, runtimeVersion: 0)
+!3 = !DIBasicType(encoding: DW_ATE_boolean, name: "bool", size: 8)
+!4 = !DISubroutineType(types: !{null})
+!5 = distinct !DISubprogram(file: !1, isDefinition: true, isLocal: false, isOptimized: false, line: 5, linkageName: "foo", name: "foo", scope: !1, scopeLine: 5, type: !4, unit: !2)
+!6 = !DILocation(column: 1, line: 5, scope: !5)
+!7 = !DILocation(column: 1, line: 7, scope: !5)
+!8 = !DILocation(column: 1, line: 8, scope: !5)
+!9 = !DILocalVariable(arg: 0, file: !1, line: 5, name: "arg", scope: !5, type: !3)
+!10 = !DIExpression()
+!11 = !{ i32 2, !"Dwarf Version", i32 4 }
+!12 = !{ i32 2, !"Debug Info Version", i32 3 }
\ No newline at end of file
diff --git a/llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll b/llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll
new file mode 100644
index 0000000000000..002a7a801c746
--- /dev/null
+++ b/llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll
@@ -0,0 +1,37 @@
+; RUN: llc < %s -asm-verbose -mattr=+ptx76 | FileCheck %s
+; RUN: %if ptxas %{ llc < %s -asm-verbose -mattr=+ptx76 | %ptxas-verify %}
+
+target triple = "nvptx64-nvidia-cuda"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"
+
+; CHECK: {{.*}}section {{.*}}debug_info
+; CHECK: {{.*}}DW_TAG_variable
+; CHECK-NEXT: {{.*}} DW_AT_address_class
+; CHECK-NEXT: .b8 1{{.*}} DW_AT_const_value
+; CHECK-NEXT: {{.*}} DW_AT_name
+
+define void @test() !dbg !5
+{
+entry:
+  %arg = alloca i1
+  store i1 true, i1* %arg, !dbg !6
+  call void @"llvm.dbg.value"(metadata i1 true, metadata !7, metadata !8), !dbg !6
+  ret void, !dbg !6
+}
+
+declare void @"llvm.dbg.value"(metadata %".1", metadata %".2", metadata %".3")
+
+!llvm.dbg.cu = !{ !2 }
+!llvm.module.flags = !{ !9, !10 }
+!nvvm.annotations = !{}
+
+!1 = !DIFile(directory: "/source/dir", filename: "test.cu")
+!2 = distinct !DICompileUnit(emissionKind: FullDebug, file: !1, isOptimized: false, language: DW_LANG_C_plus_plus, runtimeVersion: 0)
+!3 = !DIBasicType(encoding: DW_ATE_boolean, name: "bool", size: 8)
+!4 = !DISubroutineType(types: !{null})
+!5 = distinct !DISubprogram(file: !1, isDefinition: true, isLocal: false, isOptimized: false, line: 5, linkageName: "test", name: "test", scope: !1, scopeLine: 5, type: !4, unit: !2)
+!6 = !DILocation(column: 1, line: 5, scope: !5)
+!7 = !DILocalVariable(arg: 0, file: !1, line: 5, name: "arg", scope: !5, type: !3)
+!8 = !DIExpression()
+!9 = !{ i32 2, !"Dwarf Version", i32 4 }
+!10 = !{ i32 2, !"Debug Info Version", i32 3 }
\ No newline at end of file

>From f9104e6e7b667eebdda6ec0c42c16d8004a13780 Mon Sep 17 00:00:00 2001
From: Laxman Sole <lsole at nvidia.com>
Date: Wed, 20 Aug 2025 18:58:20 -0700
Subject: [PATCH 2/2] Move tests to llvm/test/DebugInfo

---
 .../{NVPTX => }/debug-bool-const-location.ll   | 18 +++++++-----------
 .../{NVPTX => }/debug-bool-const-value.ll      | 17 +++++------------
 2 files changed, 12 insertions(+), 23 deletions(-)
 rename llvm/test/DebugInfo/{NVPTX => }/debug-bool-const-location.ll (73%)
 rename llvm/test/DebugInfo/{NVPTX => }/debug-bool-const-value.ll (60%)

diff --git a/llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll b/llvm/test/DebugInfo/debug-bool-const-location.ll
similarity index 73%
rename from llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll
rename to llvm/test/DebugInfo/debug-bool-const-location.ll
index f073d51e7ef99..d3459a3168d4d 100644
--- a/llvm/test/DebugInfo/NVPTX/debug-bool-const-location.ll
+++ b/llvm/test/DebugInfo/debug-bool-const-location.ll
@@ -1,13 +1,10 @@
-; RUN: llc < %s -asm-verbose -mattr=+ptx76  -O0| FileCheck %s
-; RUN: %if ptxas %{ llc < %s -asm-verbose -mattr=+ptx76  -O0 | %ptxas-verify %}
+; REQUIRES: object-emission
+; RUN: %llc_dwarf %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
 
-target triple = "nvptx64-nvidia-cuda"
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"
-
-; CHECK: {{.*}}section {{.*}}debug_loc
-; CHECK: .b8 48{{.*}} DW_OP_lit0
-; CHECK: .b8 49{{.*}} DW_OP_lit1
-; CHECK: .b8 144{{.*}} DW_OP_regx
+; CHECK: {{.*}}DW_TAG_variable
+; CHECK: {{.*}} DW_OP_lit1
+; CHECK-NOT: {{.*}} DW_OP_lit0, DW_OP_not
+; CHECK: {{.*}} DW_AT_name    ("arg")
 
 define void @foo(i8 %"arg.arg") !dbg !5
 {
@@ -35,9 +32,8 @@ declare void @"llvm.dbg.value"(metadata %".1", metadata %".2", metadata %".3")
 
 !llvm.dbg.cu = !{ !2 }
 !llvm.module.flags = !{ !11, !12 }
-!nvvm.annotations = !{}
 
-!1 = !DIFile(directory: "/source/dir", filename: "test.cu")
+!1 = !DIFile(directory: "", filename: "test")
 !2 = distinct !DICompileUnit(emissionKind: FullDebug, file: !1, isOptimized: false, language: DW_LANG_C_plus_plus, runtimeVersion: 0)
 !3 = !DIBasicType(encoding: DW_ATE_boolean, name: "bool", size: 8)
 !4 = !DISubroutineType(types: !{null})
diff --git a/llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll b/llvm/test/DebugInfo/debug-bool-const-value.ll
similarity index 60%
rename from llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll
rename to llvm/test/DebugInfo/debug-bool-const-value.ll
index 002a7a801c746..9a057621cfe7c 100644
--- a/llvm/test/DebugInfo/NVPTX/debug-bool-const-value.ll
+++ b/llvm/test/DebugInfo/debug-bool-const-value.ll
@@ -1,20 +1,14 @@
-; RUN: llc < %s -asm-verbose -mattr=+ptx76 | FileCheck %s
-; RUN: %if ptxas %{ llc < %s -asm-verbose -mattr=+ptx76 | %ptxas-verify %}
+; REQUIRES: object-emission
+; RUN: %llc_dwarf %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
 
-target triple = "nvptx64-nvidia-cuda"
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"
 
-; CHECK: {{.*}}section {{.*}}debug_info
 ; CHECK: {{.*}}DW_TAG_variable
-; CHECK-NEXT: {{.*}} DW_AT_address_class
-; CHECK-NEXT: .b8 1{{.*}} DW_AT_const_value
-; CHECK-NEXT: {{.*}} DW_AT_name
+; CHECK-NEXT: {{.*}} DW_AT_const_value     (1)
+; CHECK-NEXT: {{.*}} DW_AT_name    ("arg")
 
 define void @test() !dbg !5
 {
 entry:
-  %arg = alloca i1
-  store i1 true, i1* %arg, !dbg !6
   call void @"llvm.dbg.value"(metadata i1 true, metadata !7, metadata !8), !dbg !6
   ret void, !dbg !6
 }
@@ -23,9 +17,8 @@ declare void @"llvm.dbg.value"(metadata %".1", metadata %".2", metadata %".3")
 
 !llvm.dbg.cu = !{ !2 }
 !llvm.module.flags = !{ !9, !10 }
-!nvvm.annotations = !{}
 
-!1 = !DIFile(directory: "/source/dir", filename: "test.cu")
+!1 = !DIFile(directory: "", filename: "test")
 !2 = distinct !DICompileUnit(emissionKind: FullDebug, file: !1, isOptimized: false, language: DW_LANG_C_plus_plus, runtimeVersion: 0)
 !3 = !DIBasicType(encoding: DW_ATE_boolean, name: "bool", size: 8)
 !4 = !DISubroutineType(types: !{null})



More information about the llvm-commits mailing list