[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