-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DWARF] Emit 0/1 for constant boolean values #151225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[DWARF] Emit 0/1 for constant boolean values #151225
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-backend-nvptx Author: Laxman (laxmansole) ChangesFor boolean values, -1 is assigned to indicate This leads to the debugger printing 255 instead of "true" for boolean variables. This change emits Full diff: https://github.com/llvm/llvm-project/pull/151225.diff 6 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 5577a7d298177..f1be286c0a746 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;
}
@@ -820,6 +833,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()) {
@@ -836,7 +865,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 71888332a6620..6d4c9c05e3aba 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -3100,8 +3100,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
|
@llvm/pr-subscribers-debuginfo Author: Laxman (laxmansole) ChangesFor boolean values, -1 is assigned to indicate This leads to the debugger printing 255 instead of "true" for boolean variables. This change emits Full diff: https://github.com/llvm/llvm-project/pull/151225.diff 6 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 5577a7d298177..f1be286c0a746 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;
}
@@ -820,6 +833,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()) {
@@ -836,7 +865,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 71888332a6620..6d4c9c05e3aba 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -3100,8 +3100,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
|
CC: @enferex |
CC: @jmorse |
Do you have an example/Github issue of this? Shouldn't the debugger know how to present booleans in a particular language, regardless of which non-zero value was used to indicate truthness? |
Arguable - it's UB to have a bool that isn't 0 or 1 ( So, yeah, I think it is important we describe the value as 0 or 1 if it is 0 or 1, conceptually, at least. |
(but yeah, still would be good to see a bug/etc) |
We encountered this issue with |
ping |
@@ -820,6 +833,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 = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered putting this boolean normalization into addConstantValue
? That way, any other place where we emit booleans with out-of-range constants would benefit from this. Some of the overloads don't take a DIType
though, so might not be as simple as I imagine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure if adding boolean normalization for the APInt or ConstantInt versions made sense, so I only modified the affected call sites.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess what's confusing me is:
- Who is assigning
-1
to indicatetrue
? - There seem to be two independent changes in this PR:
- emit
DW_OP_lit
for boolean constants when computing debug values. This seems very reasonable since it makes the DWARF expression simpler (and works regardless of how the true/false values are represented?) - Don't emit
DW_OP_constu (-1)
values for booleans. That also seems reasonable, but what I'm curious about where this-1
comes from? And then, if you do this kind of normalization for booleans here, why not any other place whereDW_AT_const_value
is emitted for booleans? You don't strictly have to but I think we can split these two changes into separate PRs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who is assigning -1 to indicate true?
llvm-project/llvm/include/llvm/CodeGen/TargetLowering.h
Lines 236 to 241 in 085d0b0
/// Enum that describes how the target represents true/false values. | |
enum BooleanContent { | |
UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage. | |
ZeroOrOneBooleanContent, // All bits zero except for bit 0. | |
ZeroOrNegativeOneBooleanContent // All bits equal to bit 0. | |
}; |
There is a target-dependent
setBooleanContents
.
While creating #DBG_VALUE
, the true/1
gets signed extednded to 0xffffffffffffffff i.e. -1(Line 736 below)
llvm-project/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
Lines 731 to 749 in 5886a27
MachineOperand GetMOForConstDbgOp(const SDDbgOperand &Op) { | |
const Value *V = Op.getConst(); | |
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { | |
if (CI->getBitWidth() > 64) | |
return MachineOperand::CreateCImm(CI); | |
return MachineOperand::CreateImm(CI->getSExtValue()); | |
} | |
if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) | |
return MachineOperand::CreateFPImm(CF); | |
// Note: This assumes that all nullptr constants are zero-valued. | |
if (isa<ConstantPointerNull>(V)) | |
return MachineOperand::CreateImm(0); | |
// Undef or unhandled value type, so return an undef operand. | |
return MachineOperand::CreateReg( | |
/* Reg */ 0U, /* isDef */ false, /* isImp */ false, | |
/* isKill */ false, /* isDead */ false, | |
/* isUndef */ false, /* isEarlyClobber */ false, | |
/* SubReg */ 0, /* isDebug */ true); | |
} |
And then, if you do this kind of normalization for booleans here, why not any other place where DW_AT_const_value is emitted for booleans?
I checked all the call sites for addConstantValue
and found that this is the most relevant one. Alternatively, as you suggested, I could add this normalization to addConstantValue
, but we don't have DIType
in all overloaded functions.
I think we can split these two changes into separate PRs
Sure. Let me spilt these into two separate PRs- current one for the changes in DwarfCompileUnit.cpp and another one for the changes to emit DW_OP_lit0/1
for booleans.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emit DW_OP_lit for boolean constants when computing debug values.
Created a separate PR #155539 for these changes
5810b2f
to
f9104e6
Compare
f9104e6
to
a3fbfa6
Compare
a3fbfa6
to
859a086
Compare
Backends like NVPTX use -1 to indicate
true
and 0 to indicatefalse
for boolean values. Machine instruction#DBG_VALUE
also uses -1 to indicate atrue
boolean constant.However, during the DWARF generation, booleans are treated as unsigned variables, and the DWARF attributes
DW_AT_const_value(0xffffffffffffffff)
is emitted for theTrue
value.This leads to the debugger printing 255 instead of "true" for boolean variables.
This change emits the attribute
DW_AT_const_value(1)
instead ofDW_AT_const_value(0xffffffffffffffff).