[Mlir-commits] [flang] [mlir] [flang][openmp] Add support for ordered regions in SIMD directives (PR #181012)

Sunil Shrestha llvmlistbot at llvm.org
Tue Feb 17 14:00:50 PST 2026


https://github.com/sshrestha-aa updated https://github.com/llvm/llvm-project/pull/181012

>From 11eac36e0f40a6ffd6437c4e3f22abd090c5ba30 Mon Sep 17 00:00:00 2001
From: Sunil Shrestha <sunil.shrestha at hpe.com>
Date: Wed, 4 Feb 2026 18:25:43 -0600
Subject: [PATCH 1/2] [flang][openmp] Add support for ordered regions in SIMD
 directives

Add support for ordered regions within SIMD directives (!$omp simd ordered
and !$omp do simd ordered). This initial implementation matches Clang's
behavior.

In SIMD directives, loop induction variables have an implicit linear clause
with deferred store semantics (storing to .linear_result). To properly support
ordered regions, the LinearClauseProcessor rewrites variable references to use
.linear_result in:
- omp.ordered.region: Code inside ordered blocks
- omp_region.finalize: Code after ordered blocks

Note: The vectorizer cannot currently vectorize loops with ordered regions.
Future enhancement would require generating lane loops or unrolling ordered
regions across SIMD lanes while maintaining ordering semantics.
---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp    |   5 +
 flang/lib/Lower/OpenMP/ClauseProcessor.h      |   1 +
 flang/lib/Lower/OpenMP/OpenMP.cpp             |   2 +-
 .../OpenMP/OpenMPToLLVMIRTranslation.cpp      |  44 ++++++--
 .../Target/LLVMIR/openmp-simd-ordered.mlir    | 100 +++++++++++++++++
 mlir/test/Target/LLVMIR/openmp-todo.mlir      |  11 --
 .../LLVMIR/openmp-wsloop-simd-ordered.mlir    | 101 ++++++++++++++++++
 7 files changed, 245 insertions(+), 19 deletions(-)
 create mode 100644 mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir
 create mode 100644 mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 9f9dd436dc6a8..60bc2db6ee5e3 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -702,6 +702,11 @@ bool ClauseProcessor::processSimdlen(
   return false;
 }
 
+bool ClauseProcessor::processSimd(
+    mlir::omp::OrderedRegionOperands &result) const {
+  return markClauseOccurrence<omp::clause::Simd>(result.parLevelSimd);
+}
+
 bool ClauseProcessor::processThreadLimit(
     lower::StatementContext &stmtCtx,
     mlir::omp::ThreadLimitClauseOps &result) const {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index ca9b28dfdd061..14ed9f5f4f12e 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -113,6 +113,7 @@ class ClauseProcessor {
   bool processSchedule(lower::StatementContext &stmtCtx,
                        mlir::omp::ScheduleClauseOps &result) const;
   bool processSimdlen(mlir::omp::SimdlenClauseOps &result) const;
+  bool processSimd(mlir::omp::OrderedRegionOperands &result) const;
   bool processThreadLimit(lower::StatementContext &stmtCtx,
                           mlir::omp::ThreadLimitClauseOps &result) const;
   bool processUntied(mlir::omp::UntiedClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index f7be823335bd9..368847a488f03 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1589,7 +1589,7 @@ genOrderedRegionClauses(lower::AbstractConverter &converter,
                         const List<Clause> &clauses, mlir::Location loc,
                         mlir::omp::OrderedRegionOperands &clauseOps) {
   ClauseProcessor cp(converter, semaCtx, clauses);
-  cp.processTODO<clause::Simd>(loc, llvm::omp::Directive::OMPD_ordered);
+  cp.processSimd(clauseOps);
 }
 
 static void genParallelClauses(
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 41b1b9c37dead..716501221935c 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -354,10 +354,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
     if (op.getOrder() || op.getOrderMod())
       result = todo("order");
   };
-  auto checkParLevelSimd = [&todo](auto op, LogicalResult &result) {
-    if (op.getParLevelSimd())
-      result = todo("parallelization-level");
-  };
   auto checkPrivate = [&todo](auto op, LogicalResult &result) {
     if (!op.getPrivateVars().empty() || op.getPrivateSyms())
       result = todo("privatization");
@@ -396,7 +392,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
         checkAllocate(op, result);
         checkOrder(op, result);
       })
-      .Case([&](omp::OrderedRegionOp op) { checkParLevelSimd(op, result); })
       .Case([&](omp::SectionsOp op) {
         checkAllocate(op, result);
         checkPrivate(op, result);
@@ -3151,9 +3146,27 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
                                                 loopInfo->getLastIter());
     if (failed(handleError(afterBarrierIP, *loopOp)))
       return failure();
-    for (size_t index = 0; index < wsloopOp.getLinearVars().size(); index++)
+
+    // Check if this worksharing loop contains ordered regions (with SIMD)
+    bool hasOrderedRegions = false;
+    wsloopOp.getRegion().walk([&](omp::OrderedRegionOp orderedOp) {
+      hasOrderedRegions = true;
+      return WalkResult::interrupt();
+    });
+
+    for (size_t index = 0; index < wsloopOp.getLinearVars().size(); index++) {
       linearClauseProcessor.rewriteInPlace(builder, "omp.loop_nest.region",
                                            index);
+      // Only do extra rewrites if we have both SIMD and ordered regions
+      if (isSimd && hasOrderedRegions) {
+        // Also rewrite uses in ordered regions so they read the current value
+        linearClauseProcessor.rewriteInPlace(builder, "omp.ordered.region",
+                                             index);
+        // Also rewrite uses in finalize blocks (code after ordered regions)
+        linearClauseProcessor.rewriteInPlace(builder, "omp_region.finalize",
+                                             index);
+      }
+    }
     builder.restoreIP(oldIP);
   }
 
@@ -3515,9 +3528,26 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
                         order, simdlen, safelen);
 
   linearClauseProcessor.emitStoresForLinearVar(builder);
-  for (size_t index = 0; index < simdOp.getLinearVars().size(); index++)
+
+  // Check if this SIMD loop contains ordered regions
+  bool hasOrderedRegions = false;
+  simdOp.getRegion().walk([&](omp::OrderedRegionOp orderedOp) {
+    hasOrderedRegions = true;
+    return WalkResult::interrupt();
+  });
+
+  for (size_t index = 0; index < simdOp.getLinearVars().size(); index++) {
     linearClauseProcessor.rewriteInPlace(builder, "omp.loop_nest.region",
                                          index);
+    if (hasOrderedRegions) {
+      // Also rewrite uses in ordered regions so they read the current value
+      linearClauseProcessor.rewriteInPlace(builder, "omp.ordered.region",
+                                           index);
+      // Also rewrite uses in finalize blocks (code after ordered regions)
+      linearClauseProcessor.rewriteInPlace(builder, "omp_region.finalize",
+                                           index);
+    }
+  }
 
   // We now need to reduce the per-simd-lane reduction variable into the
   // original variable. This works a bit differently to other reductions (e.g.
diff --git a/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir b/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir
new file mode 100644
index 0000000000000..3f2e7a3a87336
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir
@@ -0,0 +1,100 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// Test that linear variables in SIMD loops with ordered regions
+// are correctly rewritten to use .linear_result in:
+// 1. The ordered region (omp.ordered.region)
+// 2. Code after the ordered region (omp_region.finalize)
+//
+// This tests "omp ordered simd" nested in  "omp simd ordered"
+// !$omp simd
+// do i = 1, n
+//     a(i) = b(i) * 10
+//         !$omp ordered simd
+//             print *, a(i)
+//         !$omp end ordered
+//     c(i) = a(i) * 2
+// end do
+// !$omp end simd
+// !$omp end do simd
+
+module {
+  omp.private {type = private} @i_private_i32 : i32
+
+  llvm.func @_FortranAioBeginExternalListOutput(i32, !llvm.ptr, i32) -> !llvm.ptr
+  llvm.func @_FortranAioOutputInteger32(!llvm.ptr, i32) -> i1
+  llvm.func @_FortranAioEndIoStatement(!llvm.ptr) -> i32
+
+  llvm.mlir.global internal constant @str("test.f90\00") {addr_space = 0 : i32}
+
+  // CHECK-LABEL: define void @simd_ordered_linear
+  llvm.func @simd_ordered_linear() {
+    %c0_i64 = llvm.mlir.constant(0 : i64) : i64
+    %c1_i64 = llvm.mlir.constant(1 : i64) : i64
+    %c1_i32 = llvm.mlir.constant(1 : i32) : i32
+    %c10_i32 = llvm.mlir.constant(10 : i32) : i32
+    %c10_val = llvm.mlir.constant(10 : i32) : i32
+    %c2 = llvm.mlir.constant(2 : i32) : i32
+    %c6 = llvm.mlir.constant(6 : i32) : i32
+    %c18 = llvm.mlir.constant(18 : i32) : i32
+
+    // Allocate arrays and loop variable
+    %c100_i64 = llvm.mlir.constant(100 : i64) : i64
+    %a = llvm.alloca %c100_i64 x i32 : (i64) -> !llvm.ptr
+    %b = llvm.alloca %c100_i64 x i32 : (i64) -> !llvm.ptr
+    %c = llvm.alloca %c100_i64 x i32 : (i64) -> !llvm.ptr
+    %i = llvm.alloca %c1_i64 x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
+
+    // CHECK: %.linear_var = alloca i32
+    // CHECK: %.linear_result = alloca i32
+
+    omp.simd linear(%i = %c1_i32 : !llvm.ptr) private(@i_private_i32 %i -> %arg0 : !llvm.ptr) {
+      omp.loop_nest (%iv) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32) {
+        // CHECK: omp.loop_nest.region:
+        // CHECK: load i32, ptr %.linear_result
+        llvm.store %iv, %arg0 : i32, !llvm.ptr
+
+        // Compute a[i] = b[i] * 10
+        %i_val = llvm.load %arg0 : !llvm.ptr -> i32
+        %i_idx = llvm.sext %i_val : i32 to i64
+        %i_off = llvm.sub %i_idx, %c1_i64 : i64
+        %b_ptr = llvm.getelementptr %b[%i_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+        %b_val = llvm.load %b_ptr : !llvm.ptr -> i32
+        %a_val = llvm.mul %b_val, %c10_val : i32
+        %a_ptr = llvm.getelementptr %a[%i_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+        llvm.store %a_val, %a_ptr : i32, !llvm.ptr
+
+        // Ordered region
+        omp.ordered.region par_level_simd {
+          // CHECK: omp.ordered.region:
+          // CHECK: load i32, ptr %.linear_result
+          %i_ord = llvm.load %arg0 : !llvm.ptr -> i32
+          %i_ord_idx = llvm.sext %i_ord : i32 to i64
+          %i_ord_off = llvm.sub %i_ord_idx, %c1_i64 : i64
+          %a_ord_ptr = llvm.getelementptr %a[%i_ord_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+          %a_ord_val = llvm.load %a_ord_ptr : !llvm.ptr -> i32
+
+          %str_ptr = llvm.mlir.addressof @str : !llvm.ptr
+          %io = llvm.call @_FortranAioBeginExternalListOutput(%c6, %str_ptr, %c18) : (i32, !llvm.ptr, i32) -> !llvm.ptr
+          %result = llvm.call @_FortranAioOutputInteger32(%io, %a_ord_val) : (!llvm.ptr, i32) -> i1
+          %end = llvm.call @_FortranAioEndIoStatement(%io) : (!llvm.ptr) -> i32
+          omp.terminator
+        }
+
+        // Compute c[i] = a[i] * 2 (code after ordered region)
+        // CHECK: omp_region.finalize:
+        // CHECK: load i32, ptr %.linear_result
+        %i_post = llvm.load %arg0 : !llvm.ptr -> i32
+        %i_post_idx = llvm.sext %i_post : i32 to i64
+        %i_post_off = llvm.sub %i_post_idx, %c1_i64 : i64
+        %a_post_ptr = llvm.getelementptr %a[%i_post_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+        %a_post_val = llvm.load %a_post_ptr : !llvm.ptr -> i32
+        %c_val = llvm.mul %a_post_val, %c2 : i32
+        %c_ptr = llvm.getelementptr %c[%i_post_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+        llvm.store %c_val, %c_ptr : i32, !llvm.ptr
+
+        omp.yield
+      }
+    } {linear_var_types = [i32]}
+    llvm.return
+  }
+}
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index 9a10ad74baeb6..1a1286cb30251 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -52,17 +52,6 @@ llvm.func @distribute_order(%lb : i32, %ub : i32, %step : i32) {
 
 // -----
 
-llvm.func @ordered_region_par_level_simd() {
-  // expected-error at below {{not yet implemented: Unhandled clause parallelization-level in omp.ordered.region operation}}
-  // expected-error at below {{LLVM Translation failed for operation: omp.ordered.region}}
-  omp.ordered.region par_level_simd {
-    omp.terminator
-  }
-  llvm.return
-}
-
-// -----
-
 llvm.func @parallel_allocate(%x : !llvm.ptr) {
   // expected-error at below {{not yet implemented: Unhandled clause allocate in omp.parallel operation}}
   // expected-error at below {{LLVM Translation failed for operation: omp.parallel}}
diff --git a/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir b/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir
new file mode 100644
index 0000000000000..d09d339297754
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir
@@ -0,0 +1,101 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// Test that linear variables in worksharing+SIMD loops with ordered regions
+// are correctly rewritten to use .linear_result in:
+// 1. The ordered region (omp.ordered.region)
+// 2. Code after the ordered region (omp_region.finalize)
+//
+// This tests "omp ordered simd" nested in  "omp do simd ordered" case
+// !$omp do simd ordered
+// do i = 1, n
+//     a(i) = b(i) * 10
+//         !$omp ordered simd
+//             print *, a(i)
+//         !$omp end ordered
+//     c(i) = a(i) * 2
+// end do
+// !$omp end do simd
+
+module {
+  omp.private {type = private} @i_private_i32 : i32
+
+  llvm.func @_FortranAioBeginExternalListOutput(i32, !llvm.ptr, i32) -> !llvm.ptr
+  llvm.func @_FortranAioOutputInteger32(!llvm.ptr, i32) -> i1
+  llvm.func @_FortranAioEndIoStatement(!llvm.ptr) -> i32
+
+  llvm.mlir.global internal constant @str("test.f90\00") {addr_space = 0 : i32}
+
+  // CHECK-LABEL: define void @wsloop_simd_ordered_linear
+  llvm.func @wsloop_simd_ordered_linear() {
+    %c0_i64 = llvm.mlir.constant(0 : i64) : i64
+    %c1_i64 = llvm.mlir.constant(1 : i64) : i64
+    %c1_i32 = llvm.mlir.constant(1 : i32) : i32
+    %c100_i32 = llvm.mlir.constant(100 : i32) : i32
+    %c10_val = llvm.mlir.constant(10 : i32) : i32
+    %c2 = llvm.mlir.constant(2 : i32) : i32
+    %c6 = llvm.mlir.constant(6 : i32) : i32
+    %c18 = llvm.mlir.constant(18 : i32) : i32
+
+    // Allocate arrays and loop variable
+    %c100_i64 = llvm.mlir.constant(100 : i64) : i64
+    %a = llvm.alloca %c100_i64 x i32 : (i64) -> !llvm.ptr
+    %b = llvm.alloca %c100_i64 x i32 : (i64) -> !llvm.ptr
+    %c = llvm.alloca %c100_i64 x i32 : (i64) -> !llvm.ptr
+    %i = llvm.alloca %c1_i64 x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
+
+    // CHECK: %.linear_var = alloca i32
+    // CHECK: %.linear_result = alloca i32
+
+    omp.wsloop ordered(0) {
+      omp.simd linear(%i = %c1_i32 : !llvm.ptr) private(@i_private_i32 %i -> %arg0 : !llvm.ptr) {
+        omp.loop_nest (%iv) : i32 = (%c1_i32) to (%c100_i32) inclusive step (%c1_i32) {
+          // CHECK: omp.loop_nest.region:
+          // CHECK: load i32, ptr %.linear_result
+          llvm.store %iv, %arg0 : i32, !llvm.ptr
+
+          // Compute a[i] = b[i] * 10
+          %i_val = llvm.load %arg0 : !llvm.ptr -> i32
+          %i_idx = llvm.sext %i_val : i32 to i64
+          %i_off = llvm.sub %i_idx, %c1_i64 : i64
+          %b_ptr = llvm.getelementptr %b[%i_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+          %b_val = llvm.load %b_ptr : !llvm.ptr -> i32
+          %a_val = llvm.mul %b_val, %c10_val : i32
+          %a_ptr = llvm.getelementptr %a[%i_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+          llvm.store %a_val, %a_ptr : i32, !llvm.ptr
+
+          // Ordered region
+          omp.ordered.region par_level_simd {
+            // CHECK: omp.ordered.region:
+            // CHECK: load i32, ptr %.linear_result
+            %i_ord = llvm.load %arg0 : !llvm.ptr -> i32
+            %i_ord_idx = llvm.sext %i_ord : i32 to i64
+            %i_ord_off = llvm.sub %i_ord_idx, %c1_i64 : i64
+            %a_ord_ptr = llvm.getelementptr %a[%i_ord_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+            %a_ord_val = llvm.load %a_ord_ptr : !llvm.ptr -> i32
+
+            %str_ptr = llvm.mlir.addressof @str : !llvm.ptr
+            %io = llvm.call @_FortranAioBeginExternalListOutput(%c6, %str_ptr, %c18) : (i32, !llvm.ptr, i32) -> !llvm.ptr
+            %result = llvm.call @_FortranAioOutputInteger32(%io, %a_ord_val) : (!llvm.ptr, i32) -> i1
+            %end = llvm.call @_FortranAioEndIoStatement(%io) : (!llvm.ptr) -> i32
+            omp.terminator
+          }
+
+          // Compute c[i] = a[i] * 2 (code after ordered region)
+          // CHECK: omp_region.finalize:
+          // CHECK: load i32, ptr %.linear_result
+          %i_post = llvm.load %arg0 : !llvm.ptr -> i32
+          %i_post_idx = llvm.sext %i_post : i32 to i64
+          %i_post_off = llvm.sub %i_post_idx, %c1_i64 : i64
+          %a_post_ptr = llvm.getelementptr %a[%i_post_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+          %a_post_val = llvm.load %a_post_ptr : !llvm.ptr -> i32
+          %c_val = llvm.mul %a_post_val, %c2 : i32
+          %c_ptr = llvm.getelementptr %c[%i_post_off] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+          llvm.store %c_val, %c_ptr : i32, !llvm.ptr
+
+          omp.yield
+        }
+      } {linear_var_types = [i32], omp.composite}
+    } {omp.composite}
+    llvm.return
+  }
+}

>From fe62d0407f6841ca1b120a8a1eb6533aaf8fcd09 Mon Sep 17 00:00:00 2001
From: Sunil Shrestha <sunil.shrestha at hpe.com>
Date: Tue, 17 Feb 2026 13:27:19 -0600
Subject: [PATCH 2/2] Add par level simd check

---
 flang/test/Lower/OpenMP/ordered-simd.f90      | 56 +++++++++++++++++++
 .../Target/LLVMIR/openmp-simd-ordered.mlir    |  1 +
 .../LLVMIR/openmp-wsloop-simd-ordered.mlir    |  1 +
 3 files changed, 58 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/ordered-simd.f90

diff --git a/flang/test/Lower/OpenMP/ordered-simd.f90 b/flang/test/Lower/OpenMP/ordered-simd.f90
new file mode 100644
index 0000000000000..80411adf9ed38
--- /dev/null
+++ b/flang/test/Lower/OpenMP/ordered-simd.f90
@@ -0,0 +1,56 @@
+! This test checks lowering of SIMD constructs with ordered regions.
+! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+! Test that ordered regions inside SIMD have par_level_simd attribute
+subroutine ordered_simd(n)
+  integer :: n, a(100), b(100), c(100), i
+
+! CHECK-LABEL: func @_QPordered_simd
+! CHECK:         omp.simd linear({{.*}}) private({{.*}}) {
+! CHECK:           omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) {
+! CHECK:             omp.ordered.region par_level_simd {
+! CHECK:               omp.terminator
+! CHECK:             }
+! CHECK:             omp.yield
+! CHECK:           }
+! CHECK:         } {linear_var_types = [i32]}
+
+  !$omp simd
+  do i = 1, n
+    a(i) = b(i) * 10
+    !$omp ordered simd
+    print *, a(i)
+    !$omp end ordered
+    c(i) = a(i) * 2
+  end do
+  !$omp end simd
+
+end subroutine
+
+! Test that ordered regions inside DO SIMD have par_level_simd attribute
+subroutine ws_ordered_simd(n)
+  integer :: n, a(100), b(100), c(100), i
+
+! CHECK-LABEL: func @_QPws_ordered_simd
+! CHECK:         omp.wsloop ordered(0) {
+! CHECK:           omp.simd linear({{.*}}) private({{.*}}) {
+! CHECK:             omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) {
+! CHECK:               omp.ordered.region par_level_simd {
+! CHECK:                 omp.terminator
+! CHECK:               }
+! CHECK:               omp.yield
+! CHECK:             }
+! CHECK:           } {linear_var_types = [i32], omp.composite}
+! CHECK:         } {omp.composite}
+
+  !$omp do simd ordered
+  do i = 1, n
+    a(i) = b(i) * 10
+    !$omp ordered simd
+    print *, a(i)
+    !$omp end ordered
+    c(i) = a(i) * 2
+  end do
+  !$omp end do simd
+
+end subroutine
diff --git a/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir b/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir
index 3f2e7a3a87336..d6834fdde385a 100644
--- a/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-simd-ordered.mlir
@@ -97,4 +97,5 @@ module {
     } {linear_var_types = [i32]}
     llvm.return
   }
+  // CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
 }
diff --git a/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir b/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir
index d09d339297754..46960a22a2889 100644
--- a/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-wsloop-simd-ordered.mlir
@@ -98,4 +98,5 @@ module {
     } {omp.composite}
     llvm.return
   }
+  // CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
 }



More information about the Mlir-commits mailing list