Index: flang/lib/Lower/OpenMP.cpp =================================================================== --- flang/lib/Lower/OpenMP.cpp +++ flang/lib/Lower/OpenMP.cpp @@ -440,8 +440,20 @@ // Handle attribute based clauses. for (const Fortran::parser::OmpClause &clause : wsLoopOpClauseList.v) { - if (const auto &scheduleClause = - std::get_if(&clause.u)) { + if (const auto &orderedClause = + std::get_if(&clause.u)) { + if (orderedClause->v.has_value()) { + const auto *expr = Fortran::semantics::GetExpr(orderedClause->v); + const std::optional orderedClauseValue = + Fortran::evaluate::ToInt64(*expr); + wsLoopOp.ordered_valAttr( + firOpBuilder.getI64IntegerAttr(*orderedClauseValue)); + } else { + wsLoopOp.ordered_valAttr(firOpBuilder.getI64IntegerAttr(0)); + } + } else if (const auto &scheduleClause = + std::get_if( + &clause.u)) { mlir::MLIRContext *context = firOpBuilder.getContext(); const auto &scheduleType = scheduleClause->v; const auto &scheduleKind = Index: flang/test/Lower/OpenMP/omp-wsloop-ordered.f90 =================================================================== --- /dev/null +++ flang/test/Lower/OpenMP/omp-wsloop-ordered.f90 @@ -0,0 +1,40 @@ +! This test checks lowering of worksharing-loop construct with ordered clause. + +! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck %s + +! This checks lowering ordered clause specified without parameter +subroutine wsloop_ordered_no_para() + integer :: a(10), i + +! CHECK: omp.wsloop ordered(0) for (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) { +! CHECK: omp.yield +! CHECK: } + + !$omp do ordered + do i = 2, 10 + !$omp ordered + a(i) = a(i-1) + 1 + !$omp end ordered + end do + !$omp end do + +end + +! This checks lowering ordered clause specified with a parameter +subroutine wsloop_ordered_with_para() + integer :: a(10), i + +! CHECK: func @_QPwsloop_ordered_with_para() { +! CHECK: omp.wsloop ordered(1) for (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) { +! CHECK: omp.yield +! CHECK: } + + !$omp do ordered(1) + do i = 2, 10 + !!$omp ordered depend(sink: i-1) + a(i) = a(i-1) + 1 + !!$omp ordered depend(source) + end do + !$omp end do + +end Index: mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir =================================================================== --- mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir +++ mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir @@ -1,4 +1,4 @@ -// RUN: mlir-opt -convert-openmp-to-llvm %s -split-input-file | FileCheck %s +// RUN: mlir-opt -convert-openmp-to-llvm -split-input-file %s | FileCheck %s // CHECK-LABEL: llvm.func @master_block_arg func.func @master_block_arg() { @@ -15,6 +15,8 @@ return } +// ----- + // CHECK-LABEL: llvm.func @branch_loop func.func @branch_loop() { %start = arith.constant 0 : index @@ -44,6 +46,8 @@ return } +// ----- + // CHECK-LABEL: @wsloop // CHECK: (%[[ARG0:.*]]: i64, %[[ARG1:.*]]: i64, %[[ARG2:.*]]: i64, %[[ARG3:.*]]: i64, %[[ARG4:.*]]: i64, %[[ARG5:.*]]: i64) func.func @wsloop(%arg0: index, %arg1: index, %arg2: index, %arg3: index, %arg4: index, %arg5: index) { @@ -62,3 +66,43 @@ } return } + +// ----- + +// CHECK-LABEL: @wsloop_ordered_no_para +// CHECK: %[[VAL0:.*]] = llvm.mlir.constant(1 : i32) : i32 +// CHECK: %[[VAL1:.*]] = llvm.mlir.constant(10 : i32) : i32 +// CHECK: %[[VAL2:.*]] = llvm.mlir.constant(2 : i32) : i32 +// CHECK: omp.wsloop ordered(0) for (%[[ARG0:.*]]) : i32 = (%[[VAL2]]) to (%[[VAL1]]) inclusive step (%[[VAL0]]) { +// CHECK: omp.yield +// CHECK: } +// CHECK: llvm.return +func.func @wsloop_ordered_no_para() { + %c1_i32 = arith.constant 1 : i32 + %c10_i32 = arith.constant 10 : i32 + %c2_i32 = arith.constant 2 : i32 + omp.wsloop ordered(0) for (%arg0) : i32 = (%c2_i32) to (%c10_i32) inclusive step (%c1_i32) { + omp.yield + } + return +} + +// ----- + +// CHECK-LABEL: @wsloop_ordered_with_para +// CHECK: %[[VAL0:.*]] = llvm.mlir.constant(1 : i32) : i32 +// CHECK: %[[VAL1:.*]] = llvm.mlir.constant(10 : i32) : i32 +// CHECK: %[[VAL2:.*]] = llvm.mlir.constant(2 : i32) : i32 +// CHECK: omp.wsloop ordered(1) for (%[[ARG0:.*]]) : i32 = (%[[VAL2]]) to (%[[VAL1]]) inclusive step (%[[VAL0]]) { +// CHECK: omp.yield +// CHECK: } +// CHECK: llvm.return +func.func @wsloop_ordered_with_para() { + %c1_i32 = arith.constant 1 : i32 + %c10_i32 = arith.constant 10 : i32 + %c2_i32 = arith.constant 2 : i32 + omp.wsloop ordered(1) for (%arg0) : i32 = (%c2_i32) to (%c10_i32) inclusive step (%c1_i32) { + omp.yield + } + return +}