llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: ZhaoQi (zhaoqi5)

<details>
<summary>Changes</summary>

Benefit from https://github.com/llvm/llvm-project/pull/166597 and 
https://github.com/llvm/llvm-project/pull/164813, DWARF fission is now 
compatible with linker relaxation.

Similar to RISC-V, this commit allows `-gsplit-dwarf` and `-mrelax` to be used 
together.

A new test `relax_dwo_ranges.ll` same as RISC-V is also added.

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


6 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (-3) 
- (modified) clang/lib/Driver/ToolChains/Arch/LoongArch.cpp (+2-9) 
- (modified) clang/test/Driver/loongarch-relax-features.c (-12) 
- (modified) llvm/docs/ReleaseNotes.md (+3) 
- (added) llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll (+206) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c11a604a46d83..7d68467f6ada8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -725,6 +725,9 @@ LoongArch Support
 ^^^^^^^^^^^^^^^^^
 - Enable linker relaxation by default for loongarch64.
 
+- DWARF fission is now compatible with linker relaxations, allowing 
`-gsplit-dwarf` and `-mrelax`
+  to be used together when building for the LoongArch platform.
+
 RISC-V Support
 ^^^^^^^^^^^^^^
 
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index af5387b2c8f02..db0f521b73544 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -870,9 +870,6 @@ def err_drv_loongarch_invalid_simd_option_combination : 
Error<
 def err_drv_loongarch_invalid_msimd_EQ : Error<
   "invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">;
 
-def err_drv_loongarch_unsupported_with_linker_relaxation : Error<
-  "%0 is unsupported with LoongArch linker relaxation (-mrelax)">;
-
 def err_drv_expand_response_file : Error<
   "failed to expand response file: %0">;
 
diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp 
b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
index da084bdabaee3..33c61c1e4962e 100644
--- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
@@ -136,17 +136,10 @@ void loongarch::getLoongArchTargetFeatures(const Driver 
&D,
   // -mrelax is default, unless -mno-relax is specified.
   // FIXME: Only for loongarch64, loongarch32 has not been fully verified.
   if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
-                   Triple.isLoongArch64() ? true : false)) {
+                   Triple.isLoongArch64() ? true : false))
     Features.push_back("+relax");
-    // -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing
-    // into .debug_addr, which is currently not implemented.
-    Arg *A;
-    if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
-      D.Diag(clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
-          << A->getAsString(Args);
-  } else if (Args.getLastArg(options::OPT_mno_relax)) {
+  else if (Args.getLastArg(options::OPT_mno_relax))
     Features.push_back("-relax");
-  }
 
   std::string ArchName;
   const Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
diff --git a/clang/test/Driver/loongarch-relax-features.c 
b/clang/test/Driver/loongarch-relax-features.c
index 2f032516462df..4585ebfcecc07 100644
--- a/clang/test/Driver/loongarch-relax-features.c
+++ b/clang/test/Driver/loongarch-relax-features.c
@@ -7,15 +7,6 @@
 // RUN: %clang --target=loongarch32 -mrelax -S -emit-llvm %s -o - | FileCheck 
%s --check-prefix=LA32-RELAX
 // RUN: %clang --target=loongarch64 -mrelax -S -emit-llvm %s -o - | FileCheck 
%s --check-prefix=LA64-RELAX
 
-/// Error when using -gsplit-dwarf with linker relaxation (-mrelax).
-
-// RUN: %clang -### -c --target=loongarch32 -mno-relax -g -gsplit-dwarf %s 
2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
-// RUN: not %clang -c --target=loongarch32-linux-gnu -mrelax -gsplit-dwarf %s 
2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
-// RUN: not %clang -c --target=loongarch32 -mrelax -gsplit-dwarf=single %s 
2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
-// RUN: %clang -### -c --target=loongarch64 -mno-relax -g -gsplit-dwarf %s 
2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
-// RUN: not %clang -c --target=loongarch64-linux-gnu -mrelax -gsplit-dwarf %s 
2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
-// RUN: not %clang -c --target=loongarch64 -mrelax -gsplit-dwarf=single %s 
2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
-
 // LA32: "target-features"="+32bit"
 // LA64: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"
 
@@ -25,9 +16,6 @@
 // LA32-RELAX: "target-features"="+32bit,+relax"
 // LA64-RELAX: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"
 
-// SPLIT-DWARF:     "-split-dwarf-file"
-// ERR-SPLIT-DWARF: error: -gsplit-dwarf{{.*}} is unsupported with LoongArch 
linker relaxation (-mrelax)
-
 int foo(void) {
   return 3;
 }
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index e5bbf2895ad4f..9e448e974a6be 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -141,6 +141,9 @@ Changes to the Hexagon Backend
 Changes to the LoongArch Backend
 --------------------------------
 
+* DWARF fission is now compatible with linker relaxations, allowing 
`-gsplit-dwarf` and `-mrelax`
+  to be used together when building for the LoongArch platform.
+
 Changes to the MIPS Backend
 ---------------------------
 
diff --git a/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll 
b/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll
new file mode 100644
index 0000000000000..073ab562df57b
--- /dev/null
+++ b/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll
@@ -0,0 +1,206 @@
+; In the LoongArch architecture, the .text section is subject to
+; relaxation, meaning the start address of each function can change
+; during the linking process. Therefore, the .debug_rnglists.dwo
+; section must obtain function's start addresses from the .debug_addr
+; section.
+
+; Generally, a function's body can be relaxed (for example, the
+; square() and main() functions in this test, which contain call
+; instructions). For such code ranges, the linker must place the
+; start and end addresses into the .debug_addr section and use
+; the DW_RLE_startx_endx entry form in the .debug_rnglists.dwo
+; section within the .dwo file.
+
+; However, some functions may not contain any relaxable instructions
+; (for example, the boo() function in this test). In these cases,
+; it is possible to use the more space-efficient DW_RLE_startx_length
+; range entry form.
+
+; RUN: rm -rf %t && split-file %s %t && cd %t
+
+; RUN: llc -dwarf-version=5 -split-dwarf-file=foo.dwo -O0 
-mtriple=loongarch64-unknown-linux-gnu -filetype=obj relax_dwo_ranges.ll -o %t.o
+; RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=DWARF5 %s
+; RUN: llvm-dwarfdump --debug-info %t.o > /dev/null 2>&1 | count 0
+; RUN: llvm-objdump -h %t.o | FileCheck --check-prefix=HDR %s
+
+; RUN: llc -dwarf-version=4 -split-dwarf-file=foo.dwo -O0 
-mtriple=loongarch64-unknown-linux-gnu -filetype=obj relax_dwo_ranges.ll -o %t.o
+; RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=DWARF4 %s
+; RUN: llvm-dwarfdump --debug-info %t.o > /dev/null 2>&1 | count 0
+; RUN: llvm-objdump -h %t.o | FileCheck --check-prefix=HDR %s
+
+; Make sure we don't produce any relocations in any .dwo section
+; HDR-NOT: .rela.{{.*}}.dwo
+
+; Ensure that 'square()' function uses indexed start and end addresses
+; DWARF5: .debug_info.dwo contents:
+; DWARF5: DW_TAG_subprogram
+; DWARF5-NEXT: DW_AT_low_pc  [DW_FORM_addrx]    (indexed (00000000) address = 
0x0000000000000000 ".text")
+; DWARF5-NEXT: DW_AT_high_pc [DW_FORM_addrx]    (indexed (00000001) address = 
0x0000000000000040 ".text")
+; DWARF5: DW_AT_name {{.*}} "square") 
+; DWARF5: DW_TAG_formal_parameter
+
+; HDR-NOT: .rela.{{.*}}.dwo
+
+; Ensure there is no unnecessary addresses in .o file
+; DWARF5: .debug_addr contents:
+; DWARF5: Addrs: [
+; DWARF5-NEXT: 0x0000000000000000
+; DWARF5-NEXT: 0x0000000000000040
+; DWARF5-NEXT: 0x000000000000005c
+; DWARF5-NEXT: 0x000000000000009c
+; DWARF5-NEXT: 0x00000000000000e0
+; DWARF5-NEXT: ]
+
+; HDR-NOT: .rela.{{.*}}.dwo
+
+; Ensure that 'boo()' and 'main()' use DW_RLE_startx_length and 
DW_RLE_startx_endx
+; entries respectively
+; DWARF5: .debug_rnglists.dwo contents:
+; DWARF5: ranges:
+; DWARF5-NEXT: 0x00000014: [DW_RLE_startx_length]:  0x0000000000000002, 
0x0000000000000024 => [0x000000000000005c, 0x0000000000000080)
+; DWARF5-NEXT: 0x00000017: [DW_RLE_end_of_list  ]
+; DWARF5-NEXT: 0x00000018: [DW_RLE_startx_endx  ]:  0x0000000000000003, 
0x0000000000000004 => [0x000000000000009c, 0x00000000000000e0)
+; DWARF5-NEXT: 0x0000001b: [DW_RLE_end_of_list  ]
+; DWARF5-EMPTY:
+
+; HDR-NOT: .rela.{{.*}}.dwo
+
+; DWARF4: .debug_info.dwo contents:
+; DWARF4: DW_TAG_subprogram
+; DWARF4-NEXT: DW_AT_low_pc  [DW_FORM_GNU_addr_index]  (indexed (00000000) 
address = 0x0000000000000000 ".text")
+; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_GNU_addr_index] (indexed (00000001) 
address = 0x0000000000000040 ".text")
+; DWARF4: DW_AT_name {{.*}} "square") 
+
+; DWARF4: DW_TAG_subprogram
+; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index]   (indexed (00000002) 
address = 0x000000000000005c ".text")
+; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_data4]   (0x00000024)
+; DWARF4: DW_AT_name {{.*}} "boo") 
+
+; DWARF4: DW_TAG_subprogram
+; DWARF4-NEXT: DW_AT_low_pc  [DW_FORM_GNU_addr_index] (indexed (00000003) 
address = 0x000000000000009c ".text")
+; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_GNU_addr_index] (indexed (00000004) 
address = 0x00000000000000e0 ".text")
+; DWARF4: DW_AT_name {{.*}} "main") 
+
+; HDR-NOT: .rela.{{.*}}.dwo
+
+; Ensure there is no unnecessary addresses in .o file
+; DWARF4: .debug_addr contents:
+; DWARF4: Addrs: [
+; DWARF4-NEXT: 0x0000000000000000
+; DWARF4-NEXT: 0x0000000000000040
+; DWARF4-NEXT: 0x000000000000005c
+; DWARF4-NEXT: 0x000000000000009c
+; DWARF4-NEXT: 0x00000000000000e0
+; DWARF4-NEXT: ]
+
+; HDR-NOT: .rela.{{.*}}.dwo
+
+#--- relax_dwo_ranges.cpp
+__attribute__((noinline)) int boo();
+
+int square(int num) {
+  int num1 = boo();
+  return num1 * num;
+}
+
+__attribute__((noinline)) int boo() {
+  return 8;
+}
+
+int main() {
+  int a = 10;
+  int squared = square(a);
+  return squared;
+}
+
+#--- gen
+clang -g -S -emit-llvm -gsplit-dwarf --target=loongarch64 -march=loongarch64 
-O0 relax_dwo_ranges.cpp -o -
+
+#--- relax_dwo_ranges.ll
+; ModuleID = 'relax_dwo_ranges.cpp'
+source_filename = "relax_dwo_ranges.cpp"
+target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+target triple = "loongarch64"
+
+; Function Attrs: mustprogress noinline optnone
+define dso_local noundef signext i32 @_Z6squarei(i32 noundef signext %num) #0 
!dbg !8 {
+entry:
+  %num.addr = alloca i32, align 4
+  %num1 = alloca i32, align 4
+  store i32 %num, ptr %num.addr, align 4
+    #dbg_declare(ptr %num.addr, !13, !DIExpression(), !14)
+    #dbg_declare(ptr %num1, !15, !DIExpression(), !16)
+  %call = call noundef signext i32 @_Z3boov(), !dbg !17
+  store i32 %call, ptr %num1, align 4, !dbg !16
+  %0 = load i32, ptr %num1, align 4, !dbg !18
+  %1 = load i32, ptr %num.addr, align 4, !dbg !19
+  %mul = mul nsw i32 %0, %1, !dbg !20
+  ret i32 %mul, !dbg !21
+}
+
+; Function Attrs: mustprogress noinline nounwind optnone
+define dso_local noundef signext i32 @_Z3boov() #1 !dbg !22 {
+entry:
+  ret i32 8, !dbg !25
+}
+
+; Function Attrs: mustprogress noinline norecurse optnone
+define dso_local noundef signext i32 @main() #2 !dbg !26 {
+entry:
+  %retval = alloca i32, align 4
+  %a = alloca i32, align 4
+  %squared = alloca i32, align 4
+  store i32 0, ptr %retval, align 4
+    #dbg_declare(ptr %a, !27, !DIExpression(), !28)
+  store i32 10, ptr %a, align 4, !dbg !28
+    #dbg_declare(ptr %squared, !29, !DIExpression(), !30)
+  %0 = load i32, ptr %a, align 4, !dbg !31
+  %call = call noundef signext i32 @_Z6squarei(i32 noundef signext %0), !dbg 
!32
+  store i32 %call, ptr %squared, align 4, !dbg !30
+  %1 = load i32, ptr %squared, align 4, !dbg !33
+  ret i32 %1, !dbg !34
+}
+
+attributes #0 = { mustprogress noinline optnone "frame-pointer"="all" 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="loongarch64" "target-features"="+64bit,+d,+f,+relax,+ual" }
+attributes #1 = { mustprogress noinline nounwind optnone "frame-pointer"="all" 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="loongarch64" "target-features"="+64bit,+d,+f,+relax,+ual" }
+attributes #2 = { mustprogress noinline norecurse optnone 
"frame-pointer"="all" "no-trapping-math"="true" 
"stack-protector-buffer-size"="8" "target-cpu"="loongarch64" 
"target-features"="+64bit,+d,+f,+relax,+ual" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, 
producer: "clang", isOptimized: false, runtimeVersion: 0, splitDebugFilename: 
"relax_dwo_ranges.dwo", emissionKind: FullDebug, splitDebugInlining: false, 
nameTableKind: GNU)
+!1 = !DIFile(filename: "relax_dwo_ranges.cpp", directory: ".", checksumkind: 
CSK_MD5, checksum: "ecc4b1fa92df66be7da599933e4a21da")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 7, !"direct-access-external-data", i32 0}
+!6 = !{i32 7, !"frame-pointer", i32 2}
+!7 = !{!"clang"}
+!8 = distinct !DISubprogram(name: "square", linkageName: "_Z6squarei", scope: 
!1, file: !1, line: 3, type: !9, scopeLine: 3, flags: DIFlagPrototyped, 
spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
+!9 = !DISubroutineType(types: !10)
+!10 = !{!11, !11}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !{}
+!13 = !DILocalVariable(name: "num", arg: 1, scope: !8, file: !1, line: 3, 
type: !11)
+!14 = !DILocation(line: 3, column: 16, scope: !8)
+!15 = !DILocalVariable(name: "num1", scope: !8, file: !1, line: 4, type: !11)
+!16 = !DILocation(line: 4, column: 7, scope: !8)
+!17 = !DILocation(line: 4, column: 14, scope: !8)
+!18 = !DILocation(line: 5, column: 10, scope: !8)
+!19 = !DILocation(line: 5, column: 17, scope: !8)
+!20 = !DILocation(line: 5, column: 15, scope: !8)
+!21 = !DILocation(line: 5, column: 3, scope: !8)
+!22 = distinct !DISubprogram(name: "boo", linkageName: "_Z3boov", scope: !1, 
file: !1, line: 8, type: !23, scopeLine: 8, flags: DIFlagPrototyped, spFlags: 
DISPFlagDefinition, unit: !0)
+!23 = !DISubroutineType(types: !24)
+!24 = !{!11}
+!25 = !DILocation(line: 9, column: 3, scope: !22)
+!26 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 12, 
type: !23, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, 
unit: !0, retainedNodes: !12)
+!27 = !DILocalVariable(name: "a", scope: !26, file: !1, line: 13, type: !11)
+!28 = !DILocation(line: 13, column: 7, scope: !26)
+!29 = !DILocalVariable(name: "squared", scope: !26, file: !1, line: 14, type: 
!11)
+!30 = !DILocation(line: 14, column: 7, scope: !26)
+!31 = !DILocation(line: 14, column: 24, scope: !26)
+!32 = !DILocation(line: 14, column: 17, scope: !26)
+!33 = !DILocation(line: 15, column: 10, scope: !26)
+!34 = !DILocation(line: 15, column: 3, scope: !26)

``````````

</details>


https://github.com/llvm/llvm-project/pull/175727
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to