https://github.com/nikic created 
https://github.com/llvm/llvm-project/pull/230064

MergeFunctions::mergeTwoFunctions may turn identical functions into a private 
unnamed function, which trips `assert(F.hasName())`. Without assertions, all 
unnamed functions share an empty-name IR comdat (which yields no ELF section 
group per MCContext::getELFSection).

Fix #228820: Just drop comdat for unnamed functions. SanitizerCoverage then 
retains the metadata sections via `llvm.used`. It's acceptable to have redundat 
metadata sections with discarded associated text sections.

(cherry picked from commit 09b7f9faf6170f6deb7c185cc6219d5741edcba8)

-----

Manual cherry-pick to resolve conflict with noipa changes. I've dropped the 
comment-only changes from SanitizerCoverage as part of that.

>From 14dd1560b3e4107bed7719a637bd325e02c65549 Mon Sep 17 00:00:00 2001
From: Fangrui Song <[email protected]>
Date: Mon, 5 Oct 2026 18:58:35 -0700
Subject: [PATCH] [SanitizerCoverage] Don't create comdat for unnamed functions
 (#228959)

MergeFunctions::mergeTwoFunctions may turn identical functions into a
private unnamed function, which trips `assert(F.hasName())`. Without
assertions, all unnamed functions share an empty-name IR comdat (which
yields no ELF section group per MCContext::getELFSection).

Fix #228820: Just drop comdat for unnamed functions. SanitizerCoverage
then retains the metadata sections via `llvm.used`. It's acceptable to
have redundat metadata sections with discarded associated text sections.

(cherry picked from commit 09b7f9faf6170f6deb7c185cc6219d5741edcba8)
---
 llvm/lib/Transforms/Utils/Instrumentation.cpp |  5 +++-
 .../SanitizerCoverage/interposable-symbol.ll  | 25 ++++++++++++++-----
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/Instrumentation.cpp 
b/llvm/lib/Transforms/Utils/Instrumentation.cpp
index 3e43b85a11a3c..5f71703725ba1 100644
--- a/llvm/lib/Transforms/Utils/Instrumentation.cpp
+++ b/llvm/lib/Transforms/Utils/Instrumentation.cpp
@@ -96,7 +96,10 @@ GlobalVariable *llvm::createPrivateGlobalForString(Module 
&M, StringRef Str,
 Comdat *llvm::getOrCreateFunctionComdat(Function &F, Triple &T) {
   if (auto Comdat = F.getComdat())
     return Comdat;
-  assert(F.hasName());
+  // Unnamed functions would share a single empty-name comdat, which has little
+  // linker garbage collection benefit.
+  if (!F.hasName())
+    return nullptr;
   Module *M = F.getParent();
 
   // Make a new comdat for the function. Use the "no duplicates" selection kind
diff --git a/llvm/test/Instrumentation/SanitizerCoverage/interposable-symbol.ll 
b/llvm/test/Instrumentation/SanitizerCoverage/interposable-symbol.ll
index e8b23096ff33a..5143dfd0a54ae 100644
--- a/llvm/test/Instrumentation/SanitizerCoverage/interposable-symbol.ll
+++ b/llvm/test/Instrumentation/SanitizerCoverage/interposable-symbol.ll
@@ -6,6 +6,8 @@ $WeakComdat = comdat any
 
 define void @Vanilla() {
 entry:
+  call i32 @0()
+  call i32 @1()
   ret void
 }
 
@@ -36,17 +38,28 @@ entry:
   ret void
 }
 
+define private i32 @0() {
+  ret i32 0
+}
+
+define i32 @1() {
+  ret i32 1
+}
 
 ; CHECK:      $Vanilla = comdat nodeduplicate
 ; ELF:        $LinkOnceOdr = comdat nodeduplicate
 ; COFF:       $LinkOnceOdr = comdat any
 ; CHECK:      $WeakComdat = comdat any
-; CHECK:      @__sancov_gen_ = private global [1 x i32] zeroinitializer, 
section {{.*}}, comdat($Vanilla), align 4{{$}}
-; CHECK-NEXT: @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, 
section {{.*}}, align 4{{$}}
-; CHECK-NEXT: @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, 
section {{.*}}, align 4{{$}}
-; CHECK-NEXT: @__sancov_gen_.3 = private global [1 x i32] zeroinitializer, 
section {{.*}}, comdat($LinkOnceOdr), align 4{{$}}
-; CHECK-NEXT: @__sancov_gen_.4 = private global [1 x i32] zeroinitializer, 
section {{.*}}, comdat($WeakOdr), align 4{{$}}
-; CHECK-NEXT: @__sancov_gen_.5 = private global [1 x i32] zeroinitializer, 
section {{.*}}, comdat($WeakComdat), align 4{{$}}
+; CHECK:      @__sancov_gen_ = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", comdat($Vanilla), align 4{{$}}
+; ELF-NEXT:   @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", comdat($LinkOnce), align 4{{$}}
+; ELF-NEXT:   @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", comdat($Weak), align 4{{$}}
+; COFF-NEXT:  @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", align 4{{$}}
+; COFF-NEXT:  @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", align 4{{$}}
+; CHECK-NEXT: @__sancov_gen_.3 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", comdat($LinkOnceOdr), align 4{{$}}
+; CHECK-NEXT: @__sancov_gen_.4 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", comdat($WeakOdr), align 4{{$}}
+; CHECK-NEXT: @__sancov_gen_.5 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", comdat($WeakComdat), align 4{{$}}
+; CHECK-NEXT: @__sancov_gen_.6 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", align 4{{$}}
+; CHECK-NEXT: @__sancov_gen_.7 = private global [1 x i32] zeroinitializer, 
section "{{[^"]*}}", align 4{{$}}
 
 ; CHECK: define void @Vanilla() comdat {
 ; ELF:   define linkonce void @LinkOnce() comdat {

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to