Skip to content

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

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

Merged
merged 5 commits into from
Oct 5, 2024

Conversation

alx32
Copy link
Contributor

@alx32 alx32 commented Oct 4, 2024

There is a bug in the current implementation of --icf=safe_thunks where a STABS entry is emitted for generated thunks. This is problematic as we end up generating invalid DWARF as dsymutil will think the entire function body is at the thunk location, when in actuality there will only be a single branch present. This will end up causing overlapping DWARF entries.

To fix this we never generate STABS entries for such thunks.
The existing --icf=safe_thunks test is updated to also generate debug info and we add a check that no corrupt DWARF is generated.

As a future TODO we need to make --keep-icf-stabs compatible with --icf=safe_thunks.

@alx32 alx32 requested review from ellishg and kyulee-com October 4, 2024 04:04
@alx32 alx32 marked this pull request as ready for review October 4, 2024 04:04
@llvmbot
Copy link
Member

llvmbot commented Oct 4, 2024

@llvm/pr-subscribers-lld-macho

@llvm/pr-subscribers-lld

Author: None (alx32)

Changes

There is a bug in the current implementation of --icf=safe_thunks where a STABS entry is emitted for generated thunks. This is problematic as we end up generating invalid DWARF as dsymutil will think the entire function body is at the thunk location, when in actuality there will only be a single branch present. This will end up causing overlapping DWARF entries.

To fix this we never generate STABS entries for such thunks.
The existing --icf=safe_thunks test is updated to also generate debug info and we add a check that no corrupt DWARF is generated.


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

2 Files Affected:

  • (modified) lld/MachO/SyntheticSections.cpp (+11)
  • (modified) lld/test/MachO/icf-safe-thunks.ll (+149-84)
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"
-
-@g_val = global i8 0, align 1
-@g_ptr = global ptr null, align 8
-
+@g_val = global i8 0, align 1, !dbg !0
+@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

@ellishg ellishg requested review from MaskRay and dwblaikie October 4, 2024 15:41
@alx32 alx32 merged commit 9e862ae into llvm:main Oct 5, 2024
9 checks passed
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.

5 participants