[Mlir-commits] [clang] [flang] [mlir] [mlir][CIR] Separate OpenMP LLVM conversion helpers from the pass (NFC) (PR #232766)
Mehdi Amini
llvmlistbot at llvm.org
Fri Oct 16 14:45:53 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/232766
>From b060acfd4a71fb33356c8759675760870c7c6af3 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 16 Oct 2026 07:16:50 -0700
Subject: [PATCH 1/2] [mlir][CIR] Separate OpenMP LLVM conversion helpers from
the pass
Move the standalone OpenMP-to-LLVM pass to its own translation unit.
Keep MLIROpenMPToLLVM as the complete public conversion target, and
provide patterns, legality, and dialect-interface registration through
MLIROpenMPToLLVMConversion.
Use the helper target in CIR lowering and Flang code generation, and
remove the unused conversion dependency from FIRDialect. This breaks the
CIR link path through MemRef conversion and utilities to Affine without
splitting MemRef utilities or moving IR-dependent constraint analysis.
Validated static and shared CMake consumers and all 12 OpenMP-to-LLVM
and MemRef-to-LLVM regression files. The CIR suite has 1,255 passes and
one baseline-reproduced failure with identical LLVM IR. Missing-
dependency diagnostics are unchanged from baseline.
Assisted-by: Codex
---
.../CIR/Lowering/DirectToLLVM/CMakeLists.txt | 2 +-
flang/lib/Optimizer/CodeGen/CMakeLists.txt | 2 +-
flang/lib/Optimizer/Dialect/CMakeLists.txt | 1 -
.../OpenMPToLLVM/ConvertOpenMPToLLVM.h | 2 +
.../Conversion/OpenMPToLLVM/CMakeLists.txt | 38 ++++++++++++-
.../Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp | 41 -------------
.../OpenMPToLLVM/OpenMPToLLVMPass.cpp | 57 +++++++++++++++++++
7 files changed, 97 insertions(+), 46 deletions(-)
create mode 100644 mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVMPass.cpp
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt b/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
index 009d437da0f166..4b9186e5fedba8 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
@@ -27,7 +27,7 @@ add_clang_library(clangCIRLoweringDirectToLLVM
MLIRLLVMDialect
MLIRLLVMToLLVMIRTranslation
MLIROpenMPDialect
- MLIROpenMPToLLVM
+ MLIROpenMPToLLVMConversion
MLIROpenMPToLLVMIRTranslation
MLIROpenMPTransforms
MLIRIR
diff --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
index 69e1bfc4b8081b..c3cb3ca4b3ebfd 100644
--- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt
+++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
@@ -44,7 +44,7 @@ add_flang_library(FIRCodeGen
MLIRMathToLibm
MLIRMathToNVVM
MLIRMathToROCDL
- MLIROpenMPToLLVM
+ MLIROpenMPToLLVMConversion
MLIROpenACCDialect
MLIRBuiltinToLLVMIRTranslation
MLIRLLVMToLLVMIRTranslation
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt
index 08fd679c74c91c..e2a67a586752ba 100644
--- a/flang/lib/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt
@@ -43,7 +43,6 @@ add_flang_library(FIRDialect
MLIROpenACCDialect
MLIROpenACCUtils
MLIRBuiltinToLLVMIRTranslation
- MLIROpenMPToLLVM
MLIRLLVMToLLVMIRTranslation
MLIRTargetLLVMIRExport
)
diff --git a/mlir/include/mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h b/mlir/include/mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h
index 4822d6836ded11..1b1003e83bf565 100644
--- a/mlir/include/mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h
+++ b/mlir/include/mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h
@@ -18,6 +18,8 @@ class MLIRContext;
class Pass;
class RewritePatternSet;
+// MLIROpenMPToLLVMConversion provides the conversion helpers and dialect
+// interface below. MLIROpenMPToLLVM also provides the standalone pass.
#define GEN_PASS_DECL_CONVERTOPENMPTOLLVMPASS
#include "mlir/Conversion/Passes.h.inc"
diff --git a/mlir/lib/Conversion/OpenMPToLLVM/CMakeLists.txt b/mlir/lib/Conversion/OpenMPToLLVM/CMakeLists.txt
index c5f84aa95e64fb..1e2ce9efd62924 100644
--- a/mlir/lib/Conversion/OpenMPToLLVM/CMakeLists.txt
+++ b/mlir/lib/Conversion/OpenMPToLLVM/CMakeLists.txt
@@ -1,9 +1,40 @@
-add_mlir_conversion_library(MLIROpenMPToLLVM
+set(LLVM_OPTIONAL_SOURCES
+ OpenMPToLLVM.cpp
+ OpenMPToLLVMPass.cpp
+ )
+
+# Reusable OpenMP patterns, conversion legality, and dialect interface. Clients
+# with their own lowering pipeline do not need the standalone pass's conversions
+# for other dialects.
+add_mlir_conversion_library(MLIROpenMPToLLVMConversion
OpenMPToLLVM.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/OpenMPToLLVM
+ DEPENDS
+ MLIRConversionPassIncGen
+ MLIRConvertToLLVMInterfaceIncGen
+ intrinsics_gen
+
+ LINK_COMPONENTS
+ Core
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ MLIRLLVMCommonConversion
+ MLIRLLVMDialect
+ MLIROpenMPDialect
+ )
+
+# Keep the existing target as the complete conversion library, including the
+# standalone pass and all APIs provided by MLIROpenMPToLLVMConversion.
+add_mlir_conversion_library(MLIROpenMPToLLVM
+ OpenMPToLLVMPass.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/OpenMPToLLVM
+
DEPENDS
MLIRConversionPassIncGen
intrinsics_gen
@@ -13,11 +44,14 @@ add_mlir_conversion_library(MLIROpenMPToLLVM
LINK_LIBS PUBLIC
MLIRArithToLLVM
+ MLIRControlFlowToLLVM
MLIRFuncToLLVM
MLIRIR
MLIRLLVMCommonConversion
MLIRLLVMDialect
MLIRMemRefToLLVM
MLIROpenMPDialect
- MLIRTransforms
+ MLIROpenMPToLLVMConversion
+ MLIRPass
+ MLIRTransformUtils
)
diff --git a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp
index cf1bd76eda6a16..5a185adde149d8 100644
--- a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp
+++ b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp
@@ -8,21 +8,10 @@
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
-#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
-#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
-#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
-#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
-#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
-#include "mlir/Pass/Pass.h"
-
-namespace mlir {
-#define GEN_PASS_DEF_CONVERTOPENMPTOLLVMPASS
-#include "mlir/Conversion/Passes.h.inc"
-} // namespace mlir
using namespace mlir;
@@ -194,36 +183,6 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
>(converter, patterns);
}
-namespace {
-struct ConvertOpenMPToLLVMPass
- : public impl::ConvertOpenMPToLLVMPassBase<ConvertOpenMPToLLVMPass> {
- using Base::Base;
-
- void runOnOperation() override;
-};
-} // namespace
-
-void ConvertOpenMPToLLVMPass::runOnOperation() {
- auto module = getOperation();
-
- // Convert to OpenMP operations with LLVM IR dialect
- RewritePatternSet patterns(&getContext());
- LLVMTypeConverter converter(&getContext());
- arith::populateArithToLLVMConversionPatterns(converter, patterns);
- cf::populateControlFlowToLLVMConversionPatterns(converter, patterns);
- cf::populateAssertToLLVMConversionPattern(converter, patterns);
- populateFinalizeMemRefToLLVMConversionPatterns(converter, patterns);
- populateFuncToLLVMConversionPatterns(converter, patterns);
- populateOpenMPToLLVMConversionPatterns(converter, patterns);
-
- LLVMConversionTarget target(getContext());
- target.addLegalOp<omp::BarrierOp, omp::FlushOp, omp::TaskwaitOp,
- omp::TaskyieldOp, omp::TerminatorOp>();
- configureOpenMPToLLVMConversionLegality(target, converter);
- if (failed(applyPartialConversion(module, target, std::move(patterns))))
- signalPassFailure();
-}
-
//===----------------------------------------------------------------------===//
// ConvertToLLVMPatternInterface implementation
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVMPass.cpp b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVMPass.cpp
new file mode 100644
index 00000000000000..8743f7c0586253
--- /dev/null
+++ b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVMPass.cpp
@@ -0,0 +1,57 @@
+//===- OpenMPToLLVMPass.cpp - OpenMP to LLVM pass ------------------------===//
+//
+// 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 "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
+
+#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
+#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
+#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
+#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
+#include "mlir/Conversion/LLVMCommon/TypeConverter.h"
+#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+namespace mlir {
+#define GEN_PASS_DEF_CONVERTOPENMPTOLLVMPASS
+#include "mlir/Conversion/Passes.h.inc"
+} // namespace mlir
+
+using namespace mlir;
+
+namespace {
+struct ConvertOpenMPToLLVMPass
+ : public impl::ConvertOpenMPToLLVMPassBase<ConvertOpenMPToLLVMPass> {
+ using Base::Base;
+
+ void runOnOperation() override;
+};
+} // namespace
+
+void ConvertOpenMPToLLVMPass::runOnOperation() {
+ auto module = getOperation();
+
+ // Convert to OpenMP operations with LLVM IR dialect
+ RewritePatternSet patterns(&getContext());
+ LLVMTypeConverter converter(&getContext());
+ arith::populateArithToLLVMConversionPatterns(converter, patterns);
+ cf::populateControlFlowToLLVMConversionPatterns(converter, patterns);
+ cf::populateAssertToLLVMConversionPattern(converter, patterns);
+ populateFinalizeMemRefToLLVMConversionPatterns(converter, patterns);
+ populateFuncToLLVMConversionPatterns(converter, patterns);
+ populateOpenMPToLLVMConversionPatterns(converter, patterns);
+
+ LLVMConversionTarget target(getContext());
+ target.addLegalOp<omp::BarrierOp, omp::FlushOp, omp::TaskwaitOp,
+ omp::TaskyieldOp, omp::TerminatorOp>();
+ configureOpenMPToLLVMConversionLegality(target, converter);
+ if (failed(applyPartialConversion(module, target, std::move(patterns))))
+ signalPassFailure();
+}
>From 78673fb159b5727ea199391a693a9ebdff7c308d Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 16 Oct 2026 08:08:38 -0700
Subject: [PATCH 2/2] [CIR][OpenMP] Update outlined capture parameter
expectations
Account for the capture lifetime attributes added by #218453 in both
CIR and traditional Clang code generation. The stale checks fail on the
base revision as well as the OpenMP conversion library split.
Validated the full CIR suite and the OpenMPToLLVM and MemRefToLLVM
conversion tests: 1,268 passed, 56 unsupported, one expected failure.
Assisted-by: Codex
---
clang/test/CIR/CodeGenOpenMP/omp-llvmir.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/CIR/CodeGenOpenMP/omp-llvmir.c b/clang/test/CIR/CodeGenOpenMP/omp-llvmir.c
index 98f4caf8539935..383c3b483a5051 100644
--- a/clang/test/CIR/CodeGenOpenMP/omp-llvmir.c
+++ b/clang/test/CIR/CodeGenOpenMP/omp-llvmir.c
@@ -58,7 +58,7 @@
// LLVM: %[[LOAD:.*]] = load i32, ptr %[[RETVAL]], align 4
// LLVM: ret i32 %[[LOAD]]
-// LLVM-LABEL: define internal void @main..omp_par(ptr noalias %{{.*}}, ptr noalias %{{.*}}, ptr %{{.*}})
+// LLVM-LABEL: define internal void @main..omp_par(ptr noalias %{{.*}}, ptr noalias %{{.*}}, ptr noalias nofreeobj %{{.*}})
// LLVM: [[PAR_ENTRY:.*]]:
// LLVM: %[[GEP_J:.*]] = getelementptr { ptr }, ptr %{{.*}}, i32 0, i32 0
// LLVM: %[[LOAD_J:.*]] = load ptr, ptr %[[GEP_J]], align 8
@@ -123,7 +123,7 @@
// OGCG: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @main.omp_outlined, ptr %[[J]])
// OGCG: ret i32 0
-// OGCG-LABEL: define internal void @main.omp_outlined(ptr noalias noundef %{{.*}}, ptr noalias noundef %{{.*}}, ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
+// OGCG-LABEL: define internal void @main.omp_outlined(ptr noalias noundef %{{.*}}, ptr noalias noundef %{{.*}}, ptr nofreeobj noundef nonnull align 4 dereferenceable(4) %{{.*}})
// OGCG: [[OUTLINED_ENTRY:.*]]:
// OGCG: %[[GLOBAL_TID_ADDR:.*]] = alloca ptr, align 8
// OGCG: %[[BOUND_TID_ADDR:.*]] = alloca ptr, align 8
More information about the Mlir-commits
mailing list