diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index 78e1edb54768f..2200f07e70acc 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -41,9 +41,20 @@ #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. */ +/* 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. + * 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 @@ -1202,10 +1213,16 @@ 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. */ + /* 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) 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())