Skip to content

[PGO][AMDGPU] Add basic HIP offload PGO support - #177665

Merged
yxsamliu merged 20 commits into
llvm:mainfrom
yxsamliu:offload-pgo-main
May 27, 2026
Merged

[PGO][AMDGPU] Add basic HIP offload PGO support#177665
yxsamliu merged 20 commits into
llvm:mainfrom
yxsamliu:offload-pgo-main

Conversation

@yxsamliu

@yxsamliu yxsamliu commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Provide the minimum HIP/offload path for device profile collection and
merge on HIP before layering profile-format and uniformity-specific
changes separately.

This adds the ROCm collection runtime, hooks device collection into the
host write-file path, lowers AMDGPU instrumentation to
__llvm_profile_instrument_gpu with regular counters, and disables GPU
indirect-call value profiling.

@llvmbot llvmbot added compiler-rt backend:AMDGPU clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' llvm:codegen llvm:regalloc PGO Profile Guided Optimizations llvm:transforms llvm:binary-utilities labels Jan 23, 2026
@llvmbot

llvmbot commented Jan 23, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-compiler-rt-sanitizer
@llvm/pr-subscribers-libc
@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-offload
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-pgo
@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-llvm-regalloc
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-backend-amdgpu

Author: Yaxun (Sam) Liu (yxsamliu)

Changes

This patch adds device-side Profile Guided Optimization (PGO) support
for HIP/AMDGPU, enabling profile-guided compiler optimizations for GPU
kernels.

Key features:

  • Wave-aggregated counter increments to reduce atomic contention
  • Per-TU contiguous counter allocation to avoid linker reordering issues
  • Uniformity detection to identify wave-uniform vs divergent branches
  • Uniformity-aware spill placement to prevent PGO regressions on GPUs

The uniformity detection is critical because standard PGO can cause
severe performance regressions on GPUs. When PGO moves register spills
to "cold" paths, but those paths are entered divergently (different
threads take different paths), partial-wave memory accesses cause poor
coalescing and up to 3.7x slowdown. By detecting uniformity at profile
collection time and gating spill placement decisions, we achieve:

  • 12-14% speedup on uniform branches
  • No regression on divergent branches (gating prevents the issue)

Implementation spans:

  • LLVM instrumentation (InstrProfiling.cpp): AMDGPU-specific lowering,
    contiguous counter arrays, uniform counter instrumentation
  • Profile format (InstrProfData.inc): NumOffloadProfilingThreads field,
    UniformityBits in indexed profile (Version 14)
  • Profile reader/writer: Handle expanded counters, uniformity bits
  • compiler-rt (InstrProfilingPlatformROCm.c): Device profile collection
    via HIP APIs, .unifcnts file for uniform counters
  • Clang driver (HIPAMD.cpp): Profile filename rewriting for device
  • SpillPlacement.cpp: Frequency flattening for divergent blocks
  • llvm-profdata: Read .unifcnts, compute uniformity during merge

Tested with lit tests and end-to-end benchmarks on gfx1100.


Patch is 158.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/177665.diff

30 Files Affected:

  • (modified) clang/docs/UsersManual.rst (+55)
  • (modified) clang/lib/Driver/ToolChains/HIPAMD.cpp (+14)
  • (modified) compiler-rt/include/profile/InstrProfData.inc (+6-2)
  • (modified) compiler-rt/lib/profile/CMakeLists.txt (+1)
  • (modified) compiler-rt/lib/profile/InstrProfiling.h (+20)
  • (modified) compiler-rt/lib/profile/InstrProfilingFile.c (+2)
  • (modified) compiler-rt/lib/profile/InstrProfilingInternal.h (+7)
  • (added) compiler-rt/lib/profile/InstrProfilingPlatformROCm.c (+702)
  • (modified) llvm/docs/CommandGuide/llvm-profdata.rst (+11)
  • (modified) llvm/docs/InstrProfileFormat.rst (+73)
  • (modified) llvm/include/llvm/ProfileData/InstrProf.h (+46-5)
  • (modified) llvm/include/llvm/ProfileData/InstrProfData.inc (+12-3)
  • (modified) llvm/include/llvm/ProfileData/InstrProfWriter.h (+10)
  • (modified) llvm/include/llvm/Transforms/Instrumentation/CFGMST.h (+73-52)
  • (modified) llvm/lib/CodeGen/SpillPlacement.cpp (+49-1)
  • (modified) llvm/lib/Passes/StandardInstrumentations.cpp (+8-2)
  • (modified) llvm/lib/ProfileData/InstrProf.cpp (+113-26)
  • (modified) llvm/lib/ProfileData/InstrProfReader.cpp (+98-9)
  • (modified) llvm/lib/ProfileData/InstrProfWriter.cpp (+61-11)
  • (modified) llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp (+1023-6)
  • (modified) llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp (+62-8)
  • (added) llvm/test/Instrumentation/InstrProfiling/amdgpu-contiguous-counters.ll (+41)
  • (added) llvm/test/Instrumentation/InstrProfiling/amdgpu-uniform-counters.ll (+31)
  • (modified) llvm/test/Instrumentation/InstrProfiling/coverage.ll (+4-4)
  • (modified) llvm/test/Instrumentation/InstrProfiling/inline-data-var-create.ll (+12-11)
  • (modified) llvm/test/Instrumentation/InstrProfiling/platform.ll (+16)
  • (modified) llvm/test/Transforms/PGOProfile/comdat_internal.ll (+2-2)
  • (modified) llvm/test/Transforms/PGOProfile/instrprof_burst_sampling_fast.ll (+1-1)
  • (modified) llvm/test/tools/llvm-profdata/profile-version.test (+1-1)
  • (modified) llvm/tools/llvm-profdata/llvm-profdata.cpp (+120-5)
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index c624efb26f67d..cea46f5719066 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -3500,6 +3500,61 @@ generation and profile use (which can lead to discarded counters in such
 functions). Using these APIs in the program's cold regions introduces less
 overhead and leads to more optimized code.
 
+GPU/Device Profiling
+^^^^^^^^^^^^^^^^^^^^
+
+Clang supports profile-guided optimization for GPU device code when targeting
+AMD GPUs with HIP. The same ``-fprofile-generate`` and ``-fprofile-use`` flags
+work for both host and device code.
+
+The device PGO workflow differs from CPU PGO in several ways:
+
+1. **Profile collection**: Device counters are stored in GPU memory and
+   transferred to host memory at program exit by the compiler-rt profiling
+   runtime. The runtime uses HIP APIs (``hipGetSymbolAddress``, ``hipMemcpy``)
+   to read device profile data.
+
+2. **Counter expansion**: GPU kernels execute with massive parallelism
+   (thousands of concurrent threads). To reduce atomic contention, each
+   counter is expanded into multiple slots. Threads hash their position
+   to select a slot, and ``llvm-profdata merge`` sums the slots.
+
+3. **Wave uniformity**: GPU threads execute in groups called "waves" (or
+   "warps"). When all threads in a wave take the same branch, the branch
+   is "uniform". The ``--wave-size=N`` option to ``llvm-profdata merge``
+   computes uniformity information that helps the compiler make better
+   optimization decisions for GPU code.
+
+Here is an example workflow for HIP device PGO:
+
+.. code-block:: console
+
+   # Step 1: Build instrumented version
+   $ hipcc -O2 -fprofile-generate kernel.hip -o kernel
+
+   # Step 2: Run to collect profiles (device + host)
+   $ ./kernel
+   # Creates default.profraw with both host and device profiles
+
+   # Step 3: Merge profiles with wave size for uniformity detection
+   $ llvm-profdata merge --wave-size=32 -o kernel.profdata default.profraw
+
+   # Step 4: Build optimized version
+   $ hipcc -O2 -fprofile-use=kernel.profdata kernel.hip -o kernel_optimized
+
+.. note::
+
+   Device PGO requires a ROCm installation with HIP runtime support.
+   The ``--wave-size`` should match the target GPU's wave size (32 for
+   RDNA/gfx10+, 64 for GCN/gfx9).
+
+**Limitations**
+
+- Device PGO is currently supported only for AMDGPU targets
+- Sampling-based profiling is not supported for device code
+- Context-sensitive profiling (``-fcs-profile-generate``) is not supported
+  for device code
+
 Disabling Instrumentation
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index 617809285c165..d487e05909f59 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -303,6 +303,20 @@ HIPAMDToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
   const OptTable &Opts = getDriver().getOpts();
 
   for (Arg *A : Args) {
+    // Handle device-side profile data file for PGO
+    if (A->getOption().matches(options::OPT_fprofile_use_EQ)) {
+      StringRef ProfileFile = A->getValue();
+      std::string DeviceProfileFile = std::string(ProfileFile);
+      const char *Extension = strrchr(ProfileFile.data(), '.');
+      if (Extension) {
+        size_t BaseLen = Extension - ProfileFile.data();
+        DeviceProfileFile.insert(BaseLen, ".amdgcn-amd-amdhsa");
+      }
+      DAL->AddJoinedArg(A, Opts.getOption(options::OPT_fprofile_instr_use_EQ),
+                        DeviceProfileFile);
+      A->claim();
+      continue;
+    }
     // Filter unsupported sanitizers passed from the HostTC.
     if (!handleSanitizeOption(*this, *DAL, Args, BoundArch, A))
       DAL->append(A);
diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc
index 46d6bb5bd8896..fffe5a26b1cb9 100644
--- a/compiler-rt/include/profile/InstrProfData.inc
+++ b/compiler-rt/include/profile/InstrProfData.inc
@@ -90,8 +90,12 @@ INSTR_PROF_DATA(IntPtrT, llvm::PointerType::getUnqual(Ctx), Values, \
 INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \
                 ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters))
 INSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \
-                ConstantArray::get(Int16ArrayTy, Int16ArrayVals)) \
-INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumBitmapBytes, \
+                ConstantArray::get(Int16ArrayTy, Int16ArrayVals))
+INSTR_PROF_DATA(const uint16_t, llvm::Type::getInt16Ty(Ctx),
+                NumOffloadProfilingThreads,
+                ConstantInt::get(llvm::Type::getInt16Ty(Ctx),
+                                 NumOffloadProfilingThreadsVal))
+INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumBitmapBytes,
                 ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumBitmapBytes))
 #undef INSTR_PROF_DATA
 /* INSTR_PROF_DATA end. */
diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt
index 7c8473cc5f200..d4f64dcb2c6c7 100644
--- a/compiler-rt/lib/profile/CMakeLists.txt
+++ b/compiler-rt/lib/profile/CMakeLists.txt
@@ -73,6 +73,7 @@ set(PROFILE_SOURCES
   InstrProfilingPlatformFuchsia.c
   InstrProfilingPlatformLinux.c
   InstrProfilingPlatformOther.c
+  InstrProfilingPlatformROCm.c
   InstrProfilingPlatformWindows.c
   )
 
diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h
index 187ef55ef3784..e604df72d2044 100644
--- a/compiler-rt/lib/profile/InstrProfiling.h
+++ b/compiler-rt/lib/profile/InstrProfiling.h
@@ -349,4 +349,24 @@ extern char INSTR_PROF_PROFILE_NAME_VAR[1]; /* __llvm_profile_filename. */
 
 const __llvm_gcov_init_func_struct *__llvm_profile_begin_covinit();
 const __llvm_gcov_init_func_struct *__llvm_profile_end_covinit();
+
+/* A struct to hold the device pointers and sizes for the profile sections. */
+typedef struct HIPProfileSectionInfo {
+  void *CountersBegin;
+  size_t CountersSize;
+  void *DataBegin;
+  size_t DataSize;
+  void *NamesBegin;
+  size_t NamesSize;
+} HIPProfileSectionInfo;
+
+/*!
+ * \brief Register a HIP module's device-side profile data sections.
+ *
+ * This function is called by the host-side instrumentation code to provide
+ * the runtime with the necessary information to collect profile data from
+ * the device.
+ */
+void __llvm_profile_hip_register_module(HIPProfileSectionInfo *Info);
+
 #endif /* PROFILE_INSTRPROFILING_H_ */
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index 71127b05aafb8..aa9d567a1d17f 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -1198,6 +1198,8 @@ int __llvm_profile_write_file(void) {
   if (rc)
     PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));
 
+  __llvm_profile_hip_collect_device_data();
+
   // Restore SIGKILL.
   if (PDeathSig == 1)
     lprofRestoreSigKill();
diff --git a/compiler-rt/lib/profile/InstrProfilingInternal.h b/compiler-rt/lib/profile/InstrProfilingInternal.h
index 5647782527eb7..be6d2627dd100 100644
--- a/compiler-rt/lib/profile/InstrProfilingInternal.h
+++ b/compiler-rt/lib/profile/InstrProfilingInternal.h
@@ -212,5 +212,12 @@ int __llvm_write_binary_ids(ProfDataWriter *Writer);
 int lprofWriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen,
                           const uint8_t *BinaryIdData,
                           uint64_t BinaryIdPadding);
+#ifdef __cplusplus
+extern "C" {
+#endif
+COMPILER_RT_VISIBILITY int __llvm_profile_hip_collect_device_data(void);
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformROCm.c b/compiler-rt/lib/profile/InstrProfilingPlatformROCm.c
new file mode 100644
index 0000000000000..9b429cf8e8b22
--- /dev/null
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformROCm.c
@@ -0,0 +1,702 @@
+//===- InstrProfilingPlatformROCm.c - Profile data ROCm platform ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstrProfiling.h"
+#include "InstrProfilingInternal.h"
+#include "InstrProfilingPort.h"
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int ProcessDeviceOffloadPrf(void *DeviceOffloadPrf);
+
+static int IsVerboseMode() {
+  static int IsVerbose = -1;
+  if (IsVerbose == -1) {
+    if (getenv("LLVM_PROFILE_VERBOSE"))
+      IsVerbose = 1;
+    else
+      IsVerbose = 0;
+  }
+  return IsVerbose;
+}
+
+/* -------------------------------------------------------------------------- */
+/*  Dynamic loading of HIP runtime symbols                                   */
+/* -------------------------------------------------------------------------- */
+
+typedef int (*hipMemcpyFromSymbolTy)(void *, const void *, size_t, size_t, int);
+typedef int (*hipGetSymbolAddressTy)(void **, const void *);
+typedef int (*hipMemcpyTy)(void *, void *, size_t, int);
+typedef int (*hipModuleGetGlobalTy)(void **, size_t *, void *, const char *);
+
+static hipMemcpyFromSymbolTy pHipMemcpyFromSymbol = NULL;
+static hipGetSymbolAddressTy pHipGetSymbolAddress = NULL;
+static hipMemcpyTy pHipMemcpy = NULL;
+static hipModuleGetGlobalTy pHipModuleGetGlobal = NULL;
+
+/* -------------------------------------------------------------------------- */
+/*  HSA types and function pointers for direct memory copies                  */
+/*  This bypasses CLR's memory tracking, allowing copies from any device ptr  */
+/* -------------------------------------------------------------------------- */
+
+typedef uint32_t hsa_status_t;
+typedef struct {
+  uint64_t handle;
+} hsa_agent_t;
+typedef struct {
+  uint64_t handle;
+} hsa_signal_t;
+
+#define HSA_STATUS_SUCCESS 0
+#define HSA_AGENT_INFO_NAME 0
+#define HSA_AGENT_INFO_DEVICE 17
+#define HSA_DEVICE_TYPE_GPU 1
+#define HSA_SIGNAL_CONDITION_LT 0
+
+typedef hsa_status_t (*hsa_init_ty)(void);
+typedef hsa_status_t (*hsa_iterate_agents_ty)(hsa_status_t (*)(hsa_agent_t,
+                                                               void *),
+                                              void *);
+typedef hsa_status_t (*hsa_agent_get_info_ty)(hsa_agent_t, uint32_t, void *);
+typedef hsa_status_t (*hsa_signal_create_ty)(int64_t, uint32_t,
+                                             const hsa_agent_t *,
+                                             hsa_signal_t *);
+typedef hsa_status_t (*hsa_signal_destroy_ty)(hsa_signal_t);
+typedef void (*hsa_signal_store_relaxed_ty)(hsa_signal_t, int64_t);
+typedef int64_t (*hsa_signal_wait_scacquire_ty)(hsa_signal_t, uint32_t, int64_t,
+                                                uint64_t, uint32_t);
+typedef hsa_status_t (*hsa_amd_memory_lock_ty)(void *, size_t, hsa_agent_t *,
+                                               int, void **);
+typedef hsa_status_t (*hsa_amd_memory_unlock_ty)(void *);
+typedef hsa_status_t (*hsa_amd_memory_async_copy_ty)(void *, hsa_agent_t,
+                                                     const void *, hsa_agent_t,
+                                                     size_t, uint32_t,
+                                                     const hsa_signal_t *,
+                                                     hsa_signal_t);
+
+static hsa_init_ty pHsaInit = NULL;
+static hsa_iterate_agents_ty pHsaIterateAgents = NULL;
+static hsa_agent_get_info_ty pHsaAgentGetInfo = NULL;
+static hsa_signal_create_ty pHsaSignalCreate = NULL;
+static hsa_signal_destroy_ty pHsaSignalDestroy = NULL;
+static hsa_signal_store_relaxed_ty pHsaSignalStoreRelaxed = NULL;
+static hsa_signal_wait_scacquire_ty pHsaSignalWaitScacquire = NULL;
+static hsa_amd_memory_lock_ty pHsaAmdMemoryLock = NULL;
+static hsa_amd_memory_unlock_ty pHsaAmdMemoryUnlock = NULL;
+static hsa_amd_memory_async_copy_ty pHsaAmdMemoryAsyncCopy = NULL;
+
+static hsa_agent_t GpuAgent = {0};
+static hsa_agent_t CpuAgent = {0};
+static int HsaInitialized = 0;
+
+static hsa_status_t FindAgentCallback(hsa_agent_t Agent, void *Data) {
+  (void)Data;
+  uint32_t DeviceType = 0;
+  if (pHsaAgentGetInfo(Agent, HSA_AGENT_INFO_DEVICE, &DeviceType) ==
+      HSA_STATUS_SUCCESS) {
+    if (DeviceType == HSA_DEVICE_TYPE_GPU && GpuAgent.handle == 0) {
+      GpuAgent = Agent;
+    } else if (DeviceType != HSA_DEVICE_TYPE_GPU && CpuAgent.handle == 0) {
+      CpuAgent = Agent;
+    }
+  }
+  return HSA_STATUS_SUCCESS;
+}
+
+static int EnsureHsaLoaded(void) {
+  static int HsaLoadAttempted = 0;
+  if (HsaLoadAttempted)
+    return HsaInitialized;
+  HsaLoadAttempted = 1;
+
+  void *Handle = dlopen("libhsa-runtime64.so", RTLD_LAZY | RTLD_LOCAL);
+  if (!Handle) {
+    if (IsVerboseMode())
+      PROF_NOTE("HSA not available: %s\n", dlerror());
+    return 0;
+  }
+
+  pHsaInit = (hsa_init_ty)dlsym(Handle, "hsa_init");
+  pHsaIterateAgents =
+      (hsa_iterate_agents_ty)dlsym(Handle, "hsa_iterate_agents");
+  pHsaAgentGetInfo = (hsa_agent_get_info_ty)dlsym(Handle, "hsa_agent_get_info");
+  pHsaSignalCreate = (hsa_signal_create_ty)dlsym(Handle, "hsa_signal_create");
+  pHsaSignalDestroy =
+      (hsa_signal_destroy_ty)dlsym(Handle, "hsa_signal_destroy");
+  pHsaSignalStoreRelaxed =
+      (hsa_signal_store_relaxed_ty)dlsym(Handle, "hsa_signal_store_relaxed");
+  pHsaSignalWaitScacquire =
+      (hsa_signal_wait_scacquire_ty)dlsym(Handle, "hsa_signal_wait_scacquire");
+  pHsaAmdMemoryLock =
+      (hsa_amd_memory_lock_ty)dlsym(Handle, "hsa_amd_memory_lock");
+  pHsaAmdMemoryUnlock =
+      (hsa_amd_memory_unlock_ty)dlsym(Handle, "hsa_amd_memory_unlock");
+  pHsaAmdMemoryAsyncCopy =
+      (hsa_amd_memory_async_copy_ty)dlsym(Handle, "hsa_amd_memory_async_copy");
+
+  if (!pHsaInit || !pHsaIterateAgents || !pHsaAgentGetInfo ||
+      !pHsaSignalCreate || !pHsaSignalDestroy || !pHsaSignalStoreRelaxed ||
+      !pHsaSignalWaitScacquire || !pHsaAmdMemoryLock || !pHsaAmdMemoryUnlock ||
+      !pHsaAmdMemoryAsyncCopy) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA: some symbols not found\n");
+    return 0;
+  }
+
+  /* HSA is typically already initialized by HIP, but call init anyway */
+  /* Note: hsa_init is reference-counted, so this is safe */
+  if (pHsaInit() != HSA_STATUS_SUCCESS) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA init failed\n");
+    return 0;
+  }
+
+  /* Find GPU and CPU agents */
+  pHsaIterateAgents(FindAgentCallback, NULL);
+  if (GpuAgent.handle == 0 || CpuAgent.handle == 0) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA: GPU or CPU agent not found\n");
+    return 0;
+  }
+
+  HsaInitialized = 1;
+  if (IsVerboseMode())
+    PROF_NOTE("HSA initialized: GPU agent=%lx, CPU agent=%lx\n",
+              (unsigned long)GpuAgent.handle, (unsigned long)CpuAgent.handle);
+  return 1;
+}
+
+/* Copy from device to host using HSA APIs (bypasses CLR memory tracking) */
+static int hsaMemcpyDtoH(void *Dst, const void *Src, size_t Size) {
+  if (!EnsureHsaLoaded())
+    return -1;
+
+  void *PinnedDst = NULL;
+  hsa_signal_t Signal = {0};
+  int Result = -1;
+
+  /* Pin host memory */
+  if (pHsaAmdMemoryLock(Dst, Size, NULL, 0, &PinnedDst) != HSA_STATUS_SUCCESS) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA: failed to lock host memory\n");
+    return -1;
+  }
+
+  /* Create completion signal */
+  if (pHsaSignalCreate(1, 0, NULL, &Signal) != HSA_STATUS_SUCCESS) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA: failed to create signal\n");
+    pHsaAmdMemoryUnlock(Dst);
+    return -1;
+  }
+
+  /* Async copy from device to host */
+  if (pHsaAmdMemoryAsyncCopy(PinnedDst, CpuAgent, Src, GpuAgent, Size, 0, NULL,
+                             Signal) != HSA_STATUS_SUCCESS) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA: async copy failed\n");
+    goto cleanup;
+  }
+
+  /* Wait for completion (timeout: 30 seconds) */
+  if (pHsaSignalWaitScacquire(Signal, HSA_SIGNAL_CONDITION_LT, 1,
+                              30000000000ULL, 0) < 0) {
+    if (IsVerboseMode())
+      PROF_NOTE("%s", "HSA: wait failed or timeout\n");
+    goto cleanup;
+  }
+
+  Result = 0; /* Success */
+
+cleanup:
+  pHsaSignalDestroy(Signal);
+  pHsaAmdMemoryUnlock(Dst);
+  return Result;
+}
+
+static void EnsureHipLoaded(void) {
+  static int Initialized = 0;
+  if (Initialized)
+    return;
+  Initialized = 1;
+
+  void *Handle = dlopen("libamdhip64.so", RTLD_LAZY | RTLD_LOCAL);
+  if (!Handle) {
+    fprintf(stderr, "compiler-rt: failed to open libamdhip64.so: %s\n",
+            dlerror());
+    return;
+  }
+
+  pHipMemcpyFromSymbol =
+      (hipMemcpyFromSymbolTy)dlsym(Handle, "hipMemcpyFromSymbol");
+  pHipGetSymbolAddress =
+      (hipGetSymbolAddressTy)dlsym(Handle, "hipGetSymbolAddress");
+  pHipMemcpy = (hipMemcpyTy)dlsym(Handle, "hipMemcpy");
+  pHipModuleGetGlobal =
+      (hipModuleGetGlobalTy)dlsym(Handle, "hipModuleGetGlobal");
+}
+
+/* -------------------------------------------------------------------------- */
+/*  Public wrappers that forward to the loaded HIP symbols                   */
+/* -------------------------------------------------------------------------- */
+
+static int hipMemcpyFromSymbol(void *dst, const void *symbol, size_t sizeBytes,
+                               size_t offset, int kind) {
+  EnsureHipLoaded();
+  return pHipMemcpyFromSymbol
+             ? pHipMemcpyFromSymbol(dst, symbol, sizeBytes, offset, kind)
+             : -1;
+}
+
+static int hipGetSymbolAddress(void **devPtr, const void *symbol) {
+  EnsureHipLoaded();
+  return pHipGetSymbolAddress ? pHipGetSymbolAddress(devPtr, symbol) : -1;
+}
+
+static int hipMemcpy(void *dest, void *src, size_t len, int kind /*2=DToH*/) {
+  EnsureHipLoaded();
+  return pHipMemcpy ? pHipMemcpy(dest, src, len, kind) : -1;
+}
+
+/* Copy from device to host - tries HSA first (bypasses CLR), falls back to HIP.
+ * This is needed because hipMemcpy may fail on device pointers that are not
+ * registered with CLR (e.g., profile counter sections obtained from
+ * __llvm_offload_prf structure). HSA APIs work with any device pointer. */
+static int memcpyDeviceToHost(void *Dst, void *Src, size_t Size) {
+  /* Try HSA first - this works with unregistered device pointers */
+  if (hsaMemcpyDtoH(Dst, Src, Size) == 0) {
+    return 0;
+  }
+
+  /* Fall back to HIP if HSA is not available */
+  if (IsVerboseMode())
+    PROF_NOTE("%s", "HSA copy failed, falling back to HIP\n");
+  return hipMemcpy(Dst, Src, Size, 2 /* DToH */);
+}
+
+static int hipModuleGetGlobal(void **DevPtr, size_t *Bytes, void *Module,
+                              const char *Name) {
+  EnsureHipLoaded();
+  return pHipModuleGetGlobal ? pHipModuleGetGlobal(DevPtr, Bytes, Module, Name)
+                             : -1;
+}
+
+/* -------------------------------------------------------------------------- */
+/*  Dynamic module tracking                                                   */
+/* -------------------------------------------------------------------------- */
+
+#define MAX_DYNAMIC_MODULES 256
+
+typedef struct {
+  void *ModulePtr; /* hipModule_t returned by hipModuleLoad            */
+  void *DeviceVar; /* address of __llvm_offload_prf in this module     */
+  int Processed;   /* 0 = not yet collected, 1 = data already copied   */
+} HipDynamicModuleInfo;
+
+static HipDynamicModuleInfo DynamicModules[MAX_DYNAMIC_MODULES];
+static int NumDynamicModules = 0;
+
+/* -------------------------------------------------------------------------- */
+/*  Registration / un-registration helpers                                   */
+/* -------------------------------------------------------------------------- */
+
+void __llvm_profile_hip_register_dynamic_module(int ModuleLoadRc, void **Ptr) {
+  if (IsVerboseMode())
+    PROF_NOTE("Registering loaded module %d: rc=%d, module=%p\n",
+              NumDynamicModules, ModuleLoadRc, *Ptr);
+
+  if (ModuleLoadRc)
+    return;
+
+  if (NumDynamicModules >= MAX_DYNAMIC_MODULES) {
+    PROF_ERR("Too many dynamic modules registered. Maximum is %d.\n",
+             MAX_DYNAMIC_MODULES);
+    return;
+  }
+
+  HipDynamicModule...
[truncated]

@github-actions

github-actions Bot commented Jan 23, 2026

Copy link
Copy Markdown

✅ With the latest revision this PR passed the C/C++ code formatter.

Comment thread clang/lib/Driver/ToolChains/HIPAMD.cpp Outdated
Comment thread clang/lib/Driver/ToolChains/HIPAMD.cpp Outdated
Comment thread compiler-rt/lib/profile/InstrProfilingPlatformROCm.c Outdated
Comment thread llvm/lib/CodeGen/SpillPlacement.cpp Outdated
Comment thread llvm/lib/CodeGen/SpillPlacement.cpp Outdated
Comment thread llvm/lib/CodeGen/SpillPlacement.cpp Outdated

@boomanaiden154 boomanaiden154 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably needs an RFC. I'm also wondering how this ties in to existing work for PGO profiling that goes through libomptarget/offload.

@github-actions

github-actions Bot commented Jan 23, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 204701 tests passed
  • 6545 tests skipped

✅ The build succeeded and all tests passed.

@github-actions

github-actions Bot commented Jan 23, 2026

Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 136743 tests passed
  • 4667 tests skipped

✅ The build succeeded and all tests passed.

@yxsamliu

Copy link
Copy Markdown
Contributor Author

This probably needs an RFC. I'm also wondering how this ties in to existing work for PGO profiling that goes through libomptarget/offload.

will open an RFC

Comment thread llvm/include/llvm/Transforms/Instrumentation/CFGMST.h Outdated
Comment thread llvm/include/llvm/ProfileData/InstrProf.h Outdated
Comment thread llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp Outdated
Comment thread llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp Outdated
Comment thread compiler-rt/lib/profile/InstrProfilingPlatformROCm.c Outdated
Comment thread llvm/lib/CodeGen/SpillPlacement.cpp Outdated
@yxsamliu

Copy link
Copy Markdown
Contributor Author

This probably needs an RFC. I'm also wondering how this ties in to existing work for PGO profiling that goes through libomptarget/offload.

will open an RFC

RFC opened: https://discourse.llvm.org/t/rfc-offload-pgo-for-hip-amdgpu-device-side-profile-guided-optimization/89577

@github-actions

Copy link
Copy Markdown

⚠️ LLVM ABI annotation checker, ids-check found issues in your code. ⚠️

You can test this locally with the following command:
git diff origin/main HEAD -- 'llvm/include/llvm/**/*.h' 'llvm/include/llvm-c/**/*.h' 'llvm/include/llvm/Demangle/**/*.h'
Then run idt on the changed files with appropriate --export-macro and --include-header flags.

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from ids-check here.
diff --git a/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h b/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h
index bea1c7893..0c38c0c5f 100644
--- a/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -36,7 +36,7 @@ public:
     std::unique_ptr<MachineFunction> MF;
 
   public:
-    Result(std::unique_ptr<MachineFunction> MF);
+    LLVM_ABI Result(std::unique_ptr<MachineFunction> MF);
     MachineFunction &getMF() { return *MF; };
     LLVM_ABI bool invalidate(Function &, const PreservedAnalyses &PA,
                              FunctionAnalysisManager::Invalidator &);
diff --git a/llvm/include/llvm/CodeGen/OffloadBlockUniformity.h b/llvm/include/llvm/CodeGen/OffloadBlockUniformity.h
index 0afcacd48..539153123 100644
--- a/llvm/include/llvm/CodeGen/OffloadBlockUniformity.h
+++ b/llvm/include/llvm/CodeGen/OffloadBlockUniformity.h
@@ -21,6 +21,7 @@
 #ifndef LLVM_CODEGEN_OFFLOADBLOCKUNIFORMITY_H
 #define LLVM_CODEGEN_OFFLOADBLOCKUNIFORMITY_H
 
+#include "llvm/Support/Compiler.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
@@ -35,14 +36,14 @@ class OffloadBlockUniformityInfo {
 public:
   static constexpr StringLiteral MetadataName = "offload-block-uniformity";
 
-  void compute(const MachineFunction &MF);
+  LLVM_ABI void compute(const MachineFunction &MF);
 
   bool hasUniformity() const { return HasAnyUniformity; }
 
   // Returns true if the block is considered divergent. If uniformity exists for
   // the function but a block has no explicit annotation, it is treated as
   // divergent (conservative).
-  bool isDivergent(const MachineBasicBlock &MBB) const;
+  LLVM_ABI bool isDivergent(const MachineBasicBlock &MBB) const;
 
 private:
   bool HasAnyUniformity = false;
@@ -56,7 +57,7 @@ class OffloadBlockUniformityAnalysis
 
 public:
   using Result = OffloadBlockUniformityInfo;
-  Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
+  LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
 };
 
 } // end namespace llvm

@arsenm arsenm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing codegen tests.

This PR is also large enough that GitHub is unusable. This should still be broken up, the codegen pieces should be done separately from anything else

Comment thread llvm/lib/CodeGen/OffloadBlockUniformity.cpp Outdated
Comment thread llvm/lib/CodeGen/OffloadBlockUniformity.cpp Outdated
Comment thread llvm/lib/CodeGen/SpillPlacement.cpp Outdated
@vitalybuka

vitalybuka commented May 27, 2026

Copy link
Copy Markdown
Contributor

Nothing from me on this PR. No need to wait for my feedback.

@yxsamliu

Copy link
Copy Markdown
Contributor Author

I will merge this PR for now. If any concerns came up, we can do post-commit review.

@llvm-ci

llvm-ci commented May 28, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-gcc-ubuntu running on sie-linux-worker3 while building clang,compiler-rt,llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/174/builds/36179

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Profile-x86_64 :: ContinuousSyncMode/basic.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
/home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/./bin/clang   -m64  -ldl  -fprofile-instr-generate=/home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.profraw -fprofile-continuous -fcoverage-mapping -o /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.exe /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/compiler-rt/test/profile/ContinuousSyncMode/basic.c
# executed command: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/./bin/clang -m64 -ldl -fprofile-instr-generate=/home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.profraw -fprofile-continuous -fcoverage-mapping -o /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.exe /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/compiler-rt/test/profile/ContinuousSyncMode/basic.c
# .---command stderr------------
# | /usr/bin/ld: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_register_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text.__llvm_profile_offload_register_dynamic_module+0x2be): undefined reference to `pthread_once'
# | /usr/bin/ld: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_unregister_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text.__llvm_profile_offload_unregister_dynamic_module+0x12d): undefined reference to `pthread_once'
# | /usr/bin/ld: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `processDeviceOffloadPrf(void*, int, char const*)':
# | InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x26): undefined reference to `pthread_once'
# | /usr/bin/ld: InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x354): undefined reference to `pthread_once'
# | /usr/bin/ld: InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x39a): undefined reference to `pthread_once'
# | /usr/bin/ld: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x3eb): more undefined references to `pthread_once' follow
# | /usr/bin/ld: /usr/bin/ld: DWARF error: invalid or unhandled FORM value: 0x25
# | /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::internal_pthread_attr_getstack(void*, void**, unsigned long*)':
# | sanitizer_posix_libcdep.cpp:(.text._ZN11__sanitizer30internal_pthread_attr_getstackEPvPS0_Pm+0xa): undefined reference to `pthread_attr_getstack'
# | /usr/bin/ld: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::AdjustStackSize(void*)':
# | sanitizer_posix_libcdep.cpp:(.text._ZN11__sanitizer15AdjustStackSizeEPv+0x37): undefined reference to `pthread_attr_getstack'
# | /usr/bin/ld: sanitizer_posix_libcdep.cpp:(.text._ZN11__sanitizer15AdjustStackSizeEPv+0x9f): undefined reference to `pthread_attr_setstacksize'
# | /usr/bin/ld: /usr/bin/ld: DWARF error: invalid or unhandled FORM value: 0x25
# | /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_linux_libcdep.cpp.o): in function `__sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*)':
# | sanitizer_linux_libcdep.cpp:(.text._ZN11__sanitizer26GetThreadStackTopAndBottomEbPmS0_+0xfa): undefined reference to `pthread_getattr_np'
# | clang: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************


@llvm-ci

llvm-ci commented May 28, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux running on sanitizer-buildbot1 while building clang,compiler-rt,llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/66/builds/31311

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
-- Install configuration: "Release"
[415/421] Generating MSAN_INST_GTEST.gtest-all.cc.x86_64-with-call.o
[416/421] Generating MSAN_INST_GTEST.gtest-all.cc.x86_64.o
[417/421] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.x86_64-with-call.o
[418/421] Generating Msan-x86_64-with-call-Test
[419/421] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.x86_64.o
[420/421] Generating Msan-x86_64-Test
[420/421] Running compiler_rt regression tests
-- Testing: 5448 of 11540 tests, 64 workers --
Testing:  0.. 10.. 20.. 30.
FAIL: Profile-x86_64 :: Posix/instrprof-dlopen-norpath.test (2041 of 5448)
******************** TEST 'Profile-x86_64 :: Posix/instrprof-dlopen-norpath.test' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
rm -rf /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp && split-file /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/profile/Posix/instrprof-dlopen-norpath.test /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp && cd /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# executed command: rm -rf /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# note: command had no output on stdout or stderr
# executed command: split-file /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/profile/Posix/instrprof-dlopen-norpath.test /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# note: command had no output on stdout or stderr
# executed command: cd /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# note: command had no output on stdout or stderr
# RUN: at line 3
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -fPIC foo.c -c -Xclang -fprofile-instrument-path="default_foo_%m.profraw"
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -fPIC foo.c -c -Xclang -fprofile-instrument-path=default_foo_%m.profraw
# .---command stderr------------
# | clang: warning: -ldl: 'linker' input unused [-Wunused-command-line-argument]
# `-----------------------------
# RUN: at line 4
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -fPIC foo2.c -c -Xclang -fprofile-instrument-path="default_foo2_%m.profraw"
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -fPIC foo2.c -c -Xclang -fprofile-instrument-path=default_foo2_%m.profraw
# .---command stderr------------
# | clang: warning: -ldl: 'linker' input unused [-Wunused-command-line-argument]
# `-----------------------------
# RUN: at line 5
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -shared foo.o -o shr_foo.o
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -shared foo.o -o shr_foo.o
# note: command had no output on stdout or stderr
# RUN: at line 6
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -shared foo2.o -o shr_foo2.o
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -shared foo2.o -o shr_foo2.o
# note: command had no output on stdout or stderr
# RUN: at line 8
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate common.c -c
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate common.c -c
# .---command stderr------------
# | clang: warning: -ldl: 'linker' input unused [-Wunused-command-line-argument]
Step 11 (test compiler-rt debug) failure: test compiler-rt debug (failure)
...
-- Install configuration: "Release"
[415/421] Generating MSAN_INST_GTEST.gtest-all.cc.x86_64-with-call.o
[416/421] Generating MSAN_INST_GTEST.gtest-all.cc.x86_64.o
[417/421] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.x86_64-with-call.o
[418/421] Generating Msan-x86_64-with-call-Test
[419/421] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.x86_64.o
[420/421] Generating Msan-x86_64-Test
[420/421] Running compiler_rt regression tests
-- Testing: 5448 of 11540 tests, 64 workers --
Testing:  0.. 10.. 20.. 30.
FAIL: Profile-x86_64 :: Posix/instrprof-dlopen-norpath.test (2041 of 5448)
******************** TEST 'Profile-x86_64 :: Posix/instrprof-dlopen-norpath.test' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
rm -rf /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp && split-file /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/profile/Posix/instrprof-dlopen-norpath.test /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp && cd /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# executed command: rm -rf /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# note: command had no output on stdout or stderr
# executed command: split-file /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/profile/Posix/instrprof-dlopen-norpath.test /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# note: command had no output on stdout or stderr
# executed command: cd /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/Posix/Output/instrprof-dlopen-norpath.test.tmp
# note: command had no output on stdout or stderr
# RUN: at line 3
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -fPIC foo.c -c -Xclang -fprofile-instrument-path="default_foo_%m.profraw"
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -fPIC foo.c -c -Xclang -fprofile-instrument-path=default_foo_%m.profraw
# .---command stderr------------
# | clang: warning: -ldl: 'linker' input unused [-Wunused-command-line-argument]
# `-----------------------------
# RUN: at line 4
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -fPIC foo2.c -c -Xclang -fprofile-instrument-path="default_foo2_%m.profraw"
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -fPIC foo2.c -c -Xclang -fprofile-instrument-path=default_foo2_%m.profraw
# .---command stderr------------
# | clang: warning: -ldl: 'linker' input unused [-Wunused-command-line-argument]
# `-----------------------------
# RUN: at line 5
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -shared foo.o -o shr_foo.o
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -shared foo.o -o shr_foo.o
# note: command had no output on stdout or stderr
# RUN: at line 6
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate -fprofile-update=atomic -shared foo2.o -o shr_foo2.o
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate -fprofile-update=atomic -shared foo2.o -o shr_foo2.o
# note: command had no output on stdout or stderr
# RUN: at line 8
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -ldl  -fprofile-generate common.c -c
# executed command: /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -ldl -fprofile-generate common.c -c
# .---command stderr------------
# | clang: warning: -ldl: 'linker' input unused [-Wunused-command-line-argument]

@llvm-ci

llvm-ci commented May 28, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder clang-ppc64le-rhel running on ppc64le-clang-rhel-test while building clang,compiler-rt,llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/145/builds/14408

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Profile-powerpc64le :: ContinuousSyncMode/basic.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/./bin/clang   -m64 -fno-function-sections  -ldl  -fprofile-instr-generate=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/ContinuousSyncMode/Output/basic.c.tmp.profraw -fprofile-continuous -fcoverage-mapping -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/ContinuousSyncMode/Output/basic.c.tmp.exe /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/compiler-rt/test/profile/ContinuousSyncMode/basic.c
# executed command: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/./bin/clang -m64 -fno-function-sections -ldl -fprofile-instr-generate=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/ContinuousSyncMode/Output/basic.c.tmp.profraw -fprofile-continuous -fcoverage-mapping -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/ContinuousSyncMode/Output/basic.c.tmp.exe /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/compiler-rt/test/profile/ContinuousSyncMode/basic.c
# .---command stderr------------
# | ld.lld: error: undefined symbol: pthread_once
# | >>> referenced by InstrProfilingPlatformROCm.cpp
# | >>>               InstrProfilingPlatformROCm.cpp.o:(__llvm_profile_offload_register_dynamic_module) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | >>> referenced by InstrProfilingPlatformROCm.cpp
# | >>>               InstrProfilingPlatformROCm.cpp.o:(__llvm_profile_offload_unregister_dynamic_module) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | >>> referenced by InstrProfilingPlatformROCm.cpp
# | >>>               InstrProfilingPlatformROCm.cpp.o:(processDeviceOffloadPrf(void*, int, char const*)) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | >>> referenced 8 more times
# | 
# | ld.lld: error: undefined symbol: pthread_getattr_np
# | >>> referenced by sanitizer_linux_libcdep.cpp:184 (/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp:184)
# | >>>               sanitizer_linux_libcdep.cpp.o:(__sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*)) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | 
# | ld.lld: error: undefined symbol: pthread_attr_getstack
# | >>> referenced by sanitizer_posix_libcdep.cpp:496 (/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:496)
# | >>>               sanitizer_posix_libcdep.cpp.o:(__sanitizer::internal_pthread_attr_getstack(void*, void**, unsigned long*)) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | >>> referenced by sanitizer_posix_libcdep.cpp:496 (/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:496)
# | >>>               sanitizer_posix_libcdep.cpp.o:(__sanitizer::AdjustStackSize(void*)) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | 
# | ld.lld: error: undefined symbol: pthread_attr_setstacksize
# | >>> referenced by sanitizer_posix_libcdep.cpp:515 (/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:515)
# | >>>               sanitizer_posix_libcdep.cpp.o:(__sanitizer::AdjustStackSize(void*)) in archive /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a
# | clang: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************


@clementval

Copy link
Copy Markdown
Contributor

We are getting failure from this commit

CMake Error at cmake/Modules/AddCompilerRT.cmake:365 (add_library):
  Error evaluating generator expression:

    $<TARGET_OBJECTS:RTInterception.x86_64>

  Objects of target "RTInterception.x86_64" referenced but no such target
  exists.
Call Stack (most recent call first):
  lib/profile/CMakeLists.txt:233 (add_compiler_rt_runtime)

Any suggestion how to address this?

@yxsamliu

Copy link
Copy Markdown
Contributor Author

We are getting failure from this commit

CMake Error at cmake/Modules/AddCompilerRT.cmake:365 (add_library):
  Error evaluating generator expression:

    $<TARGET_OBJECTS:RTInterception.x86_64>

  Objects of target "RTInterception.x86_64" referenced but no such target
  exists.
Call Stack (most recent call first):
  lib/profile/CMakeLists.txt:233 (add_compiler_rt_runtime)

Any suggestion how to address this?

Thanks for the report — root cause is that lib/profile/CMakeLists.txt references RTInterception / sanitizer_common targets that only exist when sanitizers/memprof/xray/ctx_profile are also being built. In a profile-only config those targets aren't created.

Fix posted in #200111: gate the object-lib merge on the targets actually existing, and skip InstrProfilingPlatformROCm.cpp when they don't (the host call site is already weak, so it links fine). Reproduced your error locally and confirmed the fix.

@llvm-ci

llvm-ci commented May 28, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-gcc-ubuntu-no-asserts running on doug-worker-6 while building clang,compiler-rt,llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/202/builds/6899

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Profile-x86_64 :: ContinuousSyncMode/basic.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
/home/buildbot/buildbot-root/gcc-no-asserts/build/./bin/clang   -m64  -ldl  -fprofile-instr-generate=/home/buildbot/buildbot-root/gcc-no-asserts/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.profraw -fprofile-continuous -fcoverage-mapping -o /home/buildbot/buildbot-root/gcc-no-asserts/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.exe /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/compiler-rt/test/profile/ContinuousSyncMode/basic.c
# executed command: /home/buildbot/buildbot-root/gcc-no-asserts/build/./bin/clang -m64 -ldl -fprofile-instr-generate=/home/buildbot/buildbot-root/gcc-no-asserts/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.profraw -fprofile-continuous -fcoverage-mapping -o /home/buildbot/buildbot-root/gcc-no-asserts/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-x86_64/ContinuousSyncMode/Output/basic.c.tmp.exe /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/compiler-rt/test/profile/ContinuousSyncMode/basic.c
# .---command stderr------------
# | /usr/bin/ld: /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_register_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text.__llvm_profile_offload_register_dynamic_module+0x2be): undefined reference to `pthread_once'
# | /usr/bin/ld: /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_unregister_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text.__llvm_profile_offload_unregister_dynamic_module+0x12d): undefined reference to `pthread_once'
# | /usr/bin/ld: /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `processDeviceOffloadPrf(void*, int, char const*)':
# | InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x26): undefined reference to `pthread_once'
# | /usr/bin/ld: InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x354): undefined reference to `pthread_once'
# | /usr/bin/ld: InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x39a): undefined reference to `pthread_once'
# | /usr/bin/ld: /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:(.text._ZL23processDeviceOffloadPrfPviPKc+0x3eb): more undefined references to `pthread_once' follow
# | /usr/bin/ld: /usr/bin/ld: DWARF error: invalid or unhandled FORM value: 0x25
# | /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::internal_pthread_attr_getstack(void*, void**, unsigned long*)':
# | sanitizer_posix_libcdep.cpp:(.text._ZN11__sanitizer30internal_pthread_attr_getstackEPvPS0_Pm+0xa): undefined reference to `pthread_attr_getstack'
# | /usr/bin/ld: /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::AdjustStackSize(void*)':
# | sanitizer_posix_libcdep.cpp:(.text._ZN11__sanitizer15AdjustStackSizeEPv+0x37): undefined reference to `pthread_attr_getstack'
# | /usr/bin/ld: sanitizer_posix_libcdep.cpp:(.text._ZN11__sanitizer15AdjustStackSizeEPv+0x9f): undefined reference to `pthread_attr_setstacksize'
# | /usr/bin/ld: /usr/bin/ld: DWARF error: invalid or unhandled FORM value: 0x25
# | /home/buildbot/buildbot-root/gcc-no-asserts/build/lib/clang/23/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_linux_libcdep.cpp.o): in function `__sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*)':
# | sanitizer_linux_libcdep.cpp:(.text._ZN11__sanitizer26GetThreadStackTopAndBottomEbPmS0_+0xfa): undefined reference to `pthread_getattr_np'
# | clang: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************


@llvm-ci

llvm-ci commented May 30, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder clang-ppc64le-linux-test-suite running on ppc64le-clang-test-suite while building clang,compiler-rt,llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/95/builds/20856

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: 1200 seconds without output running [b'ninja', b'check-all'], attempting to kill
******************** TEST 'Profile-powerpc64le :: Linux/counter_promo_for.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
rm -fr /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.promo.prof
# executed command: rm -fr /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.promo.prof
# RUN: at line 2
rm -fr /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.nopromo.prof
# executed command: rm -fr /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.nopromo.prof
# RUN: at line 3
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/./bin/clang   -m64 -fno-function-sections  -ldl  -fprofile-generate=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.promo.prof/ -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.promo.gen -O2 /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/llvm-project/compiler-rt/test/profile/Linux/counter_promo_for.c -fno-slp-vectorize
# executed command: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/./bin/clang -m64 -fno-function-sections -ldl -fprofile-generate=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.promo.prof/ -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/counter_promo_for.c.tmp.promo.gen -O2 /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/llvm-project/compiler-rt/test/profile/Linux/counter_promo_for.c -fno-slp-vectorize
# .---command stderr------------
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_register_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text+0x3a4): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_unregister_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text+0x80c): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `processDeviceOffloadPrf(void*, int, char const*)':
# | InstrProfilingPlatformROCm.cpp:(.text+0xa78): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: InstrProfilingPlatformROCm.cpp:(.text+0xd50): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: InstrProfilingPlatformROCm.cpp:(.text+0xd9c): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:(.text+0xde4): more undefined references to `pthread_once' follow
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::internal_pthread_attr_getstack(void*, void**, unsigned long*)':
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:496: undefined reference to `pthread_attr_getstack'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::AdjustStackSize(void*)':
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:496: undefined reference to `pthread_attr_getstack'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:515: undefined reference to `pthread_attr_setstacksize'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/build/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_linux_libcdep.cpp.o): in function `__sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*)':
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp:184: undefined reference to `pthread_getattr_np'
# | clang: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************


@llvm-ci

llvm-ci commented May 31, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder clang-ppc64le-linux-multistage running on ppc64le-clang-multistage-test while building clang,compiler-rt,llvm at step 5 "ninja check 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/76/builds/14538

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure)
******************** TEST 'Profile-powerpc64le :: Linux/coverage_test.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/./bin/clang   -m64 -fno-function-sections  -ldl  -fprofile-instr-generate -fuse-ld=gold -O2 -fdata-sections -ffunction-sections -fcoverage-mapping -Wl,--gc-sections -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/coverage_test.cpp.tmp /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/test/profile/Linux/coverage_test.cpp
# executed command: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/./bin/clang -m64 -fno-function-sections -ldl -fprofile-instr-generate -fuse-ld=gold -O2 -fdata-sections -ffunction-sections -fcoverage-mapping -Wl,--gc-sections -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Linux/Output/coverage_test.cpp.tmp /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/test/profile/Linux/coverage_test.cpp
# .---command stderr------------
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:function __llvm_profile_offload_register_dynamic_module: error: undefined reference to 'pthread_once'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:function __llvm_profile_offload_unregister_dynamic_module: error: undefined reference to 'pthread_once'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:function processDeviceOffloadPrf(void*, int, char const*): error: undefined reference to 'pthread_once'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:function processDeviceOffloadPrf(void*, int, char const*): error: undefined reference to 'pthread_once'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o):sanitizer_posix_libcdep.cpp:function __sanitizer::internal_pthread_attr_getstack(void*, void**, unsigned long*): error: undefined reference to 'pthread_attr_getstack'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o):sanitizer_posix_libcdep.cpp:function __sanitizer::AdjustStackSize(void*): error: undefined reference to 'pthread_attr_getstack'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o):sanitizer_posix_libcdep.cpp:function __sanitizer::AdjustStackSize(void*): error: undefined reference to 'pthread_attr_setstacksize'
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage1/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_linux_libcdep.cpp.o):sanitizer_linux_libcdep.cpp:function __sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*): error: undefined reference to 'pthread_getattr_np'
# | clang: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************

Step 11 (ninja check 2) failure: stage 2 checked (failure)
******************** TEST 'Profile-powerpc64le :: Posix/instrprof-empty-profile.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 4
mkdir -p /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp.d
# executed command: mkdir -p /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp.d
# RUN: at line 5
echo "src:other.c" > /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp-file.list
# executed command: echo src:other.c
# RUN: at line 6
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/./bin/clang   -m64 -fno-function-sections  -ldl  -fprofile-instr-generate -fprofile-list=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp-file.list -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/test/profile/Posix/instrprof-empty-profile.c
# executed command: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/./bin/clang -m64 -fno-function-sections -ldl -fprofile-instr-generate -fprofile-list=/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp-file.list -o /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc64le/Posix/Output/instrprof-empty-profile.c.tmp /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/test/profile/Posix/instrprof-empty-profile.c
# .---command stderr------------
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_register_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text+0x3a4): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `__llvm_profile_offload_unregister_dynamic_module':
# | InstrProfilingPlatformROCm.cpp:(.text+0x80c): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o): in function `processDeviceOffloadPrf(void*, int, char const*)':
# | InstrProfilingPlatformROCm.cpp:(.text+0xa78): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: InstrProfilingPlatformROCm.cpp:(.text+0xd50): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: InstrProfilingPlatformROCm.cpp:(.text+0xd9c): undefined reference to `pthread_once'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(InstrProfilingPlatformROCm.cpp.o):InstrProfilingPlatformROCm.cpp:(.text+0xde4): more undefined references to `pthread_once' follow
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::internal_pthread_attr_getstack(void*, void**, unsigned long*)':
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:496: undefined reference to `pthread_attr_getstack'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_posix_libcdep.cpp.o): in function `__sanitizer::AdjustStackSize(void*)':
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:496: undefined reference to `pthread_attr_getstack'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:515: undefined reference to `pthread_attr_setstacksize'
# | /opt/rh/gcc-toolset-13/root/usr/lib/gcc/ppc64le-redhat-linux/13/../../../../bin/ld: /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/stage2/lib/clang/23/lib/powerpc64le-unknown-linux-gnu/libclang_rt.profile.a(sanitizer_linux_libcdep.cpp.o): in function `__sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*)':
# | /home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-multistage-test/clang-ppc64le-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp:184: undefined reference to `pthread_getattr_np'
# | clang: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************


@zmodem

zmodem commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

As the comment in compiler-rt/lib/profile/CMakeLists.txt points out, "profile historically used the static CRT (/MT)". This PR changed it to the dynamic CRT (/MD). That's a pretty major change. Was it discussed somewhere?

This broke all builds that were using the profiling library with the static CRT.

Given the number of issues that have come up after this landed, perhaps it's time to back it out so the project can recover?


Here's a reproducer for the breakage:

cmake -Bbuild.foo -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_RUNTIMES=compiler-rt -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF llvm 
ninja -C build.foo clang runtimes

type a.c
int main() { return 0; }

build.foo\bin\clang-cl a.c -fprofile-generate

LINK : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4217: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'lprofCreateBufferIOInternal'
LINK : warning LNK4286: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4286: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingValue.c.obj)'
LINK : warning LNK4286: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj)'
LINK : warning LNK4217: symbol 'calloc' defined in 'libucrt.lib(calloc.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'lprofCreateBufferIOInternal'
LINK : warning LNK4286: symbol 'calloc' defined in 'libucrt.lib(calloc.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingValue.c.obj)'
LINK : warning LNK4286: symbol 'calloc' defined in 'libucrt.lib(calloc.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj)'
LINK : warning LNK4217: symbol 'malloc' defined in 'libucrt.lib(malloc.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function '__llvm_profile_get_path_prefix'
LINK : warning LNK4286: symbol 'malloc' defined in 'libucrt.lib(malloc.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4286: symbol 'malloc' defined in 'libucrt.lib(malloc.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj)'
LINK : warning LNK4286: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj)'
LINK : warning LNK4217: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function '__llvm_profile_get_path_prefix'
LINK : warning LNK4286: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4286: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingMerge.c.obj)'
LINK : warning LNK4286: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingValue.c.obj)'
LINK : warning LNK4286: symbol '__stdio_common_vfprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj)'
LINK : warning LNK4217: symbol '__stdio_common_vfprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'fprintf'
LINK : warning LNK4286: symbol '__stdio_common_vfprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4286: symbol '__stdio_common_vfprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingMerge.c.obj)'
LINK : warning LNK4286: symbol '__stdio_common_vfprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingValue.c.obj)'
LINK : warning LNK4217: symbol '_errno' defined in 'libucrt.lib(errno.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function '__llvm_profile_write_file'
LINK : warning LNK4286: symbol '_errno' defined in 'libucrt.lib(errno.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4217: symbol '_fileno' defined in 'libucrt.lib(fileno.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'writeFile'
LINK : warning LNK4286: symbol '_fileno' defined in 'libucrt.lib(fileno.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4286: symbol '_fileno' defined in 'libucrt.lib(fileno.obj)' is imported by 'oldnames.lib(fileno.obi)'
LINK : warning LNK4217: symbol 'atoi' defined in 'libucrt.lib(atox.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'writeFile'
LINK : warning LNK4286: symbol 'atoi' defined in 'libucrt.lib(atox.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)'
LINK : warning LNK4286: symbol 'atoi' defined in 'libucrt.lib(atox.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingValue.c.obj)'
LINK : warning LNK4217: symbol 'fclose' defined in 'libucrt.lib(fclose.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'writeFile'
LINK : warning LNK4217: symbol 'fflush' defined in 'libucrt.lib(fflush.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'writeFile'
LINK : warning LNK4217: symbol '__stdio_common_vsprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj)' in function 'snprintf'
LINK : warning LNK4286: symbol '__stdio_common_vsprintf' defined in 'libucrt.lib(output.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj)'
LINK : warning LNK4217: symbol '_open_osfhandle' defined in 'libucrt.lib(osfinfo.obj)' is imported by 'clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj)' in function 'lprofOpenFileEx'
LINK : warning LNK4217: symbol '_get_osfhandle' defined in 'libucrt.lib(osfinfo.obj)' is imported by 'clang_rt.profile-x86_64.lib(WindowsMMap.c.obj)' in function '__llvm_profile_mmap'
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_getpid referenced in function getCurFilename
oldnames.lib(getpid.obi) : error LNK2001: unresolved external symbol __imp_getpid
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_getenv referenced in function __llvm_profile_initialize_file
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2001: unresolved external symbol __imp_getenv
clang_rt.profile-x86_64.lib(InstrProfilingValue.c.obj) : error LNK2001: unresolved external symbol __imp_getenv
clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj) : error LNK2001: unresolved external symbol __imp_getenv
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_strdup referenced in function parseAndSetFilename
oldnames.lib(strdup.obi) : error LNK2001: unresolved external symbol __imp_strdup
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_strerror referenced in function __llvm_profile_write_file
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2001: unresolved external symbol __imp_strerror
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_fopen referenced in function writeFile
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp__chsize referenced in function writeFile
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_fseek referenced in function writeFile
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_fileno referenced in function __llvm_profile_set_file_object
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2001: unresolved external symbol __imp_fileno
oldnames.lib(fileno.obi) : error LNK2001: unresolved external symbol __imp_fileno
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_ftell referenced in function getProfileFileSizeForMerging
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2001: unresolved external symbol __imp_ftell
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_fwrite referenced in function fileWriter
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp__putenv referenced in function truncateCurrentFile
clang_rt.profile-x86_64.lib(InstrProfilingFile.c.obj) : error LNK2019: unresolved external symbol __imp_strncpy referenced in function createProfileDir
clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj) : error LNK2001: unresolved external symbol __imp_strncpy
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2019: unresolved external symbol __imp__mkdir referenced in function __llvm_profile_recursive_mkdir
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2019: unresolved external symbol __imp__fdopen referenced in function lprofOpenFileEx
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2019: unresolved external symbol __imp_fread referenced in function lprofGetFileContentBuffer
clang_rt.profile-x86_64.lib(InstrProfilingUtil.c.obj) : error LNK2019: unresolved external symbol __imp_feof referenced in function lprofGetFileContentBuffer
clang_rt.profile-x86_64.lib(InstrProfilingPlatformROCm.cpp.obj) : error LNK2019: unresolved external symbol __imp_realloc referenced in function __llvm_profile_offload_register_dynamic_module
clang_rt.profile-x86_64.lib(interception_win.cpp.obj) : error LNK2019: unresolved external symbol __imp__stricmp referenced in function "bool __cdecl __interception::OverrideImportedFunction(char const *,char const *,char const *,unsigned __int64,unsigned __int64 *)" (?OverrideImportedFunction@__interception@@YA_NPEBD00_KPEA_K@Z)
oldnames.lib(getpid.obi) : error LNK2001: unresolved external symbol __imp__getpid
oldnames.lib(strdup.obi) : error LNK2001: unresolved external symbol __imp__strdup
a.exe : fatal error LNK1120: 20 unresolved externals
clang-cl: error: linker command failed with exit code 1120 (use -v to see invocation)

@jhuber6

jhuber6 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

As the comment in compiler-rt/lib/profile/CMakeLists.txt points out, "profile historically used the static CRT (/MT)". This PR changed it to the dynamic CRT (/MD). That's a pretty major change. Was it discussed somewhere?

Hm, I'm guessing this is collateral damage to the interceptors being used? Honestly, if that's an issue then I think it'd be fine to write our own layer internally to the HIP case. Originally I figured it was better to share this because it required Linux+Windows support.

@yxsamliu

yxsamliu commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

there are a few follow-up commits. let me see whether there is a quick fix, otherwise I will revert them. thanks

@yxsamliu

yxsamliu commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

the easiest fix is to turn off rocm pgo support off on windows by default, then revert to /MT by default. I will come up with a PR

@yxsamliu

yxsamliu commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

As the comment in compiler-rt/lib/profile/CMakeLists.txt points out, "profile historically used the static CRT (/MT)". This PR changed it to the dynamic CRT (/MD). That's a pretty major change. Was it discussed somewhere?

This broke all builds that were using the profiling library with the static CRT.

Given the number of issues that have come up after this landed, perhaps it's time to back it out so the project can recover?

I have a fix which recovers /MT on windows by default:

#201438

@yxsamliu

yxsamliu commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

As the comment in compiler-rt/lib/profile/CMakeLists.txt points out, "profile historically used the static CRT (/MT)". This PR changed it to the dynamic CRT (/MD). That's a pretty major change. Was it discussed somewhere?
This broke all builds that were using the profiling library with the static CRT.
Given the number of issues that have come up after this landed, perhaps it's time to back it out so the project can recover?

I have a fix which recovers /MT on windows by default:

#201438

About the change from /MT to /MD: sorry I made the change without wider discussion. Me and reviewers have an impression that more windows apps use /MD than /MT, so we thought switching to /MD might be OK. On second thought, maybe we should allow users to choose whether profile lib being built with /MT or /MD, or build both, since there are windows apps built with either /MT or /MD.

@tstellar

tstellar commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

The Windows release builds are also broken by this commit. See https://github.com/llvm/llvm-project/actions/runs/26983415611/job/79627919383?pr=200734

@yxsamliu

yxsamliu commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@tstellar Thanks Tom. The offending change has been reverted by #201416, so this release build failure should be gone from main.

For the reland, I split the change to avoid affecting the normal profile runtime. The runtime half #201606 has now landed; it keeps clang_rt.profile unchanged on Windows (/MT as before) and adds a separate opt-in clang_rt.profile_rocm library for HIP device PGO. The remaining compiler/driver half is in #201607 and only links the ROCm profile library for HIP profiling builds.

With that split, LLVM’s own Windows release/PGO build should no longer hit this failure and should build the same way it did before.

@azhan92

azhan92 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

This commit is causing a lot of profile runtime test failures on AIX, such as the following:

-- Testing: 1 of 150 tests, 1 workers --
FAIL: Profile-powerpc :: instrprof-timestamp.c (1 of 1)
******************** TEST 'Profile-powerpc :: instrprof-timestamp.c' FAILED ********************
Exit Code: 8

Command Output (stdout):
--
# RUN: at line 1
rm -f /home/alisonz/llvm/dev/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc/Output/instrprof-timestamp.c.tmp.profdata
# executed command: rm -f /home/alisonz/llvm/dev/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc/Output/instrprof-timestamp.c.tmp.profdata
# RUN: at line 2
/home/alisonz/llvm/dev/build/./bin/clang   -m32   -fprofile-generate -o /home/alisonz/llvm/dev/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc/Output/instrprof-timestamp.c.tmp -mllvm -pgo-temporal-instrumentation /home/alisonz/llvm/dev/llvm-project/compiler-rt/test/profile/instrprof-timestamp.c
# executed command: /home/alisonz/llvm/dev/build/./bin/clang -m32 -fprofile-generate -o /home/alisonz/llvm/dev/build/runtimes/runtimes-bins/compiler-rt/test/profile/Profile-powerpc/Output/instrprof-timestamp.c.tmp -mllvm -pgo-temporal-instrumentation /home/alisonz/llvm/dev/llvm-project/compiler-rt/test/profile/instrprof-timestamp.c
# .---command stderr------------
# | ld: 0711-317 ERROR: Undefined symbol: ._ZN14__interception22DynamicLoaderAvailableEv
# | ld: 0711-317 ERROR: Undefined symbol: ._ZN14__interception11OpenLibraryEPKc
# | ld: 0711-317 ERROR: Undefined symbol: ._ZN14__interception12LookupSymbolEPvPKc
# | ld: 0711-317 ERROR: Undefined symbol: .pthread_once
# | ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_lock
# | ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_unlock
# | ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
# | clang: error: linker command failed with exit code 8 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 8

--

********************
********************
Failed Tests (1):
  Profile-powerpc :: instrprof-timestamp.c

Do you know why this is happening?

@yxsamliu

yxsamliu commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the report. This is caused by the original PR pulling the ROCm/interception support into the normal profile runtime, so non-HIP profile links can end up needing interception / pthread symbols.

The original change has already been reverted by #201416, so current main should no longer have this failure. For the reland, I split the support into a separate clang_rt.profile_rocm runtime in #201606, and the driver only links it for HIP profiling builds in #201607. The normal clang_rt.profile runtime should stay unchanged and should not depend on interception or pthread.

@@ -0,0 +1,890 @@
//===- InstrProfilingPlatformROCm.cpp - Profile data ROCm platform -------===//

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the other InstrProfilingPlatform files are .c files, not .cpp. Is this intentionally different? (Sorry if this was discussed above, I didn't read all 297 previous comments. I looked through a few, which didn't ask about this.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's .cpp that does not link the C++ library so it's got the same library dependencies as the others. I don't see a compelling reason to prevent it form being C++ when useful given that compiler-rt is already a mixed C/C++ project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.