From 85b148bb43a2e4aefeb777b3e14e473dd587b16b Mon Sep 17 00:00:00 2001 From: Alex B Date: Thu, 10 Oct 2024 03:35:22 -0700 Subject: [PATCH] Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: --- lld/MachO/ICF.cpp | 11 +++++++ lld/test/MachO/icf-safe-thunks.ll | 49 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp index 2ff962b06e367..aedaecfdeb2c0 100644 --- a/lld/MachO/ICF.cpp +++ b/lld/MachO/ICF.cpp @@ -147,6 +147,17 @@ bool ICF::equalsConstant(const ConcatInputSection *ia, isecB = rb.referent.get(); } + // Typically, we should not encounter sections marked with `keepUnique` at + // this point as they would have resulted in different hashes and therefore + // no need for a full comparison. + // However, in `safe_thunks` mode, it's possible for two different + // relocations to reference identical `keepUnique` functions that will be + // distinguished later via thunks - so we need to handle this case + // explicitly. + if ((isecA != isecB) && ((isecA->keepUnique && isCodeSection(isecA)) || + (isecB->keepUnique && isCodeSection(isecB)))) + return false; + if (isecA->parent != isecB->parent) return false; // Sections with identical parents should be of the same kind. diff --git a/lld/test/MachO/icf-safe-thunks.ll b/lld/test/MachO/icf-safe-thunks.ll index 238e90f952e16..95e00a5b98385 100644 --- a/lld/test/MachO/icf-safe-thunks.ll +++ b/lld/test/MachO/icf-safe-thunks.ll @@ -22,6 +22,13 @@ ; CHECK-ARM64-NEXT: _func_3identical_v3_canmerge: ; CHECK-ARM64-NEXT: mov {{.*}}, #0x21 ; +; CHECK-ARM64: _func_call_thunked_1_nomerge: +; CHECK-ARM64-NEXT: stp x29 +; +; CHECK-ARM64: _func_call_thunked_2_nomerge: +; CHECK-ARM64-NEXT: _func_call_thunked_2_merge: +; CHECK-ARM64-NEXT: stp x29 +; ; CHECK-ARM64: _call_all_funcs: ; CHECK-ARM64-NEXT: stp x29 ; @@ -43,6 +50,9 @@ ; CHECK-ARM64-MAP-NEXT: 0x00000010 [ 2] _func_3identical_v1_canmerge ; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_3identical_v2_canmerge ; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_3identical_v3_canmerge +; CHECK-ARM64-MAP-NEXT: 0x00000020 [ 2] _func_call_thunked_1_nomerge +; CHECK-ARM64-MAP-NEXT: 0x00000020 [ 2] _func_call_thunked_2_nomerge +; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_call_thunked_2_merge ; CHECK-ARM64-MAP-NEXT: 0x00000034 [ 2] _call_all_funcs ; CHECK-ARM64-MAP-NEXT: 0x00000050 [ 2] _take_func_addr ; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_2identical_v2 @@ -125,6 +135,30 @@ entry: ret void } +; Function Attrs: mustprogress nofree noinline norecurse nounwind ssp memory(readwrite, argmem: none) uwtable(sync) +define void @func_call_thunked_1_nomerge() local_unnamed_addr #0 { +entry: + tail call void @func_2identical_v1() + store volatile i8 77, 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_call_thunked_2_nomerge() local_unnamed_addr #0 { +entry: + tail call void @func_2identical_v2() + store volatile i8 77, 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_call_thunked_2_merge() local_unnamed_addr #0 { +entry: + tail call void @func_2identical_v2() + store volatile i8 77, 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 { entry: @@ -227,6 +261,21 @@ attributes #1 = { mustprogress nofree noinline norecurse nounwind ssp uwtable(sy ; g_val = 33; ; } ; +; ATTR void func_call_thunked_1_nomerge() { +; func_2identical_v1(); +; g_val = 77; +; } +; +; ATTR void func_call_thunked_2_nomerge() { +; func_2identical_v2(); +; g_val = 77; +; } +; +; ATTR void func_call_thunked_2_merge() { +; func_2identical_v2(); +; g_val = 77; +; } +; ; ATTR void call_all_funcs() { ; func_unique_1(); ; func_unique_2_canmerge();