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
