[flang-commits] [flang] [Flang][OpenMP]Support for lowering grainsize and num_tasks clause to… (PR #128490)

Kaviya Rajendiran via flang-commits flang-commits at lists.llvm.org
Mon Feb 24 03:06:23 PST 2025


https://github.com/kaviya2510 created https://github.com/llvm/llvm-project/pull/128490

… MLIR.

Added MLIR lowering to taskloop construct.
Added MLIR lowering for grainsize and num_tasks clauses of taskloop construct.

Depends on https://github.com/llvm/llvm-project/pull/128477

>From 7ff5ba417f57fc7a3a743ee9a5867564d2e24be0 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <kaviyara2000 at gmail.com>
Date: Mon, 24 Feb 2025 16:32:32 +0530
Subject: [PATCH] [Flang][OpenMP]Support for lowering grainsize and num_tasks
 clause to MLIR.

---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp    | 42 +++++++++
 flang/lib/Lower/OpenMP/ClauseProcessor.h      |  4 +
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 39 ++++++++-
 flang/test/Lower/OpenMP/Todo/taskloop.f90     | 13 ---
 flang/test/Lower/OpenMP/masked_taskloop.f90   | 49 +++++++++++
 flang/test/Lower/OpenMP/master_taskloop.f90   | 14 ---
 .../Lower/OpenMP/parallel-master-taskloop.f90 | 45 ++++++++--
 flang/test/Lower/OpenMP/taskloop.f90          | 87 +++++++++++++++++++
 8 files changed, 259 insertions(+), 34 deletions(-)
 delete mode 100644 flang/test/Lower/OpenMP/Todo/taskloop.f90
 create mode 100644 flang/test/Lower/OpenMP/masked_taskloop.f90
 delete mode 100644 flang/test/Lower/OpenMP/master_taskloop.f90
 create mode 100644 flang/test/Lower/OpenMP/taskloop.f90

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index e21d299570b86..9fbc5e0d5ac61 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -912,6 +912,27 @@ bool ClauseProcessor::processDepend(mlir::omp::DependClauseOps &result) const {
   return findRepeatableClause<omp::clause::Depend>(process);
 }
 
+bool ClauseProcessor::processGrainsize(
+    lower::StatementContext &stmtCtx,
+    mlir::omp::GrainsizeClauseOps &result) const {
+  using grainsize = omp::clause::Grainsize;
+  if (auto *clause = findUniqueClause<grainsize>()) {
+    fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+    mlir::MLIRContext *context = firOpBuilder.getContext();
+    const auto &modifier =
+        std::get<std::optional<grainsize::Prescriptiveness>>(clause->t);
+    if (modifier) {
+      result.grainsizeMod = mlir::omp::ClauseGrainsizeTypeAttr::get(
+          context, mlir::omp::ClauseGrainsizeType::Strict);
+    }
+    const auto &grainsizeExpr = std::get<omp::SomeExpr>(clause->t);
+    result.grainsize =
+        fir::getBase(converter.genExprValue(grainsizeExpr, stmtCtx));
+    return true;
+  }
+  return false;
+}
+
 bool ClauseProcessor::processHasDeviceAddr(
     mlir::omp::HasDeviceAddrClauseOps &result,
     llvm::SmallVectorImpl<const semantics::Symbol *> &isDeviceSyms) const {
@@ -1176,6 +1197,27 @@ bool ClauseProcessor::processNontemporal(
       });
 }
 
+bool ClauseProcessor::processNumTasks(
+    lower::StatementContext &stmtCtx,
+    mlir::omp::NumTasksClauseOps &result) const {
+  using numtasks = omp::clause::NumTasks;
+  if (auto *clause = findUniqueClause<numtasks>()) {
+    fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+    mlir::MLIRContext *context = firOpBuilder.getContext();
+    const auto &modifier =
+        std::get<std::optional<numtasks::Prescriptiveness>>(clause->t);
+    if (modifier) {
+      result.numTasksMod = mlir::omp::ClauseNumTasksTypeAttr::get(
+          context, mlir::omp::ClauseNumTasksType::Strict);
+    }
+    const auto &numtasksExpr = std::get<omp::SomeExpr>(clause->t);
+    result.numTasks =
+        fir::getBase(converter.genExprValue(numtasksExpr, stmtCtx));
+    return true;
+  }
+  return false;
+}
+
 bool ClauseProcessor::processReduction(
     mlir::Location currentLocation, mlir::omp::ReductionClauseOps &result,
     llvm::SmallVectorImpl<const semantics::Symbol *> &outReductionSyms) const {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 889a09a8f0cd8..738cc81348dd7 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -105,6 +105,8 @@ class ClauseProcessor {
   bool processDepend(mlir::omp::DependClauseOps &result) const;
   bool
   processEnter(llvm::SmallVectorImpl<DeclareTargetCapturePair> &result) const;
+  bool processGrainsize(lower::StatementContext &stmtCtx,
+                        mlir::omp::GrainsizeClauseOps &result) const;
   bool processIf(omp::clause::If::DirectiveNameModifier directiveName,
                  mlir::omp::IfClauseOps &result) const;
   bool processIsDevicePtr(
@@ -125,6 +127,8 @@ class ClauseProcessor {
   bool processMotionClauses(lower::StatementContext &stmtCtx,
                             mlir::omp::MapClauseOps &result);
   bool processNontemporal(mlir::omp::NontemporalClauseOps &result) const;
+  bool processNumTasks(lower::StatementContext &stmtCtx,
+                       mlir::omp::NumTasksClauseOps &result) const;
   bool processReduction(
       mlir::Location currentLocation, mlir::omp::ReductionClauseOps &result,
       llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSyms) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index e0d23fc53eeca..63acb235fca3b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1740,6 +1740,23 @@ static void genTaskgroupClauses(lower::AbstractConverter &converter,
                                         llvm::omp::Directive::OMPD_taskgroup);
 }
 
+static void genTaskloopClauses(lower::AbstractConverter &converter,
+                               semantics::SemanticsContext &semaCtx,
+                               lower::StatementContext &stmtCtx,
+                               const List<Clause> &clauses, mlir::Location loc,
+                               mlir::omp::TaskloopOperands &clauseOps) {
+  ClauseProcessor cp(converter, semaCtx, clauses);
+  cp.processGrainsize(stmtCtx, clauseOps);
+  cp.processNumTasks(stmtCtx, clauseOps);
+
+  cp.processTODO<clause::Allocate, clause::Collapse, clause::Default,
+                 clause::Final, clause::Firstprivate, clause::If,
+                 clause::InReduction, clause::Lastprivate, clause::Mergeable,
+                 clause::Nogroup, clause::Priority, clause::Private,
+                 clause::Shared, clause::Reduction, clause::Untied>(
+      loc, llvm::omp::Directive::OMPD_taskloop);
+}
+
 static void genTaskwaitClauses(lower::AbstractConverter &converter,
                                semantics::SemanticsContext &semaCtx,
                                const List<Clause> &clauses, mlir::Location loc,
@@ -2639,7 +2656,27 @@ static void genStandaloneTaskloop(lower::AbstractConverter &converter,
                                   mlir::Location loc,
                                   const ConstructQueue &queue,
                                   ConstructQueue::const_iterator item) {
-  TODO(loc, "Taskloop construct");
+  mlir::omp::TaskloopOperands taskloopClauseOps;
+  lower::StatementContext stmtCtx;
+  genTaskloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
+                     taskloopClauseOps);
+
+  DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
+                           /*shouldCollectPreDeterminedSymbols=*/true,
+                           /*useDelayedPrivatization=*/false, symTable);
+  dsp.processStep1();
+  mlir::omp::LoopNestOperands loopNestClauseOps;
+  llvm::SmallVector<const semantics::Symbol *> iv;
+  genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
+                     loopNestClauseOps, iv);
+  EntryBlockArgs taskloopArgs;
+
+  auto taskLoopOp = genWrapperOp<mlir::omp::TaskloopOp>(
+      converter, loc, taskloopClauseOps, taskloopArgs);
+
+  genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item,
+                loopNestClauseOps, iv, {{taskLoopOp, taskloopArgs}},
+                llvm::omp::Directive::OMPD_taskloop, dsp);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/flang/test/Lower/OpenMP/Todo/taskloop.f90 b/flang/test/Lower/OpenMP/Todo/taskloop.f90
deleted file mode 100644
index aca050584cbbe..0000000000000
--- a/flang/test/Lower/OpenMP/Todo/taskloop.f90
+++ /dev/null
@@ -1,13 +0,0 @@
-! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s -fopenmp-version=50 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s -fopenmp-version=50 2>&1 | FileCheck %s
-
-! CHECK: not yet implemented: Taskloop construct
-subroutine omp_taskloop
-  integer :: res, i
-  !$omp taskloop
-  do i = 1, 10
-     res = res + 1
-  end do
-  !$omp end taskloop
-end subroutine omp_taskloop
-
diff --git a/flang/test/Lower/OpenMP/masked_taskloop.f90 b/flang/test/Lower/OpenMP/masked_taskloop.f90
new file mode 100644
index 0000000000000..57e8a02dbcefb
--- /dev/null
+++ b/flang/test/Lower/OpenMP/masked_taskloop.f90
@@ -0,0 +1,49 @@
+! This test checks lowering of OpenMP masked taskloop Directive.
+
+! RUN:  bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN:  %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+! CHECK:  func.func @_QPtest_masked_taskloop() {
+! CHECK:    %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_masked_taskloopEi"}
+! CHECK:    %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_masked_taskloopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    %[[VAL_2:.*]] = fir.address_of(@_QFtest_masked_taskloopEj) : !fir.ref<i32>
+! CHECK:    %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest_masked_taskloopEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    omp.masked {
+! CHECK:      %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "j", pinned, uniq_name = "_QFtest_masked_taskloopEj"}
+! CHECK:      %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFtest_masked_taskloopEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:      %[[VAL_6:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK:      hlfir.assign %[[VAL_6]] to %[[VAL_5]]#0 : i32, !fir.ref<i32>
+! CHECK:      %[[VAL_7:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFtest_masked_taskloopEi"}
+! CHECK:      %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFtest_masked_taskloopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:      %[[C1_I32:.*]] = arith.constant 1 : i32
+! CHECK:      %[[C10_I32:.*]] = arith.constant 10 : i32
+! CHECK:      %[[C1_I32_0:.*]] = arith.constant 1 : i32
+! CHECK:      omp.taskloop {
+! CHECK:        omp.loop_nest (%arg0) : i32 = (%[[C1_I32]]) to (%[[C10_I32]]) inclusive step (%[[C1_I32_0]]) {
+! CHECK:          fir.store %arg0 to %[[VAL_8]]#1 : !fir.ref<i32>
+! CHECK:          %[[VAL_9:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
+! CHECK:          %[[C1_I32_1:.*]] = arith.constant 1 : i32
+! CHECK:          %[[VAL_10:.*]] = arith.addi %[[VAL_9]], %[[C1_I32_1]] : i32
+! CHECK:          hlfir.assign %[[VAL_10]] to %[[VAL_5]]#0 : i32, !fir.ref<i32>
+! CHECK:          omp.yield
+! CHECK:        }
+! CHECK:      }
+! CHECK:      omp.terminator
+! CHECK:    }
+! CHECK:    return
+! CHECK:  }
+! CHECK:  fir.global internal @_QFtest_masked_taskloopEj : i32 {
+! CHECK:    %[[C1_I32:.*]] = arith.constant 1 : i32
+! CHECK:    fir.has_value %[[C1_I32]] : i32
+! CHECK: }
+
+
+subroutine test_masked_taskloop
+  integer :: i, j = 1
+  !OpenMP directive MASKED has been deprecated, so used MASKED TASKLOOP instead.
+  !$omp masked taskloop
+  do i=1,10
+   j = j + 1
+  end do
+  !$omp end masked taskloop 
+end subroutine
diff --git a/flang/test/Lower/OpenMP/master_taskloop.f90 b/flang/test/Lower/OpenMP/master_taskloop.f90
deleted file mode 100644
index 26f664b2662dc..0000000000000
--- a/flang/test/Lower/OpenMP/master_taskloop.f90
+++ /dev/null
@@ -1,14 +0,0 @@
-! This test checks lowering of OpenMP master taskloop Directive.
-
-! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-
-subroutine test_master_taskloop
-  integer :: i, j = 1
-  !CHECK: not yet implemented: Taskloop construct
-  !$omp master taskloop
-  do i=1,10
-   j = j + 1
-  end do
-  !$omp end master taskloop 
-end subroutine
diff --git a/flang/test/Lower/OpenMP/parallel-master-taskloop.f90 b/flang/test/Lower/OpenMP/parallel-master-taskloop.f90
index 17ceb9496c8d3..602772f47a0e1 100644
--- a/flang/test/Lower/OpenMP/parallel-master-taskloop.f90
+++ b/flang/test/Lower/OpenMP/parallel-master-taskloop.f90
@@ -1,14 +1,47 @@
-! This test checks lowering of OpenMP parallel master taskloop Directive.
+! This test checks lowering of OpenMP parallel masked taskloop Directive.
 
-! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: func.func @_QPtest_parallel_master_taskloop() {
+! CHECK:    %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_parallel_master_taskloopEi"}
+! CHECK:    %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_parallel_master_taskloopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    %[[VAL_2:.*]] = fir.address_of(@_QFtest_parallel_master_taskloopEj) : !fir.ref<i32>
+! CHECK:    %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest_parallel_master_taskloopEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    omp.parallel {
+! CHECK:      omp.masked {
+! CHECK:        %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFtest_parallel_master_taskloopEi"}
+! CHECK:        %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFtest_parallel_master_taskloopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:        %[[C1_I32:.*]] = arith.constant 1 : i32
+! CHECK:        %[[C10_I32:.*]] = arith.constant 10 : i32
+! CHECK:        %[[C1_I32_0:.*]] = arith.constant 1 : i32
+! CHECK:        omp.taskloop {
+! CHECK:          omp.loop_nest (%arg0) : i32 = (%[[C1_I32]]) to (%[[C10_I32]]) inclusive step (%[[C1_I32_0]]) {
+! CHECK:            fir.store %arg0 to %[[VAL_5]]#1 : !fir.ref<i32>
+! CHECK:            %[[VAL_6:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK:            %[[C1_I32_1:.*]] = arith.constant 1 : i32
+! CHECK:            %[[VAL_7:.*]] = arith.addi %[[VAL_6]], %[[C1_I32_1]] : i32
+! CHECK:            hlfir.assign %[[VAL_7]] to %[[VAL_3]]#0 : i32, !fir.ref<i32>
+! CHECK:            omp.yield
+! CHECK:          }
+! CHECK:        }
+! CHECK:        omp.terminator
+! CHECK:      }
+! CHECK:      omp.terminator
+! CHECK:    }
+! CHECK:    return
+! CHECK:  }
+! CHECK:  fir.global internal @_QFtest_parallel_master_taskloopEj : i32 {
+! CHECK:    %[[C1_I32:.*]] = arith.constant 1 : i32
+! CHECK:    fir.has_value %[[C1_I32]] : i32
+! CHECK:  }
 
 subroutine test_parallel_master_taskloop
   integer :: i, j = 1
-  !CHECK: not yet implemented: Taskloop construct
-  !$omp parallel master taskloop
+  ! OpenMP directive PARALLEL MASTER TASKLOOP has been deprecated, so used PARALLEL MASKED TASKLOOP instead.
+  !$omp parallel masked taskloop
   do i=1,10
    j = j + 1
   end do
-  !$omp end parallel master taskloop 
+  !$omp end parallel masked taskloop 
 end subroutine
diff --git a/flang/test/Lower/OpenMP/taskloop.f90 b/flang/test/Lower/OpenMP/taskloop.f90
new file mode 100644
index 0000000000000..9e0f76de3a642
--- /dev/null
+++ b/flang/test/Lower/OpenMP/taskloop.f90
@@ -0,0 +1,87 @@
+! This test checks lowering of `Taskloop` directive and taskloop clauses "grainsize" and "numtasks".
+
+! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
+
+! CHECK:  func.func @_QPomp_taskloop() {
+! CHECK:    %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloopEi"}
+! CHECK:    %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFomp_taskloopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "res", uniq_name = "_QFomp_taskloopEres"}
+! CHECK:    %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFomp_taskloopEres"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "res", pinned, uniq_name = "_QFomp_taskloopEres"}
+! CHECK:    %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFomp_taskloopEres"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    %[[VAL_6:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK:    hlfir.assign %[[VAL_6]] to %[[VAL_5]]#0 : i32, !fir.ref<i32>
+! CHECK:    %[[VAL_7:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFomp_taskloopEi"}
+! CHECK:    %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFomp_taskloopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:    %[[C1_I32:.*]] = arith.constant 1 : i32
+! CHECK:    %[[C10_I32:.*]] = arith.constant 10 : i32
+! CHECK:    %[[C1_I32_0:.*]] = arith.constant 1 : i32
+! CHECK:    omp.taskloop {
+! CHECK:      omp.loop_nest (%arg0) : i32 = (%[[C1_I32]]) to (%[[C10_I32]]) inclusive step (%[[C1_I32_0]]) {
+! CHECK:        fir.store %arg0 to %[[VAL_8]]#1 : !fir.ref<i32>
+! CHECK:        %[[VAL_9:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
+! CHECK:        %[[C1_I32_1:.*]] = arith.constant 1 : i32
+! CHECK:        %[[VAL_10:.*]] = arith.addi %[[VAL_9]], %[[C1_I32_1]] : i32
+! CHECK:        hlfir.assign %[[VAL_10]] to %[[VAL_5]]#0 : i32, !fir.ref<i32>
+! CHECK:        omp.yield
+! CHECK:      }
+! CHECK:    }
+! CHECK:    return
+! CHECK:  }
+subroutine omp_taskloop
+  integer :: res, i
+  !$omp taskloop
+  do i = 1, 10
+     res = res + 1
+  end do
+  !$omp end taskloop
+end subroutine omp_taskloop
+
+!CHECK-LABEL: func.func @_QPtest_grainsize()
+subroutine test_grainsize
+  integer :: res, i
+  !CHECK: omp.taskloop grainsize(%{{.*}}: i32) {
+  !$omp taskloop grainsize(10)
+  do i = 1, 100
+     !CHECK: arith.addi
+     res = res + 1
+  end do
+  !$omp end taskloop
+end subroutine test_grainsize
+
+!CHECK-LABEL: func.func @_QPtest_grainsize_strict()
+subroutine test_grainsize_strict
+  integer :: res, i
+  !CHECK: omp.taskloop grainsize(strict: %{{.*}}: i32) {
+  !$omp taskloop grainsize(strict:10)
+  do i = 1, 100
+     !CHECK: arith.addi
+     res = res + 1
+  end do
+  !$omp end taskloop
+end subroutine
+
+!CHECK-LABEL: func.func @_QPtest_num_tasks()
+subroutine test_num_tasks
+  integer :: res, i
+  !CHECK: omp.taskloop num_tasks(strict: %{{.*}}: i32) {
+  !$omp taskloop num_tasks(strict:10)
+  do i = 1, 100
+     !CHECK: arith.addi
+     res = res + 1
+  end do
+  !$omp end taskloop
+end subroutine
+
+!CHECK-LABEL: func.func @_QPtest_num_tasks_strict()
+subroutine test_num_tasks_strict
+  integer :: res, i
+  !CHECK: omp.taskloop num_tasks(strict: %{{.*}}: i32) {
+  !$omp taskloop num_tasks(strict:10)
+  do i = 1, 100
+     !CHECK: arith.addi
+     res = res + 1
+  end do
+  !$omp end taskloop
+end subroutine
\ No newline at end of file



More information about the flang-commits mailing list