[flang] Flush and master constructs
authorShraiysh Vaishay <Shraiysh.Vaishay@amd.com>
Wed, 23 Mar 2022 04:33:11 +0000 (10:03 +0530)
committerShraiysh Vaishay <Shraiysh.Vaishay@amd.com>
Wed, 23 Mar 2022 04:34:46 +0000 (10:04 +0530)
This patch adds tests for flush and master constructs

This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D122250

Co-authored By: Sourabh Singh Tomar <SourabhSingh.Tomar@amd.com>

flang/lib/Lower/OpenMP.cpp
flang/test/Lower/OpenMP/flush.f90 [new file with mode: 0644]
flang/test/Lower/OpenMP/master.f90 [new file with mode: 0644]

index 7c8072d..4ca8cc7 100644 (file)
@@ -112,9 +112,10 @@ genOMP(Fortran::lower::AbstractConverter &converter,
                     std::get<std::optional<Fortran::parser::OmpObjectList>>(
                         flushConstruct.t))
               genObjectList(*ompObjectList, converter, operandRange);
-            if (std::get<std::optional<
-                    std::list<Fortran::parser::OmpMemoryOrderClause>>>(
-                    flushConstruct.t))
+            const auto &memOrderClause = std::get<std::optional<
+                std::list<Fortran::parser::OmpMemoryOrderClause>>>(
+                flushConstruct.t);
+            if (memOrderClause.has_value() && memOrderClause->size() > 0)
               TODO(converter.getCurrentLocation(),
                    "Handle OmpMemoryOrderClause");
             converter.getFirOpBuilder().create<mlir::omp::FlushOp>(
diff --git a/flang/test/Lower/OpenMP/flush.f90 b/flang/test/Lower/OpenMP/flush.f90
new file mode 100644 (file)
index 0000000..86f6c68
--- /dev/null
@@ -0,0 +1,41 @@
+! This test checks lowering of OpenMP Flush Directive.
+
+!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect"
+!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect"
+
+subroutine flush_standalone(a, b, c)
+    integer, intent(inout) :: a, b, c
+
+!$omp flush(a,b,c)
+!$omp flush
+!OMPDialect: omp.flush(%{{.*}}, %{{.*}}, %{{.*}} : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
+!OMPDialect: omp.flush
+
+end subroutine flush_standalone
+
+subroutine flush_parallel(a, b, c)
+    integer, intent(inout) :: a, b, c
+
+!$omp parallel
+!OMPDialect:  omp.parallel {
+
+!OMPDialect: omp.flush(%{{.*}}, %{{.*}}, %{{.*}} : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
+!OMPDialect: omp.flush
+!$omp flush(a,b,c)
+!$omp flush
+
+!FIRDialect: %{{.*}} = fir.load %{{.*}} : !fir.ref<i32>
+!FIRDialect: %{{.*}} = fir.load %{{.*}} : !fir.ref<i32>
+!FIRDialect: %{{.*}} = arith.addi %{{.*}}, %{{.*}} : i32
+!FIRDialect: fir.store %{{.*}} to %{{.*}} : !fir.ref<i32>
+
+!LLVMIRDialect: %{{.*}} = llvm.load %{{.*}} : !llvm.ptr<i32>
+!LLVMIRDialect: %{{.*}} = llvm.load %{{.*}} : !llvm.ptr<i32>
+!LLVMIRDialect: %{{.*}} = llvm.add %{{.*}}, %{{.*}} : i32
+!LLVMIRDialect: llvm.store %{{.*}}, %{{.*}} : !llvm.ptr<i32>
+    c = a + b
+
+!OMPDialect: omp.terminator
+!$omp END parallel
+
+end subroutine flush_parallel
diff --git a/flang/test/Lower/OpenMP/master.f90 b/flang/test/Lower/OpenMP/master.f90
new file mode 100644 (file)
index 0000000..129dac4
--- /dev/null
@@ -0,0 +1,100 @@
+!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect"
+!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect"
+
+!===============================================================================
+! parallel construct with function call which has master construct internally
+!===============================================================================
+!FIRDialect-LABEL: func @_QPomp_master
+subroutine omp_master()
+
+!OMPDialect: omp.master  {
+!$omp master
+
+    !FIRDialect: fir.call @_QPmaster() : () -> ()
+    call master()
+
+!OMPDialect: omp.terminator
+!$omp end master
+
+end subroutine omp_master
+
+!FIRDialect-LABEL: func @_QPparallel_function_master
+subroutine parallel_function_master()
+
+!OMPDialect: omp.parallel {
+!$omp parallel
+
+    !FIRDialect: fir.call @_QPfoo() : () -> ()
+    call foo()
+
+!OMPDialect: omp.terminator
+!$omp end parallel
+
+end subroutine parallel_function_master
+
+!===============================================================================
+! master construct nested inside parallel construct
+!===============================================================================
+
+!FIRDialect-LABEL: func @_QPomp_parallel_master
+subroutine omp_parallel_master()
+
+!OMPDialect: omp.parallel {
+!$omp parallel
+    !FIRDialect: fir.call @_QPparallel() : () -> ()
+    call parallel()
+
+!OMPDialect: omp.master {
+!$omp master
+
+    !FIRDialect: fir.call @_QPparallel_master() : () -> ()
+    call parallel_master()
+
+!OMPDialect: omp.terminator
+!$omp end master
+
+!OMPDialect: omp.terminator
+!$omp end parallel
+
+end subroutine omp_parallel_master
+
+!===============================================================================
+! master construct nested inside parallel construct with conditional flow
+!===============================================================================
+
+!FIRDialect-LABEL: func @_QPomp_master_parallel
+subroutine omp_master_parallel()
+    integer :: alpha, beta, gama
+    alpha = 4
+    beta = 5
+    gama = 6
+
+!OMPDialect: omp.master {
+!$omp master
+
+    !FIRDialect: %{{.*}} = fir.load %{{.*}}
+    !FIRDialect: %{{.*}} = fir.load %{{.*}}
+    !FIRDialect: %[[RESULT:.*]] = arith.cmpi sge, %{{.*}}, %{{.*}}
+    !FIRDialect: fir.if %[[RESULT]] {
+    if (alpha .ge. gama) then
+
+!OMPDialect: omp.parallel {
+!$omp parallel
+        !FIRDialect: fir.call @_QPinside_if_parallel() : () -> ()
+        call inside_if_parallel()
+
+!OMPDialect: omp.terminator
+!$omp end parallel
+
+        !FIRDialect: %{{.*}} = fir.load %{{.*}}
+        !FIRDialect: %{{.*}} = fir.load %{{.*}}
+        !FIRDialect: %{{.*}} = arith.addi %{{.*}}, %{{.*}}
+        !FIRDialect: fir.store %{{.*}} to %{{.*}}
+        beta = alpha + gama
+    end if
+    !FIRDialect: else
+
+!OMPDialect: omp.terminator
+!$omp end master
+
+end subroutine omp_master_parallel