[flang-commits] [flang] [Flang][OpenMP] Port openmp task tests to HLFIR flow (PR #70781)

via flang-commits flang-commits at lists.llvm.org
Tue Oct 31 03:40:37 PDT 2023


https://github.com/harishch4 created https://github.com/llvm/llvm-project/pull/70781

None

>From d566ff5e87d0dc0cfe6d1a11a10bded68decab53 Mon Sep 17 00:00:00 2001
From: Harish Chambeti <hchambet at amd.com>
Date: Mon, 16 Oct 2023 11:15:00 +0530
Subject: [PATCH 1/2] [Flang] Move openmp task construct test to HLFIR

---
 flang/test/Lower/OpenMP/task.f90 | 264 +++++++++++++++++++++++++++++++
 1 file changed, 264 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/task.f90

diff --git a/flang/test/Lower/OpenMP/task.f90 b/flang/test/Lower/OpenMP/task.f90
new file mode 100644
index 000000000000000..1b0b8cca55a4f8e
--- /dev/null
+++ b/flang/test/Lower/OpenMP/task.f90
@@ -0,0 +1,264 @@
+!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
+
+!CHECK-LABEL: func @_QPomp_task_simple() {
+subroutine omp_task_simple
+    !CHECK: omp.task {
+    !$omp task
+    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+    call foo()
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine omp_task_simple
+  
+  !===============================================================================
+  ! `if` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPomp_task_if(%{{.+}}) {
+  subroutine omp_task_if(bar)
+    logical, intent(inout) :: bar
+    !CHECK: omp.task if(%{{.+}}) {
+    !$omp task if(bar)
+    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+    call foo()
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine omp_task_if
+  
+  !===============================================================================
+  ! `final` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPomp_task_final(%{{.+}}) {
+  subroutine omp_task_final(bar)
+    logical, intent(inout) :: bar
+    !CHECK: omp.task final(%{{.+}}) {
+    !$omp task final(bar)
+    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+    call foo()
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine omp_task_final
+  
+  !===============================================================================
+  ! `untied` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPomp_task_untied() {
+  subroutine omp_task_untied()
+    !CHECK: omp.task untied {
+    !$omp task untied
+    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+    call foo()
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine omp_task_untied
+  
+  !===============================================================================
+  ! `mergeable` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPomp_task_mergeable() {
+  subroutine omp_task_mergeable()
+    !CHECK: omp.task mergeable {
+    !$omp task mergeable
+    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+    call foo()
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine omp_task_mergeable
+  
+  !===============================================================================
+  ! `priority` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPomp_task_priority(%{{.+}}) {
+  subroutine omp_task_priority(bar)
+    integer, intent(inout) :: bar
+    !CHECK: omp.task priority(%{{.+}}) {
+    !$omp task priority(bar)
+    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+    call foo()
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine omp_task_priority
+  
+  !===============================================================================
+  ! `allocate` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPtask_allocate
+  subroutine task_allocate()
+    use omp_lib
+    integer :: x
+    !CHECK: omp.task allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) {
+    !$omp task allocate(omp_high_bw_mem_alloc: x) private(x)
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_allocate
+  
+  !===============================================================================
+  ! `depend` clause
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPtask_depend
+  subroutine task_depend()
+    integer :: x
+    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>) {
+    !$omp task depend(in : x)
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_depend
+  
+  !CHECK-LABEL: func @_QPtask_depend_non_int
+  subroutine task_depend_non_int()
+    character(len = 15) :: x
+    integer, allocatable :: y
+    complex :: z
+    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<!fir.char<1,15>>, taskdependin -> %{{.+}} : !fir.ref<!fir.box<!fir.heap<i32>>>, taskdependin ->  %{{.+}} : !fir.ref<!fir.complex<4>>) {
+    !$omp task depend(in : x, y, z)
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_depend_non_int
+  
+  !CHECK-LABEL: func @_QPtask_depend_all_kinds_one_task
+  subroutine task_depend_all_kinds_one_task()
+    integer :: x
+    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>, taskdependout -> %{{.+}} : !fir.ref<i32>, taskdependinout -> %{{.+}} : !fir.ref<i32>) {
+    !$omp task depend(in : x) depend(out : x) depend(inout : x)
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_depend_all_kinds_one_task
+  
+  !CHECK-LABEL: func @_QPtask_depend_multi_var
+  subroutine task_depend_multi_var()
+    integer :: x
+    integer :: y
+    !CHECK: omp.task depend(taskdependin -> %{{.*}} : !fir.ref<i32>, taskdependin -> %{{.+}} : !fir.ref<i32>) {
+    !$omp task depend(in :x,y)
+    !CHECK: arith.addi
+    x = x + 12
+    y = y + 12
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_depend_multi_var
+  
+  !CHECK-LABEL: func @_QPtask_depend_multi_task
+  subroutine task_depend_multi_task()
+    integer :: x
+    !CHECK: omp.task depend(taskdependout -> %{{.+}} : !fir.ref<i32>)
+    !$omp task depend(out : x)
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: omp.terminator
+    !$omp end task
+    !CHECK: omp.task depend(taskdependinout -> %{{.+}} : !fir.ref<i32>)
+    !$omp task depend(inout : x)
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: omp.terminator
+    !$omp end task
+    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>)
+    !$omp task depend(in : x)
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_depend_multi_task
+  
+  !===============================================================================
+  ! `private` clause
+  !===============================================================================
+  !CHECK-LABEL: func @_QPtask_private
+  subroutine task_private
+    type mytype
+    integer :: x
+    end type mytype
+  
+    !CHECK: %[[int_var:.+]] = fir.alloca i32
+    !CHECK: %[[mytype_var:.+]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}>
+    integer :: int_var
+    type(mytype) :: mytype_var
+  
+    !CHECK: fir.call @_QPbar(%[[int_var]], %[[mytype_var]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> ()
+    call bar(int_var, mytype_var)
+  
+    !CHECK: omp.task {
+    !$omp task private(int_var, mytype_var)
+    !CHECK: %[[int_var_private:.+]] = fir.alloca i32
+    !CHECK: %[[mytype_var_private:.+]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}>
+  
+    !CHECK: fir.call @_QPbar(%[[int_var_private]], %[[mytype_var_private]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> ()
+    call bar(int_var, mytype_var)
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_private
+  
+  !===============================================================================
+  ! `firstprivate` clause
+  !===============================================================================
+  !CHECK-LABEL: func @_QPtask_firstprivate
+  subroutine task_firstprivate
+    type mytype
+    integer :: x
+    end type mytype
+  
+    !CHECK: %[[int_var:.+]] = fir.alloca i32
+    !CHECK: %[[mytype_var:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}>
+    integer :: int_var
+    type(mytype) :: mytype_var
+  
+    !CHECK: fir.call @_QPbaz(%[[int_var]], %[[mytype_var]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> ()
+    call baz(int_var, mytype_var)
+  
+    !CHECK: omp.task {
+    !$omp task firstprivate(int_var, mytype_var)
+    !CHECK: %[[int_var_firstprivate:.+]] = fir.alloca i32
+    !CHECK: %[[int_var_load:.+]] = fir.load %[[int_var]] : !fir.ref<i32>
+    !CHECK: fir.store %[[int_var_load]] to %[[int_var_firstprivate]] : !fir.ref<i32>
+    !CHECK: %[[mytype_var_firstprivate:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}>
+    !CHECK: %[[mytype_var_load:.+]] = fir.load %[[mytype_var]] : !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>
+    !CHECK: fir.store %[[mytype_var_load]] to %[[mytype_var_firstprivate]]
+    !CHECK: fir.call @_QPbaz(%[[int_var_firstprivate]], %[[mytype_var_firstprivate]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> ()
+    call baz(int_var, mytype_var)
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_firstprivate
+  
+  !===============================================================================
+  ! Multiple clauses
+  !===============================================================================
+  
+  !CHECK-LABEL: func @_QPtask_multiple_clauses
+  subroutine task_multiple_clauses()
+    use omp_lib
+  
+    !CHECK: %[[x:.+]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtask_multiple_clausesEx"}
+    !CHECK: %[[y:.+]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFtask_multiple_clausesEy"}
+    !CHECK: %[[z:.+]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFtask_multiple_clausesEz"}
+    integer :: x, y, z
+    logical :: buzz
+  
+    !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) untied mergeable priority(%{{.+}}) allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) {
+    !$omp task if(buzz) final(buzz) untied mergeable priority(z) allocate(omp_high_bw_mem_alloc: x) private(x) firstprivate(y)
+  
+    !CHECK: %[[x_priv:.+]] = fir.alloca i32
+    !CHECK: %[[y_priv:.+]] = fir.alloca i32
+    !CHECK: %[[y_load:.+]] = fir.load %[[y]] : !fir.ref<i32>
+    !CHECK: fir.store %[[y_load]] to %[[y_priv]] : !fir.ref<i32>
+  
+    !CHECK: arith.addi
+    x = x + 12
+    !CHECK: arith.subi
+    y = y - 12
+  
+    !CHECK: omp.terminator
+    !$omp end task
+  end subroutine task_multiple_clauses
+  
\ No newline at end of file

>From 59bb1bf234113029fbc57584c7bd99ffe8302d93 Mon Sep 17 00:00:00 2001
From: Harish Chambeti <hchambet at amd.com>
Date: Mon, 16 Oct 2023 11:16:19 +0530
Subject: [PATCH 2/2] Changes to HLFIR Lowering

---
 flang/test/Lower/OpenMP/task.f90 | 531 ++++++++++++++++---------------
 1 file changed, 270 insertions(+), 261 deletions(-)

diff --git a/flang/test/Lower/OpenMP/task.f90 b/flang/test/Lower/OpenMP/task.f90
index 1b0b8cca55a4f8e..99b1740ca75a81c 100644
--- a/flang/test/Lower/OpenMP/task.f90
+++ b/flang/test/Lower/OpenMP/task.f90
@@ -1,264 +1,273 @@
-!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
 
 !CHECK-LABEL: func @_QPomp_task_simple() {
 subroutine omp_task_simple
-    !CHECK: omp.task {
-    !$omp task
-    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
-    call foo()
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine omp_task_simple
-  
-  !===============================================================================
-  ! `if` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPomp_task_if(%{{.+}}) {
-  subroutine omp_task_if(bar)
-    logical, intent(inout) :: bar
-    !CHECK: omp.task if(%{{.+}}) {
-    !$omp task if(bar)
-    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
-    call foo()
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine omp_task_if
-  
-  !===============================================================================
-  ! `final` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPomp_task_final(%{{.+}}) {
-  subroutine omp_task_final(bar)
-    logical, intent(inout) :: bar
-    !CHECK: omp.task final(%{{.+}}) {
-    !$omp task final(bar)
-    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
-    call foo()
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine omp_task_final
-  
-  !===============================================================================
-  ! `untied` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPomp_task_untied() {
-  subroutine omp_task_untied()
-    !CHECK: omp.task untied {
-    !$omp task untied
-    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
-    call foo()
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine omp_task_untied
-  
-  !===============================================================================
-  ! `mergeable` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPomp_task_mergeable() {
-  subroutine omp_task_mergeable()
-    !CHECK: omp.task mergeable {
-    !$omp task mergeable
-    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
-    call foo()
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine omp_task_mergeable
-  
-  !===============================================================================
-  ! `priority` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPomp_task_priority(%{{.+}}) {
-  subroutine omp_task_priority(bar)
-    integer, intent(inout) :: bar
-    !CHECK: omp.task priority(%{{.+}}) {
-    !$omp task priority(bar)
-    !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
-    call foo()
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine omp_task_priority
-  
-  !===============================================================================
-  ! `allocate` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPtask_allocate
-  subroutine task_allocate()
-    use omp_lib
-    integer :: x
-    !CHECK: omp.task allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) {
-    !$omp task allocate(omp_high_bw_mem_alloc: x) private(x)
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_allocate
-  
-  !===============================================================================
-  ! `depend` clause
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPtask_depend
-  subroutine task_depend()
-    integer :: x
-    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>) {
-    !$omp task depend(in : x)
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_depend
-  
-  !CHECK-LABEL: func @_QPtask_depend_non_int
-  subroutine task_depend_non_int()
-    character(len = 15) :: x
-    integer, allocatable :: y
-    complex :: z
-    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<!fir.char<1,15>>, taskdependin -> %{{.+}} : !fir.ref<!fir.box<!fir.heap<i32>>>, taskdependin ->  %{{.+}} : !fir.ref<!fir.complex<4>>) {
-    !$omp task depend(in : x, y, z)
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_depend_non_int
-  
-  !CHECK-LABEL: func @_QPtask_depend_all_kinds_one_task
-  subroutine task_depend_all_kinds_one_task()
-    integer :: x
-    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>, taskdependout -> %{{.+}} : !fir.ref<i32>, taskdependinout -> %{{.+}} : !fir.ref<i32>) {
-    !$omp task depend(in : x) depend(out : x) depend(inout : x)
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_depend_all_kinds_one_task
-  
-  !CHECK-LABEL: func @_QPtask_depend_multi_var
-  subroutine task_depend_multi_var()
-    integer :: x
-    integer :: y
-    !CHECK: omp.task depend(taskdependin -> %{{.*}} : !fir.ref<i32>, taskdependin -> %{{.+}} : !fir.ref<i32>) {
-    !$omp task depend(in :x,y)
-    !CHECK: arith.addi
-    x = x + 12
-    y = y + 12
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_depend_multi_var
-  
-  !CHECK-LABEL: func @_QPtask_depend_multi_task
-  subroutine task_depend_multi_task()
-    integer :: x
-    !CHECK: omp.task depend(taskdependout -> %{{.+}} : !fir.ref<i32>)
-    !$omp task depend(out : x)
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: omp.terminator
-    !$omp end task
-    !CHECK: omp.task depend(taskdependinout -> %{{.+}} : !fir.ref<i32>)
-    !$omp task depend(inout : x)
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: omp.terminator
-    !$omp end task
-    !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>)
-    !$omp task depend(in : x)
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_depend_multi_task
-  
-  !===============================================================================
-  ! `private` clause
-  !===============================================================================
-  !CHECK-LABEL: func @_QPtask_private
-  subroutine task_private
-    type mytype
-    integer :: x
-    end type mytype
-  
-    !CHECK: %[[int_var:.+]] = fir.alloca i32
-    !CHECK: %[[mytype_var:.+]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}>
-    integer :: int_var
-    type(mytype) :: mytype_var
-  
-    !CHECK: fir.call @_QPbar(%[[int_var]], %[[mytype_var]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> ()
-    call bar(int_var, mytype_var)
-  
-    !CHECK: omp.task {
-    !$omp task private(int_var, mytype_var)
-    !CHECK: %[[int_var_private:.+]] = fir.alloca i32
-    !CHECK: %[[mytype_var_private:.+]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}>
-  
-    !CHECK: fir.call @_QPbar(%[[int_var_private]], %[[mytype_var_private]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> ()
-    call bar(int_var, mytype_var)
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_private
-  
-  !===============================================================================
-  ! `firstprivate` clause
-  !===============================================================================
-  !CHECK-LABEL: func @_QPtask_firstprivate
-  subroutine task_firstprivate
-    type mytype
-    integer :: x
-    end type mytype
-  
-    !CHECK: %[[int_var:.+]] = fir.alloca i32
-    !CHECK: %[[mytype_var:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}>
-    integer :: int_var
-    type(mytype) :: mytype_var
-  
-    !CHECK: fir.call @_QPbaz(%[[int_var]], %[[mytype_var]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> ()
-    call baz(int_var, mytype_var)
-  
-    !CHECK: omp.task {
-    !$omp task firstprivate(int_var, mytype_var)
-    !CHECK: %[[int_var_firstprivate:.+]] = fir.alloca i32
-    !CHECK: %[[int_var_load:.+]] = fir.load %[[int_var]] : !fir.ref<i32>
-    !CHECK: fir.store %[[int_var_load]] to %[[int_var_firstprivate]] : !fir.ref<i32>
-    !CHECK: %[[mytype_var_firstprivate:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}>
-    !CHECK: %[[mytype_var_load:.+]] = fir.load %[[mytype_var]] : !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>
-    !CHECK: fir.store %[[mytype_var_load]] to %[[mytype_var_firstprivate]]
-    !CHECK: fir.call @_QPbaz(%[[int_var_firstprivate]], %[[mytype_var_firstprivate]]) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> ()
-    call baz(int_var, mytype_var)
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_firstprivate
-  
-  !===============================================================================
-  ! Multiple clauses
-  !===============================================================================
-  
-  !CHECK-LABEL: func @_QPtask_multiple_clauses
-  subroutine task_multiple_clauses()
-    use omp_lib
-  
-    !CHECK: %[[x:.+]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtask_multiple_clausesEx"}
-    !CHECK: %[[y:.+]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFtask_multiple_clausesEy"}
-    !CHECK: %[[z:.+]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFtask_multiple_clausesEz"}
-    integer :: x, y, z
-    logical :: buzz
-  
-    !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) untied mergeable priority(%{{.+}}) allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) {
-    !$omp task if(buzz) final(buzz) untied mergeable priority(z) allocate(omp_high_bw_mem_alloc: x) private(x) firstprivate(y)
-  
-    !CHECK: %[[x_priv:.+]] = fir.alloca i32
-    !CHECK: %[[y_priv:.+]] = fir.alloca i32
-    !CHECK: %[[y_load:.+]] = fir.load %[[y]] : !fir.ref<i32>
-    !CHECK: fir.store %[[y_load]] to %[[y_priv]] : !fir.ref<i32>
-  
-    !CHECK: arith.addi
-    x = x + 12
-    !CHECK: arith.subi
-    y = y - 12
-  
-    !CHECK: omp.terminator
-    !$omp end task
-  end subroutine task_multiple_clauses
-  
\ No newline at end of file
+  !CHECK: omp.task {
+  !$omp task
+  !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+  call foo()
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine omp_task_simple
+
+!===============================================================================
+! `if` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPomp_task_if(%{{.+}}) {
+subroutine omp_task_if(bar)
+  logical, intent(inout) :: bar
+  !CHECK: omp.task if(%{{.+}}) {
+  !$omp task if(bar)
+  !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+  call foo()
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine omp_task_if
+
+!===============================================================================
+! `final` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPomp_task_final(%{{.+}}) {
+subroutine omp_task_final(bar)
+  logical, intent(inout) :: bar
+  !CHECK: omp.task final(%{{.+}}) {
+  !$omp task final(bar)
+  !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+  call foo()
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine omp_task_final
+
+!===============================================================================
+! `untied` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPomp_task_untied() {
+subroutine omp_task_untied()
+  !CHECK: omp.task untied {
+  !$omp task untied
+  !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+  call foo()
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine omp_task_untied
+
+!===============================================================================
+! `mergeable` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPomp_task_mergeable() {
+subroutine omp_task_mergeable()
+  !CHECK: omp.task mergeable {
+  !$omp task mergeable
+  !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+  call foo()
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine omp_task_mergeable
+
+!===============================================================================
+! `priority` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPomp_task_priority(%{{.+}}) {
+subroutine omp_task_priority(bar)
+  integer, intent(inout) :: bar
+  !CHECK: omp.task priority(%{{.+}}) {
+  !$omp task priority(bar)
+  !CHECK: fir.call @_QPfoo() {{.*}}: () -> ()
+  call foo()
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine omp_task_priority
+
+!===============================================================================
+! `allocate` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPtask_allocate
+subroutine task_allocate()
+  use omp_lib
+  integer :: x
+  !CHECK: omp.task allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) {
+  !$omp task allocate(omp_high_bw_mem_alloc: x) private(x)
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_allocate
+
+!===============================================================================
+! `depend` clause
+!===============================================================================
+
+!CHECK-LABEL: func @_QPtask_depend
+subroutine task_depend()
+  integer :: x
+  !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>) {
+  !$omp task depend(in : x)
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_depend
+
+!CHECK-LABEL: func @_QPtask_depend_non_int
+subroutine task_depend_non_int()
+  character(len = 15) :: x
+  integer, allocatable :: y
+  complex :: z
+  !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<!fir.char<1,15>>, taskdependin -> %{{.+}} : !fir.ref<!fir.box<!fir.heap<i32>>>, taskdependin ->  %{{.+}} : !fir.ref<!fir.complex<4>>) {
+  !$omp task depend(in : x, y, z)
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_depend_non_int
+
+!CHECK-LABEL: func @_QPtask_depend_all_kinds_one_task
+subroutine task_depend_all_kinds_one_task()
+  integer :: x
+  !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>, taskdependout -> %{{.+}} : !fir.ref<i32>, taskdependinout -> %{{.+}} : !fir.ref<i32>) {
+  !$omp task depend(in : x) depend(out : x) depend(inout : x)
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_depend_all_kinds_one_task
+
+!CHECK-LABEL: func @_QPtask_depend_multi_var
+subroutine task_depend_multi_var()
+  integer :: x
+  integer :: y
+  !CHECK: omp.task depend(taskdependin -> %{{.*}} : !fir.ref<i32>, taskdependin -> %{{.+}} : !fir.ref<i32>) {
+  !$omp task depend(in :x,y)
+  !CHECK: arith.addi
+  x = x + 12
+  y = y + 12
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_depend_multi_var
+
+!CHECK-LABEL: func @_QPtask_depend_multi_task
+subroutine task_depend_multi_task()
+  integer :: x
+  !CHECK: omp.task depend(taskdependout -> %{{.+}} : !fir.ref<i32>)
+  !$omp task depend(out : x)
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: omp.terminator
+  !$omp end task
+  !CHECK: omp.task depend(taskdependinout -> %{{.+}} : !fir.ref<i32>)
+  !$omp task depend(inout : x)
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: omp.terminator
+  !$omp end task
+  !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>)
+  !$omp task depend(in : x)
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_depend_multi_task
+
+!===============================================================================
+! `private` clause
+!===============================================================================
+!CHECK-LABEL: func @_QPtask_private
+subroutine task_private
+  type mytype
+  integer :: x
+  end type mytype
+
+!CHECK: %[[INT_ALLOCA:.*]] = fir.alloca i32 {bindc_name = "int_var", uniq_name = "_QFtask_privateEint_var"}
+!CHECK: %[[INT_VAR:.+]]:2 = hlfir.declare %[[INT_ALLOCA]] {uniq_name = "_QFtask_privateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[MYTYPE_ALLOCA:.*]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}> {bindc_name = "mytype_var", uniq_name = "_QFtask_privateEmytype_var"}
+!CHECK: %[[MYTYPE_VAR:.+]]:2 = hlfir.declare %[[MYTYPE_ALLOCA]] {uniq_name = "_QFtask_privateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>)
+  integer :: int_var
+  type(mytype) :: mytype_var
+
+  !CHECK: fir.call @_QPbar(%[[INT_VAR]]#1, %[[MYTYPE_VAR]]#1) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> ()
+  call bar(int_var, mytype_var)
+
+  !CHECK: omp.task {
+  !$omp task private(int_var, mytype_var)
+!CHECK: %[[INT_PRIVATE_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "int_var", pinned, uniq_name = "_QFtask_privateEint_var"}
+!CHECK: %[[INT_VAR_PRIVATE:.+]]:2 = hlfir.declare %[[INT_PRIVATE_ALLOCA]] {uniq_name = "_QFtask_privateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[MYTYPE_PRIVATE_ALLOCA:.+]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}> {bindc_name = "mytype_var", pinned, uniq_name = "_QFtask_privateEmytype_var"}
+!CHECK: %[[MYTYPE_VAR_PRIVATE:.+]]:2 = hlfir.declare %[[MYTYPE_PRIVATE_ALLOCA]] {uniq_name = "_QFtask_privateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>)
+!CHECK: fir.call @_QPbar(%[[INT_VAR_PRIVATE]]#1, %[[MYTYPE_VAR_PRIVATE]]#1) fastmath<contract> : (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> ()
+  call bar(int_var, mytype_var)
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_private
+
+!===============================================================================
+! `firstprivate` clause
+!===============================================================================
+!CHECK-LABEL: func @_QPtask_firstprivate
+subroutine task_firstprivate
+  type mytype
+  integer :: x
+  end type mytype
+ 
+  !CHECK: %[[INT_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "int_var", uniq_name = "_QFtask_firstprivateEint_var"}
+  !CHECK: %[[INT_VAR:.+]]:2 = hlfir.declare %[[INT_ALLOCA]] {uniq_name = "_QFtask_firstprivateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  !CHECK: %[[MYTYPE_ALLOCA:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}> {bindc_name = "mytype_var", uniq_name = "_QFtask_firstprivateEmytype_var"}
+  !CHECK: %[[MYTYPE_VAR:.+]]:2 = hlfir.declare %[[MYTYPE_ALLOCA]] {uniq_name = "_QFtask_firstprivateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>)
+  integer :: int_var
+  type(mytype) :: mytype_var
+
+!CHECK: fir.call @_QPbaz(%[[INT_VAR]]#1, %[[MYTYPE_VAR]]#1) fastmath<contract> : (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> ()
+  call baz(int_var, mytype_var)
+
+  !CHECK: omp.task {
+  !$omp task firstprivate(int_var, mytype_var)
+!CHECK: %[[INT_FIRSTPRIVATE_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "int_var", pinned, uniq_name = "_QFtask_firstprivateEint_var"}
+!CHECK: %[[INT_VAR_FIRSTPRIVATE:.+]]:2 = hlfir.declare %[[INT_FIRSTPRIVATE_ALLOCA]] {uniq_name = "_QFtask_firstprivateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[INT_VAR_LOAD:.+]] = fir.load %[[INT_VAR]]#0 : !fir.ref<i32>
+!CHECK: hlfir.assign %[[INT_VAR_LOAD]] to %[[INT_VAR_FIRSTPRIVATE]]#0 temporary_lhs : i32, !fir.ref<i32>
+!CHECK: %[[MYTYPE_FIRSTPRIVATE_ALLOCA:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}> {bindc_name = "mytype_var", pinned, uniq_name = "_QFtask_firstprivateEmytype_var"}
+!CHECK: %[[MYTYPE_VAR_FIRSTPRIVATE:.+]]:2 = hlfir.declare %[[MYTYPE_FIRSTPRIVATE_ALLOCA]] {uniq_name = "_QFtask_firstprivateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>)
+!CHECK: hlfir.assign %[[MYTYPE_VAR]]#0 to %[[MYTYPE_VAR_FIRSTPRIVATE]]#0 temporary_lhs : !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>
+  call baz(int_var, mytype_var)
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_firstprivate
+
+!===============================================================================
+! Multiple clauses
+!===============================================================================
+
+!CHECK-LABEL: func @_QPtask_multiple_clauses
+subroutine task_multiple_clauses()
+  use omp_lib
+
+!CHECK: %[[X_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtask_multiple_clausesEx"}
+!CHECK: %[[X:.+]]:2 = hlfir.declare %[[X_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[Y_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFtask_multiple_clausesEy"}
+!CHECK: %[[Y:.+]]:2 = hlfir.declare %[[Y_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[Z_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFtask_multiple_clausesEz"}
+!CHECK: %[[Z:.+]]:2 = hlfir.declare %[[Z_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEz"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  integer :: x, y, z
+  logical :: buzz
+
+  !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) untied mergeable priority(%{{.+}}) allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) {
+  !$omp task if(buzz) final(buzz) untied mergeable priority(z) allocate(omp_high_bw_mem_alloc: x) private(x) firstprivate(y)
+
+!CHECK: %[[X_PRIV_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFtask_multiple_clausesEx"}
+!CHECK: %[[X_PRIV:.+]]:2 = hlfir.declare %[[X_PRIV_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[Y_PRIV_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "y", pinned, uniq_name = "_QFtask_multiple_clausesEy"}
+!CHECK: %[[Y_PRIV:.+]]:2 = hlfir.declare %[[Y_PRIV_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[Y_LOAD:.+]] = fir.load %[[Y]]#0 : !fir.ref<i32>
+!CHECK: hlfir.assign %[[Y_LOAD]] to %[[Y_PRIV]]#0 temporary_lhs : i32, !fir.ref<i32>
+
+  !CHECK: arith.addi
+  x = x + 12
+  !CHECK: arith.subi
+  y = y - 12
+
+  !CHECK: omp.terminator
+  !$omp end task
+end subroutine task_multiple_clauses



More information about the flang-commits mailing list