Author: Matt Arsenault
Date: 2026-09-15T12:19:11+02:00
New Revision: 263bbd476c9fce30acb9c70d5dae556dd994b08b

URL: 
https://github.com/llvm/llvm-project/commit/263bbd476c9fce30acb9c70d5dae556dd994b08b
DIFF: 
https://github.com/llvm/llvm-project/commit/263bbd476c9fce30acb9c70d5dae556dd994b08b.diff

LOG: clang/ARM: Derive -pg mcount name from the triple environment (#220822)

For a glibc/gnueabi ARM and AArch64 targets, GCC's -pg instrumentation
always calls __gnu_mcount_nc (with the caller pushing LR, per the "nc"
no-LR-clobber ABI). clang only produced this when -meabi=gnu was passed
explicitly; a separate gnueabi triple wrongly called plain "mcount".

On ARM, glibc's EABI profiling entry point is __gnu_mcount_nc
(sysdeps/arm/arm-mcount.S, exported since GLIBC_2.8). It does provide
plain mcount/_mcount, but only as a legacy APCS compat alias
(__mcount_arm_compat, gated on GCC_COMPAT(4,3)/SHLIB_COMPAT) 
that reads an APCS frame-pointer record rather than following the EABI push-LR 
convention. Calling it from EABI -pg code is thus an ABI mismatch, not the 
intended 
entry point.

Derive the GNU-vs-plain mcount name from the triple environment in
addition to the explicit -meabi=gnu, so a gnueabi target gets the correct
__gnu_mcount_nc call by default, matching GCC:

    push    {lr}
    bl      __gnu_mcount_nc

clang vs. gcc mismatch: https://godbolt.org/z/erEqfxs3s

Co-authored-by: Claude (Claude-Opus-4.8) <[email protected]>

Added: 
    

Modified: 
    clang/lib/Basic/Targets/AArch64.cpp
    clang/lib/Basic/Targets/ARM.cpp
    clang/test/Frontend/gnu-mcount.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index d531e26ade84a..0f36f87806e43 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -205,7 +205,10 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple 
&Triple,
     this->MCountName = "\01_mcount";
   else if (Triple.getOS() == llvm::Triple::UnknownOS)
     this->MCountName =
-        Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
+        (Opts.EABIVersion == llvm::EABI::GNU ||
+         (Opts.EABIVersion == llvm::EABI::Default && 
Triple.isGNUEnvironment()))
+            ? "\01_mcount"
+            : "mcount";
 }
 
 StringRef AArch64TargetInfo::getABI() const { return ABI; }

diff  --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 8d6e8d6990e80..2df1837aa0621 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -325,9 +325,11 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
 
   if (Triple.getOS() == llvm::Triple::Linux ||
       Triple.getOS() == llvm::Triple::UnknownOS)
-    this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
-                           ? "llvm.arm.gnu.eabi.mcount"
-                           : "\01mcount";
+    this->MCountName =
+        (Opts.EABIVersion == llvm::EABI::GNU ||
+         (Opts.EABIVersion == llvm::EABI::Default && 
Triple.isGNUEnvironment()))
+            ? "llvm.arm.gnu.eabi.mcount"
+            : "\01mcount";
 
   SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
 }

diff  --git a/clang/test/Frontend/gnu-mcount.c 
b/clang/test/Frontend/gnu-mcount.c
index 965c0010b549d..3930b34180730 100644
--- a/clang/test/Frontend/gnu-mcount.c
+++ b/clang/test/Frontend/gnu-mcount.c
@@ -2,11 +2,16 @@
 
 // RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-none-eabi 
-pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,UNSUPPORTED
 // RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-none-eabi 
-pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s 
--check-prefixes=CHECK,UNSUPPORTED
-// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-none-gnu 
-pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT
-// RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI
+// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-none-gnu 
-pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER
+// The mcount name is derived from the triple environment: gnueabi uses the GNU
+// name with or without -meabi gnu; musl uses the plain name.
+// RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-musleabi -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI
+// RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU
 // RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabi -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU
+// An explicit -meabi=5 overrides the gnueabi environment default and selects 
the plain mcount name.
+// RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabi -meabi 5 -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI
 // RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-linux -pg 
-S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER
-// RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI
+// RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s 
-check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU
 // RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-linux-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck 
%s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU
 // RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-freebsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s 
--check-prefixes=CHECK,UNDER_UNDER
 // RUN: %clang -Xclang -disable-llvm-passes -target 
armv7-unknown-freebsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | 
FileCheck %s --check-prefixes=CHECK,UNDER_UNDER


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

Reply via email to