[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
Wed Jan 14 14:19:31 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Chi-Chun, Chen (chichunchen)

<details>
<summary>Changes</summary>

Define OpenMP uniform clause in mlir and emit it from flang.

---
Full diff: https://github.com/llvm/llvm-project/pull/176046.diff


9 Files Affected:

- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+10) 
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.h (+1) 
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+21-2) 
- (added) flang/test/Lower/OpenMP/declare-simd.f90 (+140) 
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td (+24) 
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td (+36) 
- (modified) mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp (+63) 
- (modified) mlir/test/Dialect/OpenMP/invalid.mlir (+4) 
- (modified) mlir/test/Dialect/OpenMP/ops.mlir (+79) 


``````````diff
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 4381d1e9064cf..5f64408c040a5 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3815,8 +3815,27 @@ 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");
+  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);
+  cp.processUniform(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,
+                                   clauseOps.uniformVars);
 }
 
 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..6ebb82d801708
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -0,0 +1,140 @@
+! 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 -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
+
+subroutine declare_simd_no_clause()
+#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()
+! CHECK: omp.declare_simd{{$}}
+! CHECK: return
+
+subroutine declare_simd_aligned(x, y, n, i)
+#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
+  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 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)
+#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
+  if (i <= n) x(i) = x(i) + y(i)
+end subroutine  declare_simd_linear
+
+! CHECK-LABEL: func.func @_QPdeclare_simd_linear(
+! 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)
+#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: 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) uniform(x, y)
+#else
+!$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(:)
+  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: 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 bbfe805eefe48..90c32e81ba6d0 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -2240,4 +2240,40 @@ def WorkdistributeOp : OpenMP_Op<"workdistribute"> {
   let assemblyFormat = "$region attr-dict";
 }
 
+//===----------------------------------------------------------------------===//
+// declare simd Construct
+//===----------------------------------------------------------------------===//
+
+def DeclareSimdOp
+    : OpenMP_Op<"declare_simd",
+                traits = [AttrSizedOperandSegments,
+                          DeclareOpInterfaceMethods<MemoryEffectsOpInterface>],
+                clauses = [OpenMP_AlignedClause, OpenMP_LinearClause,
+                           OpenMP_SimdlenClause, OpenMP_UniformClause]> {
+  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 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..5643dba880d62 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -4458,6 +4458,69 @@ LogicalResult WorkdistributeOp::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// Declare simd [7.7]
+//===----------------------------------------------------------------------===//
+
+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";
+
+  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());
+}
+
+//===----------------------------------------------------------------------===//
+// 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
 #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 ac29e20907b55..cd0a01ee850c2 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -3367,3 +3367,82 @@ func.func @omp_target_map_clause_type_test(%arg0 : memref<?xi32>) -> () {
 
     return
 }
+
+// CHECK-LABEL: func.func @omp_declare_simd
+func.func @omp_declare_simd() -> () {
+  // CHECK: omp.declare_simd
+  omp.declare_simd
+  return
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_simdlen
+func.func @omp_declare_simd_simdlen() -> () {
+  // CHECK: omp.declare_simd
+  // CHECK-SAME: simdlen(8)
+  omp.declare_simd simdlen(8)
+  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>) -> () {
+  // 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)
+
+  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>) -> () {
+  // 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)
+  return
+}
+
+// CHECK-LABEL: func.func @omp_declare_simd_linear
+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)
+  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>,
+                                        %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: 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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/176046


More information about the Mlir-commits mailing list