[lld] [lld-macho] Fix invalid DWARF with --icf=safe_thunks (PR #111097)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 4 15:49:36 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/3] [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/3] 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
>From 955d1ccfa8a279a581e1db84406e45e2b6adccfc Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Fri, 4 Oct 2024 15:49:23 -0700
Subject: [PATCH 3/3] Address Feedback nr.2
---
lld/test/MachO/icf-safe-thunks-dwarf.ll | 122 +++++++++++++
lld/test/MachO/icf-safe-thunks.ll | 233 +++++++++---------------
2 files changed, 206 insertions(+), 149 deletions(-)
create mode 100644 lld/test/MachO/icf-safe-thunks-dwarf.ll
diff --git a/lld/test/MachO/icf-safe-thunks-dwarf.ll b/lld/test/MachO/icf-safe-thunks-dwarf.ll
new file mode 100644
index 00000000000000..060f399e414f4d
--- /dev/null
+++ b/lld/test/MachO/icf-safe-thunks-dwarf.ll
@@ -0,0 +1,122 @@
+; REQUIRES: aarch64
+
+;;; Build the
+; RUN: rm -rf %t; mkdir %t
+; RUN: llc -filetype=obj %s -O3 -o %t/icf-obj-safe-thunks-dwarf.o -enable-machine-outliner=never -mtriple arm64-apple-macos -addrsig
+; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks -dylib -o %t/icf-safe-dwarf.dylib %t/icf-obj-safe-thunks-dwarf.o
+
+;;; Check that we generate valid dSYM
+; RUN: dsymutil %t/icf-safe-dwarf.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 function thunks
+; RUN: dsymutil -s %t/icf-safe-dwarf.dylib | FileCheck %s --check-prefix=VERIFY-STABS
+; VERIFY-STABS-NOT: N_FUN{{.*}}_func_B
+; VERIFY-STABS-NOT: N_FUN{{.*}}_func_C
+
+;;; Check that we do generate STABS entries (N_FUN) for non-ICF'ed functions
+; VERIFY-STABS: N_FUN{{.*}}_func_A
+; VERIFY-STABS: N_FUN{{.*}}_take_func_addr
+
+
+; ModuleID = 'icf-safe-thunks-dwarf.cpp'
+source_filename = "icf-safe-thunks-dwarf.cpp"
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "arm64-apple-macosx11.0.0"
+
+; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
+define i32 @func_A() #0 !dbg !13 {
+entry:
+ ret i32 1, !dbg !17
+}
+
+; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
+define i32 @func_B() #0 !dbg !18 {
+entry:
+ ret i32 1, !dbg !19
+}
+
+; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
+define i32 @func_C() #0 !dbg !20 {
+entry:
+ ret i32 1, !dbg !21
+}
+
+; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
+define i64 @take_func_addr() #0 !dbg !22 {
+entry:
+ %val = alloca i64, align 8
+ store i64 0, ptr %val, align 8
+ %0 = load i64, ptr %val, align 8
+ %add = add i64 %0, ptrtoint (ptr @func_A to i64)
+ store i64 %add, ptr %val, align 8
+ %1 = load i64, ptr %val, align 8
+ %add1 = add i64 %1, ptrtoint (ptr @func_B to i64)
+ store i64 %add1, ptr %val, align 8
+ %2 = load i64, ptr %val, align 8
+ %add2 = add i64 %2, ptrtoint (ptr @func_C to i64)
+ store i64 %add2, ptr %val, align 8
+ %3 = load i64, ptr %val, align 8
+ ret i64 %3
+}
+
+attributes #0 = { mustprogress noinline nounwind optnone 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 = !{!0}
+!llvm.module.flags = !{!6, !7, !8, !9, !10, !11}
+!llvm.ident = !{!12}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0git (https://github.com/alx32/llvm-project.git b3fef1e6661efead54f05b2772b0de2ab580d756)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!1 = !DIFile(filename: "icf-safe-thunks-dwarf.cpp", directory: "/home/alexborcan/llvm_public")
+!6 = !{i32 7, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = !{i32 1, !"wchar_size", i32 4}
+!9 = !{i32 8, !"PIC Level", i32 2}
+!10 = !{i32 7, !"uwtable", i32 1}
+!11 = !{i32 7, !"frame-pointer", i32 1}
+!12 = !{!"clang version 20.0.0git (https://github.com/alx32/llvm-project.git b3fef1e6661efead54f05b2772b0de2ab580d756)"}
+!13 = distinct !DISubprogram(name: "func_A", scope: !1, file: !1, line: 4, type: !14, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!14 = !DISubroutineType(types: !15)
+!15 = !{!16}
+!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!17 = !DILocation(line: 4, column: 21, scope: !13)
+!18 = distinct !DISubprogram(name: "func_B", scope: !1, file: !1, line: 5, type: !14, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!19 = !DILocation(line: 5, column: 21, scope: !18)
+!20 = distinct !DISubprogram(name: "func_C", scope: !1, file: !1, line: 6, type: !14, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!21 = !DILocation(line: 6, column: 21, scope: !20)
+!22 = distinct !DISubprogram(name: "take_func_addr", scope: !1, file: !1, line: 8, type: !23, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!23 = !DISubroutineType(types: !24)
+!24 = !{!3}
+!3 = !DIDerivedType(tag: DW_TAG_typedef, name: "ULL", file: !1, line: 2, baseType: !4)
+!4 = !DIBasicType(name: "unsigned long long", size: 64, encoding: DW_ATE_unsigned)
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;; Generate the above LLVM IR with the below script ;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; #!/bin/bash
+; set -ex
+; TOOLCHAIN_BIN="llvm-project/build/Debug/bin"
+;
+; # Create icf-safe-thunks-dwarf.cpp file
+; cat > icf-safe-thunks-dwarf.cpp <<EOF
+; #define ATTR __attribute__((noinline)) extern "C"
+; typedef unsigned long long ULL;
+;
+; ATTR int func_A() { return 1; }
+; ATTR int func_B() { return 1; }
+; ATTR int func_C() { return 1; }
+;
+; ATTR ULL take_func_addr() {
+; ULL val = 0;
+; val += (ULL)(void*)func_A;
+; val += (ULL)(void*)func_B;
+; val += (ULL)(void*)func_C;
+; return val;
+; }
+; EOF
+;
+; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm -g \
+; icf-safe-thunks-dwarf.cpp
diff --git a/lld/test/MachO/icf-safe-thunks.ll b/lld/test/MachO/icf-safe-thunks.ll
index bc014d307d5a24..238e90f952e160 100644
--- a/lld/test/MachO/icf-safe-thunks.ll
+++ b/lld/test/MachO/icf-safe-thunks.ll
@@ -6,19 +6,6 @@
; 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
@@ -62,179 +49,127 @@
; 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, !dbg !0
- at g_ptr = global ptr null, align 8, !dbg !7
+
+ at g_val = global i8 0, align 1
+ at g_ptr = global ptr null, align 8
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_unique_1() #0 !dbg !19 {
+define void @func_unique_1() #0 {
entry:
- store volatile i8 1, ptr @g_val, align 1, !dbg !22, !tbaa !23
- ret void, !dbg !26
+ store volatile i8 1, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_unique_2_canmerge() local_unnamed_addr #0 !dbg !27 {
+define void @func_unique_2_canmerge() local_unnamed_addr #0 {
entry:
- store volatile i8 2, ptr @g_val, align 1, !dbg !28, !tbaa !23
- ret void, !dbg !29
+ store volatile i8 2, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_2identical_v1() #0 !dbg !30 {
+define void @func_2identical_v1() #0 {
entry:
- store volatile i8 2, ptr @g_val, align 1, !dbg !31, !tbaa !23
- ret void, !dbg !32
+ store volatile i8 2, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_2identical_v2() #0 !dbg !33 {
+define void @func_2identical_v2() #0 {
entry:
- store volatile i8 2, ptr @g_val, align 1, !dbg !34, !tbaa !23
- ret void, !dbg !35
+ store volatile i8 2, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v1() #0 !dbg !36 {
+define void @func_3identical_v1() #0 {
entry:
- store volatile i8 3, ptr @g_val, align 1, !dbg !37, !tbaa !23
- ret void, !dbg !38
+ store volatile i8 3, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v2() #0 !dbg !39 {
+define void @func_3identical_v2() #0 {
entry:
- store volatile i8 3, ptr @g_val, align 1, !dbg !40, !tbaa !23
- ret void, !dbg !41
+ store volatile i8 3, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v3() #0 !dbg !42 {
+define void @func_3identical_v3() #0 {
entry:
- store volatile i8 3, ptr @g_val, align 1, !dbg !43, !tbaa !23
- ret void, !dbg !44
+ store volatile i8 3, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v1_canmerge() local_unnamed_addr #0 !dbg !45 {
+define void @func_3identical_v1_canmerge() local_unnamed_addr #0 {
entry:
- store volatile i8 33, ptr @g_val, align 1, !dbg !46, !tbaa !23
- ret void, !dbg !47
+ store volatile i8 33, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v2_canmerge() local_unnamed_addr #0 !dbg !48 {
+define void @func_3identical_v2_canmerge() local_unnamed_addr #0 {
entry:
- store volatile i8 33, ptr @g_val, align 1, !dbg !49, !tbaa !23
- ret void, !dbg !50
+ store volatile i8 33, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @func_3identical_v3_canmerge() local_unnamed_addr #0 !dbg !51 {
+define void @func_3identical_v3_canmerge() local_unnamed_addr #0 {
entry:
- store volatile i8 33, ptr @g_val, align 1, !dbg !52, !tbaa !23
- ret void, !dbg !53
+ store volatile i8 33, ptr @g_val, align 1, !tbaa !5
+ ret void
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp uwtable(sync)
-define void @call_all_funcs() local_unnamed_addr #1 !dbg !54 {
+define void @call_all_funcs() local_unnamed_addr #1 {
entry:
- 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
+ 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
}
+
; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync)
-define void @take_func_addr() local_unnamed_addr #0 !dbg !66 {
+define void @take_func_addr() local_unnamed_addr #0 {
entry:
- 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
+ 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
}
-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)
+
+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}
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; Generate the above LLVM IR with the below script ;;;;;;;;;;;;;;;
@@ -315,5 +250,5 @@ attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sy
; }
; EOF
;
-; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm -g \
+; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm \
; icf-safe-thunks.cpp -O3 -o icf-safe-thunks.ll
More information about the llvm-commits
mailing list