[Mlir-commits] [flang] [mlir] [flang][mlir][OpenMP] Add support for uniform clause in declare simd (PR #176046)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Jan 15 11:55:23 PST 2026
https://github.com/chichunchen updated https://github.com/llvm/llvm-project/pull/176046
>From 5783d5b394d02a7d05fe0c9e33ed9f756451682d Mon Sep 17 00:00:00 2001
From: cchen <chichun.chen at hpe.com>
Date: Fri, 9 Jan 2026 17:48:54 -0600
Subject: [PATCH 1/6] [OpenMP][Flang][MLIR] Introduce omp.declare_simd op and
emit from Flang
Changes:
- Adds a new `omp.declare_simd` operation to the OpenMP MLIR dialect
- Lowers Fortran `!$omp declare simd` into `omp.declare_simd` inside the
enclosing function body
mlir to LLVMIR translation and uniform clause will be added in follow-up PRs.
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 13 +-
flang/test/Lower/OpenMP/declare-simd.f90 | 119 ++++++++++++++++++
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 38 ++++++
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 32 +++++
mlir/test/Dialect/OpenMP/ops.mlir | 69 ++++++++++
5 files changed, 269 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/declare-simd.f90
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 4381d1e9064cf..84377c26d30f6 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3815,8 +3815,17 @@ static void
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
const parser::OpenMPDeclareSimdConstruct &declareSimdConstruct) {
- if (!semaCtx.langOptions().OpenMPSimd)
- TODO(converter.getCurrentLocation(), "OpenMPDeclareSimdConstruct");
+ mlir::Location loc = converter.getCurrentLocation();
+ const parser::OmpDirectiveSpecification &beginSpec = declareSimdConstruct.v;
+ List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
+
+ mlir::omp::DeclareSimdOperands clauseOps;
+ ClauseProcessor cp(converter, semaCtx, clauses);
+ cp.processAligned(clauseOps);
+ cp.processLinear(clauseOps);
+ cp.processSimdlen(clauseOps);
+
+ mlir::omp::DeclareSimdOp::create(converter.getFirOpBuilder(), loc, clauseOps);
}
static void genOpenMPDeclareMapperImpl(
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
new file mode 100644
index 0000000000000..264ac222801b9
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -0,0 +1,119 @@
+! This test checks the lowering of the OpenMP `declare simd` directive with
+! different clauses (e.g. aligned, linear, simdlen). It also verifies that
+! the `omp.declare_simd` operation is emitted after the function prologue,
+! since the directive requires access to function arguments.
+
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+subroutine declare_simd_no_clause(x, y, n, i)
+ !$omp declare simd
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_no_clause
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_no_clause(
+! CHECK: %[[SCOPE_NONE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[I_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[N_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[X_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[Y_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: omp.declare_simd
+! CHECK-NOT: aligned(
+! CHECK-NOT: linear(
+! CHECK-NOT: simdlen(
+! CHECK: return
+
+subroutine declare_simd_aligned(x, y, n, i)
+ !$omp declare simd aligned(x, y : 64)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_aligned
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_aligned(
+! CHECK: %[[SCOPE_A:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[I_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[N_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[X_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[Y_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: omp.declare_simd
+! CHECK-SAME: aligned(%[[X_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
+! CHECK-SAME: %[[Y_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
+! CHECK-NOT: linear(
+! CHECK-NOT: simdlen(
+! CHECK: return
+
+subroutine declare_simd_linear(x, y, n, i)
+ !$omp declare simd linear(i)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_linear
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_linear(
+! CHECK: %[[SCOPE_L:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[I_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[N_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[X_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[Y_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[C1_L:.*]] = arith.constant 1 : i32
+! CHECK: omp.declare_simd
+! CHECK-NOT: aligned(
+! CHECK-SAME: linear(%[[I_L]]#0 = %[[C1_L]] : !fir.ref<i32>)
+! CHECK-SAME: {linear_var_types = [i32]}
+! CHECK-NOT: simdlen(
+! CHECK: return
+
+subroutine declare_simd_simdlen(x, y, n, i)
+ !$omp declare simd simdlen(8)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_simdlen
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_simdlen(
+! CHECK: %[[SCOPE_S:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[I_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[N_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[X_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[Y_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: omp.declare_simd
+! CHECK-NOT: aligned(
+! CHECK-NOT: linear(
+! CHECK-SAME: simdlen(8)
+! CHECK: return
+
+subroutine declare_simd_combined(x, y, n, i)
+ !$omp declare simd aligned(x, y : 64) linear(i) simdlen(8)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+
+ if (i <= n) then
+ x(i) = x(i) + y(i)
+end if
+end subroutine declare_simd_combined
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_combined(
+! CHECK-SAME: %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>{{.*}}fir.bindc_name = "x"
+! CHECK-SAME: %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>{{.*}}fir.bindc_name = "y"
+! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}fir.bindc_name = "n"
+! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}fir.bindc_name = "i"
+! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[N_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2 {{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+
+! CHECK: omp.declare_simd
+! CHECK-SAME: aligned(%[[X_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
+! CHECK-SAME: %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
+! CHECK-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
+! CHECK-SAME: simdlen(8)
+! CHECK-SAME: {linear_var_types = [i32]}
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index bbfe805eefe48..c77e08e1fb076 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2240,4 +2240,42 @@ def WorkdistributeOp : OpenMP_Op<"workdistribute"> {
let assemblyFormat = "$region attr-dict";
}
+//===----------------------------------------------------------------------===//
+// declare simd Construct
+//===----------------------------------------------------------------------===//
+
+def DeclareSimdOp
+ : OpenMP_Op<"declare_simd",
+ traits = [AttrSizedOperandSegments, IsolatedFromAbove],
+ clauses = [OpenMP_AlignedClause, OpenMP_LinearClause,
+ OpenMP_SimdlenClause]> {
+ let summary = "declare simd directive";
+ let description = [{
+ "omp.declare_simd" models the OpenMP `declare simd` directive.
+
+ This is a declarative operation (no region) intended to appear inside
+ a function body. It attaches clauses of declare simd to the enclosing
+ function.
+
+ Example:
+ ```mlir
+ func.func @add(%a: memref<16xi32>) {
+ omp.declare_simd simdlen(8) aligned(%a : memref<16xi32> -> 64 : i64)
+ ...
+ }
+ ```
+ }]#clausesDescription;
+
+ let arguments = clausesArgs;
+
+ let builders = [OpBuilder<(
+ ins CArg<"const DeclareSimdOperands &">:$clauses)>];
+
+ let assemblyFormat =
+ clausesReqAssemblyFormat#" oilist("#clausesOptAssemblyFormat#") "#"attr-"
+ "dict";
+
+ let hasVerifier = 1;
+}
+
#endif // OPENMP_OPS
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 103295d136dbb..f23bb659ae88e 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4458,6 +4458,38 @@ LogicalResult WorkdistributeOp::verify() {
return success();
}
+//===----------------------------------------------------------------------===//
+// Declare simd [7.7]
+//===----------------------------------------------------------------------===//
+
+void DeclareSimdOp::build(OpBuilder &odsBuilder, OperationState &odsState,
+ const DeclareSimdOperands &clauses) {
+ MLIRContext *ctx = odsBuilder.getContext();
+ DeclareSimdOp::build(odsBuilder, odsState, clauses.alignedVars,
+ makeArrayAttr(ctx, clauses.alignments),
+ clauses.linearVars, clauses.linearStepVars,
+ clauses.linearVarTypes, clauses.simdlen);
+}
+
+LogicalResult DeclareSimdOp::verify() {
+ // Must be nested inside a function-like op
+ auto func = (*this)->getParentOfType<mlir::FunctionOpInterface>();
+ if (!func)
+ return emitOpError()
+ << "'omp.declare_simd' must be nested inside a function";
+
+ // omp.declare_simd must appear in the entry block of the enclosing function
+ Block &entry = func.getFunctionBody().front();
+ if (getOperation()->getBlock() != &entry)
+ return emitError()
+ << "must appear in the entry block of the enclosing function";
+
+ if (verifyAlignedClause(*this, getAlignments(), getAlignedVars()).failed())
+ return failure();
+
+ return success();
+}
+
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.cpp.inc"
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index ac29e20907b55..8ab2ed89e5ecc 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -3367,3 +3367,72 @@ func.func @omp_target_map_clause_type_test(%arg0 : memref<?xi32>) -> () {
return
}
+
+// CHECK-LABEL: func.func @omp_declare_simd
+func.func @omp_declare_simd(%a: f64, %b: f64) -> f64 {
+ // CHECK: omp.declare_simd
+ omp.declare_simd
+ %0 = arith.addf %a, %b : f64
+ return %0 : f64
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_simdlen
+func.func @omp_declare_simd_simdlen(%a: f64, %b: f64) -> f64 {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: simdlen(8)
+ omp.declare_simd simdlen(8)
+ %0 = arith.addf %a, %b : f64
+ return %0 : f64
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_aligned
+func.func @omp_declare_simd_aligned(%a: f64, %b: f64,
+ %p0: memref<i32>, %p1: memref<i32>) -> f64 {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: aligned(
+ // CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,
+ // CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)
+ omp.declare_simd aligned(%p0 : memref<i32> -> 32 : i64,
+ %p1 : memref<i32> -> 128 : i64)
+
+ %0 = arith.addf %a, %b : f64
+ return %0 : f64
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_aligned_list_generic
+func.func @omp_declare_simd_aligned_list_generic(%arg0: f64, %arg1: f64,
+ %arg2: memref<i32>, %arg3: memref<i32>) -> f64 {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: aligned(%{{.*}} : memref<i32> -> 32 : i64, %{{.*}} : memref<i32> -> 128 : i64)
+ omp.declare_simd aligned(%arg2 : memref<i32> -> 32 : i64, %arg3 : memref<i32> -> 128 : i64)
+ %0 = arith.addf %arg0, %arg1 : f64
+ return %0 : f64
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_linear
+func.func @omp_declare_simd_linear(%a: f64, %b: f64, %iv: i32, %step: i32) -> f64 {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: linear(%{{.*}} = %{{.*}} : i32)
+ omp.declare_simd linear(%iv = %step : i32)
+ %0 = arith.addf %a, %b : f64
+ return %0 : f64
+}
+
+// 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>,
+ %iv: i32, %step: i32) -> f64 {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: aligned(
+ // CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,
+ // CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)
+ // CHECK-SAME: linear(%{{.*}} = %{{.*}} : i32)
+ // CHECK-SAME: simdlen(8)
+ omp.declare_simd simdlen(8)
+ aligned(%p0 : memref<i32> -> 32 : i64,
+ %p1 : memref<i32> -> 128 : i64)
+ linear(%iv = %step : i32)
+
+ %0 = arith.addf %a, %b : f64
+ return %0 : f64
+}
>From b5ff628de45fe13bb4f8acaa7bb35849c424d2ba Mon Sep 17 00:00:00 2001
From: "Chi-Chun, Chen" <chichun.chen at hpe.com>
Date: Tue, 13 Jan 2026 14:36:00 -0600
Subject: [PATCH 2/6] Resolve feedback
- Add uniform clause to TODO test
- Fix flang declare_simd.f90 lowering test
- Test `!$omp declare simd` for OpenMP 5.2 and 6.0
- Test `!$omp declare_simd` for OpenMP 6.0 only (guarded by -cpp -DOMP_60)
- Fix traits in omp.declare_simd
- remove IsolatedFromAbove
- implement getEffects to prevent declare_simd from being remove by
DCE
- Add invalid.mlir coverage for the DeclareSimdOp::verify
- makes sure omp.declare_simd has parent function
- remove unnecessary entry block check
- Remove redundancy in ops.mlir
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 2 +
.../OpenMP/Todo/declare-simd-uniform.f90 | 9 ++
flang/test/Lower/OpenMP/declare-simd.f90 | 135 ++++++++++++++----
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 3 +-
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 23 ++-
mlir/test/Dialect/OpenMP/invalid.mlir | 4 +
mlir/test/Dialect/OpenMP/ops.mlir | 31 ++--
7 files changed, 156 insertions(+), 51 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 84377c26d30f6..5f520635bb4c5 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3824,6 +3824,8 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
cp.processAligned(clauseOps);
cp.processLinear(clauseOps);
cp.processSimdlen(clauseOps);
+ cp.processTODO<clause::Uniform>(converter.getCurrentLocation(),
+ llvm::omp::Directive::OMPD_declare_simd);
mlir::omp::DeclareSimdOp::create(converter.getFirOpBuilder(), loc, clauseOps);
}
diff --git a/flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90 b/flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90
new file mode 100644
index 0000000000000..1ca5dd34de2d2
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90
@@ -0,0 +1,9 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: Unhandled clause UNIFORM in DECLARE SIMD construct
+subroutine declare_simd_uniform(x, y)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ !$omp declare simd uniform(x, y)
+end subroutine declare_simd_uniform
+
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
index 264ac222801b9..222ce4af1bb7c 100644
--- a/flang/test/Lower/OpenMP/declare-simd.f90
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -1,28 +1,19 @@
-! This test checks the lowering of the OpenMP `declare simd` directive with
+! This test CHECKs the lowering of the OpenMP `declare simd` directive with
! different clauses (e.g. aligned, linear, simdlen). It also verifies that
! the `omp.declare_simd` operation is emitted after the function prologue,
! since the directive requires access to function arguments.
-! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -cpp -DOMP_60 %s -o - | FileCheck %s --check-prefix=CHECK60
-subroutine declare_simd_no_clause(x, y, n, i)
+subroutine declare_simd_no_clause()
!$omp declare simd
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
- if (i <= n) x(i) = x(i) + y(i)
end subroutine declare_simd_no_clause
-! CHECK-LABEL: func.func @_QPdeclare_simd_no_clause(
-! CHECK: %[[SCOPE_NONE:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[I_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[N_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[X_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK: %[[Y_NONE:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_NONE]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK-LABEL: func.func @_QPdeclare_simd_no_clause()
! CHECK: omp.declare_simd
-! CHECK-NOT: aligned(
-! CHECK-NOT: linear(
-! CHECK-NOT: simdlen(
+! CHECK-NOT: {{omp\.declare_simd[[:space:]]*(aligned|linear|simdlen)\(}}
! CHECK: return
subroutine declare_simd_aligned(x, y, n, i)
@@ -42,8 +33,7 @@ end subroutine declare_simd_aligned
! CHECK: omp.declare_simd
! CHECK-SAME: aligned(%[[X_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
! CHECK-SAME: %[[Y_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
-! CHECK-NOT: linear(
-! CHECK-NOT: simdlen(
+! CHECK-NOT: {{[[:space:]]*(linear|simdlen)\(}}
! CHECK: return
subroutine declare_simd_linear(x, y, n, i)
@@ -62,10 +52,7 @@ end subroutine declare_simd_linear
! CHECK: %[[Y_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
! CHECK: %[[C1_L:.*]] = arith.constant 1 : i32
! CHECK: omp.declare_simd
-! CHECK-NOT: aligned(
-! CHECK-SAME: linear(%[[I_L]]#0 = %[[C1_L]] : !fir.ref<i32>)
-! CHECK-SAME: {linear_var_types = [i32]}
-! CHECK-NOT: simdlen(
+! CHECK-NOT: {{[[:space:]]*(aligned|simdlen)\(}}
! CHECK: return
subroutine declare_simd_simdlen(x, y, n, i)
@@ -83,8 +70,7 @@ end subroutine declare_simd_simdlen
! CHECK: %[[X_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
! CHECK: %[[Y_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
! CHECK: omp.declare_simd
-! CHECK-NOT: aligned(
-! CHECK-NOT: linear(
+! CHECK-NOT: {{[[:space:]]*(aligned|linear)\(}}
! CHECK-SAME: simdlen(8)
! CHECK: return
@@ -96,7 +82,7 @@ subroutine declare_simd_combined(x, y, n, i)
if (i <= n) then
x(i) = x(i) + y(i)
-end if
+ end if
end subroutine declare_simd_combined
! CHECK-LABEL: func.func @_QPdeclare_simd_combined(
@@ -117,3 +103,102 @@ end subroutine declare_simd_combined
! CHECK-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
! CHECK-SAME: simdlen(8)
! CHECK-SAME: {linear_var_types = [i32]}
+
+#ifdef OMP_60
+
+subroutine declare_simd_60_no_clause()
+ !$omp declare_simd
+end subroutine declare_simd_60_no_clause
+
+! CHECK60-LABEL: func.func @_QPdeclare_simd_60_no_clause() {
+! CHECK60: omp.declare_simd
+
+subroutine declare_simd_aligned_60(x, y, n, i)
+ !$omp declare_simd aligned(x, y : 64)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_aligned_60
+
+! CHECK60-LABEL: func.func @_QPdeclare_simd_aligned_60(
+! CHECK60: %[[SCOPE_A:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK60: %[[I_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[N_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[X_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: %[[Y_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: omp.declare_simd
+! CHECK60-SAME: aligned(%[[X_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
+! CHECK60-SAME: %[[Y_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
+! CHECK60-NOT: {{[[:space:]]*(linear|simdlen)\(}}
+! CHECK60: return
+
+subroutine declare_simd_linear_60(x, y, n, i)
+ !$omp declare_simd linear(i)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_linear_60
+
+! CHECK60-LABEL: func.func @_QPdeclare_simd_linear_60(
+! CHECK60: %[[SCOPE_L:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK60: %[[I_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[N_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[X_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: %[[Y_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: %[[C1_L:.*]] = arith.constant 1 : i32
+! CHECK60: omp.declare_simd
+! CHECK60-NOT: {{[[:space:]]*(aligned|simdlen)\(}}
+! CHECK60: return
+
+subroutine declare_simd_simdlen_60(x, y, n, i)
+ !$omp declare_simd simdlen(8)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+ if (i <= n) x(i) = x(i) + y(i)
+end subroutine declare_simd_simdlen_60
+
+! CHECK60-LABEL: func.func @_QPdeclare_simd_simdlen_60(
+! CHECK60: %[[SCOPE_S:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK60: %[[I_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[N_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[X_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: %[[Y_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: omp.declare_simd
+! CHECK60-NOT: {{[[:space:]]*(aligned|linear)\(}}
+! CHECK60-SAME: simdlen(8)
+! CHECK60: return
+
+subroutine declare_simd_combined_60(x, y, n, i)
+ !$omp declare_simd aligned(x, y : 64) linear(i) simdlen(8)
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+
+ if (i <= n) then
+ x(i) = x(i) + y(i)
+ end if
+end subroutine declare_simd_combined_60
+
+! CHECK60-LABEL: func.func @_QPdeclare_simd_combined_60(
+! CHECK60-SAME: %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>{{.*}}fir.bindc_name = "x"
+! CHECK60-SAME: %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>{{.*}}fir.bindc_name = "y"
+! CHECK60-SAME: %{{.*}}: !fir.ref<i32>{{.*}}fir.bindc_name = "n"
+! CHECK60-SAME: %{{.*}}: !fir.ref<i32>{{.*}}fir.bindc_name = "i"
+! CHECK60: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK60: %[[I_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[N_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK60: %[[X_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2 {{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
+! CHECK60: %[[C1:.*]] = arith.constant 1 : i32
+
+! CHECK60: omp.declare_simd
+! CHECK60-SAME: aligned(%[[X_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
+! CHECK60-SAME: %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
+! CHECK60-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
+! CHECK60-SAME: simdlen(8)
+! CHECK60-SAME: {linear_var_types = [i32]}
+
+#endif !OMP_60
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index c77e08e1fb076..e6c35d3c1846a 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2246,7 +2246,8 @@ def WorkdistributeOp : OpenMP_Op<"workdistribute"> {
def DeclareSimdOp
: OpenMP_Op<"declare_simd",
- traits = [AttrSizedOperandSegments, IsolatedFromAbove],
+ traits = [AttrSizedOperandSegments,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>],
clauses = [OpenMP_AlignedClause, OpenMP_LinearClause,
OpenMP_SimdlenClause]> {
let summary = "declare simd directive";
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index f23bb659ae88e..eb0374d8fdda6 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4478,18 +4478,29 @@ LogicalResult DeclareSimdOp::verify() {
return emitOpError()
<< "'omp.declare_simd' must be nested inside a function";
- // omp.declare_simd must appear in the entry block of the enclosing function
- Block &entry = func.getFunctionBody().front();
- if (getOperation()->getBlock() != &entry)
- return emitError()
- << "must appear in the entry block of the enclosing function";
-
if (verifyAlignedClause(*this, getAlignments(), getAlignedVars()).failed())
return failure();
return success();
}
+namespace mlir {
+namespace omp {
+// A non-default resource to indicate that omp.declare_simd has side effects.
+struct DeclareSimdResource
+ : public SideEffects::Resource::Base<DeclareSimdResource> {
+ StringRef getName() final { return "omp.declare_simd.resource"; }
+};
+} // namespace omp
+} // namespace mlir
+
+void DeclareSimdOp::getEffects(
+ SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
+ &effects) {
+ effects.emplace_back(MemoryEffects::Allocate::get(),
+ DeclareSimdResource::get());
+}
+
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.cpp.inc"
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index af24d969064ab..9138b70ba964d 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -3139,3 +3139,7 @@ func.func @invalid_workdistribute() -> () {
}
return
}
+
+// -----
+// expected-error @+1 {{'omp.declare_simd' must be nested inside a function}}
+omp.declare_simd
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 8ab2ed89e5ecc..95d179247fb91 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -3369,25 +3369,23 @@ func.func @omp_target_map_clause_type_test(%arg0 : memref<?xi32>) -> () {
}
// CHECK-LABEL: func.func @omp_declare_simd
-func.func @omp_declare_simd(%a: f64, %b: f64) -> f64 {
+func.func @omp_declare_simd() -> () {
// CHECK: omp.declare_simd
omp.declare_simd
- %0 = arith.addf %a, %b : f64
- return %0 : f64
+ return
}
// CHECK-LABEL: func.func @omp_declare_simd_simdlen
-func.func @omp_declare_simd_simdlen(%a: f64, %b: f64) -> f64 {
+func.func @omp_declare_simd_simdlen() -> () {
// CHECK: omp.declare_simd
// CHECK-SAME: simdlen(8)
omp.declare_simd simdlen(8)
- %0 = arith.addf %a, %b : f64
- return %0 : f64
+ return
}
// CHECK-LABEL: func.func @omp_declare_simd_aligned
func.func @omp_declare_simd_aligned(%a: f64, %b: f64,
- %p0: memref<i32>, %p1: memref<i32>) -> f64 {
+ %p0: memref<i32>, %p1: memref<i32>) -> () {
// CHECK: omp.declare_simd
// CHECK-SAME: aligned(
// CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,
@@ -3395,33 +3393,30 @@ func.func @omp_declare_simd_aligned(%a: f64, %b: f64,
omp.declare_simd aligned(%p0 : memref<i32> -> 32 : i64,
%p1 : memref<i32> -> 128 : i64)
- %0 = arith.addf %a, %b : f64
- return %0 : f64
+ return
}
// CHECK-LABEL: func.func @omp_declare_simd_aligned_list_generic
func.func @omp_declare_simd_aligned_list_generic(%arg0: f64, %arg1: f64,
- %arg2: memref<i32>, %arg3: memref<i32>) -> f64 {
+ %arg2: memref<i32>, %arg3: memref<i32>) -> () {
// CHECK: omp.declare_simd
// CHECK-SAME: aligned(%{{.*}} : memref<i32> -> 32 : i64, %{{.*}} : memref<i32> -> 128 : i64)
omp.declare_simd aligned(%arg2 : memref<i32> -> 32 : i64, %arg3 : memref<i32> -> 128 : i64)
- %0 = arith.addf %arg0, %arg1 : f64
- return %0 : f64
+ return
}
// CHECK-LABEL: func.func @omp_declare_simd_linear
-func.func @omp_declare_simd_linear(%a: f64, %b: f64, %iv: i32, %step: i32) -> f64 {
+func.func @omp_declare_simd_linear(%a: f64, %b: f64, %iv: i32, %step: i32) -> () {
// CHECK: omp.declare_simd
// CHECK-SAME: linear(%{{.*}} = %{{.*}} : i32)
omp.declare_simd linear(%iv = %step : i32)
- %0 = arith.addf %a, %b : f64
- return %0 : f64
+ 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>,
- %iv: i32, %step: i32) -> f64 {
+ %iv: i32, %step: i32) -> () {
// CHECK: omp.declare_simd
// CHECK-SAME: aligned(
// CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,
@@ -3432,7 +3427,5 @@ func.func @omp_declare_simd_all_clauses(%a: f64, %b: f64,
aligned(%p0 : memref<i32> -> 32 : i64,
%p1 : memref<i32> -> 128 : i64)
linear(%iv = %step : i32)
-
- %0 = arith.addf %a, %b : f64
- return %0 : f64
+ return
}
>From 3a9e569f542e862ff94948c91cca26ab4459e116 Mon Sep 17 00:00:00 2001
From: cchen <chichun.chen at hpe.com>
Date: Wed, 14 Jan 2026 13:56:37 -0600
Subject: [PATCH 3/6] Resolve feedback
- Fix check line of declare_simd.f90
- Update mlir::omp::DeclareSimdOp
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 12 ++++++++++--
flang/test/Lower/OpenMP/declare-simd.f90 | 5 ++---
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 5 +----
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 9 ---------
4 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 5f520635bb4c5..03531919b590a 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3815,7 +3815,6 @@ static void
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
const parser::OpenMPDeclareSimdConstruct &declareSimdConstruct) {
- mlir::Location loc = converter.getCurrentLocation();
const parser::OmpDirectiveSpecification &beginSpec = declareSimdConstruct.v;
List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
@@ -3827,7 +3826,16 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
cp.processTODO<clause::Uniform>(converter.getCurrentLocation(),
llvm::omp::Directive::OMPD_declare_simd);
- mlir::omp::DeclareSimdOp::create(converter.getFirOpBuilder(), loc, clauseOps);
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ mlir::Location loc = converter.getCurrentLocation();
+ auto *ctx = firOpBuilder.getContext();
+ mlir::ArrayAttr alignments;
+ if (!clauseOps.alignments.empty())
+ alignments = mlir::ArrayAttr::get(ctx, clauseOps.alignments);
+ mlir::omp::DeclareSimdOp::create(firOpBuilder, loc, clauseOps.alignedVars,
+ alignments, clauseOps.linearVars,
+ clauseOps.linearStepVars,
+ clauseOps.linearVarTypes, clauseOps.simdlen);
}
static void genOpenMPDeclareMapperImpl(
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
index 222ce4af1bb7c..81a75b6007d3d 100644
--- a/flang/test/Lower/OpenMP/declare-simd.f90
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -1,4 +1,4 @@
-! This test CHECKs the lowering of the OpenMP `declare simd` directive with
+! This test checks the lowering of the OpenMP `declare simd` directive with
! different clauses (e.g. aligned, linear, simdlen). It also verifies that
! the `omp.declare_simd` operation is emitted after the function prologue,
! since the directive requires access to function arguments.
@@ -12,8 +12,7 @@ subroutine declare_simd_no_clause()
end subroutine declare_simd_no_clause
! CHECK-LABEL: func.func @_QPdeclare_simd_no_clause()
-! CHECK: omp.declare_simd
-! CHECK-NOT: {{omp\.declare_simd[[:space:]]*(aligned|linear|simdlen)\(}}
+! CHECK: omp.declare_simd{{$}}
! CHECK: return
subroutine declare_simd_aligned(x, y, n, i)
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index e6c35d3c1846a..67a54df270e1e 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2265,13 +2265,10 @@ def DeclareSimdOp
...
}
```
- }]#clausesDescription;
+ }] # clausesDescription;
let arguments = clausesArgs;
- let builders = [OpBuilder<(
- ins CArg<"const DeclareSimdOperands &">:$clauses)>];
-
let assemblyFormat =
clausesReqAssemblyFormat#" oilist("#clausesOptAssemblyFormat#") "#"attr-"
"dict";
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index eb0374d8fdda6..fbd76b00b5a1a 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4462,15 +4462,6 @@ LogicalResult WorkdistributeOp::verify() {
// Declare simd [7.7]
//===----------------------------------------------------------------------===//
-void DeclareSimdOp::build(OpBuilder &odsBuilder, OperationState &odsState,
- const DeclareSimdOperands &clauses) {
- MLIRContext *ctx = odsBuilder.getContext();
- DeclareSimdOp::build(odsBuilder, odsState, clauses.alignedVars,
- makeArrayAttr(ctx, clauses.alignments),
- clauses.linearVars, clauses.linearStepVars,
- clauses.linearVarTypes, clauses.simdlen);
-}
-
LogicalResult DeclareSimdOp::verify() {
// Must be nested inside a function-like op
auto func = (*this)->getParentOfType<mlir::FunctionOpInterface>();
>From 4abaad43bdb1d0eac8e073470441902d5ff42333 Mon Sep 17 00:00:00 2001
From: cchen <chichun.chen at hpe.com>
Date: Wed, 14 Jan 2026 14:49:33 -0600
Subject: [PATCH 4/6] Overhaul flang lower test: declare-simd.f90
- remove redundancy with OMP60 macro
- no duplicate check lines
- `omp declare simd` should generate same mlir as `omp
delcare_simd`
- no duplicate fortran subroutines for declare_simd syntax
- make the check line of omp.declare_simd more robust
---
flang/test/Lower/OpenMP/declare-simd.f90 | 175 ++++++-----------------
1 file changed, 40 insertions(+), 135 deletions(-)
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
index 81a75b6007d3d..240d0f0d58305 100644
--- a/flang/test/Lower/OpenMP/declare-simd.f90
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -5,10 +5,14 @@
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -cpp -DOMP_60 %s -o - | FileCheck %s --check-prefix=CHECK60
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -cpp -DOMP_60 %s -o - | FileCheck %s
subroutine declare_simd_no_clause()
- !$omp declare simd
+#ifdef OMP_60
+!$omp declare_simd
+#else
+!$omp declare simd
+#endif
end subroutine declare_simd_no_clause
! CHECK-LABEL: func.func @_QPdeclare_simd_no_clause()
@@ -16,7 +20,11 @@ end subroutine declare_simd_no_clause
! CHECK: return
subroutine declare_simd_aligned(x, y, n, i)
- !$omp declare simd aligned(x, y : 64)
+#ifdef OMP_60
+!$omp declare_simd aligned(x, y : 64)
+#else
+!$omp declare simd aligned(x, y : 64)
+#endif
real(8), pointer, intent(inout) :: x(:)
real(8), pointer, intent(in) :: y(:)
integer, intent(in) :: n, i
@@ -29,14 +37,16 @@ end subroutine declare_simd_aligned
! CHECK: %[[N_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[X_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
! CHECK: %[[Y_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK: omp.declare_simd
-! CHECK-SAME: aligned(%[[X_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
-! CHECK-SAME: %[[Y_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
-! CHECK-NOT: {{[[:space:]]*(linear|simdlen)\(}}
+! CHECK: omp.declare_simd aligned(%[[X_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
+! CHECK-SAME: %[[Y_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64){{$}}
! CHECK: return
subroutine declare_simd_linear(x, y, n, i)
- !$omp declare simd linear(i)
+#ifdef OMP_60
+!$omp declare_simd linear(i)
+#else
+!$omp declare simd linear(i)
+#endif
real(8), pointer, intent(inout) :: x(:)
real(8), pointer, intent(in) :: y(:)
integer, intent(in) :: n, i
@@ -44,44 +54,38 @@ subroutine declare_simd_linear(x, y, n, i)
end subroutine declare_simd_linear
! CHECK-LABEL: func.func @_QPdeclare_simd_linear(
-! CHECK: %[[SCOPE_L:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[I_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[N_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[X_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK: %[[Y_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK: %[[C1_L:.*]] = arith.constant 1 : i32
-! CHECK: omp.declare_simd
-! CHECK-NOT: {{[[:space:]]*(aligned|simdlen)\(}}
+! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[I:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+! CHECK: omp.declare_simd linear(%[[I]]#0 = %[[C1]] : !fir.ref<i32>) {linear_var_types = [i32]}{{$}}
! CHECK: return
subroutine declare_simd_simdlen(x, y, n, i)
- !$omp declare simd simdlen(8)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
- if (i <= n) x(i) = x(i) + y(i)
+#ifdef OMP_60
+!$omp declare_simd simdlen(8)
+#else
+!$omp declare simd simdlen(8)
+#endif
end subroutine declare_simd_simdlen
! CHECK-LABEL: func.func @_QPdeclare_simd_simdlen(
! CHECK: %[[SCOPE_S:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[I_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[N_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[X_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK: %[[Y_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK: omp.declare_simd
-! CHECK-NOT: {{[[:space:]]*(aligned|linear)\(}}
-! CHECK-SAME: simdlen(8)
-! CHECK: return
+! CHECK: omp.declare_simd{{.*}}simdlen(8){{$}}
+! CHECK-NEXT: return
subroutine declare_simd_combined(x, y, n, i)
- !$omp declare simd aligned(x, y : 64) linear(i) simdlen(8)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
+#ifdef OMP_60
+!$omp declare_simd aligned(x, y : 64) linear(i) simdlen(8)
+#else
+!$omp declare simd aligned(x, y : 64) linear(i) simdlen(8)
+#endif
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
- if (i <= n) then
- x(i) = x(i) + y(i)
- end if
+ if (i <= n) then
+ x(i) = x(i) + y(i)
+ end if
end subroutine declare_simd_combined
! CHECK-LABEL: func.func @_QPdeclare_simd_combined(
@@ -102,102 +106,3 @@ end subroutine declare_simd_combined
! CHECK-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
! CHECK-SAME: simdlen(8)
! CHECK-SAME: {linear_var_types = [i32]}
-
-#ifdef OMP_60
-
-subroutine declare_simd_60_no_clause()
- !$omp declare_simd
-end subroutine declare_simd_60_no_clause
-
-! CHECK60-LABEL: func.func @_QPdeclare_simd_60_no_clause() {
-! CHECK60: omp.declare_simd
-
-subroutine declare_simd_aligned_60(x, y, n, i)
- !$omp declare_simd aligned(x, y : 64)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
- if (i <= n) x(i) = x(i) + y(i)
-end subroutine declare_simd_aligned_60
-
-! CHECK60-LABEL: func.func @_QPdeclare_simd_aligned_60(
-! CHECK60: %[[SCOPE_A:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK60: %[[I_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[N_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[X_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: %[[Y_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: omp.declare_simd
-! CHECK60-SAME: aligned(%[[X_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
-! CHECK60-SAME: %[[Y_A]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
-! CHECK60-NOT: {{[[:space:]]*(linear|simdlen)\(}}
-! CHECK60: return
-
-subroutine declare_simd_linear_60(x, y, n, i)
- !$omp declare_simd linear(i)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
- if (i <= n) x(i) = x(i) + y(i)
-end subroutine declare_simd_linear_60
-
-! CHECK60-LABEL: func.func @_QPdeclare_simd_linear_60(
-! CHECK60: %[[SCOPE_L:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK60: %[[I_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[N_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[X_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: %[[Y_L:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_L]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: %[[C1_L:.*]] = arith.constant 1 : i32
-! CHECK60: omp.declare_simd
-! CHECK60-NOT: {{[[:space:]]*(aligned|simdlen)\(}}
-! CHECK60: return
-
-subroutine declare_simd_simdlen_60(x, y, n, i)
- !$omp declare_simd simdlen(8)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
- if (i <= n) x(i) = x(i) + y(i)
-end subroutine declare_simd_simdlen_60
-
-! CHECK60-LABEL: func.func @_QPdeclare_simd_simdlen_60(
-! CHECK60: %[[SCOPE_S:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK60: %[[I_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[N_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[X_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 1 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: %[[Y_S:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_S]] arg 2 {{.*pointer.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: omp.declare_simd
-! CHECK60-NOT: {{[[:space:]]*(aligned|linear)\(}}
-! CHECK60-SAME: simdlen(8)
-! CHECK60: return
-
-subroutine declare_simd_combined_60(x, y, n, i)
- !$omp declare_simd aligned(x, y : 64) linear(i) simdlen(8)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- integer, intent(in) :: n, i
-
- if (i <= n) then
- x(i) = x(i) + y(i)
- end if
-end subroutine declare_simd_combined_60
-
-! CHECK60-LABEL: func.func @_QPdeclare_simd_combined_60(
-! CHECK60-SAME: %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>{{.*}}fir.bindc_name = "x"
-! CHECK60-SAME: %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>{{.*}}fir.bindc_name = "y"
-! CHECK60-SAME: %{{.*}}: !fir.ref<i32>{{.*}}fir.bindc_name = "n"
-! CHECK60-SAME: %{{.*}}: !fir.ref<i32>{{.*}}fir.bindc_name = "i"
-! CHECK60: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK60: %[[I_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[N_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 3 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK60: %[[X_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2 {{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
-! CHECK60: %[[C1:.*]] = arith.constant 1 : i32
-
-! CHECK60: omp.declare_simd
-! CHECK60-SAME: aligned(%[[X_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
-! CHECK60-SAME: %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
-! CHECK60-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
-! CHECK60-SAME: simdlen(8)
-! CHECK60-SAME: {linear_var_types = [i32]}
-
-#endif !OMP_60
>From 44cc260c26eae900b28a1df21ceca6c6e37a7b6e Mon Sep 17 00:00:00 2001
From: cchen <chichun.chen at hpe.com>
Date: Thu, 15 Jan 2026 11:43:48 -0600
Subject: [PATCH 5/6] Resolve feedback on DeclareSimdOp
- add back builders
- remove redudant `arguments` and `assemblyFormat` definition
- remove custom memory effect since the default of OpenMPOp already
has side effects
- make DeclareSimdOp::verify more concise
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 15 +++--------
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 11 +++-----
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 27 ++++++-------------
3 files changed, 14 insertions(+), 39 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 03531919b590a..163a35ec9639c 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3815,6 +3815,7 @@ static void
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
const parser::OpenMPDeclareSimdConstruct &declareSimdConstruct) {
+ mlir::Location loc = converter.getCurrentLocation();
const parser::OmpDirectiveSpecification &beginSpec = declareSimdConstruct.v;
List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
@@ -3823,19 +3824,9 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
cp.processAligned(clauseOps);
cp.processLinear(clauseOps);
cp.processSimdlen(clauseOps);
- cp.processTODO<clause::Uniform>(converter.getCurrentLocation(),
- llvm::omp::Directive::OMPD_declare_simd);
+ cp.processTODO<clause::Uniform>(loc, llvm::omp::Directive::OMPD_declare_simd);
- fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- mlir::Location loc = converter.getCurrentLocation();
- auto *ctx = firOpBuilder.getContext();
- mlir::ArrayAttr alignments;
- if (!clauseOps.alignments.empty())
- alignments = mlir::ArrayAttr::get(ctx, clauseOps.alignments);
- mlir::omp::DeclareSimdOp::create(firOpBuilder, loc, clauseOps.alignedVars,
- alignments, clauseOps.linearVars,
- clauseOps.linearStepVars,
- clauseOps.linearVarTypes, clauseOps.simdlen);
+ mlir::omp::DeclareSimdOp::create(converter.getFirOpBuilder(), loc, clauseOps);
}
static void genOpenMPDeclareMapperImpl(
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 67a54df270e1e..b044df9be56f3 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2245,9 +2245,7 @@ def WorkdistributeOp : OpenMP_Op<"workdistribute"> {
//===----------------------------------------------------------------------===//
def DeclareSimdOp
- : OpenMP_Op<"declare_simd",
- traits = [AttrSizedOperandSegments,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>],
+ : OpenMP_Op<"declare_simd", traits = [AttrSizedOperandSegments],
clauses = [OpenMP_AlignedClause, OpenMP_LinearClause,
OpenMP_SimdlenClause]> {
let summary = "declare simd directive";
@@ -2267,11 +2265,8 @@ def DeclareSimdOp
```
}] # clausesDescription;
- let arguments = clausesArgs;
-
- let assemblyFormat =
- clausesReqAssemblyFormat#" oilist("#clausesOptAssemblyFormat#") "#"attr-"
- "dict";
+ let builders = [OpBuilder<(
+ ins CArg<"const DeclareSimdOperands &">:$clauses)>];
let hasVerifier = 1;
}
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index fbd76b00b5a1a..d5085e914a16c 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4469,27 +4469,16 @@ LogicalResult DeclareSimdOp::verify() {
return emitOpError()
<< "'omp.declare_simd' must be nested inside a function";
- if (verifyAlignedClause(*this, getAlignments(), getAlignedVars()).failed())
- return failure();
-
- return success();
+ return verifyAlignedClause(*this, getAlignments(), getAlignedVars());
}
-namespace mlir {
-namespace omp {
-// A non-default resource to indicate that omp.declare_simd has side effects.
-struct DeclareSimdResource
- : public SideEffects::Resource::Base<DeclareSimdResource> {
- StringRef getName() final { return "omp.declare_simd.resource"; }
-};
-} // namespace omp
-} // namespace mlir
-
-void DeclareSimdOp::getEffects(
- SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
- &effects) {
- effects.emplace_back(MemoryEffects::Allocate::get(),
- DeclareSimdResource::get());
+void DeclareSimdOp::build(OpBuilder &odsBuilder, OperationState &odsState,
+ const DeclareSimdOperands &clauses) {
+ MLIRContext *ctx = odsBuilder.getContext();
+ DeclareSimdOp::build(odsBuilder, odsState, clauses.alignedVars,
+ makeArrayAttr(ctx, clauses.alignments),
+ clauses.linearVars, clauses.linearStepVars,
+ clauses.linearVarTypes, clauses.simdlen);
}
#define GET_ATTRDEF_CLASSES
>From ec5c7ba69b432e1f37f1d5b948bb78d6c2dce7f9 Mon Sep 17 00:00:00 2001
From: cchen <chichun.chen at hpe.com>
Date: Wed, 14 Jan 2026 16:14:24 -0600
Subject: [PATCH 6/6] [flang][mlir][OpenMP] Add support for uniform clause in
declare simd
Define OpenMP uniform clause in mlir and emit it from flang.
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 10 +++++
flang/lib/Lower/OpenMP/ClauseProcessor.h | 1 +
flang/lib/Lower/OpenMP/OpenMP.cpp | 2 +-
.../OpenMP/Todo/declare-simd-uniform.f90 | 9 -----
flang/test/Lower/OpenMP/declare-simd.f90 | 38 +++++++++++++++++--
.../mlir/Dialect/OpenMP/OpenMPClauses.td | 24 ++++++++++++
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 2 +-
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 32 +++++++++++++++-
mlir/test/Dialect/OpenMP/ops.mlir | 17 +++++++++
9 files changed, 120 insertions(+), 15 deletions(-)
delete mode 100644 flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index b923e415231d6..10c20e4dba718 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1722,6 +1722,16 @@ bool ClauseProcessor::processUseDevicePtr(
return clauseFound;
}
+bool ClauseProcessor::processUniform(
+ mlir::omp::UniformClauseOps &result) const {
+ return findRepeatableClause<omp::clause::Uniform>(
+ [&](const omp::clause::Uniform &clause, const parser::CharBlock &) {
+ const auto &objects = clause.v;
+ if (!objects.empty())
+ genObjectList(objects, converter, result.uniformVars);
+ });
+}
+
} // namespace omp
} // namespace lower
} // namespace Fortran
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index a04cd4b79dd24..063da68fb5702 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -168,6 +168,7 @@ class ClauseProcessor {
lower::StatementContext &stmtCtx,
mlir::omp::UseDevicePtrClauseOps &result,
llvm::SmallVectorImpl<const semantics::Symbol *> &useDeviceSyms) const;
+ bool processUniform(mlir::omp::UniformClauseOps &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 163a35ec9639c..71315e840b905 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3824,7 +3824,7 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
cp.processAligned(clauseOps);
cp.processLinear(clauseOps);
cp.processSimdlen(clauseOps);
- cp.processTODO<clause::Uniform>(loc, llvm::omp::Directive::OMPD_declare_simd);
+ cp.processUniform(clauseOps);
mlir::omp::DeclareSimdOp::create(converter.getFirOpBuilder(), loc, clauseOps);
}
diff --git a/flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90 b/flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90
deleted file mode 100644
index 1ca5dd34de2d2..0000000000000
--- a/flang/test/Lower/OpenMP/Todo/declare-simd-uniform.f90
+++ /dev/null
@@ -1,9 +0,0 @@
-! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-
-! CHECK: not yet implemented: Unhandled clause UNIFORM in DECLARE SIMD construct
-subroutine declare_simd_uniform(x, y)
- real(8), pointer, intent(inout) :: x(:)
- real(8), pointer, intent(in) :: y(:)
- !$omp declare simd uniform(x, y)
-end subroutine declare_simd_uniform
-
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
index 240d0f0d58305..6ebb82d801708 100644
--- a/flang/test/Lower/OpenMP/declare-simd.f90
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -73,11 +73,40 @@ end subroutine declare_simd_simdlen
! CHECK: omp.declare_simd{{.*}}simdlen(8){{$}}
! CHECK-NEXT: return
+subroutine declare_simd_uniform(x, y, n, i)
+#ifdef OMP_60
+!$omp declare_simd uniform(x, y)
+#else
+!$omp declare simd uniform(x, y)
+#endif
+
+ real(8), pointer, intent(inout) :: x(:)
+ real(8), pointer, intent(in) :: y(:)
+ integer, intent(in) :: n, i
+
+ if (i <= n) then
+ x(i) = x(i) + y(i)
+ end if
+end subroutine declare_simd_uniform
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_uniform(
+! CHECK-SAME: fir.bindc_name = "x"
+! CHECK-SAME: fir.bindc_name = "y"
+! CHECK-SAME: fir.bindc_name = "n"
+! CHECK-SAME: fir.bindc_name = "i"
+! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[IDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4
+! CHECK: %[[NDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 3
+! CHECK: %[[XDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1
+! CHECK: %[[YDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2
+! 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_combined(x, y, n, i)
#ifdef OMP_60
-!$omp declare_simd aligned(x, y : 64) linear(i) simdlen(8)
+!$omp declare_simd aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y)
#else
-!$omp declare simd aligned(x, y : 64) linear(i) simdlen(8)
+!$omp declare simd aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y)
#endif
real(8), pointer, intent(inout) :: x(:)
real(8), pointer, intent(in) :: y(:)
@@ -105,4 +134,7 @@ end subroutine declare_simd_combined
! CHECK-SAME: %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
! CHECK-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
! CHECK-SAME: simdlen(8)
-! CHECK-SAME: {linear_var_types = [i32]}
+! 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: {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 05e2ee4e5632b..3972c9aca4b12 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -1532,4 +1532,28 @@ class OpenMP_UseDevicePtrClauseSkip<
def OpenMP_UseDevicePtrClause : OpenMP_UseDevicePtrClauseSkip<>;
+//===----------------------------------------------------------------------===//
+// V5.2: [5.10] `uniform` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_UniformClauseSkip<
+ 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 Variadic<OpenMP_PointerLikeType>:$uniform_vars);
+
+ let optAssemblyFormat = [{
+ `uniform` `(` custom<UniformClause>($uniform_vars, type($uniform_vars)) `)`
+ }];
+
+ let description = [{
+ The `uniform` clause declares one or more arguments to have an invariant
+ value for all concurrent invocations of the function in the execution of
+ a single SIMD loop.
+ }];
+}
+
+def OpenMP_UniformClause : OpenMP_UniformClauseSkip<>;
+
#endif // OPENMP_CLAUSES
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index b044df9be56f3..5a33ad49fcaee 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2247,7 +2247,7 @@ def WorkdistributeOp : OpenMP_Op<"workdistribute"> {
def DeclareSimdOp
: OpenMP_Op<"declare_simd", traits = [AttrSizedOperandSegments],
clauses = [OpenMP_AlignedClause, OpenMP_LinearClause,
- OpenMP_SimdlenClause]> {
+ OpenMP_SimdlenClause, OpenMP_UniformClause]> {
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 d5085e914a16c..352c1556fd06d 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4478,7 +4478,37 @@ void DeclareSimdOp::build(OpBuilder &odsBuilder, OperationState &odsState,
DeclareSimdOp::build(odsBuilder, odsState, clauses.alignedVars,
makeArrayAttr(ctx, clauses.alignments),
clauses.linearVars, clauses.linearStepVars,
- clauses.linearVarTypes, clauses.simdlen);
+ clauses.linearVarTypes, clauses.simdlen,
+ clauses.uniformVars);
+}
+
+//===----------------------------------------------------------------------===//
+// Parser and printer for Uniform Clause
+//===----------------------------------------------------------------------===//
+
+/// uniform ::= `uniform` `(` uniform-list `)`
+/// uniform-list := uniform-val (`,` uniform-val)*
+/// uniform-val := ssa-id `:` type
+static ParseResult
+parseUniformClause(OpAsmParser &parser,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &uniformVars,
+ SmallVectorImpl<Type> &uniformTypes) {
+ return parser.parseCommaSeparatedList([&]() -> mlir::ParseResult {
+ if (parser.parseOperand(uniformVars.emplace_back()) ||
+ parser.parseColonType(uniformTypes.emplace_back()))
+ return mlir::failure();
+ return mlir::success();
+ });
+}
+
+/// Print Uniform Clauses
+static void printUniformClause(OpAsmPrinter &p, Operation *op,
+ ValueRange uniformVars, TypeRange uniformTypes) {
+ for (unsigned i = 0; i < uniformVars.size(); ++i) {
+ if (i != 0)
+ p << ", ";
+ p << uniformVars[i] << " : " << uniformTypes[i];
+ }
}
#define GET_ATTRDEF_CLASSES
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 95d179247fb91..cd0a01ee850c2 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -3413,6 +3413,19 @@ func.func @omp_declare_simd_linear(%a: f64, %b: f64, %iv: i32, %step: i32) -> ()
return
}
+// CHECK-LABEL: func.func @omp_declare_simd_uniform
+func.func @omp_declare_simd_uniform(%a: f64, %b: f64,
+ %p0: memref<i32>, %p1: memref<i32>) -> f64 {
+ // CHECK: omp.declare_simd
+ // CHECK-SAME: uniform(
+ // CHECK-SAME: %{{.*}} : memref<i32>,
+ // CHECK-SAME: %{{.*}} : memref<i32>)
+ omp.declare_simd uniform(%p0 : memref<i32>, %p1 : memref<i32>)
+
+ %0 = arith.addf %a, %b : f64
+ return %0 : f64
+}
+
// 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>,
@@ -3423,9 +3436,13 @@ func.func @omp_declare_simd_all_clauses(%a: f64, %b: f64,
// CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)
// CHECK-SAME: linear(%{{.*}} = %{{.*}} : i32)
// CHECK-SAME: simdlen(8)
+ // CHECK-SAME: uniform(
+ // CHECK-SAME: %{{.*}} : memref<i32>,
+ // CHECK-SAME: %{{.*}} : memref<i32>)
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>)
return
}
More information about the Mlir-commits
mailing list