Skip to content

Conversation

jansvoboda11
Copy link
Contributor

The frontend currently opens the path provided via -fprofile-instrument-use-path= to learn the kind of the instrumentation data and set the CodeGenOptions::ProfileUse value. This happens during command-line parsing, where we don't have a correctly configured VFS yet, so the behavior is quite different from all other frontend inputs. We need to move this logic out of the frontend command line parsing logic somewhere where we do have the configured VFS.

The complication is that the ProfileUse flag is being used to set preprocessor macros, and there isn't a great place between command line parsing and preprocessor initialization to perform this logic.

This PR solves the issue by deducing the kind of instrumentation data right in the driver and then passing it via a new flag to the frontend. This shouldn't change observable behavior of Clang on the driver level, and only affects the frontend command line interface, which is an implementation detail anyway.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. labels Sep 18, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2025

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang-codegen

Author: Jan Svoboda (jansvoboda11)

Changes

The frontend currently opens the path provided via -fprofile-instrument-use-path= to learn the kind of the instrumentation data and set the CodeGenOptions::ProfileUse value. This happens during command-line parsing, where we don't have a correctly configured VFS yet, so the behavior is quite different from all other frontend inputs. We need to move this logic out of the frontend command line parsing logic somewhere where we do have the configured VFS.

The complication is that the ProfileUse flag is being used to set preprocessor macros, and there isn't a great place between command line parsing and preprocessor initialization to perform this logic.

This PR solves the issue by deducing the kind of instrumentation data right in the driver and then passing it via a new flag to the frontend. This shouldn't change observable behavior of Clang on the driver level, and only affects the frontend command line interface, which is an implementation detail anyway.


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

46 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3)
  • (modified) clang/include/clang/Driver/Options.td (+5)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+8-4)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+35-6)
  • (modified) clang/lib/Frontend/CompilerInvocation.cpp (+4-38)
  • (modified) clang/test/CodeGen/cspgo-instrumentation.c (+3-3)
  • (modified) clang/test/CodeGen/cspgo-instrumentation_lto.c (+3-3)
  • (modified) clang/test/CodeGen/cspgo-instrumentation_thinlto.c (+4-4)
  • (modified) clang/test/CodeGen/opt-record.c (+1-1)
  • (modified) clang/test/CodeGen/pgo-instrumentation.c (+2-2)
  • (modified) clang/test/CodeGen/thinlto-clang-diagnostic-handler-in-be.c (+1-1)
  • (modified) clang/test/CodeGenCXX/profile-remap.cpp (+2-2)
  • (modified) clang/test/DebugInfo/CXX/fdebug-info-for-profiling.cpp (+1-1)
  • (added) clang/test/Driver/Inputs/a.proftext (+2)
  • (modified) clang/test/Driver/cl-options.c (+11-6)
  • (modified) clang/test/Driver/clang_f_opts.c (+11-5)
  • (modified) clang/test/Driver/fcs-profile-generate.c (+8-4)
  • (modified) clang/test/Driver/fsplit-machine-functions.c (+8-4)
  • (modified) clang/test/Frontend/optimization-remark-with-hotness-new-pm.c (+6-5)
  • (modified) clang/test/Profile/c-captured.c (+1-1)
  • (modified) clang/test/Profile/c-counter-overflows.c (+1-1)
  • (modified) clang/test/Profile/c-general.c (+4-4)
  • (modified) clang/test/Profile/c-outdated-data.c (+2-2)
  • (modified) clang/test/Profile/c-unprofiled-blocks.c (+1-1)
  • (modified) clang/test/Profile/c-unprofiled.c (+1-1)
  • (modified) clang/test/Profile/cxx-class.cpp (+1-1)
  • (modified) clang/test/Profile/cxx-hash-v2.cpp (+2-2)
  • (modified) clang/test/Profile/cxx-lambda.cpp (+1-1)
  • (modified) clang/test/Profile/cxx-missing-bodies.cpp (+1-1)
  • (modified) clang/test/Profile/cxx-never-executed-branch.cpp (+1-1)
  • (modified) clang/test/Profile/cxx-rangefor.cpp (+1-1)
  • (modified) clang/test/Profile/cxx-templates.cpp (+1-1)
  • (modified) clang/test/Profile/cxx-throws.cpp (+2-2)
  • (modified) clang/test/Profile/func-entry.c (+1-1)
  • (modified) clang/test/Profile/misexpect-branch-cold.c (+1-1)
  • (modified) clang/test/Profile/misexpect-branch-nonconst-expected-val.c (+1-1)
  • (modified) clang/test/Profile/misexpect-branch-unpredictable.c (+1-1)
  • (modified) clang/test/Profile/misexpect-branch.c (+4-4)
  • (modified) clang/test/Profile/misexpect-switch-default.c (+1-1)
  • (modified) clang/test/Profile/misexpect-switch-nonconst.c (+1-1)
  • (modified) clang/test/Profile/misexpect-switch-only-default-case.c (+1-1)
  • (modified) clang/test/Profile/misexpect-switch.c (+1-1)
  • (modified) clang/test/Profile/objc-general.m (+1-1)
  • (modified) clang/test/Profile/profile-does-not-exist-ir.c (+7-3)
  • (modified) clang/test/Profile/profile-does-not-exist.c (+5-1)
  • (modified) clang/test/Profile/profile-summary.c (+1-1)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ceb69091b2a51..0581bf353d936 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -683,6 +683,9 @@ def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
   "option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">,
   InGroup<OptionIgnored>;
 
+def err_drv_profile_instrument_use_path_with_no_kind : Error<
+  "option '-fprofile-instrument-use-path=' requires -fprofile-instrument-use=<kind>">;
+
 def note_drv_verify_prefix_spelling : Note<
   "-verify prefixes must start with a letter and contain only alphanumeric"
   " characters, hyphens, and underscores">;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 16e1c396fedbe..42ee687dc917a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7937,6 +7937,11 @@ def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">,
     HelpText<"Generate instrumented code to collect execution counts into "
              "<file> (overridden by LLVM_PROFILE_FILE env var)">,
     MarshallingInfoString<CodeGenOpts<"InstrProfileOutput">>;
+def fprofile_instrument_use_EQ : Joined<["-"], "fprofile-instrument-use=">,
+    HelpText<"Enable PGO use instrumentation">, Values<"none,clang,llvm,csllvm,sample-coldcov">,
+    NormalizedValuesScope<"llvm::driver::ProfileInstrKind">,
+    NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr", "ProfileIRSampleColdCov"]>,
+    MarshallingInfoEnum<CodeGenOpts<"ProfileUse">, "ProfileNone">;
 def fprofile_instrument_use_path_EQ :
     Joined<["-"], "fprofile-instrument-use-path=">,
     HelpText<"Specify the profile path in PGO use compilation">,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 0b660e3daaf81..6d16b214c8159 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -492,10 +492,14 @@ CodeGenModule::CodeGenModule(ASTContext &C,
     auto ReaderOrErr = llvm::IndexedInstrProfReader::create(
         CodeGenOpts.ProfileInstrumentUsePath, *FS,
         CodeGenOpts.ProfileRemappingFile);
-    // We're checking for profile read errors in CompilerInvocation, so if
-    // there was an error it should've already been caught. If it hasn't been
-    // somehow, trip an assertion.
-    assert(ReaderOrErr);
+    if (auto E = ReaderOrErr.takeError()) {
+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+                                              "Error in reading profile %0: %1");
+      llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
+        Diags.Report(DiagID) << CodeGenOpts.ProfileInstrumentUsePath << EI.message();
+      });
+      return;
+    }
     PGOReader = std::move(ReaderOrErr.get());
   }
 
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index e7aabee273a34..b1acdfc4dc1b5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -41,6 +41,7 @@
 #include "llvm/Frontend/Debug/Options.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
@@ -485,20 +486,48 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
   }
 
   if (ProfileUseArg) {
+    SmallString<128> Path;
+    StringRef UsePath;
     if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
-      CmdArgs.push_back(Args.MakeArgString(
-          Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
+      UsePath = ProfileUseArg->getValue();
     else if ((ProfileUseArg->getOption().matches(
                   options::OPT_fprofile_use_EQ) ||
               ProfileUseArg->getOption().matches(
                   options::OPT_fprofile_instr_use))) {
-      SmallString<128> Path(
-          ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
+      Path =
+          ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue();
       if (Path.empty() || llvm::sys::fs::is_directory(Path))
         llvm::sys::path::append(Path, "default.profdata");
-      CmdArgs.push_back(
-          Args.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path));
+      UsePath = Path;
+    }
+    StringRef UseKind;
+    auto ReaderOrErr = llvm::IndexedInstrProfReader::create(
+        UsePath, D.getVFS());
+    if (auto E = ReaderOrErr.takeError()) {
+      auto DiagID = D.getDiags().getCustomDiagID(
+          DiagnosticsEngine::Error, "Error in reading profile %0: %1");
+      llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
+        D.Diag(DiagID) << UsePath.str() << EI.message();
+      });
+      return;
     }
+    std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
+        std::move(ReaderOrErr.get());
+    // Currently memprof profiles are only added at the IR level. Mark the
+    // profile type as IR in that case as well and the subsequent matching needs
+    // to detect which is available (might be one or both).
+    if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {
+      if (PGOReader->hasCSIRLevelProfile())
+        UseKind = "csllvm";
+      else
+        UseKind = "llvm";
+    } else
+      UseKind = "clang";
+
+    CmdArgs.push_back(
+        Args.MakeArgString("-fprofile-instrument-use=" + UseKind));
+    CmdArgs.push_back(
+        Args.MakeArgString("-fprofile-instrument-use-path=" + UsePath));
   }
 
   bool EmitCovNotes = Args.hasFlag(options::OPT_ftest_coverage,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 422375240bab6..a0e0f3771846a 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1473,34 +1473,6 @@ static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S) {
   return Buffer;
 }
 
-// Set the profile kind using fprofile-instrument-use-path.
-static void setPGOUseInstrumentor(CodeGenOptions &Opts,
-                                  const Twine &ProfileName,
-                                  llvm::vfs::FileSystem &FS,
-                                  DiagnosticsEngine &Diags) {
-  auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);
-  if (auto E = ReaderOrErr.takeError()) {
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                            "Error in reading profile %0: %1");
-    llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
-      Diags.Report(DiagID) << ProfileName.str() << EI.message();
-    });
-    return;
-  }
-  std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
-    std::move(ReaderOrErr.get());
-  // Currently memprof profiles are only added at the IR level. Mark the profile
-  // type as IR in that case as well and the subsequent matching needs to detect
-  // which is available (might be one or both).
-  if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {
-    if (PGOReader->hasCSIRLevelProfile())
-      Opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileCSIRInstr);
-    else
-      Opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileIRInstr);
-  } else
-    Opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileClangInstr);
-}
-
 void CompilerInvocation::setDefaultPointerAuthOptions(
     PointerAuthOptions &Opts, const LangOptions &LangOpts,
     const llvm::Triple &Triple) {
@@ -5090,16 +5062,10 @@ bool CompilerInvocation::CreateFromArgsImpl(
     append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
   }
 
-  // Set PGOOptions. Need to create a temporary VFS to read the profile
-  // to determine the PGO type.
-  if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
-    auto FS =
-        createVFSFromOverlayFiles(Res.getHeaderSearchOpts().VFSOverlayFiles,
-                                  Diags, llvm::vfs::getRealFileSystem());
-    setPGOUseInstrumentor(Res.getCodeGenOpts(),
-                          Res.getCodeGenOpts().ProfileInstrumentUsePath, *FS,
-                          Diags);
-  }
+  if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty() &&
+      Res.getCodeGenOpts().getProfileUse() ==
+          llvm::driver::ProfileInstrKind::ProfileNone)
+    Diags.Report(diag::err_drv_profile_instrument_use_path_with_no_kind);
 
   FixupInvocation(Res, Diags, Args, DashX);
 
diff --git a/clang/test/CodeGen/cspgo-instrumentation.c b/clang/test/CodeGen/cspgo-instrumentation.c
index 3f90bb4396d70..f42d68aba0eaa 100644
--- a/clang/test/CodeGen/cspgo-instrumentation.c
+++ b/clang/test/CodeGen/cspgo-instrumentation.c
@@ -9,19 +9,19 @@
 // RUN: llvm-profdata merge -o %t/noncs.profdata %S/Inputs/pgotestir.proftext
 //
 // Ensure Pass PGOInstrumentationUsePass and PGOInstrumentationGenPass are invoked.
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw  %s -fdebug-pass-manager  -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=llvm -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw  %s -fdebug-pass-manager  -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2: Running pass: PGOInstrumentationGenCreateVar on
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2: Running pass: PGOInstrumentationGen on
 
 // Ensure Pass PGOInstrumentationUsePass is invoked only once.
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata %s -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=llvm -fprofile-instrument-use-path=%t/noncs.profdata %s -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE
 // CHECK-PGOUSEPASS-INVOKED-USE: Running pass: PGOInstrumentationUse
 // CHECK-PGOUSEPASS-INVOKED-USE-NOT: Running pass: PGOInstrumentationGenCreateVar
 // CHECK-PGOUSEPASS-INVOKED-USE-NOT: Running pass: PGOInstrumentationUse
 //
 // Ensure Pass PGOInstrumentationUsePass is invoked twice.
 // RUN: llvm-profdata merge -o %t/cs.profdata %S/Inputs/pgotestir_cs.proftext
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -fdebug-pass-manager  -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE2
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=csllvm -fprofile-instrument-use-path=%t/cs.profdata %s -fdebug-pass-manager  -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE2
 // CHECK-PGOUSEPASS-INVOKED-USE2: Running pass: PGOInstrumentationUse
 // CHECK-PGOUSEPASS-INVOKED-USE2: Running pass: PGOInstrumentationUse
diff --git a/clang/test/CodeGen/cspgo-instrumentation_lto.c b/clang/test/CodeGen/cspgo-instrumentation_lto.c
index c4296842ae50e..5d541c6688a1f 100644
--- a/clang/test/CodeGen/cspgo-instrumentation_lto.c
+++ b/clang/test/CodeGen/cspgo-instrumentation_lto.c
@@ -4,7 +4,7 @@
 // RUN: llvm-profdata merge -o %t/noncs.profdata %S/Inputs/pgotestir.proftext
 //
 // Ensure Pass PGOInstrumentationGenPass is not invoked in PreLink.
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -flto -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=llvm -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -flto -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: Running pass: PGOInstrumentationGenCreateVar
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NOT: Running pass: PGOInstrumentationGen on
@@ -18,12 +18,12 @@
 // RUN: llvm-profdata merge -o %t/cs.profdata %S/Inputs/pgotestir_cs.proftext
 //
 // Ensure Pass PGOInstrumentationUsePass is invoked Once in PreLink.
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -flto -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=csllvm -fprofile-instrument-use-path=%t/cs.profdata %s -flto -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NOT: Running pass: PGOInstrumentationGenCreateVar
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NOT: Running pass: PGOInstrumentationUse
 //
 // Ensure Pass PGOInstrumentationUSEPass is invoked in PostLink.
-// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fdebug-pass-manager -fprofile-instrument-use-path=%t/cs.profdata -flto -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fdebug-pass-manager -fprofile-instrument-use=csllvm -fprofile-instrument-use-path=%t/cs.profdata -flto -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NOT: Running pass: PGOInstrumentationUse
diff --git a/clang/test/CodeGen/cspgo-instrumentation_thinlto.c b/clang/test/CodeGen/cspgo-instrumentation_thinlto.c
index f79433827ce17..0627f64a69728 100644
--- a/clang/test/CodeGen/cspgo-instrumentation_thinlto.c
+++ b/clang/test/CodeGen/cspgo-instrumentation_thinlto.c
@@ -4,7 +4,7 @@
 // RUN: llvm-profdata merge -o %t/noncs.profdata %S/Inputs/pgotestir.proftext
 //
 // Ensure Pass PGOInstrumentationGenPass is not invoked in PreLink.
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -fprofile-instrument-path=default.profraw  -flto=thin -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=llvm -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -fprofile-instrument-path=default.profraw  -flto=thin -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: Running pass: PGOInstrumentationGenCreateVar
 // CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NOT: Running pass: PGOInstrumentationGen on
@@ -19,16 +19,16 @@
 // RUN: llvm-profdata merge -o %t/cs.profdata %S/Inputs/pgotestir_cs.proftext
 //
 // Ensure Pass PGOInstrumentationUsePass is invoked Once in PreLink.
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -flto=thin -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=csllvm -fprofile-instrument-use-path=%t/cs.profdata %s -flto=thin -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NOT: Running pass: PGOInstrumentationUse
 //
 // RUN: llvm-lto -thinlto -o %t/foo_pm %t/foo_fe_pm.bc
 // Ensure Pass PGOInstrumentationUSEPass is invoked in PostLink.
-// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fdebug-pass-manager -fprofile-instrument-use-path=%t/cs.profdata -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fdebug-pass-manager -fprofile-instrument-use=csllvm -fprofile-instrument-use-path=%t/cs.profdata -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST: Running pass: PGOInstrumentationUse
 // CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NOT: Running pass: PGOInstrumentationUse
 //
 // Finally, test if a non-cs profile is passed to PostLink passes, PGO UsePass is not invoked.
-// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fdebug-pass-manager -fprofile-instrument-use-path=%t/noncs.profdata -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fdebug-pass-manager -fprofile-instrument-use=llvm -fprofile-instrument-use-path=%t/noncs.profdata -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST
 // CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST-NOT: Running pass: PGOInstrumentationUse
diff --git a/clang/test/CodeGen/opt-record.c b/clang/test/CodeGen/opt-record.c
index 391c14b7bbcc2..f54a6225760aa 100644
--- a/clang/test/CodeGen/opt-record.c
+++ b/clang/test/CodeGen/opt-record.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -emit-obj
 // RUN: cat %t.yaml | FileCheck %s
 // RUN: llvm-profdata merge %S/Inputs/opt-record.proftext -o %t.profdata
-// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -fprofile-instrument-use-path=%t.profdata %s -o %t -opt-record-file %t.yaml -emit-obj
+// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -fprofile-instrument-use=clang -fprofile-instrument-use-path=%t.profdata %s -o %t -opt-record-file %t.yaml -emit-obj
 // RUN: cat %t.yaml | FileCheck -check-prefix=CHECK -check-prefix=CHECK-PGO %s
 // RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -opt-record-passes inline -emit-obj
 // RUN: cat %t.yaml | FileCheck -check-prefix=CHECK-PASSES %s
diff --git a/clang/test/CodeGen/pgo-instrumentation.c b/clang/test/CodeGen/pgo-instrumentation.c
index c01658065497e..7c878250ae33e 100644
--- a/clang/test/CodeGen/pgo-instrumentation.c
+++ b/clang/test/CodeGen/pgo-instrumentation.c
@@ -15,10 +15,10 @@
 
 // Ensure Pass PGOInstrumentationUsePass is invoked.
 // RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestir.profraw
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t.profdata %s -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=llvm -fprofile-instrument-use-path=%t.profdata %s -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE
 // CHECK-PGOUSEPASS-INVOKED-INSTR-USE: Running pass: PGOInstrumentationUse on
 //
 // Ensure Pass PGOInstrumentationUsePass is not invoked.
 // RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestclang.profraw
-// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t.profdata %s -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE-CLANG
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use=clang -fprofile-instrument-use-path=%t.profdata %s -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE-CLANG
 // CHECK-PGOUSEPASS-INVOKED-USE-CLANG-NOT: Running pass: PGOInstrumentationUse on
diff --git a/clang/test/CodeGen/thinlto-clang-diagnostic-handler-in-be.c b/clang/test/CodeGen/thinlto-clang-diagnostic-handler-in-be.c
index efbcc851ad770..a12574d28c...
[truncated]

Copy link

github-actions bot commented Sep 18, 2025

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

@jansvoboda11 jansvoboda11 requested a review from bogner September 29, 2025 16:18
@jansvoboda11
Copy link
Contributor Author

Also requesting a review from @bogner as the LLVM maintainer of InstrProfiling.

jansvoboda11 added a commit to jansvoboda11/llvm-project that referenced this pull request Oct 1, 2025
@jansvoboda11 jansvoboda11 merged commit 839b91c into llvm:main Oct 6, 2025
9 checks passed
@jansvoboda11 jansvoboda11 deleted the profile-instrument-use-in-driver branch October 6, 2025 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants