[offload] Fix duplicate __llvm_write_custom_profile on Windows PGO builds (#207366)
MSVC/clang-cl lack __attribute__((weak)), so GlobalHandler.cpp provided
a strong stub for __llvm_write_custom_profile. When clang_rt.profile is
linked (e.g. instrumented/PGO builds) lld-link rejects the duplicate
strong symbol.
Replace the stub + CMake workaround with the /alternatename linker
pragma, which is the standard Windows weak-symbol equivalent used by
compiler-rt itself. The linker picks compiler-rt's strong definition
when present.
Fix the guard: use _WIN32 && !__MINGW32__ (not _MSC_VER) so the stub and
/alternatename pragma apply to plain clang-on-Windows too, while MinGW
(which supports __attribute__((weak)) natively) continues to use the
real weak declaration.
Also fix the stub signature from 8 to 10 parameters to match the header.
Assisted-by: Claude
diff --git a/offload/plugins-nextgen/common/src/GlobalHandler.cpp b/offload/plugins-nextgen/common/src/GlobalHandler.cpp
index 0298e23..1611a7a 100644
--- a/offload/plugins-nextgen/common/src/GlobalHandler.cpp
+++ b/offload/plugins-nextgen/common/src/GlobalHandler.cpp
@@ -30,17 +30,20 @@
using namespace error;
using namespace llvm::offload::debug;
-// Windows/MSVC doesn't support weak symbols properly, so provide a stub
-// implementation that will be used if compiler-rt is not linked.
-#ifdef _WIN32
-extern "C" int __llvm_write_custom_profile(
- const char *Target, const __llvm_profile_data *DataBegin,
- const __llvm_profile_data *DataEnd, const char *CountersBegin,
- const char *CountersEnd, const char *NamesBegin, const char *NamesEnd,
- const uint64_t *VersionOverride) {
- // Return error code indicating profiling is not available
+// Windows (MSVC/clang, but not MinGW) does not support __attribute__((weak)),
+// so provide a fallback stub via /alternatename. The linker picks compiler-rt's
+// strong definition when clang_rt.profile is linked; otherwise the stub is
+// used.
+#if defined(_WIN32) && !defined(__MINGW32__)
+extern "C" int __llvm_write_custom_profile_default(
+ const char *, const __llvm_profile_data *, const __llvm_profile_data *,
+ const char *, const char *, const char *, const char *, const char *,
+ const char *, const uint64_t *) {
return -1;
}
+#pragma comment( \
+ linker, \
+ "/alternatename:__llvm_write_custom_profile=__llvm_write_custom_profile_default")
#endif
Expected<std::unique_ptr<ObjectFile>>
@@ -275,9 +278,8 @@
}
Error GPUProfGlobals::write() const {
-#ifndef _WIN32
- // On Windows __llvm_write_custom_profile is a strong stub (see above), so its
- // address is never null and this check triggers -Wpointer-bool-conversion.
+#if !defined(_WIN32) || defined(__MINGW32__)
+ // On Windows (non-MinGW) the /alternatename stub above is never null.
if (!__llvm_write_custom_profile)
return Plugin::error(ErrorCode::INVALID_BINARY,
"could not find symbol __llvm_write_custom_profile. "