[flang-commits] [flang] [flang][OpenMP] Set the default schedule modifier (PR #139572)

via flang-commits flang-commits at lists.llvm.org
Mon May 12 09:11:00 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-openmp

Author: Tom Eccles (tblah)

<details>
<summary>Changes</summary>

This is fixing "Default loop schedule modifier for worksharing-loop constructs without static schedule and ordered clause is nonmonotonic since OpenMP 5.0" in the to-do list for removing the OpenMP experimental status warning. I quote the relevant part of OpenMP 6.0 in the patch.

So far as I can tell, in OpenMP 4.5 the default schedule modifier was the `def-sched-var` ICV. The initial value of this ICV is implementation defined (table 2.1). So I believe we don't need to check the version for this.

It wasn't obvious to me whether this should be done in Semantics, Lowering, or LLVMIR codegen. I didn't do it in semantics so that we didn't add modifiers which could be seen in the unparse. It was more convenient to implement in lowering than in codegen.

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


6 Files Affected:

- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+15-1) 
- (modified) flang/test/Lower/OpenMP/distribute-parallel-do.f90 (+1-1) 
- (modified) flang/test/Lower/OpenMP/parallel-wsloop.f90 (+1-1) 
- (modified) flang/test/Lower/OpenMP/wsloop-chunks.f90 (+3-3) 
- (modified) flang/test/Lower/OpenMP/wsloop-schedule.f90 (+29-3) 
- (modified) flang/test/Lower/OpenMP/wsloop.f90 (+1-1) 


``````````diff
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index f4876256a378f..960e9fe63ad88 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -547,9 +547,23 @@ bool ClauseProcessor::processSchedule(
         mlir::omp::ClauseScheduleKindAttr::get(context, scheduleKind);
 
     mlir::omp::ScheduleModifier scheduleMod = getScheduleModifier(*clause);
-    if (scheduleMod != mlir::omp::ScheduleModifier::none)
+    if (scheduleMod != mlir::omp::ScheduleModifier::none) {
       result.scheduleMod =
           mlir::omp::ScheduleModifierAttr::get(context, scheduleMod);
+    } else {
+      // OpenMP 6.0 13.6.3:
+      // If an ordering-modifier is not specified, the effect is as if the
+      // monotonic ordering modifier is specified if the kind argument is
+      // static or an ordered clause is specified on the construct; otherwise,
+      // the effect is as if the nonmonotonic ordering modifier is specified.
+      mlir::omp::ScheduleModifier defaultMod =
+          mlir::omp::ScheduleModifier::nonmonotonic;
+      if (scheduleKind == mlir::omp::ClauseScheduleKind::Static ||
+          findUniqueClause<omp::clause::Ordered>())
+        defaultMod = mlir::omp::ScheduleModifier::monotonic;
+      result.scheduleMod =
+          mlir::omp::ScheduleModifierAttr::get(context, defaultMod);
+    }
 
     if (getSimdModifier(*clause) != mlir::omp::ScheduleModifier::none)
       result.scheduleSimd = firOpBuilder.getUnitAttr();
diff --git a/flang/test/Lower/OpenMP/distribute-parallel-do.f90 b/flang/test/Lower/OpenMP/distribute-parallel-do.f90
index cddf61647ead3..ad69e3a163799 100644
--- a/flang/test/Lower/OpenMP/distribute-parallel-do.f90
+++ b/flang/test/Lower/OpenMP/distribute-parallel-do.f90
@@ -42,7 +42,7 @@ subroutine distribute_parallel_do_schedule()
 
   ! CHECK:      omp.parallel private({{.*}}) {
   ! CHECK:      omp.distribute {
-  ! CHECK-NEXT: omp.wsloop schedule(runtime) {
+  ! CHECK-NEXT: omp.wsloop schedule(runtime, nonmonotonic) {
   ! CHECK-NEXT: omp.loop_nest
   !$omp distribute parallel do schedule(runtime)
   do index_ = 1, 10
diff --git a/flang/test/Lower/OpenMP/parallel-wsloop.f90 b/flang/test/Lower/OpenMP/parallel-wsloop.f90
index 15a68e2c0e65b..f61b81f1d9b12 100644
--- a/flang/test/Lower/OpenMP/parallel-wsloop.f90
+++ b/flang/test/Lower/OpenMP/parallel-wsloop.f90
@@ -64,7 +64,7 @@ subroutine parallel_do_with_clauses(nt)
   ! CHECK:      %[[WS_LB:.*]] = arith.constant 1 : i32
   ! CHECK:      %[[WS_UB:.*]] = arith.constant 9 : i32
   ! CHECK:      %[[WS_STEP:.*]] = arith.constant 1 : i32
-  ! CHECK:      omp.wsloop schedule(dynamic) private({{.*}}) {
+  ! CHECK:      omp.wsloop schedule(dynamic, nonmonotonic) private({{.*}}) {
   ! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB]]) to (%[[WS_UB]]) inclusive step (%[[WS_STEP]]) {
   !$OMP PARALLEL DO NUM_THREADS(nt) SCHEDULE(dynamic)
   do i=1, 9
diff --git a/flang/test/Lower/OpenMP/wsloop-chunks.f90 b/flang/test/Lower/OpenMP/wsloop-chunks.f90
index 29c02a3b3c8d5..f3df1e6249693 100644
--- a/flang/test/Lower/OpenMP/wsloop-chunks.f90
+++ b/flang/test/Lower/OpenMP/wsloop-chunks.f90
@@ -20,7 +20,7 @@ program wsloop
 ! CHECK:         %[[VAL_3:.*]] = arith.constant 1 : i32
 ! CHECK:         %[[VAL_4:.*]] = arith.constant 9 : i32
 ! CHECK:         %[[VAL_5:.*]] = arith.constant 1 : i32
-! CHECK:         omp.wsloop nowait schedule(static = %[[VAL_2]] : i32) private({{.*}}) {
+! CHECK:         omp.wsloop nowait schedule(static = %[[VAL_2]] : i32, monotonic) private({{.*}}) {
 ! CHECK-NEXT:      omp.loop_nest (%[[ARG0:.*]]) : i32 = (%[[VAL_3]]) to (%[[VAL_4]]) inclusive step (%[[VAL_5]]) {
 ! CHECK:             hlfir.assign %[[ARG0]] to %[[STORE_IV:.*]]#0 : i32, !fir.ref<i32>
 ! CHECK:             %[[LOAD_IV:.*]] = fir.load %[[STORE_IV]]#0 : !fir.ref<i32>
@@ -40,7 +40,7 @@ program wsloop
 ! CHECK:         %[[VAL_15:.*]] = arith.constant 1 : i32
 ! CHECK:         %[[VAL_16:.*]] = arith.constant 9 : i32
 ! CHECK:         %[[VAL_17:.*]] = arith.constant 1 : i32
-! CHECK:         omp.wsloop nowait schedule(static = %[[VAL_14]] : i32) private({{.*}}) {
+! CHECK:         omp.wsloop nowait schedule(static = %[[VAL_14]] : i32, monotonic) private({{.*}}) {
 ! CHECK-NEXT:      omp.loop_nest (%[[ARG1:.*]]) : i32 = (%[[VAL_15]]) to (%[[VAL_16]]) inclusive step (%[[VAL_17]]) {
 ! CHECK:             hlfir.assign %[[ARG1]] to %[[STORE_IV1:.*]]#0 : i32, !fir.ref<i32>
 ! CHECK:             %[[VAL_24:.*]] = arith.constant 2 : i32
@@ -66,7 +66,7 @@ program wsloop
 ! CHECK:         %[[VAL_30:.*]] = arith.constant 1 : i32
 ! CHECK:         %[[VAL_31:.*]] = arith.constant 9 : i32
 ! CHECK:         %[[VAL_32:.*]] = arith.constant 1 : i32
-! CHECK:         omp.wsloop nowait schedule(static = %[[VAL_29]] : i32) private({{.*}}) {
+! CHECK:         omp.wsloop nowait schedule(static = %[[VAL_29]] : i32, monotonic) private({{.*}}) {
 ! CHECK-NEXT:      omp.loop_nest (%[[ARG2:.*]]) : i32 = (%[[VAL_30]]) to (%[[VAL_31]]) inclusive step (%[[VAL_32]]) {
 ! CHECK:             hlfir.assign %[[ARG2]] to %[[STORE_IV2:.*]]#0 : i32, !fir.ref<i32>
 ! CHECK:             %[[VAL_39:.*]] = arith.constant 3 : i32
diff --git a/flang/test/Lower/OpenMP/wsloop-schedule.f90 b/flang/test/Lower/OpenMP/wsloop-schedule.f90
index 5e672927c41ba..bbab01a912c3e 100644
--- a/flang/test/Lower/OpenMP/wsloop-schedule.f90
+++ b/flang/test/Lower/OpenMP/wsloop-schedule.f90
@@ -14,7 +14,7 @@ program wsloop_dynamic
 !CHECK:      %[[WS_LB:.*]] = arith.constant 1 : i32
 !CHECK:      %[[WS_UB:.*]] = arith.constant 9 : i32
 !CHECK:      %[[WS_STEP:.*]] = arith.constant 1 : i32
-!CHECK:      omp.wsloop nowait schedule(runtime, simd) private({{.*}}) {
+!CHECK:      omp.wsloop nowait schedule(runtime, nonmonotonic, simd) private({{.*}}) {
 !CHECK-NEXT:   omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB]]) to (%[[WS_UB]]) inclusive step (%[[WS_STEP]]) {
 !CHECK:          hlfir.assign %[[I]] to %[[STORE:.*]]#0 : i32, !fir.ref<i32>
 
@@ -28,9 +28,35 @@ program wsloop_dynamic
 !CHECK:          omp.yield
 !CHECK:        }
 !CHECK:      }
-!CHECK:      omp.terminator
-!CHECK:    }
 
 !$OMP END DO NOWAIT
+
+! Check that the schedule modifier is set correctly when the ordered clause is
+! used
+!$OMP DO SCHEDULE(runtime) ORDERED(1)
+!CHECK:      %[[WS_LB2:.*]] = arith.constant 1 : i32
+!CHECK:      %[[WS_UB2:.*]] = arith.constant 9 : i32
+!CHECK:      %[[WS_STEP2:.*]] = arith.constant 1 : i32
+!CHECK:      omp.wsloop nowait ordered(1) schedule(runtime, monotonic) private({{.*}}) {
+!CHECK-NEXT:   omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB2]]) to (%[[WS_UB2]]) inclusive step (%[[WS_STEP2]]) {
+  do i=1, 9
+    print*, i
+  end do
+!$OMP END DO NOWAIT
+
+! Check that the schedule modifier is set correctly with a static schedule
+!$OMP DO SCHEDULE(static)
+!CHECK:      %[[WS_LB3:.*]] = arith.constant 1 : i32
+!CHECK:      %[[WS_UB3:.*]] = arith.constant 9 : i32
+!CHECK:      %[[WS_STEP3:.*]] = arith.constant 1 : i32
+!CHECK:      omp.wsloop nowait schedule(static, monotonic) private({{.*}}) {
+!CHECK-NEXT:   omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB3]]) to (%[[WS_UB3]]) inclusive step (%[[WS_STEP3]]) {
+  do i=1, 9
+    print*, i
+  end do
+!$OMP END DO NOWAIT
+
+!CHECK:      omp.terminator
+!CHECK:    }
 !$OMP END PARALLEL
 end
diff --git a/flang/test/Lower/OpenMP/wsloop.f90 b/flang/test/Lower/OpenMP/wsloop.f90
index b4e02ea3c73f8..75219c9a78e87 100644
--- a/flang/test/Lower/OpenMP/wsloop.f90
+++ b/flang/test/Lower/OpenMP/wsloop.f90
@@ -58,7 +58,7 @@ subroutine loop_with_schedule_nowait
   ! CHECK:      %[[WS_LB:.*]] = arith.constant 1 : i32
   ! CHECK:      %[[WS_UB:.*]] = arith.constant 9 : i32
   ! CHECK:      %[[WS_STEP:.*]] = arith.constant 1 : i32
-  ! CHECK:      omp.wsloop nowait schedule(runtime) private(@{{.*}} %{{.*}}#0 -> %[[ALLOCA_IV:.*]] : !fir.ref<i32>) {
+  ! CHECK:      omp.wsloop nowait schedule(runtime, nonmonotonic) private(@{{.*}} %{{.*}}#0 -> %[[ALLOCA_IV:.*]] : !fir.ref<i32>) {
   ! CHECK-NEXT:   omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB]]) to (%[[WS_UB]]) inclusive step (%[[WS_STEP]]) {
   !$OMP DO SCHEDULE(runtime)
   do i=1, 9

``````````

</details>


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


More information about the flang-commits mailing list