diff --git a/flang/test/Lower/OpenMP/sections.f90 b/flang/test/Lower/OpenMP/sections.f90 new file mode 100644 index 0000000000000..7abbe32eaa02e --- /dev/null +++ b/flang/test/Lower/OpenMP/sections.f90 @@ -0,0 +1,310 @@ +! This test checks the lowering of OpenMP sections construct with several clauses present + +! RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s +! RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s + +!CHECK: func @_QQmain() attributes {fir.bindc_name = "sample"} { +!CHECK: %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref +!CHECK: %[[COUNT_DECL:.*]]:2 = hlfir.declare %[[COUNT]] {uniq_name = "_QFEcount"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"} +!CHECK: %[[CONST_1:.*]] = arith.constant 1 : i32 +!CHECK: omp.sections allocate(%[[CONST_1]] : i32 -> %[[COUNT_DECL]]#1 : !fir.ref) { +!CHECK: omp.section { +!CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"} +!CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} +!CHECK: %[[PRIVATE_DOUBLE_COUNT_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_DOUBLE_COUNT]] {uniq_name = "_QFEdouble_count"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[CONST5:.*]] = arith.constant 5 : i32 +!CHECK: hlfir.assign %[[CONST5]] to %[[COUNT_DECL]]#0 : i32, !fir.ref +!CHECK: %[[TEMP_COUNT:.*]] = fir.load %[[COUNT_DECL]]#0 : !fir.ref +!CHECK: %[[TEMP_DOUBLE_COUNT:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : !fir.ref +!CHECK: %[[RESULT:.*]] = arith.muli %[[TEMP_COUNT]], %[[TEMP_DOUBLE_COUNT]] : i32 +!CHECK: %[[RESULT_CONVERT:.*]] = fir.convert %[[RESULT]] : (i32) -> f32 +!CHECK: hlfir.assign %[[RESULT_CONVERT]] to %[[PRIVATE_ETA_DECL]]#0 : f32, !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.section { +!CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"} +!CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} +!CHECK: %[[PRIVATE_DOUBLE_COUNT_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_DOUBLE_COUNT]] {uniq_name = "_QFEdouble_count"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : !fir.ref +!CHECK: %[[CONST:.*]] = arith.constant 1 : i32 +!CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : i32, !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.section { +!CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"} +!CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} +!CHECK: %[[PRIVATE_DOUBLE_COUNT_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_DOUBLE_COUNT]] {uniq_name = "_QFEdouble_count"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_ETA_DECL]]#0 : !fir.ref +!CHECK: %[[CONST:.*]] = arith.constant 7.000000e+00 : f32 +!CHECK: %[[RESULT:.*]] = arith.subf %[[TEMP]], %[[CONST]] {{.*}}: f32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_ETA_DECL]]#0 : f32, !fir.ref +!CHECK: %[[TEMP_COUNT1:.*]] = fir.load %[[COUNT_DECL]]#0 : !fir.ref +!CHECK: %[[TEMP_COUNT:.*]] = fir.convert %[[TEMP_COUNT1]] : (i32) -> f32 +!CHECK: %[[TEMP_ETA:.*]] = fir.load %[[PRIVATE_ETA_DECL]]#0 : !fir.ref +!CHECK: %[[TEMP_COUNT2:.*]] = arith.mulf %[[TEMP_COUNT]], %[[TEMP_ETA]] {{.*}}: f32 +!CHECK: %[[RESULT:.*]] = fir.convert %[[TEMP_COUNT2]] : (f32) -> i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[COUNT_DECL]]#0 : i32, !fir.ref +!CHECK: %[[TEMP_COUNT3:.*]] = fir.load %[[COUNT_DECL]]#0 : !fir.ref +!CHECK: %[[TEMP_COUNT4:.*]] = fir.convert %[[TEMP_COUNT3]] : (i32) -> f32 +!CHECK: %[[TEMP_ETA:.*]] = fir.load %[[PRIVATE_ETA_DECL]]#0 : !fir.ref +!CHECK: %[[TEMP_COUNT5:.*]] = arith.subf %[[TEMP_COUNT4]], %[[TEMP_ETA]] {{.*}}: f32 +!CHECK: %[[RESULT2:.*]] = fir.convert %[[TEMP_COUNT5]] : (f32) -> i32 +!CHECK: hlfir.assign %[[RESULT2]] to %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : i32, !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.sections nowait { +!CHECK: omp.terminator +!CHECK: } +!CHECK: return +!CHECK: } + +program sample + use omp_lib + integer :: count = 0, double_count = 1 + !$omp sections private (eta, double_count) allocate(omp_high_bw_mem_alloc: count) + !$omp section + count = 1 + 4 + eta = count * double_count + !$omp section + double_count = double_count + 1 + !$omp section + eta = eta - 7 + count = count * eta + double_count = count - eta + !$omp end sections + + !$omp sections + !$omp end sections nowait +end program sample + +!CHECK: func @_QPfirstprivate(%[[ARG:.*]]: !fir.ref {fir.bindc_name = "alpha"}) { +!CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]] {uniq_name = "_QFfirstprivateEalpha"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: omp.sections { +!CHECK: omp.section { +!CHECK: %[[PRIVATE_ALPHA:.*]] = fir.alloca f32 {bindc_name = "alpha", pinned, uniq_name = "_QFfirstprivateEalpha"} +!CHECK: %[[PRIVATE_ALPHA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ALPHA]] {uniq_name = "_QFfirstprivateEalpha"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[ARG_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[PRIVATE_ALPHA_DECL]]#1 : !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.sections { +!CHECK: omp.section { +!CHECK: %[[PRIVATE_VAR:.*]] = fir.load %[[ARG_DECL]]#0 : !fir.ref +!CHECK: %[[CONSTANT:.*]] = arith.constant 5.000000e+00 : f32 +!CHECK: %[[PRIVATE_VAR_2:.*]] = arith.mulf %[[PRIVATE_VAR]], %[[CONSTANT]] {{.*}}: f32 +!CHECK: hlfir.assign %[[PRIVATE_VAR_2]] to %[[ARG_DECL]]#0 : f32, !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } +!CHECK: return +!CHECK: } + +subroutine firstprivate(alpha) + real :: alpha + !$omp sections firstprivate(alpha) + !$omp end sections + + !$omp sections + alpha = alpha * 5 + !$omp end sections +end subroutine + +!CHECK-LABEL: func @_QPlastprivate +subroutine lastprivate() + integer :: x +!CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFlastprivateEx"} +!CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: omp.sections { + !$omp sections lastprivate(x) +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[CONST10:.*]] = arith.constant 10 : i32 +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[RESULT:.*]] = arith.muli %[[CONST10]], %[[TEMP]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: omp.terminator +!CHECK: } + !$omp section + x = x * 10 + +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TRUE:.*]] = arith.constant true +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[CONST:.*]] = arith.constant 1 : i32 +!CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: fir.if %[[TRUE]] { +!CHECK: %[[TEMP1:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP1]] to %[[X_DECL]]#1 : !fir.ref +!CHECK: } +!CHECK: omp.terminator +!CHECK: } + !$omp section + x = x + 1 +!CHECK: omp.terminator +!CHECK: } + !$omp end sections + +!CHECK: omp.sections { + !$omp sections firstprivate(x) lastprivate(x) +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: omp.barrier +!CHECK: %[[CONST:.*]] = arith.constant 10 : i32 +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[RESULT:.*]] = arith.muli %[[CONST]], %[[TEMP]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: omp.terminator +!CHECK: } + !$omp section + x = x * 10 +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: omp.barrier +!CHECK: %[[TRUE:.*]] = arith.constant true +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[CONST:.*]] = arith.constant 1 : i32 +!CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: fir.if %[[TRUE]] { +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[X_DECL]]#1 : !fir.ref +!CHECK: } +!CHECK: omp.terminator +!CHECK: } + !$omp section + x = x + 1 +!CHECK: omp.terminator +!CHECK: } + !$omp end sections + +!CHECK: omp.sections nowait { + !$omp sections firstprivate(x) lastprivate(x) +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: omp.barrier +!CHECK: %[[CONST:.*]] = arith.constant 10 : i32 +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[RESULT:.*]] = arith.muli %[[CONST]], %[[TEMP]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: omp.terminator +!CHECK: } + !$omp section + x = x * 10 +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: omp.barrier +!CHECK: %[[TRUE:.*]] = arith.constant true +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[CONST:.*]] = arith.constant 1 : i32 +!CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: fir.if %[[TRUE]] { +!CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[X_DECL]]#1 : !fir.ref +!CHECK: omp.barrier +!CHECK: } +!CHECK: omp.terminator +!CHECK: } + !$omp section + x = x + 1 +!CHECK: omp.terminator +!CHECK: } + !$omp end sections nowait + +!CHECK: omp.sections { +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: cf.br ^bb1 +!CHECK: ^bb1: // pred: ^bb0 +!CHECK: %[[INNER_PRIVATE_X:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[CONST:.*]] = arith.constant 1 : i32 +!CHECK: %[[RESULT:.*]] = arith.addi %[[INNER_PRIVATE_X]], %[[CONST]] : i32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref +!CHECK: %[[LOADED_VALUE:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[LOADED_VALUE]] to %[[X_DECL]]#1 : !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } +!CHECK: return +!CHECK: } + + !$omp sections lastprivate(x) + !$omp section + goto 30 + 30 x = x + 1 + !$omp end sections +end subroutine + +!CHECK-LABEL: func @_QPunstructured_sections_privatization +subroutine unstructured_sections_privatization() +!CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFunstructured_sections_privatizationEx"} +!CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFunstructured_sections_privatizationEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: omp.sections { +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFunstructured_sections_privatizationEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFunstructured_sections_privatizationEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: cf.br ^bb1 +!CHECK: ^bb1: // pred: ^bb0 +!CHECK: %[[INNER_PRIVATE_X:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[CONSTANT:.*]] = arith.constant 1.000000e+00 : f32 +!CHECK: %[[RESULT:.*]] = arith.addf %[[INNER_PRIVATE_X]], %[[CONSTANT]] fastmath : f32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : f32, !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } + !$omp sections private(x) + !$omp section + goto 40 + 40 x = x + 1 + !$omp end sections +!CHECK: omp.sections { +!CHECK: omp.section { +!CHECK: %[[PRIVATE_X:.*]] = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFunstructured_sections_privatizationEx"} +!CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFunstructured_sections_privatizationEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref +!CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref +!CHECK: cf.br ^bb1 +!CHECK: ^bb1: +!CHECK: %[[INNER_PRIVATE_X:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref +!CHECK: %[[CONSTANT:.*]] = arith.constant 1.000000e+00 : f32 +!CHECK: %[[RESULT:.*]] = arith.addf %[[INNER_PRIVATE_X]], %[[CONSTANT]] fastmath : f32 +!CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : f32, !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } + !$omp sections firstprivate(x) + !$omp section + goto 50 + 50 x = x + 1 + !$omp end sections +end subroutine diff --git a/flang/test/Lower/OpenMP/simd.f90 b/flang/test/Lower/OpenMP/simd.f90 new file mode 100644 index 0000000000000..135b38c792623 --- /dev/null +++ b/flang/test/Lower/OpenMP/simd.f90 @@ -0,0 +1,174 @@ +! Tests for 2.9.3.1 Simd + +!RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s +!RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s + +!CHECK-LABEL: func @_QPsimdloop() +subroutine simdloop +integer :: i + !$OMP SIMD + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK-NEXT: %[[UB:.*]] = arith.constant 9 : i32 + ! CHECK-NEXT: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK-NEXT: omp.simdloop for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i=1, 9 + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_if_clause +subroutine simdloop_with_if_clause(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_if_clauseEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold + !$OMP SIMD IF( n .GE. threshold ) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: %[[COND:.*]] = arith.cmpi sge + ! CHECK: omp.simdloop if(%[[COND:.*]]) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause +subroutine simdloop_with_simdlen_clause(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_clauseEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold + !$OMP SIMD SIMDLEN(2) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: omp.simdloop simdlen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause_from_param +subroutine simdloop_with_simdlen_clause_from_param(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_clause_from_paramEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold +integer, parameter :: simdlen = 2; + !$OMP SIMD SIMDLEN(simdlen) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: omp.simdloop simdlen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause_from_expr_from_param +subroutine simdloop_with_simdlen_clause_from_expr_from_param(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_clause_from_expr_from_paramEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold +integer, parameter :: simdlen = 2; + !$OMP SIMD SIMDLEN(simdlen*2 + 2) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: omp.simdloop simdlen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause +subroutine simdloop_with_safelen_clause(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_safelen_clauseEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold + !$OMP SIMD SAFELEN(2) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: omp.simdloop safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause_from_expr_from_param +subroutine simdloop_with_safelen_clause_from_expr_from_param(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_safelen_clause_from_expr_from_paramEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold +integer, parameter :: safelen = 2; + !$OMP SIMD SAFELEN(safelen*2 + 2) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: omp.simdloop safelen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_simdlen_safelen_clause +subroutine simdloop_with_simdlen_safelen_clause(n, threshold) + ! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_safelen_clauseEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) +integer :: i, n, threshold + !$OMP SIMD SIMDLEN(1) SAFELEN(2) + ! CHECK: %[[LB:.*]] = arith.constant 1 : i32 + ! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0 + ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 + ! CHECK: omp.simdloop simdlen(1) safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + do i = 1, n + ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref + ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref, i32) -> i1 + print*, i + end do + !$OMP END SIMD +end subroutine + +!CHECK-LABEL: func @_QPsimdloop_with_collapse_clause +subroutine simdloop_with_collapse_clause(n) +integer :: i, j, n +integer :: A(n,n) +! CHECK: %[[LOWER_I:.*]] = arith.constant 1 : i32 +! CHECK: %[[UPPER_I:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref +! CHECK: %[[STEP_I:.*]] = arith.constant 1 : i32 +! CHECK: %[[LOWER_J:.*]] = arith.constant 1 : i32 +! CHECK: %[[UPPER_J:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref +! CHECK: %[[STEP_J:.*]] = arith.constant 1 : i32 +! CHECK: omp.simdloop for (%[[ARG_0:.*]], %[[ARG_1:.*]]) : i32 = ( +! CHECK-SAME: %[[LOWER_I]], %[[LOWER_J]]) to ( +! CHECK-SAME: %[[UPPER_I]], %[[UPPER_J]]) inclusive step ( +! CHECK-SAME: %[[STEP_I]], %[[STEP_J]]) { + !$OMP SIMD COLLAPSE(2) + do i = 1, n + do j = 1, n + A(i,j) = i + j + end do + end do + !$OMP END SIMD +end subroutine diff --git a/flang/test/Lower/OpenMP/simple-barrier.f90 b/flang/test/Lower/OpenMP/simple-barrier.f90 new file mode 100644 index 0000000000000..cc996330a2a73 --- /dev/null +++ b/flang/test/Lower/OpenMP/simple-barrier.f90 @@ -0,0 +1,7 @@ +!RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s +!RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s + +subroutine sample() +! CHECK: omp.barrier +!$omp barrier +end subroutine sample diff --git a/flang/test/Lower/OpenMP/stop-stmt-in-region.f90 b/flang/test/Lower/OpenMP/stop-stmt-in-region.f90 new file mode 100644 index 0000000000000..fdbabc21b2c9e --- /dev/null +++ b/flang/test/Lower/OpenMP/stop-stmt-in-region.f90 @@ -0,0 +1,156 @@ +! This test checks lowering of stop statement in OpenMP region. + +! RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s +! RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s + + +! CHECK-LABEL: func.func @_QPtest_stop_in_region1() { +! CHECK: omp.parallel { +! CHECK: %[[VAL_0:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_1:.*]] = arith.constant false +! CHECK: %[[VAL_2:.*]] = arith.constant false +! CHECK: %[[VAL_3:.*]] = fir.call @_FortranAStopStatement(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {{.*}} : (i32, i1, i1) -> none +! CHECK-NOT: fir.unreachable +! CHECK: omp.terminator +! CHECK: } +! CHECK: return +! CHECK: } + +subroutine test_stop_in_region1() + !$omp parallel + stop 1 + !$omp end parallel +end + +! CHECK-LABEL: func.func @_QPtest_stop_in_region2() { +! CHECK: %{{.*}} = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtest_stop_in_region2Ex"} +! CHECK: omp.parallel { +! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_2:.*]] = arith.constant false +! CHECK: %[[VAL_3:.*]] = arith.constant false +! CHECK: %[[VAL_4:.*]] = fir.call @_FortranAStopStatement(%[[VAL_1]], %[[VAL_2]], %[[VAL_3]]) {{.*}} : (i32, i1, i1) -> none +! CHECK: omp.terminator +! CHECK: } +! CHECK: return +! CHECK: } + +subroutine test_stop_in_region2() + integer :: x + !$omp parallel + stop 1 + x = 2 + !$omp end parallel +end + +! CHECK-LABEL: func.func @_QPtest_stop_in_region3() { +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtest_stop_in_region3Ex"} +! CHECK: %[[VAL_0_DECL:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_stop_in_region3Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: omp.parallel { +! CHECK: %[[VAL_1:.*]] = arith.constant 3 : i32 +! CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0_DECL]]#0 : i32, !fir.ref +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0_DECL]]#0 : !fir.ref +! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_4:.*]] = arith.cmpi sgt, %[[VAL_2]], %[[VAL_3]] : i32 +! CHECK: cf.cond_br %[[VAL_4]], ^bb1, ^bb2 +! CHECK: ^bb1: +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_0_DECL]]#0 : !fir.ref +! CHECK: %[[VAL_6:.*]] = arith.constant false +! CHECK: %[[VAL_7:.*]] = arith.constant false +! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAStopStatement(%[[VAL_5]], %[[VAL_6]], %[[VAL_7]]) {{.*}} : (i32, i1, i1) -> none +! CHECK: omp.terminator +! CHECK: ^bb2: +! CHECK: omp.terminator +! CHECK: } +! CHECK: return +! CHECK: } + +subroutine test_stop_in_region3() + integer :: x + !$omp parallel + x = 3 + if (x > 1) stop x + !$omp end parallel +end + +! CHECK-LABEL: func.func @_QPtest_stop_in_region4() { +! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} +! CHECK: %[[VAL_0_DECL:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_stop_in_region4Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_stop_in_region4Ei"} +! CHECK: %[[VAL_1_DECL:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest_stop_in_region4Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtest_stop_in_region4Ex"} +! CHECK: %[[VAL_2_DECL:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest_stop_in_region4Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_4:.*]] = arith.constant 10 : i32 +! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32 +! CHECK: omp.wsloop for (%[[VAL_6:.*]]) : i32 = (%[[VAL_3]]) to (%[[VAL_4]]) inclusive step (%[[VAL_5]]) { +! CHECK: fir.store %[[VAL_6]] to %[[VAL_0_DECL]]#1 : !fir.ref +! CHECK: cf.br ^bb1 +! CHECK: ^bb1: +! CHECK: %[[VAL_7:.*]] = arith.constant 3 : i32 +! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_2_DECL]]#0 : i32, !fir.ref +! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2_DECL]]#0 : !fir.ref +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : i32 +! CHECK: cf.cond_br %[[VAL_10]], ^bb2, ^bb3 +! CHECK: ^bb2: +! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_2_DECL]]#0 : !fir.ref +! CHECK: %[[VAL_12:.*]] = arith.constant false +! CHECK: %[[VAL_13:.*]] = arith.constant false +! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAStopStatement(%[[VAL_11]], %[[VAL_12]], %[[VAL_13]]) {{.*}} : (i32, i1, i1) -> none +! CHECK: omp.yield +! CHECK: ^bb3: +! CHECK: omp.yield +! CHECK: } +! CHECK: cf.br ^bb1 +! CHECK: ^bb1: +! CHECK: return +! CHECK: } + +subroutine test_stop_in_region4() + integer :: x + !$omp do + do i = 1, 10 + x = 3 + if (x > 1) stop x + enddo + !$omp end do +end + + +!CHECK-LABEL: func.func @_QPtest_stop_in_region5 +!CHECK: omp.parallel { +!CHECK: {{.*}} fir.call @_FortranAStopStatement({{.*}}, {{.*}}, {{.*}}) fastmath : (i32, i1, i1) -> none +!CHECK: omp.terminator +!CHECK: } +!CHECK: return + +subroutine test_stop_in_region5() + !$omp parallel + block + stop 1 + end block + !$omp end parallel +end + +!CHECK-LABEL: func.func @_QPtest_stop_in_region6 +!CHECK: omp.parallel { +!CHECK: cf.cond_br %{{.*}}, ^[[BB1:.*]], ^[[BB2:.*]] +!CHECK: ^[[BB1]]: +!CHECK: {{.*}}fir.call @_FortranAStopStatement({{.*}}, {{.*}}, {{.*}}) fastmath : (i32, i1, i1) -> none +!CHECK: omp.terminator +!CHECK: ^[[BB2]]: +!CHECK: {{.*}}fir.call @_FortranAStopStatement({{.*}}, {{.*}}, {{.*}}) fastmath : (i32, i1, i1) -> none +!CHECK: omp.terminator +!CHECK: } +!CHECK: return + +subroutine test_stop_in_region6(x) + integer :: x + !$omp parallel + if (x .gt. 1) then + stop 1 + else + stop 2 + end if + !$omp end parallel +end