Skip to content
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

[NVPTX] add support for .debug_loc section #110905

Merged
merged 2 commits into from
Oct 3, 2024

Conversation

willghatch
Copy link
Contributor

Enable .debug_loc section for NVPTX backend.

This commit makes NVPTX omit DW_AT_low_pc (and DW_AT_high_pc) for DW_TAG_compile_unit. This is because cuda-gdb uses the compile unit's low_pc as a base address, and adds the addresses in the debug_loc section to it. Removing low_pc is equivalent to setting that base address to zero, so addition doesn't break the location ranges. Additionally, this patch forces debug_loc label emission to emit single labels with no subtraction or base. This would not be necessary if we could emit label1 - label2 expressions in PTX. The PTX documentation at https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section makes it seem like this is supported, but it doesn't actually work. I believe when that documentation says that you can subtract “label addresses between labels in the same dwarf section”, it doesn't merely mean that the labels need to be in the same section as each other, but in fact they need to be in the same section as the use. If support for label subtraction is supported such that in the debug_loc section you can subtract labels from the main code section, then we can remove the workarounds added in this PR.

Also, since this now emits valid .debug_loc sections, it replaces the empty .debug_loc to force existence of at least one debug section with an empty .debug_macinfo section, which matches what nvcc does.

Enable .debug_loc section for NVPTX backend.

This commit makes NVPTX omit DW_AT_low_pc (and DW_AT_high_pc) for DW_TAG_compile_unit.  This is because cuda-gdb uses the compile unit's low_pc as a base address, and adds the addresses in the debug_loc section to it.  Removing low_pc is equivalent to setting that base address to zero, so addition doesn't break the location ranges.  Additionally, this patch forces debug_loc label emission to emit single labels with no subtraction or base.  This would not be necessary if we could emit `label1 - label2` expressions in PTX.  The PTX documentation at https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section makes it seem like this is supported, but it doesn't actually work.  I believe when that documentation says that you can subtract “label addresses between labels in the same dwarf section”, it doesn't merely mean that the labels need to be in the same section as each other, but in fact they need to be in the same section as the use.  If support for label subtraction is supported such that in the debug_loc section you can subtract labels from the main code section, then we can remove the workarounds added in this PR.

Also, since this now emits valid .debug_loc sections, it replaces the empty .debug_loc to force existence of at least one debug section with an empty .debug_macinfo section, which matches what nvcc does.
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2024

@llvm/pr-subscribers-backend-nvptx

Author: William G Hatch (willghatch)

Changes

Enable .debug_loc section for NVPTX backend.

This commit makes NVPTX omit DW_AT_low_pc (and DW_AT_high_pc) for DW_TAG_compile_unit. This is because cuda-gdb uses the compile unit's low_pc as a base address, and adds the addresses in the debug_loc section to it. Removing low_pc is equivalent to setting that base address to zero, so addition doesn't break the location ranges. Additionally, this patch forces debug_loc label emission to emit single labels with no subtraction or base. This would not be necessary if we could emit label1 - label2 expressions in PTX. The PTX documentation at https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section makes it seem like this is supported, but it doesn't actually work. I believe when that documentation says that you can subtract “label addresses between labels in the same dwarf section”, it doesn't merely mean that the labels need to be in the same section as each other, but in fact they need to be in the same section as the use. If support for label subtraction is supported such that in the debug_loc section you can subtract labels from the main code section, then we can remove the workarounds added in this PR.

Also, since this now emits valid .debug_loc sections, it replaces the empty .debug_loc to force existence of at least one debug section with an empty .debug_macinfo section, which matches what nvcc does.


Patch is 555.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110905.diff

10 Files Affected:

  • (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (+17-8)
  • (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h (-6)
  • (modified) llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp (+2-2)
  • (modified) llvm/test/DebugInfo/NVPTX/cu-range-hole.ll (+125-131)
  • (modified) llvm/test/DebugInfo/NVPTX/dbg-declare-alloca.ll (+143-149)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-addr-class.ll (+296-302)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-empty.ll (+1-1)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-file-loc.ll (+33-39)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-info.ll (+1644-1591)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll (+212-186)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index aa44d62da47be9..90ad6b9565a1ab 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -352,8 +352,6 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
   else
     UseInlineStrings = DwarfInlinedStrings == Enable;
 
-  UseLocSection = !TT.isNVPTX();
-
   // Always emit .debug_aranges for SCE tuning.
   UseARangesSection = GenerateARangeSection || tuneForSCE();
 
@@ -1324,7 +1322,12 @@ void DwarfDebug::finalizeModuleInfo() {
     // ranges for all subprogram DIEs for mach-o.
     DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
 
-    if (unsigned NumRanges = TheCU.getRanges().size()) {
+    if (Asm->TM.getTargetTriple().isNVPTX() && tuneForGDB()) {
+      // PTX does not support subtracting labels from the code section in the
+      // debug_loc section.  To work around this, the NVPTX backend needs the
+      // compile unit to have no low_pc in order to have a zero base_address
+      // when handling debug_loc in cuda-gdb.
+    } else if (unsigned NumRanges = TheCU.getRanges().size()) {
       if (NumRanges > 1 && useRangesSection())
         // A DW_AT_low_pc attribute may also be specified in combination with
         // DW_AT_ranges to specify the default base address for use in
@@ -1920,10 +1923,6 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
       }
     }
 
-    // Do not emit location lists if .debug_loc secton is disabled.
-    if (!useLocSection())
-      continue;
-
     // Handle multiple DBG_VALUE instructions describing one variable.
     DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar);
 
@@ -2841,7 +2840,17 @@ static void emitRangeList(
   bool BaseIsSet = false;
   for (const auto &P : SectionRanges) {
     auto *Base = CUBase;
-    if (!Base && ShouldUseBaseAddress) {
+    if ((Asm->TM.getTargetTriple().isNVPTX() && DD.tuneForGDB())) {
+      // PTX does not support subtracting labels from the code section in the
+      // debug_loc section.  To work around this, the NVPTX backend needs the
+      // compile unit to have no low_pc in order to have a zero base_address
+      // when handling debug_loc in cuda-gdb.  Additionally, cuda-gdb doesn't
+      // seem to handle setting a per-variable base to zero.  To make cuda-gdb
+      // happy, just emit labels with no base while having no compile unit
+      // low_pc.
+      BaseIsSet = false;
+      Base = nullptr;
+    } else if (!Base && ShouldUseBaseAddress) {
       const MCSymbol *Begin = P.second.front()->Begin;
       const MCSymbol *NewBase = DD.getSectionLabel(&Begin->getSection());
       if (!UseDwarf5) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 19f5b677bb8d06..6ed03124a2626f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -432,9 +432,6 @@ class DwarfDebug : public DebugHandlerBase {
   /// temp symbols inside DWARF sections.
   bool UseSectionsAsReferences = false;
 
-  ///Allow emission of the .debug_loc section.
-  bool UseLocSection = true;
-
   /// Allow emission of .debug_aranges section
   bool UseARangesSection = false;
 
@@ -791,9 +788,6 @@ class DwarfDebug : public DebugHandlerBase {
     return UseSectionsAsReferences;
   }
 
-  /// Returns whether .debug_loc section should be emitted.
-  bool useLocSection() const { return UseLocSection; }
-
   /// Returns whether to generate DWARF v4 type units.
   bool generateTypeUnits() const { return GenerateTypeUnits; }
 
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index 09d84d41a22942..12f6161cbf61bc 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -964,8 +964,8 @@ bool NVPTXAsmPrinter::doFinalization(Module &M) {
   // Close the last emitted section
   if (hasDebugInfo()) {
     TS->closeLastSection();
-    // Emit empty .debug_loc section for better support of the empty files.
-    OutStreamer->emitRawText("\t.section\t.debug_loc\t{\t}");
+    // Emit empty .debug_macinfo section for better support of the empty files.
+    OutStreamer->emitRawText("\t.section\t.debug_macinfo\t{\t}");
   }
 
   // Output last DWARF .file directives, if any.
diff --git a/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll b/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll
index 2d927b18d976d9..1f4c44eaf455c0 100644
--- a/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll
+++ b/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll
@@ -73,89 +73,85 @@ entry:
   ret i32 %add, !dbg !16
 }
 
-; CHECK: .section .debug_abbrev
-; CHECK-NEXT: {
-; CHECK-NEXT: .b8 1                                // Abbreviation Code
-; CHECK-NEXT: .b8 17                               // DW_TAG_compile_unit
-; CHECK-NEXT: .b8 1                                // DW_CHILDREN_yes
-; CHECK-NEXT: .b8 37                               // DW_AT_producer
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 19                               // DW_AT_language
-; CHECK-NEXT: .b8 5                                // DW_FORM_data2
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 16                               // DW_AT_stmt_list
-; CHECK-NEXT: .b8 6                                // DW_FORM_data4
-; CHECK-NEXT: .b8 27                               // DW_AT_comp_dir
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 17                               // DW_AT_low_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 18                               // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 2                                // Abbreviation Code
-; CHECK-NEXT: .b8 46                               // DW_TAG_subprogram
-; CHECK-NEXT: .b8 1                                // DW_CHILDREN_yes
-; CHECK-NEXT: .b8 17                               // DW_AT_low_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 18                               // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 64                               // DW_AT_frame_base
-; CHECK-NEXT: .b8 10                               // DW_FORM_block1
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 58                               // DW_AT_decl_file
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 59                               // DW_AT_decl_line
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 39                               // DW_AT_prototyped
-; CHECK-NEXT: .b8 12                               // DW_FORM_flag
-; CHECK-NEXT: .b8 73                               // DW_AT_type
-; CHECK-NEXT: .b8 19                               // DW_FORM_ref4
-; CHECK-NEXT: .b8 63                               // DW_AT_external
-; CHECK-NEXT: .b8 12                               // DW_FORM_flag
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 3                                // Abbreviation Code
-; CHECK-NEXT: .b8 5                                // DW_TAG_formal_parameter
-; CHECK-NEXT: .b8 0                                // DW_CHILDREN_no
-; CHECK-NEXT: .b8 51                               // DW_AT_address_class
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 2                                // DW_AT_location
-; CHECK-NEXT: .b8 10                               // DW_FORM_block1
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 58                               // DW_AT_decl_file
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 59                               // DW_AT_decl_line
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 73                               // DW_AT_type
-; CHECK-NEXT: .b8 19                               // DW_FORM_ref4
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 4                                // Abbreviation Code
-; CHECK-NEXT: .b8 36                               // DW_TAG_base_type
-; CHECK-NEXT: .b8 0                                // DW_CHILDREN_no
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 62                               // DW_AT_encoding
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 11                               // DW_AT_byte_size
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 0                                // EOM(3)
-; CHECK-NEXT: }
-; CHECK-NEXT: .section .debug_info
-; CHECK-NEXT: {
-; CHECK-NEXT: .b32 197                             // Length of Unit
-; CHECK-NEXT: .b8 2                                // DWARF version number
+; CHECK: 	.section	.debug_abbrev
+; CHECK-NEXT: 	{
+; CHECK-NEXT: .b8 1                                   // Abbreviation Code
+; CHECK-NEXT: .b8 17                                  // DW_TAG_compile_unit
+; CHECK-NEXT: .b8 1                                   // DW_CHILDREN_yes
+; CHECK-NEXT: .b8 37                                  // DW_AT_producer
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 19                                  // DW_AT_language
+; CHECK-NEXT: .b8 5                                   // DW_FORM_data2
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 16                                  // DW_AT_stmt_list
+; CHECK-NEXT: .b8 6                                   // DW_FORM_data4
+; CHECK-NEXT: .b8 27                                  // DW_AT_comp_dir
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 2                                   // Abbreviation Code
+; CHECK-NEXT: .b8 46                                  // DW_TAG_subprogram
+; CHECK-NEXT: .b8 1                                   // DW_CHILDREN_yes
+; CHECK-NEXT: .b8 17                                  // DW_AT_low_pc
+; CHECK-NEXT: .b8 1                                   // DW_FORM_addr
+; CHECK-NEXT: .b8 18                                  // DW_AT_high_pc
+; CHECK-NEXT: .b8 1                                   // DW_FORM_addr
+; CHECK-NEXT: .b8 64                                  // DW_AT_frame_base
+; CHECK-NEXT: .b8 10                                  // DW_FORM_block1
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 58                                  // DW_AT_decl_file
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 59                                  // DW_AT_decl_line
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 39                                  // DW_AT_prototyped
+; CHECK-NEXT: .b8 12                                  // DW_FORM_flag
+; CHECK-NEXT: .b8 73                                  // DW_AT_type
+; CHECK-NEXT: .b8 19                                  // DW_FORM_ref4
+; CHECK-NEXT: .b8 63                                  // DW_AT_external
+; CHECK-NEXT: .b8 12                                  // DW_FORM_flag
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 3                                   // Abbreviation Code
+; CHECK-NEXT: .b8 5                                   // DW_TAG_formal_parameter
+; CHECK-NEXT: .b8 0                                   // DW_CHILDREN_no
+; CHECK-NEXT: .b8 51                                  // DW_AT_address_class
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 2                                   // DW_AT_location
+; CHECK-NEXT: .b8 10                                  // DW_FORM_block1
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 58                                  // DW_AT_decl_file
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 59                                  // DW_AT_decl_line
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 73                                  // DW_AT_type
+; CHECK-NEXT: .b8 19                                  // DW_FORM_ref4
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 4                                   // Abbreviation Code
+; CHECK-NEXT: .b8 36                                  // DW_TAG_base_type
+; CHECK-NEXT: .b8 0                                   // DW_CHILDREN_no
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 62                                  // DW_AT_encoding
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 11                                  // DW_AT_byte_size
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 0                                   // EOM(3)
+; CHECK-NEXT: 	}
+; CHECK-NEXT: 	.section	.debug_info
+; CHECK-NEXT: 	{
+; CHECK-NEXT: .b32 181                                // Length of Unit
+; CHECK-NEXT: .b8 2                                   // DWARF version number
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b32 .debug_abbrev                   // Offset Into Abbrev. Section
-; CHECK-NEXT: .b8 8                                // Address Size (in bytes)
-; CHECK-NEXT: .b8 1                                // Abbrev [1] 0xb:0xbe DW_TAG_compile_unit
-; CHECK-NEXT: .b8 99                               // DW_AT_producer
+; CHECK-NEXT: .b32 .debug_abbrev                      // Offset Into Abbrev. Section
+; CHECK-NEXT: .b8 8                                   // Address Size (in bytes)
+; CHECK-NEXT: .b8 1                                   // Abbrev [1] 0xb:0xae DW_TAG_compile_unit
+; CHECK-NEXT: .b8 99                                  // DW_AT_producer
 ; CHECK-NEXT: .b8 108
 ; CHECK-NEXT: .b8 97
 ; CHECK-NEXT: .b8 110
@@ -210,14 +206,14 @@ entry:
 ; CHECK-NEXT: .b8 51
 ; CHECK-NEXT: .b8 41
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 12                               // DW_AT_language
+; CHECK-NEXT: .b8 12                                  // DW_AT_language
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 98                               // DW_AT_name
+; CHECK-NEXT: .b8 98                                  // DW_AT_name
 ; CHECK-NEXT: .b8 46
 ; CHECK-NEXT: .b8 99
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b32 .debug_line                     // DW_AT_stmt_list
-; CHECK-NEXT: .b8 47                               // DW_AT_comp_dir
+; CHECK-NEXT: .b32 .debug_line                        // DW_AT_stmt_list
+; CHECK-NEXT: .b8 47                                  // DW_AT_comp_dir
 ; CHECK-NEXT: .b8 115
 ; CHECK-NEXT: .b8 111
 ; CHECK-NEXT: .b8 117
@@ -225,70 +221,68 @@ entry:
 ; CHECK-NEXT: .b8 99
 ; CHECK-NEXT: .b8 101
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b64 $L__func_begin0                 // DW_AT_low_pc
-; CHECK-NEXT: .b64 $L__func_end2                   // DW_AT_high_pc
-; CHECK-NEXT: .b8 2                                // Abbrev [2] 0x65:0x2e DW_TAG_subprogram
-; CHECK-NEXT: .b64 $L__func_begin0                 // DW_AT_low_pc
-; CHECK-NEXT: .b64 $L__func_end0                   // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_AT_frame_base
+; CHECK-NEXT: .b8 2                                   // Abbrev [2] 0x55:0x2e DW_TAG_subprogram
+; CHECK-NEXT: .b64 $L__func_begin0                    // DW_AT_low_pc
+; CHECK-NEXT: .b64 $L__func_end0                      // DW_AT_high_pc
+; CHECK-NEXT: .b8 1                                   // DW_AT_frame_base
 ; CHECK-NEXT: .b8 156
-; CHECK-NEXT: .b8 98                               // DW_AT_name
+; CHECK-NEXT: .b8 98                                  // DW_AT_name
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_file
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_line
-; CHECK-NEXT: .b8 1                                // DW_AT_prototyped
-; CHECK-NEXT: .b32 193                             // DW_AT_type
-; CHECK-NEXT: .b8 1                                // DW_AT_external
-; CHECK-NEXT: .b8 3                                // Abbrev [3] 0x82:0x10 DW_TAG_formal_parameter
-; CHECK-NEXT: .b8 2                                // DW_AT_address_class
-; CHECK-NEXT: .b8 5                                // DW_AT_location
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_file
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_line
+; CHECK-NEXT: .b8 1                                   // DW_AT_prototyped
+; CHECK-NEXT: .b32 177                                // DW_AT_type
+; CHECK-NEXT: .b8 1                                   // DW_AT_external
+; CHECK-NEXT: .b8 3                                   // Abbrev [3] 0x72:0x10 DW_TAG_formal_parameter
+; CHECK-NEXT: .b8 2                                   // DW_AT_address_class
+; CHECK-NEXT: .b8 5                                   // DW_AT_location
 ; CHECK-NEXT: .b8 144
 ; CHECK-NEXT: .b8 177
 ; CHECK-NEXT: .b8 228
 ; CHECK-NEXT: .b8 149
 ; CHECK-NEXT: .b8 1
-; CHECK-NEXT: .b8 99                               // DW_AT_name
+; CHECK-NEXT: .b8 99                                  // DW_AT_name
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_file
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_line
-; CHECK-NEXT: .b32 193                             // DW_AT_type
-; CHECK-NEXT: .b8 0                                // End Of Children Mark
-; CHECK-NEXT: .b8 2                                // Abbrev [2] 0x93:0x2e DW_TAG_subprogram
-; CHECK-NEXT: .b64 $L__func_begin2                 // DW_AT_low_pc
-; CHECK-NEXT: .b64 $L__func_end2                   // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_AT_frame_base
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_file
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_line
+; CHECK-NEXT: .b32 177                                // DW_AT_type
+; CHECK-NEXT: .b8 0                                   // End Of Children Mark
+; CHECK-NEXT: .b8 2                                   // Abbrev [2] 0x83:0x2e DW_TAG_subprogram
+; CHECK-NEXT: .b64 $L__func_begin2                    // DW_AT_low_pc
+; CHECK-NEXT: .b64 $L__func_end2                      // DW_AT_high_pc
+; CHECK-NEXT: .b8 1                                   // DW_AT_frame_base
 ; CHECK-NEXT: .b8 156
-; CHECK-NEXT: .b8 100                              // DW_AT_name
+; CHECK-NEXT: .b8 100                                 // DW_AT_name
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_file
-; CHECK-NEXT: .b8 3                     ...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2024

@llvm/pr-subscribers-debuginfo

Author: William G Hatch (willghatch)

Changes

Enable .debug_loc section for NVPTX backend.

This commit makes NVPTX omit DW_AT_low_pc (and DW_AT_high_pc) for DW_TAG_compile_unit. This is because cuda-gdb uses the compile unit's low_pc as a base address, and adds the addresses in the debug_loc section to it. Removing low_pc is equivalent to setting that base address to zero, so addition doesn't break the location ranges. Additionally, this patch forces debug_loc label emission to emit single labels with no subtraction or base. This would not be necessary if we could emit label1 - label2 expressions in PTX. The PTX documentation at https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section makes it seem like this is supported, but it doesn't actually work. I believe when that documentation says that you can subtract “label addresses between labels in the same dwarf section”, it doesn't merely mean that the labels need to be in the same section as each other, but in fact they need to be in the same section as the use. If support for label subtraction is supported such that in the debug_loc section you can subtract labels from the main code section, then we can remove the workarounds added in this PR.

Also, since this now emits valid .debug_loc sections, it replaces the empty .debug_loc to force existence of at least one debug section with an empty .debug_macinfo section, which matches what nvcc does.


Patch is 555.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110905.diff

10 Files Affected:

  • (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (+17-8)
  • (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h (-6)
  • (modified) llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp (+2-2)
  • (modified) llvm/test/DebugInfo/NVPTX/cu-range-hole.ll (+125-131)
  • (modified) llvm/test/DebugInfo/NVPTX/dbg-declare-alloca.ll (+143-149)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-addr-class.ll (+296-302)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-empty.ll (+1-1)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-file-loc.ll (+33-39)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-info.ll (+1644-1591)
  • (modified) llvm/test/DebugInfo/NVPTX/debug-loc-offset.ll (+212-186)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index aa44d62da47be9..90ad6b9565a1ab 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -352,8 +352,6 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
   else
     UseInlineStrings = DwarfInlinedStrings == Enable;
 
-  UseLocSection = !TT.isNVPTX();
-
   // Always emit .debug_aranges for SCE tuning.
   UseARangesSection = GenerateARangeSection || tuneForSCE();
 
@@ -1324,7 +1322,12 @@ void DwarfDebug::finalizeModuleInfo() {
     // ranges for all subprogram DIEs for mach-o.
     DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
 
-    if (unsigned NumRanges = TheCU.getRanges().size()) {
+    if (Asm->TM.getTargetTriple().isNVPTX() && tuneForGDB()) {
+      // PTX does not support subtracting labels from the code section in the
+      // debug_loc section.  To work around this, the NVPTX backend needs the
+      // compile unit to have no low_pc in order to have a zero base_address
+      // when handling debug_loc in cuda-gdb.
+    } else if (unsigned NumRanges = TheCU.getRanges().size()) {
       if (NumRanges > 1 && useRangesSection())
         // A DW_AT_low_pc attribute may also be specified in combination with
         // DW_AT_ranges to specify the default base address for use in
@@ -1920,10 +1923,6 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
       }
     }
 
-    // Do not emit location lists if .debug_loc secton is disabled.
-    if (!useLocSection())
-      continue;
-
     // Handle multiple DBG_VALUE instructions describing one variable.
     DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar);
 
@@ -2841,7 +2840,17 @@ static void emitRangeList(
   bool BaseIsSet = false;
   for (const auto &P : SectionRanges) {
     auto *Base = CUBase;
-    if (!Base && ShouldUseBaseAddress) {
+    if ((Asm->TM.getTargetTriple().isNVPTX() && DD.tuneForGDB())) {
+      // PTX does not support subtracting labels from the code section in the
+      // debug_loc section.  To work around this, the NVPTX backend needs the
+      // compile unit to have no low_pc in order to have a zero base_address
+      // when handling debug_loc in cuda-gdb.  Additionally, cuda-gdb doesn't
+      // seem to handle setting a per-variable base to zero.  To make cuda-gdb
+      // happy, just emit labels with no base while having no compile unit
+      // low_pc.
+      BaseIsSet = false;
+      Base = nullptr;
+    } else if (!Base && ShouldUseBaseAddress) {
       const MCSymbol *Begin = P.second.front()->Begin;
       const MCSymbol *NewBase = DD.getSectionLabel(&Begin->getSection());
       if (!UseDwarf5) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 19f5b677bb8d06..6ed03124a2626f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -432,9 +432,6 @@ class DwarfDebug : public DebugHandlerBase {
   /// temp symbols inside DWARF sections.
   bool UseSectionsAsReferences = false;
 
-  ///Allow emission of the .debug_loc section.
-  bool UseLocSection = true;
-
   /// Allow emission of .debug_aranges section
   bool UseARangesSection = false;
 
@@ -791,9 +788,6 @@ class DwarfDebug : public DebugHandlerBase {
     return UseSectionsAsReferences;
   }
 
-  /// Returns whether .debug_loc section should be emitted.
-  bool useLocSection() const { return UseLocSection; }
-
   /// Returns whether to generate DWARF v4 type units.
   bool generateTypeUnits() const { return GenerateTypeUnits; }
 
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index 09d84d41a22942..12f6161cbf61bc 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -964,8 +964,8 @@ bool NVPTXAsmPrinter::doFinalization(Module &M) {
   // Close the last emitted section
   if (hasDebugInfo()) {
     TS->closeLastSection();
-    // Emit empty .debug_loc section for better support of the empty files.
-    OutStreamer->emitRawText("\t.section\t.debug_loc\t{\t}");
+    // Emit empty .debug_macinfo section for better support of the empty files.
+    OutStreamer->emitRawText("\t.section\t.debug_macinfo\t{\t}");
   }
 
   // Output last DWARF .file directives, if any.
diff --git a/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll b/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll
index 2d927b18d976d9..1f4c44eaf455c0 100644
--- a/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll
+++ b/llvm/test/DebugInfo/NVPTX/cu-range-hole.ll
@@ -73,89 +73,85 @@ entry:
   ret i32 %add, !dbg !16
 }
 
-; CHECK: .section .debug_abbrev
-; CHECK-NEXT: {
-; CHECK-NEXT: .b8 1                                // Abbreviation Code
-; CHECK-NEXT: .b8 17                               // DW_TAG_compile_unit
-; CHECK-NEXT: .b8 1                                // DW_CHILDREN_yes
-; CHECK-NEXT: .b8 37                               // DW_AT_producer
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 19                               // DW_AT_language
-; CHECK-NEXT: .b8 5                                // DW_FORM_data2
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 16                               // DW_AT_stmt_list
-; CHECK-NEXT: .b8 6                                // DW_FORM_data4
-; CHECK-NEXT: .b8 27                               // DW_AT_comp_dir
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 17                               // DW_AT_low_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 18                               // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 2                                // Abbreviation Code
-; CHECK-NEXT: .b8 46                               // DW_TAG_subprogram
-; CHECK-NEXT: .b8 1                                // DW_CHILDREN_yes
-; CHECK-NEXT: .b8 17                               // DW_AT_low_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 18                               // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_FORM_addr
-; CHECK-NEXT: .b8 64                               // DW_AT_frame_base
-; CHECK-NEXT: .b8 10                               // DW_FORM_block1
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 58                               // DW_AT_decl_file
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 59                               // DW_AT_decl_line
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 39                               // DW_AT_prototyped
-; CHECK-NEXT: .b8 12                               // DW_FORM_flag
-; CHECK-NEXT: .b8 73                               // DW_AT_type
-; CHECK-NEXT: .b8 19                               // DW_FORM_ref4
-; CHECK-NEXT: .b8 63                               // DW_AT_external
-; CHECK-NEXT: .b8 12                               // DW_FORM_flag
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 3                                // Abbreviation Code
-; CHECK-NEXT: .b8 5                                // DW_TAG_formal_parameter
-; CHECK-NEXT: .b8 0                                // DW_CHILDREN_no
-; CHECK-NEXT: .b8 51                               // DW_AT_address_class
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 2                                // DW_AT_location
-; CHECK-NEXT: .b8 10                               // DW_FORM_block1
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 58                               // DW_AT_decl_file
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 59                               // DW_AT_decl_line
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 73                               // DW_AT_type
-; CHECK-NEXT: .b8 19                               // DW_FORM_ref4
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 4                                // Abbreviation Code
-; CHECK-NEXT: .b8 36                               // DW_TAG_base_type
-; CHECK-NEXT: .b8 0                                // DW_CHILDREN_no
-; CHECK-NEXT: .b8 3                                // DW_AT_name
-; CHECK-NEXT: .b8 8                                // DW_FORM_string
-; CHECK-NEXT: .b8 62                               // DW_AT_encoding
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 11                               // DW_AT_byte_size
-; CHECK-NEXT: .b8 11                               // DW_FORM_data1
-; CHECK-NEXT: .b8 0                                // EOM(1)
-; CHECK-NEXT: .b8 0                                // EOM(2)
-; CHECK-NEXT: .b8 0                                // EOM(3)
-; CHECK-NEXT: }
-; CHECK-NEXT: .section .debug_info
-; CHECK-NEXT: {
-; CHECK-NEXT: .b32 197                             // Length of Unit
-; CHECK-NEXT: .b8 2                                // DWARF version number
+; CHECK: 	.section	.debug_abbrev
+; CHECK-NEXT: 	{
+; CHECK-NEXT: .b8 1                                   // Abbreviation Code
+; CHECK-NEXT: .b8 17                                  // DW_TAG_compile_unit
+; CHECK-NEXT: .b8 1                                   // DW_CHILDREN_yes
+; CHECK-NEXT: .b8 37                                  // DW_AT_producer
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 19                                  // DW_AT_language
+; CHECK-NEXT: .b8 5                                   // DW_FORM_data2
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 16                                  // DW_AT_stmt_list
+; CHECK-NEXT: .b8 6                                   // DW_FORM_data4
+; CHECK-NEXT: .b8 27                                  // DW_AT_comp_dir
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 2                                   // Abbreviation Code
+; CHECK-NEXT: .b8 46                                  // DW_TAG_subprogram
+; CHECK-NEXT: .b8 1                                   // DW_CHILDREN_yes
+; CHECK-NEXT: .b8 17                                  // DW_AT_low_pc
+; CHECK-NEXT: .b8 1                                   // DW_FORM_addr
+; CHECK-NEXT: .b8 18                                  // DW_AT_high_pc
+; CHECK-NEXT: .b8 1                                   // DW_FORM_addr
+; CHECK-NEXT: .b8 64                                  // DW_AT_frame_base
+; CHECK-NEXT: .b8 10                                  // DW_FORM_block1
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 58                                  // DW_AT_decl_file
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 59                                  // DW_AT_decl_line
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 39                                  // DW_AT_prototyped
+; CHECK-NEXT: .b8 12                                  // DW_FORM_flag
+; CHECK-NEXT: .b8 73                                  // DW_AT_type
+; CHECK-NEXT: .b8 19                                  // DW_FORM_ref4
+; CHECK-NEXT: .b8 63                                  // DW_AT_external
+; CHECK-NEXT: .b8 12                                  // DW_FORM_flag
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 3                                   // Abbreviation Code
+; CHECK-NEXT: .b8 5                                   // DW_TAG_formal_parameter
+; CHECK-NEXT: .b8 0                                   // DW_CHILDREN_no
+; CHECK-NEXT: .b8 51                                  // DW_AT_address_class
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 2                                   // DW_AT_location
+; CHECK-NEXT: .b8 10                                  // DW_FORM_block1
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 58                                  // DW_AT_decl_file
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 59                                  // DW_AT_decl_line
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 73                                  // DW_AT_type
+; CHECK-NEXT: .b8 19                                  // DW_FORM_ref4
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 4                                   // Abbreviation Code
+; CHECK-NEXT: .b8 36                                  // DW_TAG_base_type
+; CHECK-NEXT: .b8 0                                   // DW_CHILDREN_no
+; CHECK-NEXT: .b8 3                                   // DW_AT_name
+; CHECK-NEXT: .b8 8                                   // DW_FORM_string
+; CHECK-NEXT: .b8 62                                  // DW_AT_encoding
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 11                                  // DW_AT_byte_size
+; CHECK-NEXT: .b8 11                                  // DW_FORM_data1
+; CHECK-NEXT: .b8 0                                   // EOM(1)
+; CHECK-NEXT: .b8 0                                   // EOM(2)
+; CHECK-NEXT: .b8 0                                   // EOM(3)
+; CHECK-NEXT: 	}
+; CHECK-NEXT: 	.section	.debug_info
+; CHECK-NEXT: 	{
+; CHECK-NEXT: .b32 181                                // Length of Unit
+; CHECK-NEXT: .b8 2                                   // DWARF version number
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b32 .debug_abbrev                   // Offset Into Abbrev. Section
-; CHECK-NEXT: .b8 8                                // Address Size (in bytes)
-; CHECK-NEXT: .b8 1                                // Abbrev [1] 0xb:0xbe DW_TAG_compile_unit
-; CHECK-NEXT: .b8 99                               // DW_AT_producer
+; CHECK-NEXT: .b32 .debug_abbrev                      // Offset Into Abbrev. Section
+; CHECK-NEXT: .b8 8                                   // Address Size (in bytes)
+; CHECK-NEXT: .b8 1                                   // Abbrev [1] 0xb:0xae DW_TAG_compile_unit
+; CHECK-NEXT: .b8 99                                  // DW_AT_producer
 ; CHECK-NEXT: .b8 108
 ; CHECK-NEXT: .b8 97
 ; CHECK-NEXT: .b8 110
@@ -210,14 +206,14 @@ entry:
 ; CHECK-NEXT: .b8 51
 ; CHECK-NEXT: .b8 41
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 12                               // DW_AT_language
+; CHECK-NEXT: .b8 12                                  // DW_AT_language
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 98                               // DW_AT_name
+; CHECK-NEXT: .b8 98                                  // DW_AT_name
 ; CHECK-NEXT: .b8 46
 ; CHECK-NEXT: .b8 99
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b32 .debug_line                     // DW_AT_stmt_list
-; CHECK-NEXT: .b8 47                               // DW_AT_comp_dir
+; CHECK-NEXT: .b32 .debug_line                        // DW_AT_stmt_list
+; CHECK-NEXT: .b8 47                                  // DW_AT_comp_dir
 ; CHECK-NEXT: .b8 115
 ; CHECK-NEXT: .b8 111
 ; CHECK-NEXT: .b8 117
@@ -225,70 +221,68 @@ entry:
 ; CHECK-NEXT: .b8 99
 ; CHECK-NEXT: .b8 101
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b64 $L__func_begin0                 // DW_AT_low_pc
-; CHECK-NEXT: .b64 $L__func_end2                   // DW_AT_high_pc
-; CHECK-NEXT: .b8 2                                // Abbrev [2] 0x65:0x2e DW_TAG_subprogram
-; CHECK-NEXT: .b64 $L__func_begin0                 // DW_AT_low_pc
-; CHECK-NEXT: .b64 $L__func_end0                   // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_AT_frame_base
+; CHECK-NEXT: .b8 2                                   // Abbrev [2] 0x55:0x2e DW_TAG_subprogram
+; CHECK-NEXT: .b64 $L__func_begin0                    // DW_AT_low_pc
+; CHECK-NEXT: .b64 $L__func_end0                      // DW_AT_high_pc
+; CHECK-NEXT: .b8 1                                   // DW_AT_frame_base
 ; CHECK-NEXT: .b8 156
-; CHECK-NEXT: .b8 98                               // DW_AT_name
+; CHECK-NEXT: .b8 98                                  // DW_AT_name
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_file
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_line
-; CHECK-NEXT: .b8 1                                // DW_AT_prototyped
-; CHECK-NEXT: .b32 193                             // DW_AT_type
-; CHECK-NEXT: .b8 1                                // DW_AT_external
-; CHECK-NEXT: .b8 3                                // Abbrev [3] 0x82:0x10 DW_TAG_formal_parameter
-; CHECK-NEXT: .b8 2                                // DW_AT_address_class
-; CHECK-NEXT: .b8 5                                // DW_AT_location
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_file
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_line
+; CHECK-NEXT: .b8 1                                   // DW_AT_prototyped
+; CHECK-NEXT: .b32 177                                // DW_AT_type
+; CHECK-NEXT: .b8 1                                   // DW_AT_external
+; CHECK-NEXT: .b8 3                                   // Abbrev [3] 0x72:0x10 DW_TAG_formal_parameter
+; CHECK-NEXT: .b8 2                                   // DW_AT_address_class
+; CHECK-NEXT: .b8 5                                   // DW_AT_location
 ; CHECK-NEXT: .b8 144
 ; CHECK-NEXT: .b8 177
 ; CHECK-NEXT: .b8 228
 ; CHECK-NEXT: .b8 149
 ; CHECK-NEXT: .b8 1
-; CHECK-NEXT: .b8 99                               // DW_AT_name
+; CHECK-NEXT: .b8 99                                  // DW_AT_name
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_file
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_line
-; CHECK-NEXT: .b32 193                             // DW_AT_type
-; CHECK-NEXT: .b8 0                                // End Of Children Mark
-; CHECK-NEXT: .b8 2                                // Abbrev [2] 0x93:0x2e DW_TAG_subprogram
-; CHECK-NEXT: .b64 $L__func_begin2                 // DW_AT_low_pc
-; CHECK-NEXT: .b64 $L__func_end2                   // DW_AT_high_pc
-; CHECK-NEXT: .b8 1                                // DW_AT_frame_base
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_file
+; CHECK-NEXT: .b8 1                                   // DW_AT_decl_line
+; CHECK-NEXT: .b32 177                                // DW_AT_type
+; CHECK-NEXT: .b8 0                                   // End Of Children Mark
+; CHECK-NEXT: .b8 2                                   // Abbrev [2] 0x83:0x2e DW_TAG_subprogram
+; CHECK-NEXT: .b64 $L__func_begin2                    // DW_AT_low_pc
+; CHECK-NEXT: .b64 $L__func_end2                      // DW_AT_high_pc
+; CHECK-NEXT: .b8 1                                   // DW_AT_frame_base
 ; CHECK-NEXT: .b8 156
-; CHECK-NEXT: .b8 100                              // DW_AT_name
+; CHECK-NEXT: .b8 100                                 // DW_AT_name
 ; CHECK-NEXT: .b8 0
-; CHECK-NEXT: .b8 1                                // DW_AT_decl_file
-; CHECK-NEXT: .b8 3                     ...
[truncated]

@willghatch
Copy link
Contributor Author

Note that the test changes are a bit noisy. Some of the tests had drifted in terms of white space emitted for ASM comments, and there were enough test updates in this PR that I decided to just get in the whitespace changes as well.

Comment on lines +1326 to +1329
// PTX does not support subtracting labels from the code section in the
// debug_loc section. To work around this, the NVPTX backend needs the
// compile unit to have no low_pc in order to have a zero base_address
// when handling debug_loc in cuda-gdb.
Copy link
Member

Choose a reason for hiding this comment

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

These if/else blocks read a bit weird. Better collapse them into a single if condition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've moved the PTX test inside the other block, which is probably easier to read. I don't want to merge the two conditions, exactly, since one is an assignment, and a type-preserving merge would be ugly there.

@willghatch willghatch merged commit ae635d6 into main Oct 3, 2024
8 checks passed
@willghatch willghatch deleted the users/willghatch/nvptx-support-debug-loc branch October 3, 2024 22:31
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 3, 2024

LLVM Buildbot has detected a new failure on builder lldb-arm-ubuntu running on linaro-lldb-arm-ubuntu while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/4896

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py (801 of 2809)
PASS: lldb-api :: lang/cpp/multiple-inheritance/TestCppMultipleInheritance.py (802 of 2809)
PASS: lldb-api :: lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py (803 of 2809)
PASS: lldb-api :: lang/cpp/namespace_conflicts/TestNamespaceConflicts.py (804 of 2809)
PASS: lldb-api :: lang/cpp/namespace/TestNamespace.py (805 of 2809)
PASS: lldb-api :: lang/cpp/namespace_definitions/TestNamespaceDefinitions.py (806 of 2809)
PASS: lldb-api :: lang/cpp/nested-template/TestNestedTemplate.py (807 of 2809)
PASS: lldb-api :: lang/cpp/nested-class-other-compilation-unit/TestNestedClassWithParentInAnotherCU.py (808 of 2809)
PASS: lldb-api :: lang/cpp/non-type-template-param/TestCppNonTypeTemplateParam.py (809 of 2809)
PASS: lldb-api :: lang/cpp/no_unique_address/TestNoUniqueAddress.py (810 of 2809)
FAIL: lldb-api :: lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py (811 of 2809)
******************** TEST 'lldb-api :: lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env ARCHIVER=/usr/local/bin/llvm-ar --env OBJCOPY=/usr/bin/llvm-objcopy --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --arch armv8l --build-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/dsymutil --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/lang/c/shared_lib_stripped_symbols -p TestSharedLibStrippedSymbols.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 20.0.0git (https://github.com/llvm/llvm-project.git revision ae635d6f997a28c81a01bfffe70fd849d0eafcca)
  clang revision ae635d6f997a28c81a01bfffe70fd849d0eafcca
  llvm revision ae635d6f997a28c81a01bfffe70fd849d0eafcca
Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_expr_dsym (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase) (test case does not fall in any category of interest for this run) 
FAIL: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_expr_dwarf (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_expr_dwo (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_frame_variable_dsym (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase) (test case does not fall in any category of interest for this run) 
XFAIL: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_frame_variable_dwarf (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase)
XFAIL: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_frame_variable_dwo (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase)
======================================================================
FAIL: test_expr_dwarf (TestSharedLibStrippedSymbols.SharedLibStrippedTestCase)
   Test that types work when defined in a shared library and forwa/d-declared in the main executable
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1769, in test_method
    return attrvalue(self)
  File "/home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py", line 24, in test_expr
    self.expect(
  File "/home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2370, in expect
    self.runCmd(
  File "/home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1000, in runCmd
    self.assertTrue(self.res.Succeeded(), msg + output)
AssertionError: False is not true : Variable(s) displayed correctly
Error output:

@walter-erquinigo
Copy link
Member

The buildbot error seems to be unrelated

xgupta pushed a commit to xgupta/llvm-project that referenced this pull request Oct 4, 2024
Enable .debug_loc section for NVPTX backend.

This commit makes NVPTX omit DW_AT_low_pc (and DW_AT_high_pc) for
DW_TAG_compile_unit. This is because cuda-gdb uses the compile unit's
low_pc as a base address, and adds the addresses in the debug_loc
section to it. Removing low_pc is equivalent to setting that base
address to zero, so addition doesn't break the location ranges.
Additionally, this patch forces debug_loc label emission to emit single
labels with no subtraction or base. This would not be necessary if we
could emit `label1 - label2` expressions in PTX. The PTX documentation
at
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section
makes it seem like this is supported, but it doesn't actually work. I
believe when that documentation says that you can subtract “label
addresses between labels in the same dwarf section”, it doesn't merely
mean that the labels need to be in the same section as each other, but
in fact they need to be in the same section as the use. If support for
label subtraction is supported such that in the debug_loc section you
can subtract labels from the main code section, then we can remove the
workarounds added in this PR.

Also, since this now emits valid .debug_loc sections, it replaces the
empty .debug_loc to force existence of at least one debug section with
an empty .debug_macinfo section, which matches what nvcc does.
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.

4 participants