[Mlir-commits] [flang] [mlir] [flang][mlir][OpenMP] Support inbranch and not inbranch clause (PR #177310)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Jan 21 22:04:12 PST 2026
https://github.com/chichunchen created https://github.com/llvm/llvm-project/pull/177310
None
>From bb6649a4916132625424038669e3af69aa551d03 Mon Sep 17 00:00:00 2001
From: cchen <chichun.chen at hpe.com>
Date: Thu, 22 Jan 2026 00:02:34 -0600
Subject: [PATCH] [flang][mlir][OpenMP] Support inbranch and not inbranch
clause
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 20 ++++++++
flang/lib/Lower/OpenMP/ClauseProcessor.h | 2 +
flang/lib/Lower/OpenMP/OpenMP.cpp | 2 +
flang/test/Lower/OpenMP/declare-simd.f90 | 29 ++++++++++-
.../mlir/Dialect/OpenMP/OpenMPClauses.td | 48 +++++++++++++++++++
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 3 +-
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 6 ++-
mlir/test/Dialect/OpenMP/invalid.mlir | 7 +++
mlir/test/Dialect/OpenMP/ops.mlir | 37 ++++++++++++++
9 files changed, 150 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index ec2c880437f33..dc5465ca192a9 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1726,6 +1726,26 @@ bool ClauseProcessor::processUniform(
});
}
+bool ClauseProcessor::processInbranch(
+ mlir::omp::InbranchClauseOps &result) const {
+ if (findUniqueClause<omp::clause::Inbranch>()) {
+ result.inbranch = mlir::UnitAttr::get(
+ converter.getFirOpBuilder().getContext());
+ return true;
+ }
+ return false;
+}
+
+bool ClauseProcessor::processNotinbranch(
+ mlir::omp::NotinbranchClauseOps &result) const {
+ if (findUniqueClause<omp::clause::Notinbranch>()) {
+ result.notinbranch = mlir::UnitAttr::get(
+ converter.getFirOpBuilder().getContext());
+ return true;
+ }
+ return false;
+}
+
} // namespace omp
} // namespace lower
} // namespace Fortran
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 063da68fb5702..69e957ec717ec 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -169,6 +169,8 @@ class ClauseProcessor {
mlir::omp::UseDevicePtrClauseOps &result,
llvm::SmallVectorImpl<const semantics::Symbol *> &useDeviceSyms) const;
bool processUniform(mlir::omp::UniformClauseOps &result) const;
+ bool processInbranch(mlir::omp::InbranchClauseOps &result) const;
+ bool processNotinbranch(mlir::omp::NotinbranchClauseOps &result) const;
// Call this method for these clauses that should be supported but are not
// implemented yet. It triggers a compilation error if any of the given
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index eab04ab13f9fa..b9e37a0555d8a 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3849,6 +3849,8 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
cp.processLinear(clauseOps);
cp.processSimdlen(clauseOps);
cp.processUniform(clauseOps);
+ cp.processInbranch(clauseOps);
+ cp.processNotinbranch(clauseOps);
mlir::omp::DeclareSimdOp::create(converter.getFirOpBuilder(), loc, clauseOps);
}
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
index 6ebb82d801708..59b8cc07a8f28 100644
--- a/flang/test/Lower/OpenMP/declare-simd.f90
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -102,11 +102,35 @@ end subroutine declare_simd_uniform
! CHECK: omp.declare_simd uniform(%[[XDECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, %[[YDECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
! CHECK: return
+subroutine declare_simd_inbranch()
+#ifdef OMP_60
+!$omp declare_simd inbranch
+#else
+!$omp declare simd inbranch
+#endif
+end subroutine declare_simd_inbranch
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_inbranch()
+! CHECK: omp.declare_simd inbranch{{$}}
+! CHECK: return
+
+subroutine declare_simd_notinbranch()
+#ifdef OMP_60
+!$omp declare_simd notinbranch
+#else
+!$omp declare simd notinbranch
+#endif
+end subroutine declare_simd_notinbranch
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_notinbranch()
+! CHECK: omp.declare_simd notinbranch{{$}}
+! CHECK: return
+
subroutine declare_simd_combined(x, y, n, i)
#ifdef OMP_60
-!$omp declare_simd aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y)
+!$omp declare_simd inbranch aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y)
#else
-!$omp declare simd aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y)
+!$omp declare simd inbranch aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y)
#endif
real(8), pointer, intent(inout) :: x(:)
real(8), pointer, intent(in) :: y(:)
@@ -136,5 +160,6 @@ end subroutine declare_simd_combined
! CHECK-SAME: simdlen(8)
! CHECK-SAME: uniform(%[[X_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>,
! CHECK-SAME: %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK-SAME: inbranch
! CHECK-SAME: {linear_var_types = [i32]}{{$}}
! CHECK: return
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index 3972c9aca4b12..62d897030a3f8 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -1556,4 +1556,52 @@ class OpenMP_UniformClauseSkip<
def OpenMP_UniformClause : OpenMP_UniformClauseSkip<>;
+//===----------------------------------------------------------------------===//
+// V5.2: [9.8.1.1]: `inbranch` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_InbranchClauseSkip<
+ bit traits = false, bit arguments = false, bit assemblyFormat = false,
+ bit description = false, bit extraClassDeclaration = false>
+ : OpenMP_Clause<traits, arguments, assemblyFormat, description,
+ extraClassDeclaration> {
+ let arguments = (ins
+ UnitAttr:$inbranch
+ );
+
+ let optAssemblyFormat = [{
+ `inbranch` $inbranch
+ }];
+
+ let description = [{
+ The `inbranch` clause indicates that the generated SIMD function variant
+ is intended for use in conditional branches.
+ }];
+}
+def OpenMP_InbranchClause : OpenMP_InbranchClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [9.8.1.2]: `notinbranch` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_NotinbranchClauseSkip<
+ bit traits = false, bit arguments = false, bit assemblyFormat = false,
+ bit description = false, bit extraClassDeclaration = false>
+ : OpenMP_Clause<traits, arguments, assemblyFormat, description,
+ extraClassDeclaration> {
+ let arguments = (ins
+ OptionalAttr<UnitAttr>:$notinbranch
+ );
+
+ let optAssemblyFormat = [{
+ `notinbranch` $notinbranch
+ }];
+
+ let description = [{
+ The `notinbranch` clause indicates that the generated SIMD function variant
+ is intended for use when not in conditional branches.
+ }];
+}
+def OpenMP_NotinbranchClause : OpenMP_NotinbranchClauseSkip<>;
+
#endif // OPENMP_CLAUSES
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 8e48e50464532..34641b4edaa75 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2248,7 +2248,8 @@ def WorkdistributeOp : OpenMP_Op<"workdistribute"> {
def DeclareSimdOp
: OpenMP_Op<"declare_simd", traits = [AttrSizedOperandSegments],
clauses = [OpenMP_AlignedClause, OpenMP_LinearClause,
- OpenMP_SimdlenClause, OpenMP_UniformClause]> {
+ OpenMP_SimdlenClause, OpenMP_UniformClause,
+ OpenMP_InbranchClause, OpenMP_NotinbranchClause]> {
let summary = "declare simd directive";
let description = [{
"omp.declare_simd" models the OpenMP `declare simd` directive.
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 9d548c76d37da..b609095859f96 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4476,6 +4476,9 @@ LogicalResult DeclareSimdOp::verify() {
if (!func)
return emitOpError() << "must be nested inside a function";
+ if (getInbranch() && getNotinbranch())
+ return emitOpError("cannot have both 'inbranch' and 'notinbranch'");
+
return verifyAlignedClause(*this, getAlignments(), getAlignedVars());
}
@@ -4486,7 +4489,8 @@ void DeclareSimdOp::build(OpBuilder &odsBuilder, OperationState &odsState,
makeArrayAttr(ctx, clauses.alignments),
clauses.linearVars, clauses.linearStepVars,
clauses.linearVarTypes, clauses.simdlen,
- clauses.uniformVars);
+ clauses.uniformVars, clauses.inbranch,
+ clauses.notinbranch);
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 1350c5e2ee8d2..0d9d1f1663ef9 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -3143,3 +3143,10 @@ func.func @invalid_workdistribute() -> () {
// -----
// expected-error @+1 {{'omp.declare_simd' op must be nested inside a function}}
omp.declare_simd
+
+// -----
+func.func @omp_declare_simd_branch() -> () {
+ // expected-error @+1 {{'omp.declare_simd' op cannot have both 'inbranch' and 'notinbranch'}}
+ omp.declare_simd inbranch notinbranch
+ return
+}
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 54534cca766d9..4f61a1f3c8c57 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -3425,6 +3425,41 @@ func.func @omp_declare_simd_uniform(%a: f64, %b: f64,
return
}
+// CHECK-LABEL: func.func @omp_declare_simd_inbranch
+func.func @omp_declare_simd_inbranch() -> () {
+ // CHECK: omp.declare_simd inbranch
+ omp.declare_simd inbranch
+ return
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_notinbranch
+func.func @omp_declare_simd_notinbranch() -> () {
+ // CHECK: omp.declare_simd notinbranch
+ omp.declare_simd notinbranch
+ return
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_multiple_clauses
+func.func @omp_declare_simd_multiple_clauses(%a: f64, %b: f64,
+ %p0: memref<i32>, %p1: memref<i32>,
+ %iv: i32, %step: i32) -> () {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: aligned(
+ // CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,
+ // CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)
+ // CHECK-SAME: simdlen(8)
+ // CHECK-SAME: uniform(
+ // CHECK-SAME: %{{.*}} : memref<i32>,
+ // CHECK-SAME: %{{.*}} : memref<i32>)
+ // CHECK-SAME: notinbranch
+ omp.declare_simd simdlen(8)
+ aligned(%p0 : memref<i32> -> 32 : i64,
+ %p1 : memref<i32> -> 128 : i64)
+ uniform(%p0 : memref<i32>, %p1 : memref<i32>)
+ notinbranch
+ return
+}
+
// CHECK-LABEL: func.func @omp_declare_simd_all_clauses
func.func @omp_declare_simd_all_clauses(%a: f64, %b: f64,
%p0: memref<i32>, %p1: memref<i32>,
@@ -3438,10 +3473,12 @@ func.func @omp_declare_simd_all_clauses(%a: f64, %b: f64,
// CHECK-SAME: uniform(
// CHECK-SAME: %{{.*}} : memref<i32>,
// CHECK-SAME: %{{.*}} : memref<i32>)
+ // CHECK-SAME: inbranch
omp.declare_simd simdlen(8)
aligned(%p0 : memref<i32> -> 32 : i64,
%p1 : memref<i32> -> 128 : i64)
linear(%iv = %step : i32)
uniform(%p0 : memref<i32>, %p1 : memref<i32>)
+ inbranch
return
}
More information about the Mlir-commits
mailing list