[flang-commits] [flang] [Flang][OpenMP] Skip unrelated passes in simd-only mode (PR #219193)
Sergio Afonso via flang-commits
flang-commits at lists.llvm.org
Thu Aug 27 07:46:29 PDT 2026
https://github.com/skatrak updated https://github.com/llvm/llvm-project/pull/219193
>From 357dd1b792ed76cda259e5c2ff07faf7c3046d90 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Thu, 27 Aug 2026 12:54:50 +0100
Subject: [PATCH 1/2] [Flang][OpenMP] Skip unrelated passes in simd-only mode
The `-fopenmp-simd` option allows the compiler to lower OpenMP `simd`
constructs while ignoring all other OpenMP directives.
This patch updates the compilation pipeline to avoid triggering passes
associated to any of these other OpenMP directives when compiling in
simd-only mode.
---
.../flang/Optimizer/Passes/Pipelines.h | 3 ++
flang/lib/Frontend/FrontendActions.cpp | 4 +--
flang/lib/Optimizer/Passes/Pipelines.cpp | 32 ++++++++++++-------
flang/tools/bbc/bbc.cpp | 1 +
4 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/flang/include/flang/Optimizer/Passes/Pipelines.h b/flang/include/flang/Optimizer/Passes/Pipelines.h
index 726607613260a..744c4c584d46a 100644
--- a/flang/include/flang/Optimizer/Passes/Pipelines.h
+++ b/flang/include/flang/Optimizer/Passes/Pipelines.h
@@ -166,6 +166,9 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm,
const MLIRToLLVMPassPipelineConfig &config);
struct OpenMPFIRPassPipelineOpts {
+ /// Whether only OpenMP simd constructs are being honored.
+ bool isSimdOnly;
+
/// Whether code is being generated for a target device rather than the host
/// device
bool isTargetDevice;
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 7ecda651027e2..7c664def5f000 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -310,9 +310,9 @@ bool CodeGenAction::beginSourceFileAction() {
bool isOpenMPEnabled =
ci.getInvocation().getFrontendOpts().features.IsEnabled(
Fortran::common::LanguageFeature::OpenMP);
- bool isOpenMPSimd = ci.getInvocation().getLangOpts().OpenMPSimd;
fir::OpenMPFIRPassPipelineOpts opts;
+ opts.isSimdOnly = ci.getInvocation().getLangOpts().OpenMPSimd;
using DoConcurrentMappingKind =
Fortran::frontend::CodeGenOptions::DoConcurrentMappingKind;
@@ -340,7 +340,7 @@ bool CodeGenAction::beginSourceFileAction() {
// WARNING: This pipeline must be run immediately after the lowering to
// ensure that the FIR is correct with respect to OpenMP operations/
// attributes.
- if (isOpenMPEnabled || isOpenMPSimd)
+ if (isOpenMPEnabled || opts.isSimdOnly)
fir::createOpenMPFIRPassPipeline(pm, opts);
pm.enableVerifier(/*verifyPasses=*/true);
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 4c5fd32cf342b..f7000ddfea624 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -316,7 +316,8 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm,
addNestedPassToAllTopLevelOperations<PassConstructor>(
pm, hlfir::createInlineHLFIRCopy);
}
- } else if (config.EnableOpenMPIsTargetDevice) {
+ } else if (config.EnableOpenMPIsTargetDevice &&
+ enableOpenMP == EnableOpenMP::Full) {
// At O0, only inline scalar-to-array broadcasts when compiling for an
// OpenMP target device. This avoids emitting Fortran runtime calls
// (e.g. _FortranAAssign) that use malloc/free in device code generated
@@ -354,12 +355,17 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm,
addNestedPassToAllTopLevelOperations<PassConstructor>(
pm, hlfir::createInlineHLFIRAssign);
pm.addPass(hlfir::createConvertHLFIRtoFIR());
- if (enableOpenMP != EnableOpenMP::None) {
+ switch (enableOpenMP) {
+ case EnableOpenMP::Full:
pm.addPass(flangomp::createLowerWorkshare());
pm.addPass(flangomp::createLowerWorkdistribute());
- }
- if (enableOpenMP == EnableOpenMP::Simd)
+ break;
+ case EnableOpenMP::Simd:
pm.addPass(flangomp::createSimdOnlyPass());
+ break;
+ case EnableOpenMP::None:
+ break;
+ }
}
/// Create a pass pipeline for handling certain OpenMP transformations needed
@@ -376,6 +382,10 @@ void createOpenMPFIRPassPipeline(mlir::PassManager &pm,
using DoConcurrentMappingKind =
Fortran::frontend::CodeGenOptions::DoConcurrentMappingKind;
+ // None of the passes below apply to simd constructs, so skip them.
+ if (opts.isSimdOnly)
+ return;
+
if (opts.doConcurrentMappingKind != DoConcurrentMappingKind::DCMK_None)
pm.addPass(flangomp::createDoConcurrentConversionPass(
opts.doConcurrentMappingKind == DoConcurrentMappingKind::DCMK_Device));
@@ -454,13 +464,11 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile,
/*tuneCPU=*/"", setNoCapture, setNoAlias, setReadOnly}));
- if (config.EnableOpenMP) {
+ bool runOMPNonSimdPasses = config.EnableOpenMP && !config.EnableOpenMPSimd;
+ if (runOMPNonSimdPasses) {
pm.addNestedPass<mlir::func::FuncOp>(
flangomp::createLowerNontemporalPass());
- }
- bool runOMPNonSimdPasses = config.EnableOpenMP && !config.EnableOpenMPSimd;
- if (runOMPNonSimdPasses) {
// Propagate implicit declare target information early in order to diagnose
// target device not-yet-implemented cases based on FIR.
pm.addPass(mlir::omp::createMarkDeclareTargetPass());
@@ -518,9 +526,11 @@ void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
// Run a pass to prepare for translation of delayed privatization in the
// context of deferred target tasks.
- addPassConditionally(pm, disableFirToLlvmIr, [&]() {
- return mlir::omp::createPrepareForOMPOffloadPrivatizationPass();
- });
+ if (enableOpenMP == EnableOpenMP::Full) {
+ addPassConditionally(pm, disableFirToLlvmIr, [&]() {
+ return mlir::omp::createPrepareForOMPOffloadPrivatizationPass();
+ });
+ }
}
/// Register the passes used in flang's MLIR pass pipeline so that
diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp
index 7860a0fc77cf3..cbc1a9df143bd 100644
--- a/flang/tools/bbc/bbc.cpp
+++ b/flang/tools/bbc/bbc.cpp
@@ -376,6 +376,7 @@ static llvm::LogicalResult runOpenMPPasses(mlir::ModuleOp mlirModule) {
Fortran::frontend::CodeGenOptions::DoConcurrentMappingKind;
fir::OpenMPFIRPassPipelineOpts opts;
+ opts.isSimdOnly = false;
opts.isTargetDevice = enableOpenMPDevice;
opts.doConcurrentMappingKind =
llvm::StringSwitch<DoConcurrentMappingKind>(
>From f8c818352a2d921da72b59da0098374393212020 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Thu, 27 Aug 2026 15:46:16 +0100
Subject: [PATCH 2/2] address review comments
---
flang/lib/Optimizer/Passes/Pipelines.cpp | 6 +-
flang/test/Driver/mlir-omp-pass-pipeline.f90 | 77 ++++++++++++++++++++
2 files changed, 81 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Driver/mlir-omp-pass-pipeline.f90
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index f7000ddfea624..981c69bbfb976 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -464,11 +464,13 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile,
/*tuneCPU=*/"", setNoCapture, setNoAlias, setReadOnly}));
- bool runOMPNonSimdPasses = config.EnableOpenMP && !config.EnableOpenMPSimd;
- if (runOMPNonSimdPasses) {
+ if (config.EnableOpenMP) {
pm.addNestedPass<mlir::func::FuncOp>(
flangomp::createLowerNontemporalPass());
+ }
+ bool runOMPNonSimdPasses = config.EnableOpenMP && !config.EnableOpenMPSimd;
+ if (runOMPNonSimdPasses) {
// Propagate implicit declare target information early in order to diagnose
// target device not-yet-implemented cases based on FIR.
pm.addPass(mlir::omp::createMarkDeclareTargetPass());
diff --git a/flang/test/Driver/mlir-omp-pass-pipeline.f90 b/flang/test/Driver/mlir-omp-pass-pipeline.f90
new file mode 100644
index 0000000000000..40e2c52b993a4
--- /dev/null
+++ b/flang/test/Driver/mlir-omp-pass-pipeline.f90
@@ -0,0 +1,77 @@
+! Test the MLIR pass pipeline for OpenMP
+
+! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefix=NO_OMP %s
+! RUN: %flang_fc1 -S -fopenmp -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefix=FULL %s
+! RUN: %flang_fc1 -S -fopenmp -fopenmp-simd -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefix=FULL %s
+! RUN: %flang_fc1 -S -fopenmp-simd -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefix=SIMD %s
+! RUN: %flang_fc1 -S -fopenmp -fopenmp-is-target-device -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefix=DEVICE %s
+
+! REQUIRES: asserts
+
+end program
+
+! NO_OMP-NOT: MapsForPrivatizedSymbolsPass
+! NO_OMP-NOT: AutomapToTargetDataPass
+! NO_OMP-NOT: MapInfoFinalizationPass
+! NO_OMP-NOT: GenericLoopConversionPass
+! NO_OMP-NOT: InlineHLFIRAssign
+! NO_OMP-NOT: LowerWorkshare
+! NO_OMP-NOT: LowerWorkdistribute
+! NO_OMP-NOT: SimdOnlyPass
+! NO_OMP-NOT: LowerNontemporalPass
+! NO_OMP-NOT: MarkDeclareTargetPass
+! NO_OMP-NOT: UnimplementedDeviceCheckPass
+! NO_OMP-NOT: FunctionFilteringPass
+! NO_OMP-NOT: HostOpFilteringPass
+! NO_OMP-NOT: StackToSharedPass
+! NO_OMP-NOT: PrepareForOMPOffloadPrivatizationPass
+
+! FULL: MapsForPrivatizedSymbolsPass
+! FULL: AutomapToTargetDataPass
+! FULL: MapInfoFinalizationPass
+! FULL: GenericLoopConversionPass
+! FULL-NOT: InlineHLFIRAssign
+! FULL: LowerWorkshare
+! FULL: LowerWorkdistribute
+! FULL-NOT: SimdOnlyPass
+! FULL: LowerNontemporalPass
+! FULL: MarkDeclareTargetPass
+! FULL: UnimplementedDeviceCheckPass
+! FULL: MarkDeclareTargetPass
+! FULL: FunctionFilteringPass
+! FULL: HostOpFilteringPass
+! FULL: StackToSharedPass
+! FULL: PrepareForOMPOffloadPrivatizationPass
+
+! SIMD-NOT: MapsForPrivatizedSymbolsPass
+! SIMD-NOT: AutomapToTargetDataPass
+! SIMD-NOT: MapInfoFinalizationPass
+! SIMD-NOT: GenericLoopConversionPass
+! SIMD-NOT: InlineHLFIRAssign
+! SIMD-NOT: LowerWorkshare
+! SIMD-NOT: LowerWorkdistribute
+! SIMD: SimdOnlyPass
+! SIMD: LowerNontemporalPass
+! SIMD-NOT: MarkDeclareTargetPass
+! SIMD-NOT: UnimplementedDeviceCheckPass
+! SIMD-NOT: FunctionFilteringPass
+! SIMD-NOT: HostOpFilteringPass
+! SIMD-NOT: StackToSharedPass
+! SIMD-NOT: PrepareForOMPOffloadPrivatizationPass
+
+! DEVICE: MapsForPrivatizedSymbolsPass
+! DEVICE: AutomapToTargetDataPass
+! DEVICE: MapInfoFinalizationPass
+! DEVICE: GenericLoopConversionPass
+! DEVICE: InlineHLFIRAssign
+! DEVICE: LowerWorkshare
+! DEVICE: LowerWorkdistribute
+! DEVICE-NOT: SimdOnlyPass
+! DEVICE: LowerNontemporalPass
+! DEVICE: MarkDeclareTargetPass
+! DEVICE: UnimplementedDeviceCheckPass
+! DEVICE: MarkDeclareTargetPass
+! DEVICE: FunctionFilteringPass
+! DEVICE: HostOpFilteringPass
+! DEVICE: StackToSharedPass
+! DEVICE: PrepareForOMPOffloadPrivatizationPass
More information about the flang-commits
mailing list