From 901ddcb65da2056ffd314fe6b816593237c0d04c Mon Sep 17 00:00:00 2001 From: "Yaxun (Sam) Liu" Date: Wed, 27 May 2026 21:44:20 -0400 Subject: [PATCH 1/2] [PGO][HIP] Stop pulling ROCm.o into every PGO host link PR #177665 added an unconditional extern reference to __llvm_profile_hip_collect_device_data from InstrProfilingFile.c, which forces InstrProfilingPlatformROCm.o (and its sanitizer_common / interception dependencies) out of libclang_rt.profile.a in every PGO binary. That breaks bots without -lpthread and races dlsym/PLT state in non-HIP programs via the interceptor constructor. Fix: - Declare the hook COMPILER_RT_WEAK and gate the call on its address. No COMPILER_RT_VISIBILITY: a hidden weak-undef function would be non-preemptible and the address test would fold to true. - Gate installHipModuleInterceptors on dlsym(hipModuleLoad) so the constructor is a no-op if ROCm.o is still pulled in. Fixes: https://lab.llvm.org/buildbot/#/builders/66/builds/31311 https://lab.llvm.org/buildbot/#/builders/174/builds/36180 --- compiler-rt/lib/profile/InstrProfilingFile.c | 20 ++++++++++++------- .../profile/InstrProfilingPlatformROCm.cpp | 7 +++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index 78e1edb54768f..8d068c103574f 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -41,9 +41,14 @@ #include "InstrProfilingPort.h" #include "InstrProfilingUtil.h" -/* HIP / offload collection hook implemented in InstrProfilingPlatformROCm.c. - * It is a no-op when no offload profile data was registered. */ -extern int __llvm_profile_hip_collect_device_data(void); +/* Weak so non-HIP programs do not force InstrProfilingPlatformROCm.o (and its + * transitive sanitizer_common / interception dependencies) into the host link + * out of libclang_rt.profile.a. HIP programs emit strong references to other + * ROCm-runtime symbols (e.g. __llvm_profile_offload_register_shadow_variable) + * that pull in the strong definition. + * No COMPILER_RT_VISIBILITY: a hidden weak-undefined symbol is non-preemptible + * and the address test at the call site would fold to true. */ +COMPILER_RT_WEAK int __llvm_profile_hip_collect_device_data(void); /* From where is profile name specified. * The order the enumerators define their @@ -1202,10 +1207,11 @@ int __llvm_profile_write_file(void) { if (rc) PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno)); - /* No-op when no HIP shadow variables or dynamic modules are registered, - * or when the HIP runtime is not loaded. Warning on failure is handled - * inside the callee so non-HIP programs do not see spurious noise. */ - (void)__llvm_profile_hip_collect_device_data(); + /* Weak: only invoked when InstrProfilingPlatformROCm.o is in the link, + * which happens when the program references other ROCm-runtime symbols + * (HIP-with-PGO). Warning on failure is handled inside the callee. */ + if (__llvm_profile_hip_collect_device_data) + (void)__llvm_profile_hip_collect_device_data(); // Restore SIGKILL. if (PDeathSig == 1) diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp b/compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp index 9e234da5b5cc4..ee00c572e3a42 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp +++ b/compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp @@ -24,6 +24,7 @@ extern "C" { #define WIN32_LEAN_AND_MEAN #include #else +#include #include #endif @@ -878,6 +879,12 @@ INTERCEPTOR(int, hipModuleUnload, void *module) { } __attribute__((constructor)) static void installHipModuleInterceptors() { + /* Skip when the HIP runtime is not loaded. INTERCEPT_FUNCTION uses the + * sanitizer interception framework, which can perturb dlsym/PLT state for + * the rest of the process even when the target symbol is absent; non-HIP + * programs linked with libclang_rt.profile.a must see zero side effects. */ + if (!dlsym(RTLD_DEFAULT, "hipModuleLoad")) + return; if (!INTERCEPT_FUNCTION(hipModuleLoad)) return; if (isVerboseMode()) From fa045b345cd64d1092c670d241311987559ec380 Mon Sep 17 00:00:00 2001 From: "Yaxun (Sam) Liu" Date: Wed, 27 May 2026 22:24:26 -0400 Subject: [PATCH 2/2] [PGO][HIP] Windows: keep strong extern (selectany is data-only) --- compiler-rt/lib/profile/InstrProfilingFile.c | 23 +++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index 8d068c103574f..2200f07e70acc 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -47,8 +47,14 @@ * ROCm-runtime symbols (e.g. __llvm_profile_offload_register_shadow_variable) * that pull in the strong definition. * No COMPILER_RT_VISIBILITY: a hidden weak-undefined symbol is non-preemptible - * and the address test at the call site would fold to true. */ -COMPILER_RT_WEAK int __llvm_profile_hip_collect_device_data(void); + * and the address test at the call site would fold to true. + * Windows: __declspec(selectany) is data-only, and the ROCm interceptor path + * is not used there, so keep the original strong extern. */ +#if defined(_WIN32) +extern int __llvm_profile_hip_collect_device_data(void); +#else +__attribute__((weak)) int __llvm_profile_hip_collect_device_data(void); +#endif /* From where is profile name specified. * The order the enumerators define their @@ -1207,11 +1213,16 @@ int __llvm_profile_write_file(void) { if (rc) PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno)); - /* Weak: only invoked when InstrProfilingPlatformROCm.o is in the link, - * which happens when the program references other ROCm-runtime symbols - * (HIP-with-PGO). Warning on failure is handled inside the callee. */ - if (__llvm_profile_hip_collect_device_data) + /* On non-Windows the declaration is weak: only invoked when + * InstrProfilingPlatformROCm.o is in the link, which happens when the program + * references other ROCm-runtime symbols (HIP-with-PGO). Warning on failure is + * handled inside the callee. */ +#if defined(_WIN32) + (void)__llvm_profile_hip_collect_device_data(); +#else + if (&__llvm_profile_hip_collect_device_data) (void)__llvm_profile_hip_collect_device_data(); +#endif // Restore SIGKILL. if (PDeathSig == 1)