[lld] [lld-macho] Fix invalid DWARF with --icf=safe_thunks (PR #111097)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 4 09:01:08 PDT 2024


https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/111097

>From f593abeecdd9b5d1d39dcca3f236a16eaa5bd1f4 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Thu, 3 Oct 2024 18:10:12 -0700
Subject: [PATCH 1/2] [lld-macho] Fix invalid DWARF with --icf=safe_thunks

---
 lld/MachO/SyntheticSections.cpp   |  11 ++
 lld/test/MachO/icf-safe-thunks.ll | 233 +++++++++++++++++++-----------
 2 files changed, 160 insertions(+), 84 deletions(-)

diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 7b0078856c5e22..319e7ec52c1ed4 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1229,6 +1229,17 @@ void SymtabSection::emitStabs() {
       if (defined->isAbsolute())
         continue;
 
+      // Never generate a STABS entry for a symbol that has been ICF'ed using a
+      // thunk - just like we do for fully ICF'ed functions. Otherwise we end up
+      // generating invalid DWARF as dsymutil will think the entire function
+      // body is at that location, when in actuality only the thunk will be
+      // present. This will end up causing overlapping DWARF entries.
+      // TODO: Find an implementation that works in combination with
+      // `--keep-icf-stabs`.
+      if (defined->identicalCodeFoldingKind == Symbol::ICFFoldKind::Thunk) {
+        continue;
+      }
+
       // Constant-folded symbols go in the executable's symbol table, but don't
       // get a stabs entry unless --keep-icf-stabs flag is specified
       if (!config->keepICFStabs &&
diff --git a/lld/test/MachO/icf-safe-thunks.ll b/lld/test/MachO/icf-safe-thunks.ll
index 238e90f952e160..bc014d307d5a24 100644
--- a/lld/test/MachO/icf-safe-thunks.ll
+++ b/lld/test/MachO/icf-safe-thunks.ll
@@ -6,6 +6,19 @@
 ; RUN: llvm-objdump %t/icf-safe.dylib -d --macho | FileCheck %s --check-prefixes=CHECK-ARM64
 ; RUN: cat %t/icf-safe.map | FileCheck %s --check-prefixes=CHECK-ARM64-MAP
 
+;;; Check that we generate valid dSYM and that stabs entries are not created for the ICF'ed functions (thunks)
+; RUN: dsymutil %t/icf-safe.dylib -o %t/icf-safe.dSYM
+; RUN: llvm-dwarfdump --verify %t/icf-safe.dSYM | FileCheck %s --check-prefix=VERIFY-DSYM
+; VERIFY-DSYM: No errors.
+
+;;; Check that we don't generate STABS entries (N_FUN) for ICF'ed functions
+; RUN: dsymutil -s %t/icf-safe.dylib | FileCheck %s --check-prefix=VERIFY-STABS
+; VERIFY-STABS-NOT:  N_FUN {{.*}} _func_2identical_v2
+; VERIFY-STABS-NOT:  N_FUN {{.*}} _func_3identical_v2
+; VERIFY-STABS-NOT:  N_FUN {{.*}} _func_3identical_v3
+; VERIFY-STABS-NOT:  N_FUN {{.*}} _func_3identical_v2_canmerge
+; VERIFY-STABS-NOT:  N_FUN {{.*}} _func_3identical_v3_canmerge
+
 ; CHECK-ARM64:        (__TEXT,__text) section
 ; CHECK-ARM64-NEXT:   _func_unique_1:
 ; CHECK-ARM64-NEXT:        mov {{.*}}, #0x1
@@ -49,127 +62,179 @@
 ; CHECK-ARM64-MAP-NEXT: 0x00000004 [  2] _func_3identical_v2
 ; CHECK-ARM64-MAP-NEXT: 0x00000004 [  2] _func_3identical_v3
 
+; ModuleID = 'icf-safe-thunks.cpp'
+source_filename = "icf-safe-thunks.cpp"
 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
 target triple = "arm64-apple-macosx11.0.0"
-
- at g_val = global i8 0, align 1
- at g_ptr = global ptr null, align 8
-
+ at g_val = global i8 0, align 1, !dbg !0
+ at g_ptr = global ptr null, align 8, !dbg !7
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_unique_1() #0 {
+define void @func_unique_1() #0 !dbg !19 {
 entry:
-  store volatile i8 1, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 1, ptr @g_val, align 1, !dbg !22, !tbaa !23
+  ret void, !dbg !26
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_unique_2_canmerge() local_unnamed_addr #0 {
+define void @func_unique_2_canmerge() local_unnamed_addr #0 !dbg !27 {
 entry:
-  store volatile i8 2, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 2, ptr @g_val, align 1, !dbg !28, !tbaa !23
+  ret void, !dbg !29
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_2identical_v1() #0 {
+define void @func_2identical_v1() #0 !dbg !30 {
 entry:
-  store volatile i8 2, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 2, ptr @g_val, align 1, !dbg !31, !tbaa !23
+  ret void, !dbg !32
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_2identical_v2() #0 {
+define void @func_2identical_v2() #0 !dbg !33 {
 entry:
-  store volatile i8 2, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 2, ptr @g_val, align 1, !dbg !34, !tbaa !23
+  ret void, !dbg !35
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v1() #0 {
+define void @func_3identical_v1() #0 !dbg !36 {
 entry:
-  store volatile i8 3, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 3, ptr @g_val, align 1, !dbg !37, !tbaa !23
+  ret void, !dbg !38
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v2() #0 {
+define void @func_3identical_v2() #0 !dbg !39 {
 entry:
-  store volatile i8 3, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 3, ptr @g_val, align 1, !dbg !40, !tbaa !23
+  ret void, !dbg !41
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v3() #0 {
+define void @func_3identical_v3() #0 !dbg !42 {
 entry:
-  store volatile i8 3, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 3, ptr @g_val, align 1, !dbg !43, !tbaa !23
+  ret void, !dbg !44
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v1_canmerge() local_unnamed_addr #0 {
+define void @func_3identical_v1_canmerge() local_unnamed_addr #0 !dbg !45 {
 entry:
-  store volatile i8 33, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 33, ptr @g_val, align 1, !dbg !46, !tbaa !23
+  ret void, !dbg !47
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v2_canmerge() local_unnamed_addr #0 {
+define void @func_3identical_v2_canmerge() local_unnamed_addr #0 !dbg !48 {
 entry:
-  store volatile i8 33, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 33, ptr @g_val, align 1, !dbg !49, !tbaa !23
+  ret void, !dbg !50
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v3_canmerge() local_unnamed_addr #0 {
+define void @func_3identical_v3_canmerge() local_unnamed_addr #0 !dbg !51 {
 entry:
-  store volatile i8 33, ptr @g_val, align 1, !tbaa !5
-  ret void
+  store volatile i8 33, ptr @g_val, align 1, !dbg !52, !tbaa !23
+  ret void, !dbg !53
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync)
-define void @call_all_funcs() local_unnamed_addr #1 {
+define void @call_all_funcs() local_unnamed_addr #1 !dbg !54 {
 entry:
-  tail call void @func_unique_1()
-  tail call void @func_unique_2_canmerge()
-  tail call void @func_2identical_v1()
-  tail call void @func_2identical_v2()
-  tail call void @func_3identical_v1()
-  tail call void @func_3identical_v2()
-  tail call void @func_3identical_v3()
-  tail call void @func_3identical_v1_canmerge()
-  tail call void @func_3identical_v2_canmerge()
-  tail call void @func_3identical_v3_canmerge()
-  ret void
+  tail call void @func_unique_1(), !dbg !55
+  tail call void @func_unique_2_canmerge(), !dbg !56
+  tail call void @func_2identical_v1(), !dbg !57
+  tail call void @func_2identical_v2(), !dbg !58
+  tail call void @func_3identical_v1(), !dbg !59
+  tail call void @func_3identical_v2(), !dbg !60
+  tail call void @func_3identical_v3(), !dbg !61
+  tail call void @func_3identical_v1_canmerge(), !dbg !62
+  tail call void @func_3identical_v2_canmerge(), !dbg !63
+  tail call void @func_3identical_v3_canmerge(), !dbg !64
+  ret void, !dbg !65
 }
-
 ; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @take_func_addr() local_unnamed_addr #0 {
+define void @take_func_addr() local_unnamed_addr #0 !dbg !66 {
 entry:
-  store volatile ptr @func_unique_1, ptr @g_ptr, align 8, !tbaa !8
-  store volatile ptr @func_2identical_v1, ptr @g_ptr, align 8, !tbaa !8
-  store volatile ptr @func_2identical_v2, ptr @g_ptr, align 8, !tbaa !8
-  store volatile ptr @func_3identical_v1, ptr @g_ptr, align 8, !tbaa !8
-  store volatile ptr @func_3identical_v2, ptr @g_ptr, align 8, !tbaa !8
-  store volatile ptr @func_3identical_v3, ptr @g_ptr, align 8, !tbaa !8
-  ret void
+  store volatile ptr @func_unique_1, ptr @g_ptr, align 8, !dbg !67, !tbaa !68
+  store volatile ptr @func_2identical_v1, ptr @g_ptr, align 8, !dbg !70, !tbaa !68
+  store volatile ptr @func_2identical_v2, ptr @g_ptr, align 8, !dbg !71, !tbaa !68
+  store volatile ptr @func_3identical_v1, ptr @g_ptr, align 8, !dbg !72, !tbaa !68
+  store volatile ptr @func_3identical_v2, ptr @g_ptr, align 8, !dbg !73, !tbaa !68
+  store volatile ptr @func_3identical_v3, ptr @g_ptr, align 8, !dbg !74, !tbaa !68
+  ret void, !dbg !75
 }
-
-attributes #0 = { mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" }
-attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" }
-
-!llvm.module.flags = !{!0, !1, !2, !3}
-!llvm.ident = !{!4}
-
-!0 = !{i32 1, !"wchar_size", i32 4}
-!1 = !{i32 8, !"PIC Level", i32 2}
-!2 = !{i32 7, !"uwtable", i32 1}
-!3 = !{i32 7, !"frame-pointer", i32 1}
-!4 = !{!"clang"}
-!5 = !{!6, !6, i64 0}
-!6 = !{!"omnipotent char", !7, i64 0}
-!7 = !{!"Simple C++ TBAA"}
-!8 = !{!9, !9, i64 0}
-!9 = !{!"any pointer", !6, i64 0}
-
+attributes #0 = { mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" }
+attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,+zcm,+zcz" }
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!12, !13, !14, !15, !16, !17}
+!llvm.ident = !{!18}
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g_val", scope: !2, file: !3, line: 5, type: !10, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 20.0.0git (https://github.com/alx32/llvm-project.git 02d6aad5cc940f17904c1288dfabc3fd2d439279)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !6, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!3 = !DIFile(filename: "icf-safe-thunks.cpp", directory: "/tmp/safe_thunks")
+!4 = !{!5}
+!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
+!6 = !{!0, !7}
+!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
+!8 = distinct !DIGlobalVariable(name: "g_ptr", scope: !2, file: !3, line: 6, type: !9, isLocal: false, isDefinition: true)
+!9 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !5)
+!10 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !11)
+!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!12 = !{i32 7, !"Dwarf Version", i32 4}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"wchar_size", i32 4}
+!15 = !{i32 8, !"PIC Level", i32 2}
+!16 = !{i32 7, !"uwtable", i32 1}
+!17 = !{i32 7, !"frame-pointer", i32 1}
+!18 = !{!"clang version 20.0.0git (https://github.com/alx32/llvm-project.git 02d6aad5cc940f17904c1288dfabc3fd2d439279)"}
+!19 = distinct !DISubprogram(name: "func_unique_1", scope: !3, file: !3, line: 8, type: !20, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!20 = !DISubroutineType(types: !21)
+!21 = !{null}
+!22 = !DILocation(line: 9, column: 11, scope: !19)
+!23 = !{!24, !24, i64 0}
+!24 = !{!"omnipotent char", !25, i64 0}
+!25 = !{!"Simple C++ TBAA"}
+!26 = !DILocation(line: 10, column: 1, scope: !19)
+!27 = distinct !DISubprogram(name: "func_unique_2_canmerge", scope: !3, file: !3, line: 12, type: !20, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!28 = !DILocation(line: 13, column: 11, scope: !27)
+!29 = !DILocation(line: 14, column: 1, scope: !27)
+!30 = distinct !DISubprogram(name: "func_2identical_v1", scope: !3, file: !3, line: 16, type: !20, scopeLine: 16, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!31 = !DILocation(line: 17, column: 11, scope: !30)
+!32 = !DILocation(line: 18, column: 1, scope: !30)
+!33 = distinct !DISubprogram(name: "func_2identical_v2", scope: !3, file: !3, line: 20, type: !20, scopeLine: 20, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!34 = !DILocation(line: 21, column: 11, scope: !33)
+!35 = !DILocation(line: 22, column: 1, scope: !33)
+!36 = distinct !DISubprogram(name: "func_3identical_v1", scope: !3, file: !3, line: 24, type: !20, scopeLine: 24, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!37 = !DILocation(line: 25, column: 11, scope: !36)
+!38 = !DILocation(line: 26, column: 1, scope: !36)
+!39 = distinct !DISubprogram(name: "func_3identical_v2", scope: !3, file: !3, line: 28, type: !20, scopeLine: 28, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!40 = !DILocation(line: 29, column: 11, scope: !39)
+!41 = !DILocation(line: 30, column: 1, scope: !39)
+!42 = distinct !DISubprogram(name: "func_3identical_v3", scope: !3, file: !3, line: 32, type: !20, scopeLine: 32, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!43 = !DILocation(line: 33, column: 11, scope: !42)
+!44 = !DILocation(line: 34, column: 1, scope: !42)
+!45 = distinct !DISubprogram(name: "func_3identical_v1_canmerge", scope: !3, file: !3, line: 36, type: !20, scopeLine: 36, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!46 = !DILocation(line: 37, column: 11, scope: !45)
+!47 = !DILocation(line: 38, column: 1, scope: !45)
+!48 = distinct !DISubprogram(name: "func_3identical_v2_canmerge", scope: !3, file: !3, line: 40, type: !20, scopeLine: 40, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!49 = !DILocation(line: 41, column: 11, scope: !48)
+!50 = !DILocation(line: 42, column: 1, scope: !48)
+!51 = distinct !DISubprogram(name: "func_3identical_v3_canmerge", scope: !3, file: !3, line: 44, type: !20, scopeLine: 44, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!52 = !DILocation(line: 45, column: 11, scope: !51)
+!53 = !DILocation(line: 46, column: 1, scope: !51)
+!54 = distinct !DISubprogram(name: "call_all_funcs", scope: !3, file: !3, line: 48, type: !20, scopeLine: 48, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!55 = !DILocation(line: 49, column: 5, scope: !54)
+!56 = !DILocation(line: 50, column: 5, scope: !54)
+!57 = !DILocation(line: 51, column: 5, scope: !54)
+!58 = !DILocation(line: 52, column: 5, scope: !54)
+!59 = !DILocation(line: 53, column: 5, scope: !54)
+!60 = !DILocation(line: 54, column: 5, scope: !54)
+!61 = !DILocation(line: 55, column: 5, scope: !54)
+!62 = !DILocation(line: 56, column: 5, scope: !54)
+!63 = !DILocation(line: 57, column: 5, scope: !54)
+!64 = !DILocation(line: 58, column: 5, scope: !54)
+!65 = !DILocation(line: 59, column: 1, scope: !54)
+!66 = distinct !DISubprogram(name: "take_func_addr", scope: !3, file: !3, line: 61, type: !20, scopeLine: 61, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!67 = !DILocation(line: 62, column: 11, scope: !66)
+!68 = !{!69, !69, i64 0}
+!69 = !{!"any pointer", !24, i64 0}
+!70 = !DILocation(line: 63, column: 11, scope: !66)
+!71 = !DILocation(line: 64, column: 11, scope: !66)
+!72 = !DILocation(line: 65, column: 11, scope: !66)
+!73 = !DILocation(line: 66, column: 11, scope: !66)
+!74 = !DILocation(line: 67, column: 11, scope: !66)
+!75 = !DILocation(line: 68, column: 1, scope: !66)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;; Generate the above LLVM IR with the below script ;;;;;;;;;;;;;;;
@@ -250,5 +315,5 @@ attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sy
 ; }
 ; EOF
 ;
-; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm \
+; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm -g \
 ;                      icf-safe-thunks.cpp -O3 -o icf-safe-thunks.ll

>From b3fef1e6661efead54f05b2772b0de2ab580d756 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Fri, 4 Oct 2024 09:00:48 -0700
Subject: [PATCH 2/2] Address Feedback Nr.1

---
 lld/MachO/SyntheticSections.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 319e7ec52c1ed4..6e730bc4a75c0b 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1236,9 +1236,8 @@ void SymtabSection::emitStabs() {
       // present. This will end up causing overlapping DWARF entries.
       // TODO: Find an implementation that works in combination with
       // `--keep-icf-stabs`.
-      if (defined->identicalCodeFoldingKind == Symbol::ICFFoldKind::Thunk) {
+      if (defined->identicalCodeFoldingKind == Symbol::ICFFoldKind::Thunk)
         continue;
-      }
 
       // Constant-folded symbols go in the executable's symbol table, but don't
       // get a stabs entry unless --keep-icf-stabs flag is specified



More information about the llvm-commits mailing list