diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 7c8072d03179f..4ca8cc709d040 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -112,9 +112,10 @@ genOMP(Fortran::lower::AbstractConverter &converter, std::get>( flushConstruct.t)) genObjectList(*ompObjectList, converter, operandRange); - if (std::get>>( - flushConstruct.t)) + const auto &memOrderClause = std::get>>( + flushConstruct.t); + if (memOrderClause.has_value() && memOrderClause->size() > 0) TODO(converter.getCurrentLocation(), "Handle OmpMemoryOrderClause"); converter.getFirOpBuilder().create( diff --git a/flang/test/Lower/OpenMP/flush.f90 b/flang/test/Lower/OpenMP/flush.f90 new file mode 100644 index 0000000000000..86f6c68c166f2 --- /dev/null +++ b/flang/test/Lower/OpenMP/flush.f90 @@ -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, !fir.ref, !fir.ref) +!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, !fir.ref, !fir.ref) +!OMPDialect: omp.flush +!$omp flush(a,b,c) +!$omp flush + +!FIRDialect: %{{.*}} = fir.load %{{.*}} : !fir.ref +!FIRDialect: %{{.*}} = fir.load %{{.*}} : !fir.ref +!FIRDialect: %{{.*}} = arith.addi %{{.*}}, %{{.*}} : i32 +!FIRDialect: fir.store %{{.*}} to %{{.*}} : !fir.ref + +!LLVMIRDialect: %{{.*}} = llvm.load %{{.*}} : !llvm.ptr +!LLVMIRDialect: %{{.*}} = llvm.load %{{.*}} : !llvm.ptr +!LLVMIRDialect: %{{.*}} = llvm.add %{{.*}}, %{{.*}} : i32 +!LLVMIRDialect: llvm.store %{{.*}}, %{{.*}} : !llvm.ptr + 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 index 0000000000000..129dac49c5e52 --- /dev/null +++ b/flang/test/Lower/OpenMP/master.f90 @@ -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