[Mlir-commits] [clang] [flang] [mlir] [Flang][Driver] Add support for '-fprofile-sample-use' option (PR #188697)
Kaviya Rajendiran
llvmlistbot at llvm.org
Thu Apr 2 03:49:29 PDT 2026
https://github.com/kaviya2510 updated https://github.com/llvm/llvm-project/pull/188697
>From 7136550a72ad25ad320af509e7ac4eebbaf6cb81 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <kaviyara2000 at gmail.com>
Date: Thu, 26 Mar 2026 12:26:57 +0530
Subject: [PATCH 1/5] [LLVM-Flang][Options] Add support for
'-fprofile-sample-use' option
---
clang/include/clang/Options/Options.td | 4 +--
clang/lib/Driver/ToolChains/Flang.cpp | 23 +++++++++++++
flang/include/flang/Frontend/CodeGenOptions.h | 3 ++
.../flang/Optimizer/Transforms/Passes.td | 4 +++
flang/include/flang/Tools/CrossToolHelpers.h | 2 ++
flang/lib/Frontend/CompilerInvocation.cpp | 3 ++
flang/lib/Frontend/FrontendActions.cpp | 6 ++++
flang/lib/Optimizer/Passes/Pipelines.cpp | 4 +--
.../lib/Optimizer/Transforms/FunctionAttr.cpp | 4 +++
flang/test/Driver/Inputs/pgo-sample.prof | 2 ++
flang/test/Driver/fprofile-sample-use.f90 | 30 ++++++++++++++++
flang/test/Integration/inputs/pgo-sample.prof | 2 ++
flang/test/Integration/profile-sample-use.f90 | 34 +++++++++++++++++++
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 3 +-
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 3 ++
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 3 ++
16 files changed, 125 insertions(+), 5 deletions(-)
create mode 100644 flang/test/Driver/Inputs/pgo-sample.prof
create mode 100644 flang/test/Driver/fprofile-sample-use.f90
create mode 100644 flang/test/Integration/inputs/pgo-sample.prof
create mode 100644 flang/test/Integration/profile-sample-use.f90
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 412683fd968b0..d904e5f268f4d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1768,10 +1768,10 @@ defm gnu_inline_asm : BoolFOption<"gnu-inline-asm",
PosFlag<SetTrue>>;
def fno_profile_sample_use : Flag<["-"], "fno-profile-sample-use">, Group<f_Group>,
- Visibility<[ClangOption, CLOption]>;
+ Visibility<[ClangOption, CLOption, FlangOption, FC1Option]>;
def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
Group<f_Group>,
- Visibility<[ClangOption, CLOption, CC1Option]>,
+ Visibility<[ClangOption, CLOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Enable sample-based profile guided optimizations">,
MarshallingInfoString<CodeGenOpts<"SampleProfileFile">>;
def fprofile_sample_accurate : Flag<["-"], "fprofile-sample-accurate">,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index e6a57fc89bc8b..1da0f29e4b8ec 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -987,6 +987,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = TC.getDriver();
ArgStringList CmdArgs;
+ bool IsCudaDevice = JA.isDeviceOffloading(Action::OFK_Cuda);
+ bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
+
// Invoke ourselves in -fc1 mode.
CmdArgs.push_back("-fc1");
@@ -1100,6 +1103,26 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
Args.addAllArgs(
CmdArgs, {options::OPT_fprofile_generate, options::OPT_fprofile_use_EQ});
+ if (!(IsCudaDevice || IsHIPDevice)) {
+ // recognise options: -fprofile-sample-use= and -fno-profile-sample-use=
+ if (Arg *A = getLastProfileSampleUseArg(Args)) {
+
+ auto *PGOArg = Args.getLastArg(options::OPT_fprofile_generate,
+ options::OPT_fprofile_generate_EQ);
+
+ if (PGOArg) {
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << PGOArg->getAsString(Args) << A->getAsString(Args);
+ }
+
+ StringRef fname = A->getValue();
+ if (!llvm::sys::fs::exists(fname))
+ D.Diag(diag::err_drv_no_such_file) << fname;
+ else
+ A->render(Args, CmdArgs);
+ }
+ }
+
// Forward flags for OpenMP. We don't do this if the current action is an
// device offloading action other than OpenMP.
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 0fc0063128547..ac3392667d79e 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -181,6 +181,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Output filename for the split debug info, not used in the skeleton CU.
std::string SplitDwarfOutput;
+ /// Name of the profile file to use with -fprofile-sample-use.
+ std::string SampleProfileFile;
+
/// Check if Clang profile instrumenation is on.
bool hasProfileClangInstr() const {
return getProfileInstr() == llvm::driver::ProfileClangInstr;
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 82d89c4df42c3..1d636038a72ce 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -463,6 +463,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> {
/*default=*/"",
"Set the prefer-vector-width attribute on functions in the "
"module.">,
+ Option<"UseSampleProfile", "use-sample-profile", "bool",
+ /*default=*/"false",
+ "Set the use-sample-profile attribute on functions in the "
+ "module.">,
Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"",
"Set the tune-cpu attribute on functions in the module.">,
Option<"setNoCapture", "set-nocapture", "bool", /*default=*/"false",
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h
index 4415a0417be01..9c868c67099f5 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -106,6 +106,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
ApproxFuncFPMath && mathOpts.getFPContractEnabled();
Reciprocals = opts.Reciprocals;
PreferVectorWidth = opts.PreferVectorWidth;
+ UseSampleProfile = !opts.SampleProfileFile.empty();
DebugInfoForProfiling = opts.DebugInfoForProfiling;
if (opts.InstrumentFunctions) {
InstrumentFunctionEntry = "__cyg_profile_func_enter";
@@ -140,6 +141,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
///< functions.
bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments.
bool EnableOpenMP = false; ///< Enable OpenMP lowering.
+ bool UseSampleProfile = false; /// Enable sample based profiling
bool DebugInfoForProfiling = false; /// Enable extra debugging info
bool EnableOpenMPSimd = false; ///< Enable OpenMP simd-only mode.
bool SkipConvertComplexPow = false; ///< Do not run complex pow conversion.
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 8d99fc9d4403e..4190be358b8fa 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -469,6 +469,9 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.ProfileInstrumentUsePath = A->getValue();
}
+ opts.SampleProfileFile =
+ args.getLastArgValue(clang::options::OPT_fprofile_sample_use_EQ);
+
// -mcmodel option.
if (const llvm::opt::Arg *a =
args.getLastArg(clang::options::OPT_mcmodel_EQ)) {
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index ec9e8f48693fe..4e058786a9a72 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -991,6 +991,12 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
llvm::PGOOptions::NoAction,
llvm::PGOOptions::NoCSAction,
llvm::PGOOptions::ColdFuncOpt::Default, true);
+ } else if (!opts.SampleProfileFile.empty()) {
+ pgoOpt = llvm::PGOOptions(
+ opts.SampleProfileFile, "", opts.ProfileRemappingFile,
+ opts.MemoryProfileUsePath, llvm::PGOOptions::SampleUse,
+ llvm::PGOOptions::NoCSAction, llvm::PGOOptions::ColdFuncOpt::Default,
+ opts.DebugInfoForProfiling, /*PseudoProbeForProfiling=*/false);
}
llvm::StandardInstrumentations si(llvmModule->getContext(),
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 2216fc0c68494..73e647a1c3956 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -420,8 +420,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
{framePointerKind, config.InstrumentFunctionEntry,
config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath,
config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath,
- config.Reciprocals, config.PreferVectorWidth, /*tuneCPU=*/"",
- setNoCapture, setNoAlias}));
+ config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile,
+ /*tuneCPU=*/"", setNoCapture, setNoAlias}));
if (config.EnableOpenMP) {
pm.addNestedPass<mlir::func::FuncOp>(
diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
index 857491fc90cc3..2b17eb03792f2 100644
--- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
+++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
@@ -123,6 +123,10 @@ void FunctionAttrPass::runOnOperation() {
context, mlir::LLVM::LLVMFuncOp::getPreferVectorWidthAttrName(
llvmFuncOpName)),
mlir::StringAttr::get(context, preferVectorWidth));
+ if (UseSampleProfile)
+ func->setAttr(
+ mlir::LLVM::LLVMFuncOp::getUseSampleProfileAttrName(llvmFuncOpName),
+ mlir::BoolAttr::get(context, true));
LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
}
diff --git a/flang/test/Driver/Inputs/pgo-sample.prof b/flang/test/Driver/Inputs/pgo-sample.prof
new file mode 100644
index 0000000000000..1ba66a38d713b
--- /dev/null
+++ b/flang/test/Driver/Inputs/pgo-sample.prof
@@ -0,0 +1,2 @@
+hot_:100:100
+ 2: 100
diff --git a/flang/test/Driver/fprofile-sample-use.f90 b/flang/test/Driver/fprofile-sample-use.f90
new file mode 100644
index 0000000000000..f2271081a019d
--- /dev/null
+++ b/flang/test/Driver/fprofile-sample-use.f90
@@ -0,0 +1,30 @@
+! Test to check the working of option "-fprofile-sample-use".
+
+! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE
+! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: %flang -### -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: not %flang -fsyntax-only -fprofile-sample-use=%t/missing-profile.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-NO-FILE
+! RUN: not %flang -fsyntax-only -fprofile-generate -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-ERROR
+
+! PROFILE-SAMPLE-USE: "-fprofile-sample-use={{.*}}/Inputs/pgo-sample.prof"
+! NO-PROFILE-SAMPLE-USE-NOT: "-fprofile-sample-use"
+! PROFILE-SAMPLE-USE-NO-FILE: error: no such file or directory: {{.*}}missing-profile.prof{{.*}}
+! PROFILE-SAMPLE-USE-ERROR: error: invalid argument '-fprofile-generate' not allowed with '-fprofile-sample-use={{.*}}'
+
+integer function hot(x)
+ integer, intent(in) :: x
+ hot = x*2
+end function hot
+
+integer function cold(x)
+ integer, intent(in) :: x
+ cold = x - 10
+end function
+
+program test_sample_use
+ integer :: i, r
+ do i = 1, 100
+ r = hot(i)
+ end do
+ end program test_sample_use
diff --git a/flang/test/Integration/inputs/pgo-sample.prof b/flang/test/Integration/inputs/pgo-sample.prof
new file mode 100644
index 0000000000000..1ba66a38d713b
--- /dev/null
+++ b/flang/test/Integration/inputs/pgo-sample.prof
@@ -0,0 +1,2 @@
+hot_:100:100
+ 2: 100
diff --git a/flang/test/Integration/profile-sample-use.f90 b/flang/test/Integration/profile-sample-use.f90
new file mode 100644
index 0000000000000..c92a2f235a0ab
--- /dev/null
+++ b/flang/test/Integration/profile-sample-use.f90
@@ -0,0 +1,34 @@
+! Test to check the working of option "-fprofile-sample-use".
+! RUN: %flang -S -emit-llvm -g -fprofile-sample-use=%S/inputs/pgo-sample.prof -o - %s | FileCheck %s
+
+! CHECK: attributes #[[A:.*]] = { {{.*}}"use-sample-profile"{{.*}} }
+! CHECK: !{i32 {{.*}}, !"ProfileSummary"{{.*}}}
+! CHECK: !{!"ProfileFormat", !"SampleProfile"}
+! CHECK: !{!"TotalCount", i64 100}
+! CHECK: !{!"MaxCount", i64 100}
+! CHECK: !{!"MaxInternalCount", i64 0}
+! CHECK: !{!"MaxFunctionCount", i64 100}
+! CHECK: !{!"NumCounts", i64 1}
+! CHECK: !{!"NumFunctions", i64 1}
+! CHECK: !{!"IsPartialProfile", i64 0}
+! CHECK: !{!"PartialProfileRatio", double 0.000000e+00}
+! CHECK: distinct !DISubprogram(name: "hot", linkageName: "hot_", scope: !1
+! CHECK: !{!"function_entry_count", i64 101}
+
+integer function hot(x)
+ integer, intent(in) :: x
+ hot = x * 2
+end function hot
+
+integer function cold(x)
+ integer, intent(in) :: x
+ cold = x - 10
+end function cold
+
+program test_sample_use
+ implicit none
+ integer :: i, r
+ do i = 1, 100
+ r = hot(i)
+ end do
+end program test_sample_use
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index ccb933230b65a..98f7e4e43870b 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2051,7 +2051,8 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
OptionalAttr<DenseI32ArrayAttr>:$work_group_size_hint,
OptionalAttr<DenseI32ArrayAttr>:$reqd_work_group_size,
OptionalAttr<I32Attr>:$intel_reqd_sub_group_size,
- OptionalAttr<UWTableKindAttr>:$uwtable_kind
+ OptionalAttr<UWTableKindAttr>:$uwtable_kind,
+ OptionalAttr<BoolAttr>:$use_sample_profile
);
let regions = (region AnyRegion:$body);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 25aaccecc56a2..4ea16800d8982 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -2880,6 +2880,9 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func,
.value()));
}
+ if (func->hasFnAttribute("use-sample-profile"))
+ funcOp.setUseSampleProfile(true);
+
if (llvm::Attribute attr = func->getFnAttribute("target-cpu");
attr.isStringAttribute())
funcOp.setTargetCpuAttr(StringAttr::get(context, attr.getValueAsString()));
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index f4a6e5f6fc8f6..cf398f151ed0b 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1564,6 +1564,9 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
if (auto preferVectorWidth = func.getPreferVectorWidth())
llvmFunc->addFnAttr("prefer-vector-width", *preferVectorWidth);
+ if (func.getUseSampleProfile())
+ llvmFunc->addFnAttr("use-sample-profile");
+
if (auto attr = func.getVscaleRange())
llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
getLLVMContext(), attr->getMinRange().getInt(),
>From f30fa4e89288c57b4ce6677be428c679bf490b4f Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <kaviyara2000 at gmail.com>
Date: Tue, 31 Mar 2026 23:08:44 +0530
Subject: [PATCH 2/5] [Flang][Driver] Addressed review comments
---
clang/lib/Driver/ToolChains/Flang.cpp | 56 ++++++++++++-------
.../lib/Optimizer/Transforms/FunctionAttr.cpp | 4 +-
flang/test/Driver/fprofile-sample-use.f90 | 14 ++++-
flang/test/Integration/profile-sample-use.f90 | 2 +-
4 files changed, 50 insertions(+), 26 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 1da0f29e4b8ec..88bc1592b5651 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -977,6 +977,39 @@ static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
}
}
+static void addPGOAndCoverageFlags(const ToolChain &TC, const JobAction &JA,
+ const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ const Driver &D = TC.getDriver();
+ const llvm::Triple &T = TC.getTriple();
+
+ bool IsCudaDevice = JA.isDeviceOffloading(Action::OFK_Cuda);
+ bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
+
+ if (T.isOSAIX()) {
+ if (Arg *ProfileSampleUseArg = getLastProfileSampleUseArg(Args))
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << ProfileSampleUseArg->getSpelling() << TC.getTriple().str();
+ }
+
+ if (!(IsCudaDevice || IsHIPDevice)) {
+ // recognise options: -fprofile-sample-use= and -fno-profile-sample-use=
+ if (Arg *A = getLastProfileSampleUseArg(Args)) {
+ if (Arg *PGOArg = Args.getLastArg(options::OPT_fprofile_generate,
+ options::OPT_fprofile_generate_EQ)) {
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << PGOArg->getAsString(Args) << A->getAsString(Args);
+ }
+
+ StringRef fname = A->getValue();
+ if (!llvm::sys::fs::exists(fname))
+ D.Diag(diag::err_drv_no_such_file) << fname;
+ else
+ A->render(Args, CmdArgs);
+ }
+ }
+}
+
void Flang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const ArgList &Args, const char *LinkingOutput) const {
@@ -987,9 +1020,6 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = TC.getDriver();
ArgStringList CmdArgs;
- bool IsCudaDevice = JA.isDeviceOffloading(Action::OFK_Cuda);
- bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
-
// Invoke ourselves in -fc1 mode.
CmdArgs.push_back("-fc1");
@@ -1103,24 +1133,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
Args.addAllArgs(
CmdArgs, {options::OPT_fprofile_generate, options::OPT_fprofile_use_EQ});
- if (!(IsCudaDevice || IsHIPDevice)) {
- // recognise options: -fprofile-sample-use= and -fno-profile-sample-use=
- if (Arg *A = getLastProfileSampleUseArg(Args)) {
-
- auto *PGOArg = Args.getLastArg(options::OPT_fprofile_generate,
- options::OPT_fprofile_generate_EQ);
-
- if (PGOArg) {
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << PGOArg->getAsString(Args) << A->getAsString(Args);
- }
-
- StringRef fname = A->getValue();
- if (!llvm::sys::fs::exists(fname))
- D.Diag(diag::err_drv_no_such_file) << fname;
- else
- A->render(Args, CmdArgs);
- }
+ if (!Triple.isNVPTX()) {
+ addPGOAndCoverageFlags(TC, JA, Args, CmdArgs);
}
// Forward flags for OpenMP. We don't do this if the current action is an
diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
index 2b17eb03792f2..b49803e989265 100644
--- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
+++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
@@ -125,7 +125,9 @@ void FunctionAttrPass::runOnOperation() {
mlir::StringAttr::get(context, preferVectorWidth));
if (UseSampleProfile)
func->setAttr(
- mlir::LLVM::LLVMFuncOp::getUseSampleProfileAttrName(llvmFuncOpName),
+ getLlvmFuncPropertyAttrName(
+ context, mlir::LLVM::LLVMFuncOp::getUseSampleProfileAttrName(
+ llvmFuncOpName)),
mlir::BoolAttr::get(context, true));
LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
diff --git a/flang/test/Driver/fprofile-sample-use.f90 b/flang/test/Driver/fprofile-sample-use.f90
index f2271081a019d..a7fb6f61fa9c5 100644
--- a/flang/test/Driver/fprofile-sample-use.f90
+++ b/flang/test/Driver/fprofile-sample-use.f90
@@ -1,17 +1,25 @@
! Test to check the working of option "-fprofile-sample-use".
-! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE
! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
-! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE
! RUN: %flang -### -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+
+! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+
! RUN: not %flang -fsyntax-only -fprofile-sample-use=%t/missing-profile.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-NO-FILE
! RUN: not %flang -fsyntax-only -fprofile-generate -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-ERROR
-! PROFILE-SAMPLE-USE: "-fprofile-sample-use={{.*}}/Inputs/pgo-sample.prof"
+! RUN: not %flang -target powerpc-ibm-aix -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 \
+! RUN: | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-UNSUPPORTED-AIX
+
! NO-PROFILE-SAMPLE-USE-NOT: "-fprofile-sample-use"
+! PROFILE-SAMPLE-USE: "-fprofile-sample-use={{.*}}/Inputs/pgo-sample.prof"
+
! PROFILE-SAMPLE-USE-NO-FILE: error: no such file or directory: {{.*}}missing-profile.prof{{.*}}
! PROFILE-SAMPLE-USE-ERROR: error: invalid argument '-fprofile-generate' not allowed with '-fprofile-sample-use={{.*}}'
+! PROFILE-SAMPLE-USE-UNSUPPORTED-AIX: error: unsupported option '-fprofile-sample-use=' for target 'powerpc-ibm-aix'
+
integer function hot(x)
integer, intent(in) :: x
hot = x*2
diff --git a/flang/test/Integration/profile-sample-use.f90 b/flang/test/Integration/profile-sample-use.f90
index c92a2f235a0ab..6292ef817077c 100644
--- a/flang/test/Integration/profile-sample-use.f90
+++ b/flang/test/Integration/profile-sample-use.f90
@@ -1,5 +1,5 @@
! Test to check the working of option "-fprofile-sample-use".
-! RUN: %flang -S -emit-llvm -g -fprofile-sample-use=%S/inputs/pgo-sample.prof -o - %s | FileCheck %s
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone -fprofile-sample-use=%S/inputs/pgo-sample.prof -o - %s | FileCheck %s
! CHECK: attributes #[[A:.*]] = { {{.*}}"use-sample-profile"{{.*}} }
! CHECK: !{i32 {{.*}}, !"ProfileSummary"{{.*}}}
>From 2443bfe3b3d4bf378add09610a0c4016d7076e4b Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <kaviyara2000 at gmail.com>
Date: Thu, 2 Apr 2026 10:16:29 +0530
Subject: [PATCH 3/5] [flang][driver] Addressed NIT
---
clang/lib/Driver/ToolChains/Flang.cpp | 4 +---
flang/include/flang/Tools/CrossToolHelpers.h | 4 ++--
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 88bc1592b5651..edd3c4eb90dfe 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -1133,9 +1133,7 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
Args.addAllArgs(
CmdArgs, {options::OPT_fprofile_generate, options::OPT_fprofile_use_EQ});
- if (!Triple.isNVPTX()) {
- addPGOAndCoverageFlags(TC, JA, Args, CmdArgs);
- }
+ addPGOAndCoverageFlags(TC, JA, Args, CmdArgs);
// Forward flags for OpenMP. We don't do this if the current action is an
// device offloading action other than OpenMP.
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h
index 9c868c67099f5..6240354bd899a 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -141,8 +141,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
///< functions.
bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments.
bool EnableOpenMP = false; ///< Enable OpenMP lowering.
- bool UseSampleProfile = false; /// Enable sample based profiling
- bool DebugInfoForProfiling = false; /// Enable extra debugging info
+ bool UseSampleProfile = false; ///< Enable sample based profiling
+ bool DebugInfoForProfiling = false; ///< Enable extra debugging info
bool EnableOpenMPSimd = false; ///< Enable OpenMP simd-only mode.
bool SkipConvertComplexPow = false; ///< Do not run complex pow conversion.
std::string InstrumentFunctionEntry =
>From 66b6edc7b7fdf181df08e0495ef2051f2e490888 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <kaviyara2000 at gmail.com>
Date: Thu, 2 Apr 2026 11:30:17 +0530
Subject: [PATCH 4/5] [flang][driver] Modified testcase to check for target
x86_64-unknown-linux
---
flang/test/Driver/fprofile-sample-use.f90 | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/flang/test/Driver/fprofile-sample-use.f90 b/flang/test/Driver/fprofile-sample-use.f90
index a7fb6f61fa9c5..536ab23b8a220 100644
--- a/flang/test/Driver/fprofile-sample-use.f90
+++ b/flang/test/Driver/fprofile-sample-use.f90
@@ -1,15 +1,15 @@
! Test to check the working of option "-fprofile-sample-use".
-! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
-! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE
-! RUN: %flang -### -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: %flang -### -target x86_64-unknown-linux %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: %flang -### -target x86_64-unknown-linux -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE
+! RUN: %flang -### -target x86_64-unknown-linux -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
-! RUN: %flang -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
+! RUN: %flang -### -target x86_64-unknown-linux -fprofile-sample-use=%S/Inputs/pgo-sample.prof -fno-profile-sample-use %s 2>&1 | FileCheck %s --check-prefix=NO-PROFILE-SAMPLE-USE
-! RUN: not %flang -fsyntax-only -fprofile-sample-use=%t/missing-profile.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-NO-FILE
-! RUN: not %flang -fsyntax-only -fprofile-generate -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-ERROR
+! RUN: not %flang -target x86_64-unknown-linux -fsyntax-only -fprofile-sample-use=%t/missing-profile.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-NO-FILE
+! RUN: not %flang -target x86_64-unknown-linux -fsyntax-only -fprofile-generate -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-ERROR
-! RUN: not %flang -target powerpc-ibm-aix -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 \
+! RUN: not %flang -target powerpc64-ibm-aix -### -fprofile-sample-use=%S/Inputs/pgo-sample.prof %s 2>&1 \
! RUN: | FileCheck %s --check-prefix=PROFILE-SAMPLE-USE-UNSUPPORTED-AIX
! NO-PROFILE-SAMPLE-USE-NOT: "-fprofile-sample-use"
@@ -18,7 +18,7 @@
! PROFILE-SAMPLE-USE-NO-FILE: error: no such file or directory: {{.*}}missing-profile.prof{{.*}}
! PROFILE-SAMPLE-USE-ERROR: error: invalid argument '-fprofile-generate' not allowed with '-fprofile-sample-use={{.*}}'
-! PROFILE-SAMPLE-USE-UNSUPPORTED-AIX: error: unsupported option '-fprofile-sample-use=' for target 'powerpc-ibm-aix'
+! PROFILE-SAMPLE-USE-UNSUPPORTED-AIX: error: unsupported option '-fprofile-sample-use=' for target 'powerpc64-ibm-aix'
integer function hot(x)
integer, intent(in) :: x
>From 7f3858ad720d36ba2c78e257cbeea0ee5fb2eda6 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <kaviyara2000 at gmail.com>
Date: Thu, 2 Apr 2026 14:55:05 +0530
Subject: [PATCH 5/5] [flang][driver] Added MLIR import and export testcase for
use-sample-profile
---
mlir/test/Target/LLVMIR/Import/use-sample-profile.ll | 9 +++++++++
mlir/test/Target/LLVMIR/use-sample-profile.mlir | 7 +++++++
2 files changed, 16 insertions(+)
create mode 100644 mlir/test/Target/LLVMIR/Import/use-sample-profile.ll
create mode 100644 mlir/test/Target/LLVMIR/use-sample-profile.mlir
diff --git a/mlir/test/Target/LLVMIR/Import/use-sample-profile.ll b/mlir/test/Target/LLVMIR/Import/use-sample-profile.ll
new file mode 100644
index 0000000000000..0df93194b07b6
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/use-sample-profile.ll
@@ -0,0 +1,9 @@
+; RUN: mlir-translate -import-llvm %s | FileCheck %s
+
+; CHECK-LABEL: llvm.func @use_sample_profile()
+; CHECK-SAME: use_sample_profile = true
+define void @use_sample_profile() #0 {
+ ret void
+}
+
+attributes #0 = { "use-sample-profile" }
diff --git a/mlir/test/Target/LLVMIR/use-sample-profile.mlir b/mlir/test/Target/LLVMIR/use-sample-profile.mlir
new file mode 100644
index 0000000000000..646187ab47b36
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/use-sample-profile.mlir
@@ -0,0 +1,7 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// CHECK: define void @use_sample_profile() #[[ATTRS:.*]] {
+// CHECK: attributes #[[ATTRS]] = { "use-sample-profile" }
+llvm.func @use_sample_profile() attributes {use_sample_profile = true} {
+ llvm.return
+}
More information about the Mlir-commits
mailing list