diff --git a/flang/test/SemanticsChecked/OpenMP/map-clause.f90 b/flang/test/SemanticsChecked/OpenMP/map-clause.f90 new file mode 100644 index 00000000000000..a7430c3edeb949 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/map-clause.f90 @@ -0,0 +1,35 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! Check OpenMP MAP clause validity. Section 5.8.3 OpenMP 5.2. + +subroutine sb(arr) + implicit none + real(8) :: arr(*) + real :: a + integer:: b, c, i + common /var/ b, c + + !ERROR: Assumed-size whole arrays may not appear on the MAP clause + !$omp target map(arr) + do i = 1, 100 + a = 3.14 + enddo + !$omp end target + + !ERROR: Assumed-size array 'arr' must have explicit final subscript upper bound value + !$omp target map(arr(:)) + do i = 1, 100 + a = 3.14 + enddo + !$omp end target + + !$omp target map(arr(3:5)) + do i = 1, 100 + a = 3.14 + enddo + !$omp end target + + !$omp target map(tofrom: /var/) + b = 1 + c = 2 + !$omp end target +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90 b/flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90 new file mode 100644 index 00000000000000..74147c0494a544 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90 @@ -0,0 +1,35 @@ +! RUN: %python %S/../test_modfile.py %s %flang_fc1 -fopenmp +! Check correct modfile generation for OpenMP threadprivate directive. + +module m + implicit none + type :: my_type(kind_param, len_param) + integer, KIND :: kind_param + integer, LEN :: len_param + integer :: t_i + integer :: t_arr(10) + end type + type(my_type(kind_param=2, len_param=4)) :: t + real, dimension(3) :: thrtest + real :: x + common /blk/ x + + !$omp threadprivate(thrtest, t, /blk/) +end + +!Expect: m.mod +!module m +!type::my_type(kind_param,len_param) +!integer(4),kind::kind_param +!integer(4),len::len_param +!integer(4)::t_i +!integer(4)::t_arr(1_8:10_8) +!end type +!type(my_type(kind_param=2_4,len_param=4_4))::t +!!$omp threadprivate(t) +!real(4)::thrtest(1_8:3_8) +!!$omp threadprivate(thrtest) +!real(4)::x +!!$omp threadprivate(x) +!common/blk/x +!end diff --git a/flang/test/SemanticsChecked/OpenMP/nested-barrier.f90 b/flang/test/SemanticsChecked/OpenMP/nested-barrier.f90 new file mode 100644 index 00000000000000..cad31d7985607c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-barrier.f90 @@ -0,0 +1,166 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! Various checks with the nesting of BARRIER construct + +program omp_nest_barrier + integer i, k, j + k = 0; + + !$omp do + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp do simd + do i = 1, 10 + k = k + 1 + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp parallel do + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp parallel do simd + do i = 1, 10 + k = k + 1 + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp parallel + do i = 1, 10 + k = k + 1 + !$omp barrier + j = j -1 + end do + !$omp end parallel + + !$omp task + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end task + + !$omp taskloop + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end taskloop + + !$omp critical + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end critical + + !$omp master + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end master + + !$omp ordered + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end ordered + + !$omp ordered + do i = 1, 10 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end ordered + + !$omp master + do i = 1, 10 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end master + + !$omp critical + do i = 1, 10 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end critical + + !$omp taskloop + do i = 1, 10 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end taskloop + + !$omp task + do i = 1, 10 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end task + +end program omp_nest_barrier diff --git a/flang/test/SemanticsChecked/OpenMP/nested-cancel.f90 b/flang/test/SemanticsChecked/OpenMP/nested-cancel.f90 new file mode 100644 index 00000000000000..afd94a591a0674 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-cancel.f90 @@ -0,0 +1,249 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 5.0 +! Check OpenMP construct validity for the following directives: +! 2.18.1 Cancel Construct + +program main + integer :: i, N = 10 + real :: a + + !ERROR: CANCEL TASKGROUP directive is not closely nested inside TASK or TASKLOOP + !$omp cancel taskgroup + + !ERROR: CANCEL SECTIONS directive is not closely nested inside SECTION or SECTIONS + !$omp cancel sections + + !ERROR: CANCEL DO directive is not closely nested inside the construct that matches the DO clause type + !$omp cancel do + + !ERROR: CANCEL PARALLEL directive is not closely nested inside the construct that matches the PARALLEL clause type + !$omp cancel parallel + + !$omp parallel + !$omp sections + !$omp cancel sections + !$omp section + a = 3.14 + !$omp end sections + !$omp end parallel + + !$omp sections + !$omp section + !$omp cancel sections + a = 3.14 + !$omp end sections + + !$omp parallel + !ERROR: With SECTIONS clause, CANCEL construct cannot be closely nested inside PARALLEL construct + !$omp cancel sections + a = 3.14 + !$omp end parallel + + !$omp parallel sections + !$omp cancel sections + a = 3.14 + !$omp end parallel sections + + !$omp do + do i = 1, N + a = 3.14 + !$omp cancel do + end do + !$omp end do + + !$omp parallel do + do i = 1, N + a = 3.14 + !$omp cancel do + end do + !$omp end parallel do + + !$omp target + !$omp teams + !$omp distribute parallel do + do i = 1, N + a = 3.14 + !$omp cancel do + end do + !$omp end distribute parallel do + !$omp end teams + !$omp end target + + !$omp target + !$omp teams distribute parallel do + do i = 1, N + a = 3.14 + !$omp cancel do + end do + !$omp end teams distribute parallel do + !$omp end target + + !$omp target teams distribute parallel do + do i = 1, N + a = 3.14 + !$omp cancel do + end do + !$omp end target teams distribute parallel do + + !$omp target parallel do + do i = 1, N + a = 3.14 + !$omp cancel do + end do + !$omp end target parallel do + + !$omp parallel + do i = 1, N + a = 3.14 + !ERROR: With DO clause, CANCEL construct cannot be closely nested inside PARALLEL construct + !$omp cancel do + end do + !$omp end parallel + + !$omp parallel + do i = 1, N + a = 3.14 + !$omp cancel parallel + end do + !$omp end parallel + + !$omp target parallel + do i = 1, N + a = 3.14 + !$omp cancel parallel + end do + !$omp end target parallel + + !$omp target parallel do + do i = 1, N + a = 3.14 + !ERROR: With PARALLEL clause, CANCEL construct cannot be closely nested inside TARGET PARALLEL DO construct + !$omp cancel parallel + end do + !$omp end target parallel do + + !$omp do + do i = 1, N + a = 3.14 + !ERROR: With PARALLEL clause, CANCEL construct cannot be closely nested inside DO construct + !$omp cancel parallel + end do + !$omp end do + +contains + subroutine sub1() + !$omp task + !$omp cancel taskgroup + a = 3.14 + !$omp end task + + !$omp taskloop + do i = 1, N + !$omp parallel + !$omp end parallel + !$omp cancel taskgroup + a = 3.14 + end do + !$omp end taskloop + + !$omp taskloop nogroup + do i = 1, N + !$omp cancel taskgroup + a = 3.14 + end do + + !$omp parallel + !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region + !$omp cancel taskgroup + a = 3.14 + !$omp end parallel + + !$omp do + do i = 1, N + !$omp task + !$omp cancel taskgroup + a = 3.14 + !$omp end task + end do + !$omp end do + + !$omp parallel + !$omp taskgroup + !$omp task + !$omp cancel taskgroup + a = 3.14 + !$omp end task + !$omp end taskgroup + !$omp end parallel + + !$omp parallel + !$omp task + !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region + !$omp cancel taskgroup + a = 3.14 + !$omp end task + !$omp end parallel + + !$omp parallel + !$omp do + do i = 1, N + !$omp task + !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region + !$omp cancel taskgroup + a = 3.14 + !$omp end task + end do + !$omp end do + !$omp end parallel + + !$omp target parallel + !$omp task + !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region + !$omp cancel taskgroup + a = 3.14 + !$omp end task + !$omp end target parallel + + !$omp parallel + !$omp taskloop private(j) nogroup + do i = 1, N + !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region + !$omp cancel taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end parallel + + !$omp parallel + !$omp taskloop + do i = 1, N + !$omp cancel taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end parallel + + !$omp parallel + !$omp taskgroup + !$omp taskloop nogroup + do i = 1, N + !$omp cancel taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end taskgroup + !$omp end parallel + + !$omp target parallel + !$omp taskloop nogroup + do i = 1, N + !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region + !$omp cancel taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end target parallel + end subroutine sub1 + +end program main diff --git a/flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90 b/flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90 new file mode 100644 index 00000000000000..5392a31b23312d --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90 @@ -0,0 +1,249 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 5.0 +! Check OpenMP construct validity for the following directives: +! 2.18.2 Cancellation Point Construct + +program main + integer :: i, N = 10 + real :: a + + !ERROR: CANCELLATION POINT TASKGROUP directive is not closely nested inside TASK or TASKLOOP + !$omp cancellation point taskgroup + + !ERROR: CANCELLATION POINT SECTIONS directive is not closely nested inside SECTION or SECTIONS + !$omp cancellation point sections + + !ERROR: CANCELLATION POINT DO directive is not closely nested inside the construct that matches the DO clause type + !$omp cancellation point do + + !ERROR: CANCELLATION POINT PARALLEL directive is not closely nested inside the construct that matches the PARALLEL clause type + !$omp cancellation point parallel + + !$omp parallel + !$omp sections + !$omp cancellation point sections + !$omp section + a = 3.14 + !$omp end sections + !$omp end parallel + + !$omp sections + !$omp section + !$omp cancellation point sections + a = 3.14 + !$omp end sections + + !$omp parallel + !ERROR: With SECTIONS clause, CANCELLATION POINT construct cannot be closely nested inside PARALLEL construct + !$omp cancellation point sections + a = 3.14 + !$omp end parallel + + !$omp parallel sections + !$omp cancellation point sections + a = 3.14 + !$omp end parallel sections + + !$omp do + do i = 1, N + a = 3.14 + !$omp cancellation point do + end do + !$omp end do + + !$omp parallel do + do i = 1, N + a = 3.14 + !$omp cancellation point do + end do + !$omp end parallel do + + !$omp target + !$omp teams + !$omp distribute parallel do + do i = 1, N + a = 3.14 + !$omp cancellation point do + end do + !$omp end distribute parallel do + !$omp end teams + !$omp end target + + !$omp target + !$omp teams distribute parallel do + do i = 1, N + a = 3.14 + !$omp cancellation point do + end do + !$omp end teams distribute parallel do + !$omp end target + + !$omp target teams distribute parallel do + do i = 1, N + a = 3.14 + !$omp cancellation point do + end do + !$omp end target teams distribute parallel do + + !$omp target parallel do + do i = 1, N + a = 3.14 + !$omp cancellation point do + end do + !$omp end target parallel do + + !$omp parallel + do i = 1, N + a = 3.14 + !ERROR: With DO clause, CANCELLATION POINT construct cannot be closely nested inside PARALLEL construct + !$omp cancellation point do + end do + !$omp end parallel + + !$omp parallel + do i = 1, N + a = 3.14 + !$omp cancellation point parallel + end do + !$omp end parallel + + !$omp target parallel + do i = 1, N + a = 3.14 + !$omp cancellation point parallel + end do + !$omp end target parallel + + !$omp target parallel do + do i = 1, N + a = 3.14 + !ERROR: With PARALLEL clause, CANCELLATION POINT construct cannot be closely nested inside TARGET PARALLEL DO construct + !$omp cancellation point parallel + end do + !$omp end target parallel do + + !$omp do + do i = 1, N + a = 3.14 + !ERROR: With PARALLEL clause, CANCELLATION POINT construct cannot be closely nested inside DO construct + !$omp cancellation point parallel + end do + !$omp end do + +contains + subroutine sub1() + !$omp task + !$omp cancellation point taskgroup + a = 3.14 + !$omp end task + + !$omp taskloop + do i = 1, N + !$omp parallel + !$omp end parallel + !$omp cancellation point taskgroup + a = 3.14 + end do + !$omp end taskloop + + !$omp taskloop nogroup + do i = 1, N + !$omp cancellation point taskgroup + a = 3.14 + end do + + !$omp parallel + !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region + !$omp cancellation point taskgroup + a = 3.14 + !$omp end parallel + + !$omp do + do i = 1, N + !$omp task + !$omp cancellation point taskgroup + a = 3.14 + !$omp end task + end do + !$omp end do + + !$omp parallel + !$omp taskgroup + !$omp task + !$omp cancellation point taskgroup + a = 3.14 + !$omp end task + !$omp end taskgroup + !$omp end parallel + + !$omp parallel + !$omp task + !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region + !$omp cancellation point taskgroup + a = 3.14 + !$omp end task + !$omp end parallel + + !$omp parallel + !$omp do + do i = 1, N + !$omp task + !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region + !$omp cancellation point taskgroup + a = 3.14 + !$omp end task + end do + !$omp end do + !$omp end parallel + + !$omp target parallel + !$omp task + !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region + !$omp cancellation point taskgroup + a = 3.14 + !$omp end task + !$omp end target parallel + + !$omp parallel + !$omp taskloop private(j) nogroup + do i = 1, N + !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region + !$omp cancellation point taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end parallel + + !$omp parallel + !$omp taskloop + do i = 1, N + !$omp cancellation point taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end parallel + + !$omp parallel + !$omp taskgroup + !$omp taskloop nogroup + do i = 1, N + !$omp cancellation point taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end taskgroup + !$omp end parallel + + !$omp target parallel + !$omp taskloop nogroup + do i = 1, N + !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region + !$omp cancellation point taskgroup + a = 3.14 + end do + !$omp end taskloop + !$omp end target parallel + end subroutine sub1 + +end program main diff --git a/flang/test/SemanticsChecked/OpenMP/nested-distribute.f90 b/flang/test/SemanticsChecked/OpenMP/nested-distribute.f90 new file mode 100644 index 00000000000000..ba8c3bf04b3377 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-distribute.f90 @@ -0,0 +1,111 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! Check OpenMP clause validity for the following directives: +! 2.10 Device constructs +program main + + real(8) :: arrayA(256), arrayB(256) + integer :: N + + arrayA = 1.414 + arrayB = 3.14 + N = 256 + + !$omp task + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do i = 1, N + a = 3.14 + enddo + !$omp end distribute + !$omp end task + + !$omp teams + do i = 1, N + !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region. + !$omp task + do k = 1, N + a = 3.14 + enddo + !$omp end task + enddo + !$omp end teams + + !$omp teams + do i = 1, N + !$omp parallel + do k = 1, N + a = 3.14 + enddo + !$omp end parallel + enddo + !$omp end teams + + !$omp parallel + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do i = 1, N + a = 3.14 + enddo + !$omp end distribute + !$omp end parallel + + !$omp teams + !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region. + !$omp target + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute + do i = 1, 10 + j = j + 1 + end do + !$omp end distribute + !$omp end target + !$omp end teams + + !$omp teams + !$omp parallel + do k = 1,10 + print *, "hello" + end do + !$omp end parallel + !$omp distribute firstprivate(a) + do i = 1, 10 + j = j + 1 + end do + !$omp end distribute + !$omp end teams + + !$omp target teams + !$omp distribute + do i = 1, 10 + end do + !$omp end distribute + !$omp end target teams + + !$omp teams + !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region. + !$omp task + do k = 1,10 + print *, "hello" + end do + !$omp end task + !$omp distribute firstprivate(a) + do i = 1, 10 + j = j + 1 + end do + !$omp end distribute + !$omp end teams + + !$omp task + !$omp parallel + do k = 1,10 + print *, "hello" + end do + !$omp end parallel + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute firstprivate(a) + do i = 1, 10 + j = j + 1 + end do + !$omp end distribute + !$omp end task +end program main diff --git a/flang/test/SemanticsChecked/OpenMP/nested-master.f90 b/flang/test/SemanticsChecked/OpenMP/nested-master.f90 new file mode 100644 index 00000000000000..ef7d2cef6f88a1 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-master.f90 @@ -0,0 +1,153 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! Various checks with the nesting of MASTER construct + +program omp_nest_master + integer i, k, j + k = 0; + + !$omp do + do i = 1, 10 + k = k + 1 + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + + !$omp sections + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + do i = 1, 10 + k = k + 1 + end do + !$omp end master + !$omp end sections + + !$omp single + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + do i = 1, 10 + k = k + 1 + end do + !$omp end master + !$omp end single + + + + !$omp task + do i = 1, 10 + k = k + 1 + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end task + + !$omp taskloop + do i = 1, 10 + k = k + 1 + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end taskloop + + !$omp target parallel do simd + do i = 1, 10 + k = k + 1 + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end target parallel do simd + + !$omp critical + do i = 1, 10 + k = k + 1 + !$omp master + j = j -1 + !$omp end master + end do + !$omp end critical + + !$omp ordered + do i = 1, 10 + k = k + 1 + !$omp master + j = j -1 + !$omp end master + end do + !$omp end ordered + + !$omp ordered + do i = 1, 10 + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + !$omp distribute + do k =1, 10 + print *, "hello" + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + !$omp end teams + end do + !$omp end ordered + + !$omp critical + do i = 1, 10 + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + !$omp distribute + do k =1, 10 + print *, "hello" + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + !$omp end teams + end do + !$omp end critical + + !$omp taskloop + do i = 1, 10 + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + !$omp end teams + end do + !$omp end taskloop + + !$omp task + do i = 1, 10 + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + !$omp end teams + end do + !$omp end task + +end program omp_nest_master diff --git a/flang/test/SemanticsChecked/OpenMP/nested-simd.f90 b/flang/test/SemanticsChecked/OpenMP/nested-simd.f90 new file mode 100644 index 00000000000000..4149b6d97e9dc7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-simd.f90 @@ -0,0 +1,191 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! Various checks with the nesting of SIMD construct + +SUBROUTINE NESTED_GOOD(N) + INTEGER N, I, J, K, A(10), B(10) + !$OMP SIMD + DO I = 1,N + !$OMP ATOMIC + K = K + 1 + IF (I <= 10) THEN + !$OMP ORDERED SIMD + DO J = 1,N + A(J) = J + END DO + !$OMP END ORDERED + ENDIF + END DO + !$OMP END SIMD + + !$OMP SIMD + DO I = 1,N + IF (I <= 10) THEN + !$OMP SIMD + DO J = 1,N + A(J) = J + END DO + !$OMP END SIMD + ENDIF + END DO + !$OMP END SIMD +END SUBROUTINE NESTED_GOOD + +SUBROUTINE NESTED_BAD(N) + INTEGER N, I, J, K, A(10), B(10) + + !$OMP SIMD + DO I = 1,N + IF (I <= 10) THEN + !$OMP ORDERED SIMD + DO J = 1,N + print *, "Hi" + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + DO K = 1,N + print *, 'Hello' + END DO + !$omp end teams + END DO + !$OMP END ORDERED + ENDIF + END DO + !$OMP END SIMD + + !$OMP SIMD + DO I = 1,N + !$OMP ATOMIC + K = K + 1 + IF (I <= 10) THEN + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp task + do J = 1, N + K = 2 + end do + !$omp end task + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp target + do J = 1, N + K = 2 + end do + !$omp end target + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$OMP DO + DO J = 1,N + A(J) = J + END DO + !$OMP END DO + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$OMP PARALLEL DO + DO J = 1,N + A(J) = J + END DO + !$OMP END PARALLEL DO + ENDIF + END DO + !$OMP END SIMD + + !$OMP DO SIMD + DO I = 1,N + !$OMP ATOMIC + K = K + 1 + IF (I <= 10) THEN + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp task + do J = 1, N + K = 2 + end do + !$omp end task + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp target + do J = 1, N + K = 2 + end do + !$omp end target + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$OMP DO + DO J = 1,N + A(J) = J + END DO + !$OMP END DO + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$OMP PARALLEL DO + DO J = 1,N + A(J) = J + END DO + !$OMP END PARALLEL DO + ENDIF + END DO + !$OMP END DO SIMD + + !$OMP PARALLEL DO SIMD + DO I = 1,N + !$OMP ATOMIC + K = K + 1 + IF (I <= 10) THEN + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp task + do J = 1, N + K = 2 + end do + !$omp end task + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp target + do J = 1, N + K = 2 + end do + !$omp end target + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$OMP DO + DO J = 1,N + A(J) = J + END DO + !$OMP END DO + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$OMP PARALLEL DO + DO J = 1,N + A(J) = J + END DO + !$OMP END PARALLEL DO + ENDIF + END DO + !$OMP END PARALLEL DO SIMD + + !$OMP TARGET SIMD + DO I = 1,N + !$OMP ATOMIC + K = K + 1 + IF (I <= 10) THEN + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp task + do J = 1, N + K = 2 + end do + !$omp end task + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$omp target + do J = 1, N + K = 2 + end do + !$omp end target + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$OMP DO + DO J = 1,N + A(J) = J + END DO + !$OMP END DO + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !$OMP PARALLEL DO + DO J = 1,N + A(J) = J + END DO + !$OMP END PARALLEL DO + ENDIF + END DO + !$OMP END TARGET SIMD + + +END SUBROUTINE NESTED_BAD diff --git a/flang/test/SemanticsChecked/OpenMP/nested-target.f90 b/flang/test/SemanticsChecked/OpenMP/nested-target.f90 new file mode 100644 index 00000000000000..2267f70715d3ed --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-target.f90 @@ -0,0 +1,53 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror -pedantic + +! OpenMP Version 5.0 +! Check OpenMP construct validity for the following directives: +! 2.12.5 Target Construct + +program main + integer :: i, j, N = 10 + real :: a, arrayA(512), arrayB(512), ai(10) + real, allocatable :: B(:) + + !$omp target + !PORTABILITY: If TARGET UPDATE directive is nested inside TARGET region, the behaviour is unspecified + !$omp target update from(arrayA) to(arrayB) + do i = 1, 512 + arrayA(i) = arrayB(i) + end do + !$omp end target + + !$omp parallel + !$omp target + !$omp parallel + !PORTABILITY: If TARGET UPDATE directive is nested inside TARGET region, the behaviour is unspecified + !$omp target update from(arrayA) to(arrayB) + do i = 1, 512 + arrayA(i) = arrayB(i) + end do + !$omp end parallel + !$omp end target + !$omp end parallel + + !$omp target + !PORTABILITY: If TARGET DATA directive is nested inside TARGET region, the behaviour is unspecified + !$omp target data map(to: a) + do i = 1, N + a = 3.14 + end do + !$omp end target data + !$omp end target + + allocate(B(N)) + !$omp target + !PORTABILITY: If TARGET ENTER DATA directive is nested inside TARGET region, the behaviour is unspecified + !$omp target enter data map(alloc:B) + !$omp end target + + !$omp target + !PORTABILITY: If TARGET EXIT DATA directive is nested inside TARGET region, the behaviour is unspecified + !$omp target exit data map(delete:B) + !$omp end target + deallocate(B) + +end program main diff --git a/flang/test/SemanticsChecked/OpenMP/nested-teams.f90 b/flang/test/SemanticsChecked/OpenMP/nested-teams.f90 new file mode 100644 index 00000000000000..80c59e07fbaa68 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested-teams.f90 @@ -0,0 +1,112 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 5.0 +! Check OpenMP construct validity for the following directives: +! 2.7 Teams Construct + +program main + integer :: i, j, N = 10 + real :: a, b, c + + !$omp teams + a = 3.14 + !$omp end teams + + !$omp target + !$omp teams + a = 3.14 + !$omp end teams + !$omp end target + + !$omp target + !$omp parallel + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + !$omp end parallel + !$omp end target + + !$omp parallel + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + !$omp end parallel + + !$omp do + do i = 1, N + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + end do + + !$omp master + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + !$omp end master + + !$omp target parallel + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + !$omp end target parallel + + !$omp target + !$omp teams + !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region. + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + !$omp end teams + !$omp end target + + !$omp target teams + !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region + !$omp teams + a = 3.14 + !$omp end teams + !$omp end target teams + + !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct + !$omp target + do i = 1, N + !$omp teams + a = 3.14 + !$omp end teams + enddo + !$omp end target + + !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct + !$omp target + if (i .GT. 1) then + if (j .GT. 1) then + !$omp teams + a = 3.14 + !$omp end teams + end if + end if + !$omp end target + + !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct + !$omp target + b = 3.14 + !$omp teams + a = 3.14 + !$omp end teams + !$omp end target + + !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct + !$omp target + !$omp teams + a = 3.14 + !$omp end teams + c = 3.14 + !$omp end target + +end program main diff --git a/flang/test/SemanticsChecked/OpenMP/nested01.f90 b/flang/test/SemanticsChecked/OpenMP/nested01.f90 new file mode 100644 index 00000000000000..49c964ab86aa6b --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nested01.f90 @@ -0,0 +1,40 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! Check OpenMP 2.17 Nesting of Regions + + N = 1024 + !$omp do + do i = 1, N + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp do + do j = 1, N + a = 3.14 + enddo + enddo + + !$omp do + do i = 1, N + !$omp target + do k = 1,N + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp do + do j = 1, N + a = 3.14 + enddo + enddo + !$omp end target + enddo + + + !$omp do + do i = 1, N + !$omp parallel + do k = 1,N + !$omp do + do j = 1, N + a = 3.14 + enddo + enddo + !$omp end parallel + enddo +end diff --git a/flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90 b/flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90 new file mode 100644 index 00000000000000..fb864fd32ef007 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90 @@ -0,0 +1,28 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +subroutine bug48308(x,i) + real :: x(:) + integer :: i + !$omp parallel firstprivate(i) + do while (i>0) + x(i) = i + i = i - 1 + end do + !$omp end parallel +end subroutine + +subroutine s1(x,i) + real :: x(:) + integer :: i + !$omp parallel firstprivate(i) + do i = 10, 1, -1 + x(i) = i + end do + !$omp end parallel + + !$omp parallel firstprivate(i) + do concurrent (i = 1:10:1) + x(i) = i + end do + !$omp end parallel +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/nontemporal.f90 b/flang/test/SemanticsChecked/OpenMP/nontemporal.f90 new file mode 100644 index 00000000000000..6d24849575ee93 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/nontemporal.f90 @@ -0,0 +1,95 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! REQUIRES: shell +! Check OpenMP clause validity for NONTEMPORAL clause + +program omp_simd + integer i + integer, allocatable :: a(:) + + allocate(a(10)) + + !$omp simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end parallel do simd + + !$omp parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end parallel do simd + + !ERROR: NONTEMPORAL clause is not allowed on the DO SIMD directive + !$omp do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end do simd + + !$omp taskloop simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end taskloop simd + + !$omp teams + !$omp distribute parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end distribute parallel do simd + !$omp end teams + + !$omp teams + !$omp distribute simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end distribute simd + !$omp end teams + + !$omp target parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target parallel do simd + + !$omp target simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target simd + + !$omp teams distribute simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end teams distribute simd + + !$omp teams distribute parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end teams distribute parallel do simd + + !$omp target teams distribute parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target teams distribute parallel do simd + + !$omp target teams distribute simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target teams distribute simd + + +end program omp_simd diff --git a/flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90 b/flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90 new file mode 100644 index 00000000000000..a346056dee383b --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90 @@ -0,0 +1,87 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! Semantic checks for various assignments related to atomic constructs + +program sample + use omp_lib + integer :: x, v + integer :: y(10) + integer, allocatable :: k + integer a(10) + type sample_type + integer :: y + integer :: m + endtype + type(sample_type) :: z + !$omp atomic read + v = x + + !$omp atomic read + !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4) + !ERROR: Expected scalar expression on the RHS of atomic assignment statement + v = y(1:3) + + !$omp atomic read + !ERROR: Expected scalar variable of intrinsic type on RHS of atomic assignment statement + v = x * (10 + x) + + !$omp atomic read + !ERROR: Expected scalar variable of intrinsic type on RHS of atomic assignment statement + v = 4 + + !$omp atomic read + !ERROR: k must not have ALLOCATABLE attribute + v = k + + !$omp atomic write + !ERROR: k must not have ALLOCATABLE attribute + k = x + + !$omp atomic update + !ERROR: k must not have ALLOCATABLE attribute + k = k + x * (v * x) + + !$omp atomic + !ERROR: k must not have ALLOCATABLE attribute + k = v * k + + !$omp atomic write + !ERROR: RHS expression on atomic assignment statement cannot access 'z%y' + z%y = x + z%y + + !$omp atomic write + !ERROR: RHS expression on atomic assignment statement cannot access 'x' + x = x + + !$omp atomic write + !ERROR: RHS expression on atomic assignment statement cannot access 'm' + m = min(m, x, z%m) + k + + !$omp atomic read + !ERROR: RHS expression on atomic assignment statement cannot access 'x' + x = x + + !$omp atomic read + !ERROR: Expected scalar variable of intrinsic type on RHS of atomic assignment statement + !ERROR: RHS expression on atomic assignment statement cannot access 'm' + m = min(m, x, z%m) + k + + !$omp atomic read + !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4) + !ERROR: Expected scalar expression on the RHS of atomic assignment statement + x = a + + !$omp atomic read + !ERROR: Expected scalar variable on the LHS of atomic assignment statement + a = x + + !$omp atomic write + !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4) + !ERROR: Expected scalar expression on the RHS of atomic assignment statement + x = a + + !$omp atomic write + !ERROR: Expected scalar variable on the LHS of atomic assignment statement + a = x +end program diff --git a/flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90 b/flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90 new file mode 100644 index 00000000000000..81f87d8239e534 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90 @@ -0,0 +1,14 @@ +! RUN: not %flang_fc1 -fdebug-unparse-with-symbols -fopenmp %s 2>&1 | FileCheck %s +! OpenMP Version 4.5 +! 2.7.1 Loop Construct +program omp_doCollapse + integer:: i + !$omp parallel do collapse(2) + do i = 1, 3 + !CHECK: Loop control is not present in the DO LOOP + !CHECK: associated with the enclosing LOOP construct + do + end do + end do +end program omp_doCollapse + diff --git a/flang/test/SemanticsChecked/OpenMP/order-clause01.f90 b/flang/test/SemanticsChecked/OpenMP/order-clause01.f90 new file mode 100644 index 00000000000000..247791fac15b49 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/order-clause01.f90 @@ -0,0 +1,10 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp + +subroutine omp_order() + integer :: i, j = 1 + !ERROR: At most one ORDER clause can appear on the SIMD directive + !$omp simd order(concurrent) order(concurrent) + do i=1,10 + j = j + 1 + end do +end subroutine omp_order diff --git a/flang/test/SemanticsChecked/OpenMP/ordered-simd.f90 b/flang/test/SemanticsChecked/OpenMP/ordered-simd.f90 new file mode 100644 index 00000000000000..c33ec745f2dda1 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/ordered-simd.f90 @@ -0,0 +1,148 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! Various checks with the ordered construct + +SUBROUTINE WORK(I) + INTEGER I +END SUBROUTINE WORK + +SUBROUTINE ORDERED_GOOD(N) + INTEGER N, I, A(10), B(10), C(10) + !$OMP SIMD + DO I = 1,N + IF (I <= 10) THEN + !$OMP ORDERED SIMD + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END SIMD +END SUBROUTINE ORDERED_GOOD + +SUBROUTINE ORDERED_BAD(N) + INTEGER N, I, A(10), B(10), C(10) + + !$OMP DO SIMD + DO I = 1,N + IF (I <= 10) THEN + !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause. + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END DO SIMD + + !$OMP PARALLEL DO + DO I = 1,N + IF (I <= 10) THEN + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END PARALLEL DO + + !$OMP CRITICAL + DO I = 1,N + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END CRITICAL + + !$OMP CRITICAL + WRITE(*,*) I + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + !$OMP END CRITICAL + + !$OMP ORDERED + WRITE(*,*) I + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + !$OMP END ORDERED + + !$OMP TASK + C = C - A * B + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + !$OMP END TASK + + !$OMP TASKLOOP + DO I = 1,N + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END TASKLOOP + + !$OMP CRITICAL + C = C - A * B + !$OMP MASTER + DO I = 1,N + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + END DO + !$OMP END MASTER + !$OMP END CRITICAL + + !$OMP ORDERED + C = C - A * B + !$OMP MASTER + DO I = 1,N + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + END DO + !$OMP END MASTER + !$OMP END ORDERED + + !$OMP TASK + C = C - A * B + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$OMP MASTER + DO I = 1,N + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + END DO + !$OMP END MASTER + !$OMP END TASK + + !$OMP TASKLOOP + DO J= 1,N + C = C - A * B + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$OMP MASTER + DO I = 1,N + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + END DO + !$OMP END MASTER + END DO + !$OMP END TASKLOOP + +END SUBROUTINE ORDERED_BAD diff --git a/flang/test/SemanticsChecked/OpenMP/ordered01.f90 b/flang/test/SemanticsChecked/OpenMP/ordered01.f90 new file mode 100644 index 00000000000000..9433120fab10f6 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/ordered01.f90 @@ -0,0 +1,80 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.19.9 Ordered Construct + +program main + integer :: i, N = 10 + real :: a, arrayA(10), arrayB(10), arrayC(10) + real, external :: foo, bar, baz + + !$omp do ordered + do i = 1, N + !ERROR: At most one THREADS clause can appear on the ORDERED directive + !$omp ordered threads threads + arrayA(i) = i + !$omp end ordered + end do + !$omp end do + + !$omp simd + do i = 1, N + !ERROR: At most one SIMD clause can appear on the ORDERED directive + !$omp ordered simd simd + arrayA(i) = i + !$omp end ordered + end do + !$omp end simd + + !$omp do simd ordered + do i = 1, N + !ERROR: At most one SIMD clause can appear on the ORDERED directive + !$omp ordered simd simd + arrayA(i) = i + !$omp end ordered + end do + !$omp end do simd + + !$omp do ordered(1) + do i = 2, N + !ERROR: Only DEPEND(SOURCE) or DEPEND(SINK: vec) are allowed when ORDERED construct is a standalone construct with no ORDERED region + !ERROR: At most one DEPEND(SOURCE) clause can appear on the ORDERED directive + !$omp ordered depend(source) depend(inout: arrayA) depend(source) + arrayA(i) = foo(i) + !ERROR: DEPEND(SOURCE) is not allowed when DEPEND(SINK: vec) is present on ORDERED directive + !ERROR: DEPEND(SOURCE) is not allowed when DEPEND(SINK: vec) is present on ORDERED directive + !ERROR: At most one DEPEND(SOURCE) clause can appear on the ORDERED directive + !$omp ordered depend(sink: i - 1) depend(source) depend(source) + arrayB(i) = bar(arrayA(i), arrayB(i-1)) + !ERROR: Only DEPEND(SOURCE) or DEPEND(SINK: vec) are allowed when ORDERED construct is a standalone construct with no ORDERED region + !ERROR: Only DEPEND(SOURCE) or DEPEND(SINK: vec) are allowed when ORDERED construct is a standalone construct with no ORDERED region + !$omp ordered depend(out: arrayC) depend(in: arrayB) + arrayC(i) = baz(arrayB(i-1)) + end do + !$omp end do + + !$omp do ordered(1) + do i = 2, N + !ERROR: DEPEND(*) clauses are not allowed when ORDERED construct is a block construct with an ORDERED region + !$omp ordered depend(source) + arrayA(i) = foo(i) + !$omp end ordered + !ERROR: DEPEND(*) clauses are not allowed when ORDERED construct is a block construct with an ORDERED region + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(arrayA(i), arrayB(i-1)) + !$omp end ordered + end do + !$omp end do + +contains + subroutine work1() + !ERROR: THREADS, SIMD clauses are not allowed when ORDERED construct is a standalone construct with no ORDERED region + !$omp ordered simd + end subroutine work1 + + subroutine work2() + !ERROR: THREADS, SIMD clauses are not allowed when ORDERED construct is a standalone construct with no ORDERED region + !$omp ordered threads + end subroutine work2 + +end program main diff --git a/flang/test/SemanticsChecked/OpenMP/ordered02.f90 b/flang/test/SemanticsChecked/OpenMP/ordered02.f90 new file mode 100644 index 00000000000000..ed320c82a9794f --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/ordered02.f90 @@ -0,0 +1,146 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.19.9 Ordered Construct + +subroutine sub1() + integer :: i, j, N = 10 + real :: arrayA(10), arrayB(10) + real, external :: foo, bar + + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + + !$omp ordered threads + arrayA(i) = foo(i) + !$omp end ordered + + !$omp ordered simd + arrayA(i) = foo(i) + !$omp end ordered + + !$omp sections + do i = 1, N + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end sections + + !$omp do ordered + do i = 1, N + arrayB(i) = bar(i) + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do + + !$omp sections + do i = 1, N + !ERROR: An ORDERED directive with SIMD clause must be closely nested in a SIMD or worksharing-loop SIMD region + !$omp ordered simd + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end sections + + !$omp do ordered + do i = 1, N + !$omp parallel + do j = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a SIMD, worksharing-loop, or worksharing-loop SIMD region + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end parallel + end do + !$omp end do + + !$omp do ordered + do i = 1, N + !$omp target parallel + do j = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a SIMD, worksharing-loop, or worksharing-loop SIMD region + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end target parallel + end do + !$omp end do + + !$omp do + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do + + !$omp do + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered threads + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do + + !$omp do ordered(1) + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do + + !$omp do ordered(1) + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered threads + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do + + !$omp parallel do ordered(1) + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end parallel do + + !$omp parallel do ordered(1) + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered threads + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end parallel do + + !$omp target parallel do ordered(1) + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end target parallel do + + !$omp target parallel do ordered(1) + do i = 1, N + !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter + !$omp ordered threads + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end target parallel do +end diff --git a/flang/test/SemanticsChecked/OpenMP/ordered03.f90 b/flang/test/SemanticsChecked/OpenMP/ordered03.f90 new file mode 100644 index 00000000000000..8dd4d035212d8a --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/ordered03.f90 @@ -0,0 +1,122 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.19.9 Ordered Construct + +subroutine sub1() + integer :: i, j, N = 10 + real :: arrayA(10), arrayB(10) + real, external :: foo, bar + + !$omp do ordered(1) + do i = 1, N + !$omp ordered depend(source) + arrayA(i) = foo(i) + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end do + + !$omp do ordered(1) + do i = 1, N + !$omp target + do j = 1, N + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(source) + arrayA(i) = foo(i) + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end target + end do + !$omp end do + + !$omp target + !$omp parallel do ordered(1) + do i = 1, N + !$omp ordered depend(source) + arrayA(i) = foo(i) + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end parallel do + !$omp end target + + !$omp target parallel do ordered(1) + do i = 1, N + !$omp ordered depend(source) + arrayA(i) = foo(i) + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end target parallel do + + !$omp target teams distribute parallel do ordered(1) + do i = 1, N + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(source) + arrayA(i) = foo(i) + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end target teams distribute parallel do + + !$omp do ordered + do i = 1, N + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(source) + arrayA(i) = foo(i) + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end do + + !$omp parallel do ordered + do i = 1, N + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(source) + arrayA(i) = foo(i) + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end parallel do + + !$omp target parallel do ordered + do i = 1, N + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(source) + arrayA(i) = foo(i) + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(sink: i - 1) + arrayB(i) = bar(i - 1) + end do + !$omp end target parallel do + + !$omp do ordered(1) + do i = 1, N + !ERROR: The number of variables in DEPEND(SINK: vec) clause does not match the parameter specified in ORDERED clause + !$omp ordered depend(sink: i - 1) depend(sink: i - 1, j) + arrayB(i) = bar(i - 1, j) + end do + !$omp end do + + !$omp do ordered(2) + do i = 1, N + do j = 1, N + !ERROR: The number of variables in DEPEND(SINK: vec) clause does not match the parameter specified in ORDERED clause + !$omp ordered depend(sink: i - 1) depend(sink: i - 1, j) + arrayB(i) = foo(i - 1) + bar(i - 1, j) + end do + end do + !$omp end do + + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(source) + + !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter + !$omp ordered depend(sink: i - 1) +end diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90 new file mode 100644 index 00000000000000..6e10b46dea9a00 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90 @@ -0,0 +1,18 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! Check that loop iteration variables are private and predetermined, even when +! nested inside parallel/critical constructs. + +!DEF: /test1 (Subroutine) Subprogram +subroutine test1 + !DEF: /test1/i ObjectEntity INTEGER(4) + integer i + + !$omp parallel default(none) + !$omp critical + !DEF: /test1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i = 1, 10 + end do + !$omp end critical + !$omp end parallel +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private01.f90 new file mode 100644 index 00000000000000..a3d332c95ed251 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-private01.f90 @@ -0,0 +1,20 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 parallel private Clause +program omp_parallel_private + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause + !$omp parallel private(my_var%array) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k + end do + !$omp end parallel +end program omp_parallel_private diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private02.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private02.f90 new file mode 100644 index 00000000000000..8cb72159d6ab5c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-private02.f90 @@ -0,0 +1,20 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 parallel private Clause +program omp_parallel_private + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + integer :: array(10) + + do i = 1, 10 + array(i) = i + end do + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause + !$omp parallel private(array(i)) + do i = 1, 10 + c(i) = a(i) + b(i) + k + array(i) = k + end do + !$omp end parallel +end program omp_parallel_private diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private03.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private03.f90 new file mode 100644 index 00000000000000..24a096302e53d8 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-private03.f90 @@ -0,0 +1,28 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 parallel private Clause +program omp_parallel_private + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + real :: arr(10) + integer :: intx = 10 + + do i = 1, 10 + arr(i) = 0.0 + end do + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause + !$omp parallel private(arr(i),intx) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k+intx + arr(i) = k + end do + !$omp end parallel +end program omp_parallel_private diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private04.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private04.f90 new file mode 100644 index 00000000000000..67a669c9882a53 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-private04.f90 @@ -0,0 +1,28 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 parallel private Clause +program omp_parallel_private + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + real :: arr(10) + integer :: intx = 10 + + do i = 1, 10 + arr(i) = 0.0 + end do + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause + !$omp parallel private(arr,intx,my_var%array(1)) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k+intx + arr(i) = k + end do + !$omp end parallel +end program omp_parallel_private diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90 new file mode 100644 index 00000000000000..39102175299bab --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90 @@ -0,0 +1,19 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! Check that loop iteration variables are private and predetermined, even when +! nested inside parallel/sections constructs. + +!DEF: /test1 (Subroutine) Subprogram +subroutine test1 + !DEF: /test1/i ObjectEntity INTEGER(4) + integer i + + !$omp parallel default(none) + !$omp sections + !$omp section + !DEF: /test1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i = 1, 10 + end do + !$omp end sections + !$omp end parallel +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90 new file mode 100644 index 00000000000000..6c5a053bf49c95 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90 @@ -0,0 +1,155 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang %openmp_flags +! OpenMP version 5.0.0 +! 2.13.3 parallel sections Construct +! The restrictions for the parallel construct and the sections construct apply +program OmpConstructSections01 + use omp_lib + integer :: section_count = 0 + integer, parameter :: NT = 4 + integer :: i, array(10) + type my_type + integer :: array(10) + end type my_type + type(my_type) :: my_var + print *, 'section_count', section_count + do i = 1, 10 + array(i) = i + end do +!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause +!$omp parallel sections shared(array(i)) +!$omp end parallel sections +!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause +!$omp parallel sections shared(my_var%array) +!$omp end parallel sections + +!ERROR: invalid branch into an OpenMP structured block +!ERROR: invalid branch into an OpenMP structured block +!ERROR: invalid branch into an OpenMP structured block + if (NT) 20, 30, 40 +!ERROR: invalid branch into an OpenMP structured block + goto 20 +!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause +!$omp parallel sections private(my_var%array) + !$omp section + print *, "This is a single statement structured block" + !$omp section + open (10, file="random-file-name.txt", err=30) + !ERROR: invalid branch into an OpenMP structured block + !ERROR: invalid branch leaving an OpenMP structured block + open (10, file="random-file-name.txt", err=40) + !$omp section + section_count = section_count + 1 +20 print *, 'Entering into section' + call calledFromWithinSection() + print *, 'section_count', section_count + !$omp section + section_count = section_count + 1 + print *, 'section_count', section_count + !ERROR: invalid branch leaving an OpenMP structured block + goto 10 + !$omp section +30 print *, "Error in opening file" +!$omp end parallel sections +10 print *, 'Jump from section' +!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause +!$omp parallel sections private(array(i)) + !$omp section +40 print *, 'Error in opening file' +!$omp end parallel sections +end program OmpConstructSections01 + +function returnFromSections() + !$omp parallel sections + !$omp section + !ERROR: RETURN statement is not allowed in a PARALLEL SECTIONS construct + RETURN + !$omp end parallel sections +end function + +subroutine calledFromWithinSection() + print *, "I am called from within a 'section' structured block" + return +end subroutine calledFromWithinSection + +subroutine continueWithinSections() + integer i + do i = 1, 10 + print *, "Statement within loop but outside section construct" + !$omp parallel sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: CYCLE to construct outside of PARALLEL SECTIONS construct is not allowed + CYCLE + END IF + !$omp end parallel sections + print *, "Statement within loop but outside section contruct" + end do + + !$omp parallel sections + !$omp section + do i = 1, 10 + CYCLE + end do + !$omp end parallel sections + + !$omp parallel sections + !$omp section + loop_1: do i = 1, 10 + IF (i .EQ. 5) THEN + CYCLE loop_1 + END IF + end do loop_1 + !$omp end parallel sections + + loop_2: do i = 1, 10 + !$omp parallel sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: CYCLE to construct 'loop_2' outside of PARALLEL SECTIONS construct is not allowed + CYCLE loop_2 + END IF + !$omp end parallel sections + end do loop_2 +end subroutine continueWithinSections + +subroutine breakWithinSections() + loop_3: do i = 1, 10 + !$omp parallel sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: EXIT to construct 'loop_3' outside of PARALLEL SECTIONS construct is not allowed + EXIT loop_3 + END IF + !$omp end parallel sections + end do loop_3 + + loop_4: do i = 1, 10 + !$omp parallel sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: EXIT to construct outside of PARALLEL SECTIONS construct is not allowed + EXIT + END IF + !$omp end parallel sections + end do loop_4 + + !$omp parallel sections + !$omp section + do i = 1, 10 + IF (i .EQ. 5) THEN + EXIT + END IF + end do + !$omp end parallel sections + + !$omp parallel sections + !$omp section + loop_5: do i = 1, 10 + IF (i .EQ. 5) THEN + EXIT loop_5 + END IF + end do loop_5 + !$omp end parallel sections +end subroutine breakWithinSections diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90 new file mode 100644 index 00000000000000..7abfe1f7b16374 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90 @@ -0,0 +1,20 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.2 parallel shared Clause +program omp_parallel_shared + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause + !$omp parallel shared(my_var%array) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k + end do + !$omp end parallel +end program omp_parallel_shared diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90 new file mode 100644 index 00000000000000..f59f5236dfd932 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90 @@ -0,0 +1,20 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.2 parallel shared Clause +program omp_parallel_shared + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + integer :: array(10) + + do i = 1, 10 + array(i) = i + end do + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause + !$omp parallel shared(array(i)) + do i = 1, 10 + c(i) = a(i) + b(i) + k + array(i) = k + end do + !$omp end parallel +end program omp_parallel_shared diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90 new file mode 100644 index 00000000000000..3d9111c7aaf106 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90 @@ -0,0 +1,28 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.2 parallel shared Clause +program omp_parallel_shared + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + real :: arr(10) + integer :: intx = 10 + + do i = 1, 10 + arr(i) = 0.0 + end do + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause + !$omp parallel shared(arr(i),intx) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k+intx + arr(i) = k + end do + !$omp end parallel +end program omp_parallel_shared diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90 new file mode 100644 index 00000000000000..06b7fcfa01d7ab --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90 @@ -0,0 +1,28 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.2 parallel shared Clause +program omp_parallel_shared + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + real :: arr(10) + integer :: intx = 10 + + do i = 1, 10 + arr(i) = 0.0 + end do + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause + !$omp parallel shared(arr,intx,my_var%array(1)) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k+intx + arr(i) = k + end do + !$omp end parallel +end program omp_parallel_shared diff --git a/flang/test/SemanticsChecked/OpenMP/parallel01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel01.f90 new file mode 100644 index 00000000000000..6d5dd581a9f233 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel01.f90 @@ -0,0 +1,23 @@ +! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s +! OpenMP Version 4.5 +! 2.5 parallel construct. +! A program that branches into or out of a parallel region +! is non-conforming. + +program omp_parallel + integer i, j, k + + !$omp parallel + do i = 1, 10 + do j = 1, 10 + print *, "Hello" + !CHECK: invalid branch leaving an OpenMP structured block + goto 10 + end do + end do + !$omp end parallel + + !CHECK: Outside the enclosing PARALLEL directive + 10 stop + +end program omp_parallel diff --git a/flang/test/SemanticsChecked/OpenMP/parallel02.f90 b/flang/test/SemanticsChecked/OpenMP/parallel02.f90 new file mode 100644 index 00000000000000..eff0e7c70d1a0c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/parallel02.f90 @@ -0,0 +1,23 @@ +! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s +! OpenMP Version 4.5 +! 2.5 parallel construct. +! A program that branches into or out of a parallel region +! is non-conforming. + +program omp_parallel + integer i, j, k + + !CHECK: invalid branch into an OpenMP structured block + goto 10 + + !$omp parallel + do i = 1, 10 + do j = 1, 10 + print *, "Hello" + !CHECK: In the enclosing PARALLEL directive branched into + 10 stop + end do + end do + !$omp end parallel + +end program omp_parallel diff --git a/flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90 b/flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90 new file mode 100644 index 00000000000000..7b3915d9a1104f --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90 @@ -0,0 +1,18 @@ +! RUN: %flang_fc1 -fopenmp -fsyntax-only %s + +subroutine s + integer, pointer :: p + integer, target :: t + real(4), allocatable :: arr + + !$omp parallel private(p) + p=>t + !$omp end parallel + + allocate(arr) + !$omp parallel private(arr) + if (.not. allocated(arr)) then + print *, 'not allocated' + endif + !$omp end parallel +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/private01.f90 b/flang/test/SemanticsChecked/OpenMP/private01.f90 new file mode 100644 index 00000000000000..052823a9f78a6d --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/private01.f90 @@ -0,0 +1,20 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 private Clause +! Pointers with the INTENT(IN) attribute may not appear in a private clause. + +subroutine omp_private(p) + integer :: a(10), b(10), c(10) + integer, pointer, intent(in) :: p + + a = 10 + b = 20 + + !ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a PRIVATE clause + !$omp parallel private(p) + c = a + b + p + !$omp end parallel + + print *, c + +end subroutine omp_private diff --git a/flang/test/SemanticsChecked/OpenMP/private02.f90 b/flang/test/SemanticsChecked/OpenMP/private02.f90 new file mode 100644 index 00000000000000..a81e31998eebb6 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/private02.f90 @@ -0,0 +1,46 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 private Clause +! Variables that appear in namelist statements may not appear in a private clause. + +module test + integer :: a, b, c + namelist /nlist1/ a, b +end module + +program omp_private + use test + + integer :: p(10) ,q(10) + namelist /nlist2/ c, d + + a = 5 + b = 10 + c = 100 + + !ERROR: Variable 'a' in NAMELIST cannot be in a PRIVATE clause + !ERROR: Variable 'c' in NAMELIST cannot be in a PRIVATE clause + !$omp parallel private(a, c) + d = a + b + !$omp end parallel + + call sb() + + contains + subroutine sb() + namelist /nlist3/ p, q + + !ERROR: Variable 'p' in NAMELIST cannot be in a PRIVATE clause + !ERROR: Variable 'd' in NAMELIST cannot be in a PRIVATE clause + !$omp parallel private(p, d) + p = c * b + q = p * d + !$omp end parallel + + write(*, nlist1) + write(*, nlist2) + write(*, nlist3) + + end subroutine + +end program omp_private diff --git a/flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90 b/flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90 new file mode 100644 index 00000000000000..d4034743a14dc7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90 @@ -0,0 +1,13 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.2 +! Minus operation is deprecated in reduction + +subroutine reduction_subtract + integer :: x + !ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause. + !$omp do reduction(-:x) + do i=1, 100 + x = x - i + end do + !$omp end do +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/reduction01.f90 b/flang/test/SemanticsChecked/OpenMP/reduction01.f90 new file mode 100644 index 00000000000000..0e1a8a571c5847 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction01.f90 @@ -0,0 +1,14 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + integer :: i + integer :: k = 10 + + !ERROR: Invalid reduction operator in REDUCTION clause. + !$omp parallel do reduction(**:k) + do i = 1, 10 + k = k ** 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction02.f90 b/flang/test/SemanticsChecked/OpenMP/reduction02.f90 new file mode 100644 index 00000000000000..4fd9fbe2d8a53d --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction02.f90 @@ -0,0 +1,43 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + + integer :: i + integer :: k = 10 + integer :: j = 10 + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:k), reduction(*:k) + do i = 1, 10 + k = k + 1 + k = k * 3 + end do + !$omp end parallel do + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:k), reduction(*:j), reduction(+:k) + do i = 1, 10 + k = k + 1 + j = j * 3 + end do + !$omp end parallel do + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:j), reduction(*:k), reduction(+:k) + do i = 1, 10 + j = j + 1 + k = k + 1 + k = k * 3 + end do + !$omp end parallel do + + !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel do reduction(+:j), reduction(*:k), private(k) + do i = 1, 10 + j = j + 1 + k = k + 1 + k = k * 3 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction03.f90 b/flang/test/SemanticsChecked/OpenMP/reduction03.f90 new file mode 100644 index 00000000000000..1ddc2903fecc4e --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction03.f90 @@ -0,0 +1,18 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause + +subroutine omp_target(p) + integer, pointer, intent(in) :: p + + integer :: i + integer :: k = 10 + + !ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a REDUCTION clause + !$omp parallel do reduction(+:p) + do i = 1, 10 + k= k + 1 + end do + !$omp end parallel do + +end subroutine omp_target diff --git a/flang/test/SemanticsChecked/OpenMP/reduction04.f90 b/flang/test/SemanticsChecked/OpenMP/reduction04.f90 new file mode 100644 index 00000000000000..319ed9f245abe8 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction04.f90 @@ -0,0 +1,24 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_Reduction + integer :: i + integer, parameter :: k = 10 + common /c/ a, b + + !ERROR: Variable 'k' on the REDUCTION clause is not definable + !BECAUSE: 'k' is not a variable + !$omp parallel do reduction(+:k) + do i = 1, 10 + l = k + 1 + end do + !$omp end parallel do + + !ERROR: Variable 'c' on the REDUCTION clause is not definable + !BECAUSE: 'c' is not a variable + !$omp parallel do reduction(*:/c/) + do i = 1, 10 + l = k + 1 + end do + !$omp end parallel do +end program omp_Reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction05.f90 b/flang/test/SemanticsChecked/OpenMP/reduction05.f90 new file mode 100644 index 00000000000000..aa115ed7454ba2 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction05.f90 @@ -0,0 +1,38 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause + +program omp_reduction + + integer :: i + integer :: k = 10 + integer :: a(10),b(10,10,10) + + !ERROR: 'a' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:a(1:0:2)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'a' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:a(1:0)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'b' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:b(1:6,5,1:0)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: 'b' in REDUCTION clause is a zero size array section + !$omp parallel do reduction(+:b(1:6,1:0:5,1:10)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction06.f90 b/flang/test/SemanticsChecked/OpenMP/reduction06.f90 new file mode 100644 index 00000000000000..58290c61cae860 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction06.f90 @@ -0,0 +1,31 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause + +program omp_reduction + + integer :: i + integer :: k = 10 + integer :: a(10), b(10,10,10) + + !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !$omp parallel do reduction(+:a(1:10:3)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !$omp parallel do reduction(+:b(1:10:3,1:8:1,1:5:1)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do + + !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !$omp parallel do reduction(+:b(1:10:1,1:8:2,1:5:1)) + do i = 1, 10 + k = k + 1 + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction07.f90 b/flang/test/SemanticsChecked/OpenMP/reduction07.f90 new file mode 100644 index 00000000000000..98ed69a8d846d4 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction07.f90 @@ -0,0 +1,101 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + + integer :: a,i,j,l + integer :: k = 10 + !$omp parallel private(k) + !ERROR: REDUCTION variable 'k' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(+:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + !$omp end parallel + + + !$omp parallel private(j),reduction(+:k) + !ERROR: REDUCTION variable 'k' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(+:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + !$omp end parallel + + !$omp parallel private(j),firstprivate(k) + !ERROR: REDUCTION variable 'k' is FIRSTPRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(min:k) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + !$omp end parallel + + + !$omp parallel private(l,j),firstprivate(k) + !ERROR: REDUCTION variable 'k' is FIRSTPRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !ERROR: REDUCTION variable 'j' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp sections reduction(ior:k) reduction(*:j) + do i = 1, 10 + k = ior(k, 1) + j = j * 3 + end do + !$omp end sections + !$omp end parallel + +!$omp sections private(k) + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !ERROR: REDUCTION variable 'k' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. + !$omp do reduction(+:k) reduction(max:j) + do i = 1, 10 + k = k + 1 + end do + !$omp end do +!$omp end sections + +!$omp sections private(k) + !$omp target + do j = 1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp do reduction(+:k) reduction(max:j) + do i = 1, 10 + k = k + 1 + end do + !$omp end do + end do + !$omp end target +!$omp end sections + +!$omp parallel reduction(+:a) +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp sections reduction(*:a) +a = a + 10 +!$omp end sections +!$omp end parallel + +!$omp parallel reduction(*:a) +!$omp end parallel + +!$omp parallel reduction(ieor:a) +!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. +!$omp sections reduction(+:a) +a = ieor(a, 10) +!$omp end sections +!$omp end parallel + +!$omp parallel private(a) +!$omp parallel reduction(ieor:a) +!$omp end parallel +!$omp end parallel + +!$omp task firstprivate(a) +!$omp parallel do reduction(+:a) +do i=1,10 + a=a+j +end do +!$omp end parallel do +!$omp end task + +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction08.f90 b/flang/test/SemanticsChecked/OpenMP/reduction08.f90 new file mode 100644 index 00000000000000..99163327cdafa6 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction08.f90 @@ -0,0 +1,63 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause Positive cases + +!DEF: /omp_reduction MainProgram +program omp_reduction + !DEF: /omp_reduction/i ObjectEntity INTEGER(4) + integer i + !DEF: /omp_reduction/k ObjectEntity INTEGER(4) + integer :: k = 10 + !DEF: /omp_reduction/m ObjectEntity INTEGER(4) + integer :: m = 12 + !$omp parallel do reduction(max:k) + !DEF: /omp_reduction/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct1/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/max ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = max(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(min:k) + !DEF: /omp_reduction/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct2/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/min ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = min(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(iand:k) + !DEF: /omp_reduction/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct3/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/iand ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = iand(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(ior:k) + !DEF: /omp_reduction/OtherConstruct4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct4/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/ior ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = ior(k, m) + end do + !$omp end parallel do + + !$omp parallel do reduction(ieor:k) + !DEF: /omp_reduction/OtherConstruct5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct5/k (OmpReduction) HostAssoc INTEGER(4) + !DEF: /omp_reduction/ieor ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /omp_reduction/m + k = ieor(k,m) + end do + !$omp end parallel do + +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction09.f90 b/flang/test/SemanticsChecked/OpenMP/reduction09.f90 new file mode 100644 index 00000000000000..095b49ba0c400f --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction09.f90 @@ -0,0 +1,86 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause Positive cases. +!DEF: /omp_reduction MainProgram +program omp_reduction + !DEF: /omp_reduction/i ObjectEntity INTEGER(4) + integer i + !DEF: /omp_reduction/k ObjectEntity INTEGER(4) + integer :: k = 10 + !DEF: /omp_reduction/a ObjectEntity INTEGER(4) + integer a(10) + !DEF: /omp_reduction/b ObjectEntity INTEGER(4) + integer b(10,10,10) + + !$omp parallel shared(k) + !$omp do reduction(+:k) + !DEF: /omp_reduction/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct1/OtherConstruct1/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + !$omp end parallel + + + !$omp parallel do reduction(+:a(10)) + !DEF: /omp_reduction/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + + !$omp parallel do reduction(+:a(1:10:1)) + !DEF: /omp_reduction/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + !$omp parallel do reduction(+:b(1:10:1,1:5,2)) + !DEF: /omp_reduction/OtherConstruct4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + !$omp parallel do reduction(+:b(1:10:1,1:5,2:5:1)) + !DEF: /omp_reduction/OtherConstruct5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /omp_reduction/k + k = k+1 + end do + !$omp end parallel do + + !$omp parallel private(i) + !$omp do reduction(+:k) reduction(+:j) + !DEF: /omp_reduction/OtherConstruct6/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct6/OtherConstruct1/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + !$omp end parallel + + !$omp do reduction(+:k) reduction(*:j) reduction(+:l) + !DEF: /omp_reduction/OtherConstruct7/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct7/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + + + !$omp do reduction(.and.:k) reduction(.or.:j) reduction(.eqv.:l) + !DEF: /omp_reduction/OtherConstruct8/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_reduction/OtherConstruct8/k (OmpReduction) HostAssoc INTEGER(4) + k = k+1 + end do + !$omp end do + +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction10.f90 b/flang/test/SemanticsChecked/OpenMP/reduction10.f90 new file mode 100644 index 00000000000000..0f94594408b884 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction10.f90 @@ -0,0 +1,15 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.6 Reduction Clause +program omp_reduction + + integer :: i + integer :: k = 10 + + !ERROR: Invalid reduction identifier in REDUCTION clause. + !$omp parallel do reduction(foo:k) + do i = 1, 10 + k = foo(k) + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction11.f90 b/flang/test/SemanticsChecked/OpenMP/reduction11.f90 new file mode 100644 index 00000000000000..3893fe70b407f4 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction11.f90 @@ -0,0 +1,22 @@ +! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols -o - %s 2>&1 | FileCheck %s +! Check intrinsic reduction symbols (in this case "max" are marked as INTRINSIC + +! CHECK: MainProgram scope: omp_reduction +program omp_reduction + ! CHECK: i size=4 offset=0: ObjectEntity type: INTEGER(4) + integer i + ! CHECK: k size=4 offset=4: ObjectEntity type: INTEGER(4) init:10_4 + integer :: k = 10 + ! CHECK: m size=4 offset=8: ObjectEntity type: INTEGER(4) init:12_4 + integer :: m = 12 + + ! CHECK: OtherConstruct scope + ! CHECK: i (OmpPrivate, OmpPreDetermined): HostAssoc + ! CHECK: k (OmpReduction): HostAssoc + ! CHECK: max, INTRINSIC: ProcEntity + !$omp parallel do reduction(max:k) + do i=1,10 + k = i + end do + !$omp end parallel do +end program omp_reduction diff --git a/flang/test/SemanticsChecked/OpenMP/reduction12.f90 b/flang/test/SemanticsChecked/OpenMP/reduction12.f90 new file mode 100644 index 00000000000000..f896ca4aa60b67 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/reduction12.f90 @@ -0,0 +1,16 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp + +! OpenMP 5.2: Section 5.5.5 : A procedure pointer must not appear in a +! reduction clause. + + procedure(foo), pointer :: ptr + integer :: i + ptr => foo +!ERROR: A procedure pointer 'ptr' must not appear in a REDUCTION clause. +!$omp do reduction (+ : ptr) + do i = 1, 10 + end do +contains + subroutine foo + end subroutine +end diff --git a/flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90 b/flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90 new file mode 100644 index 00000000000000..b39c9cdcc0bb33 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90 @@ -0,0 +1,109 @@ +! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s +! Ensure that requires atomic_default_mem_order is used to update atomic +! operations with no explicit memory order set. +program requires + implicit none + !$omp requires atomic_default_mem_order(seq_cst) + integer :: i, j + + ! ---------------------------------------------------------------------------- + ! READ + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead + ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst + !$omp atomic read + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed read + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic read relaxed + i = j + + ! ---------------------------------------------------------------------------- + ! WRITE + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite + ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst + !$omp atomic write + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed write + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic write relaxed + i = j + + ! ---------------------------------------------------------------------------- + ! UPDATE + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate + ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst + !$omp atomic update + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed update + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic update relaxed + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic + ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst + !$omp atomic + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed + i = i + j + + ! ---------------------------------------------------------------------------- + ! CAPTURE + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture + ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst + !$omp atomic capture + i = j + i = j + !$omp end atomic + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed capture + i = j + i = j + !$omp end atomic + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic capture relaxed + i = j + i = j + !$omp end atomic +end program requires diff --git a/flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90 b/flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90 new file mode 100644 index 00000000000000..3af83970e7927a --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90 @@ -0,0 +1,109 @@ +! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s +! Ensure that requires atomic_default_mem_order is used to update atomic +! operations with no explicit memory order set. ACQ_REL clause tested here. +program requires + implicit none + !$omp requires atomic_default_mem_order(acq_rel) + integer :: i, j + + ! ---------------------------------------------------------------------------- + ! READ + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Acquire + !$omp atomic read + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Acquire + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed read + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Acquire + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic read relaxed + i = j + + ! ---------------------------------------------------------------------------- + ! WRITE + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Release + !$omp atomic write + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed write + i = j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic write relaxed + i = j + + ! ---------------------------------------------------------------------------- + ! UPDATE + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Release + !$omp atomic update + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed update + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic update relaxed + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Release + !$omp atomic + i = i + j + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed + i = i + j + + ! ---------------------------------------------------------------------------- + ! CAPTURE + ! ---------------------------------------------------------------------------- + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture + ! CHECK: OmpMemoryOrderClause -> OmpClause -> AcqRel + !$omp atomic capture + i = j + i = j + !$omp end atomic + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> AcqRel + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic relaxed capture + i = j + i = j + !$omp end atomic + + ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture + ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> AcqRel + ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed + !$omp atomic capture relaxed + i = j + i = j + !$omp end atomic +end program requires diff --git a/flang/test/SemanticsChecked/OpenMP/requires01.f90 b/flang/test/SemanticsChecked/OpenMP/requires01.f90 new file mode 100644 index 00000000000000..007135749cc823 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires01.f90 @@ -0,0 +1,7 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +!$omp requires reverse_offload unified_shared_memory + +!ERROR: NOWAIT clause is not allowed on the REQUIRES directive +!$omp requires nowait +end diff --git a/flang/test/SemanticsChecked/OpenMP/requires02.f90 b/flang/test/SemanticsChecked/OpenMP/requires02.f90 new file mode 100644 index 00000000000000..974bcceb10c6f1 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires02.f90 @@ -0,0 +1,17 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! All atomic_default_mem_order clauses in 'requires' directives must come +! strictly before any atomic directives on which the memory_order clause is not +! specified. + +subroutine f + integer :: a = 0 + !$omp atomic + a = a + 1 +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'ATOMIC_DEFAULT_MEM_ORDER' clause found lexically after atomic operation without a memory order clause + !$omp requires atomic_default_mem_order(relaxed) +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires03.f90 b/flang/test/SemanticsChecked/OpenMP/requires03.f90 new file mode 100644 index 00000000000000..4a23a6a4105fe2 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires03.f90 @@ -0,0 +1,21 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! Target-related clauses in 'requires' directives must come strictly before any +! device constructs, such as target regions. + +subroutine f + !$omp target + !$omp end target +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct + !$omp requires dynamic_allocators + !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct + !$omp requires reverse_offload + !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct + !$omp requires unified_address + !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct + !$omp requires unified_shared_memory +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires04.f90 b/flang/test/SemanticsChecked/OpenMP/requires04.f90 new file mode 100644 index 00000000000000..bb4101c1cbd6c4 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires04.f90 @@ -0,0 +1,23 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! Target-related clauses in 'requires' directives must come strictly before any +! device constructs, such as declare target with device_type=nohost|any. + +subroutine f + integer, save :: x + !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. + !$omp declare target to(x) device_type(nohost) + !$omp declare target enter(x) device_type(nohost) +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct + !$omp requires dynamic_allocators + !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct + !$omp requires reverse_offload + !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct + !$omp requires unified_address + !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct + !$omp requires unified_shared_memory +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires05.f90 b/flang/test/SemanticsChecked/OpenMP/requires05.f90 new file mode 100644 index 00000000000000..dd27e3895e394c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires05.f90 @@ -0,0 +1,22 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! Target-related clauses in 'requires' directives must come strictly before any +! device constructs, such as declare target with 'to' clause and no device_type. + +subroutine f + !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead. + !$omp declare target to(f) + !$omp declare target enter(f) +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct + !$omp requires dynamic_allocators + !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct + !$omp requires reverse_offload + !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct + !$omp requires unified_address + !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct + !$omp requires unified_shared_memory +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires06.f90 b/flang/test/SemanticsChecked/OpenMP/requires06.f90 new file mode 100644 index 00000000000000..ba9bbf31b6e070 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires06.f90 @@ -0,0 +1,20 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! Target-related clauses in 'requires' directives must come strictly before any +! device constructs, such as declare target with extended list. + +subroutine f + !$omp declare target (f) +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct + !$omp requires dynamic_allocators + !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct + !$omp requires reverse_offload + !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct + !$omp requires unified_address + !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct + !$omp requires unified_shared_memory +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires07.f90 b/flang/test/SemanticsChecked/OpenMP/requires07.f90 new file mode 100644 index 00000000000000..2a36b4def9199c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires07.f90 @@ -0,0 +1,21 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! Target-related clauses in 'requires' directives must come strictly before any +! device constructs, such as target parallel regions. + +subroutine f + !$omp target parallel + !$omp end target parallel +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct + !$omp requires dynamic_allocators + !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct + !$omp requires reverse_offload + !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct + !$omp requires unified_address + !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct + !$omp requires unified_shared_memory +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires08.f90 b/flang/test/SemanticsChecked/OpenMP/requires08.f90 new file mode 100644 index 00000000000000..5f3b084078ccfd --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires08.f90 @@ -0,0 +1,23 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! Target-related clauses in 'requires' directives must come strictly before any +! device constructs, such as target teams distribute parallel do loops. + +subroutine f + !$omp target teams distribute parallel do + do i=1, 10 + end do + !$omp end target teams distribute parallel do +end subroutine f + +subroutine g + !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct + !$omp requires dynamic_allocators + !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct + !$omp requires reverse_offload + !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct + !$omp requires unified_address + !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct + !$omp requires unified_shared_memory +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/requires09.f90 b/flang/test/SemanticsChecked/OpenMP/requires09.f90 new file mode 100644 index 00000000000000..2fa5d950b9c2d8 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/requires09.f90 @@ -0,0 +1,14 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.4 Requires directive +! All atomic_default_mem_order clauses in 'requires' directives found within a +! compilation unit must specify the same ordering. + +subroutine f + !$omp requires atomic_default_mem_order(seq_cst) +end subroutine f + +!ERROR: Conflicting 'ATOMIC_DEFAULT_MEM_ORDER' REQUIRES clauses found in compilation unit +subroutine g + !$omp requires atomic_default_mem_order(relaxed) +end subroutine g diff --git a/flang/test/SemanticsChecked/OpenMP/resolve01.f90 b/flang/test/SemanticsChecked/OpenMP/resolve01.f90 new file mode 100644 index 00000000000000..79b67885b8b9c7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/resolve01.f90 @@ -0,0 +1,15 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! 2.4 An array section designates a subset of the elements in an array. Although +! Substring shares similar syntax but cannot be treated as valid array section. + + character*8 c, b + character a + + b = "HIFROMPGI" + c = b(2:7) + !ERROR: Substrings are not allowed on OpenMP directives or clauses + !$omp parallel private(c(1:3)) + a = c(1:1) + !$omp end parallel +end diff --git a/flang/test/SemanticsChecked/OpenMP/resolve02.f90 b/flang/test/SemanticsChecked/OpenMP/resolve02.f90 new file mode 100644 index 00000000000000..7c3d6331c82ae1 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/resolve02.f90 @@ -0,0 +1,18 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! Test the effect to name resolution from illegal clause + + !a = 1.0 + b = 2 + !$omp parallel private(a) shared(b) + a = 3. + b = 4 + !ERROR: LASTPRIVATE clause is not allowed on the PARALLEL directive + !ERROR: 'a' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel private(a) shared(b) lastprivate(a) + a = 5. + b = 6 + !$omp end parallel + !$omp end parallel + print *,a, b +end diff --git a/flang/test/SemanticsChecked/OpenMP/resolve03.f90 b/flang/test/SemanticsChecked/OpenMP/resolve03.f90 new file mode 100644 index 00000000000000..ebc66ca12ebf44 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/resolve03.f90 @@ -0,0 +1,47 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! 2.15.3 Although variables in common blocks can be accessed by use association +! or host association, common block names cannot. As a result, a common block +! name specified in a data-sharing attribute clause must be declared to be a +! common block in the same scoping unit in which the data-sharing attribute +! clause appears. + + common /c/ a, b + integer a(3), b + common /tc/ x + integer x + !$omp threadprivate(/tc/) + + A = 1 + B = 2 + block + !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears + !$omp parallel shared(/c/) + a(1:2) = 3 + B = 4 + !$omp end parallel + end block + print *, a, b + + !$omp parallel + block + !$omp single + x = 18 + !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears + !$omp end single copyprivate(/tc/) + end block + !$omp end parallel + + ! Common block names may be used inside nested OpenMP directives. + !$omp parallel + !$omp parallel copyin(/tc/) + x = x + 10 + !$omp end parallel + !$omp end parallel + + !$omp parallel + !$omp single + x = 18 + !$omp end single copyprivate(/tc/) + !$omp end parallel +end diff --git a/flang/test/SemanticsChecked/OpenMP/resolve04.f90 b/flang/test/SemanticsChecked/OpenMP/resolve04.f90 new file mode 100644 index 00000000000000..7c61950c57f665 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/resolve04.f90 @@ -0,0 +1,19 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! 2.15.3 Data-Sharing Attribute Clauses +! A list item that specifies a given variable may not appear in more than +! one clause on the same directive, except that a variable may be specified +! in both firstprivate and lastprivate clauses. + + common /c/ a, b + integer a(3), b + + A = 1 + B = 2 + !ERROR: 'c' appears in more than one data-sharing clause on the same OpenMP directive + !$omp parallel shared(/c/,c) private(/c/) + a(1:2) = 3 + B = 4 + !$omp end parallel + print *, a, b, c +end diff --git a/flang/test/SemanticsChecked/OpenMP/resolve05.f90 b/flang/test/SemanticsChecked/OpenMP/resolve05.f90 new file mode 100644 index 00000000000000..c4cebb48ac5c2b --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/resolve05.f90 @@ -0,0 +1,36 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! 2.15.3 Data-Sharing Attribute Clauses +! 2.15.3.1 default Clause + +subroutine default_none() + integer a(3) + integer, parameter :: D=10 + A = 1 + B = 2 + !$omp parallel default(none) private(c) + !ERROR: The DEFAULT(NONE) clause requires that 'a' must be listed in a data-sharing attribute clause + A(1:2) = 3 + !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-sharing attribute clause + B = 4 + C = 5 + D + !$omp end parallel +end subroutine default_none + +! Test that indices of sequential loops are privatised and hence do not error +! for DEFAULT(NONE) +subroutine default_none_seq_loop + integer :: i + + !$omp parallel do default(none) + do i = 1, 10 + do j = 1, 20 + enddo + enddo +end subroutine + +program mm + call default_none() + call default_none_seq_loop() + !TODO: private, firstprivate, shared +end diff --git a/flang/test/SemanticsChecked/OpenMP/resolve06.f90 b/flang/test/SemanticsChecked/OpenMP/resolve06.f90 new file mode 100644 index 00000000000000..358b1b1cc2826b --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/resolve06.f90 @@ -0,0 +1,56 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +use omp_lib +!2.11.4 Allocate Clause +!For any list item that is specified in the allocate +!clause on a directive, a data-sharing attribute clause +!that may create a private copy of that list item must be +!specified on the same directive. + + integer :: N = 2 + + !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive + !$omp parallel allocate(omp_default_mem_space : x) + do i = 1, N + x = 2 + enddo + !$omp end parallel + + !ERROR: The ALLOCATE clause requires that 'y' must be listed in a private data-sharing attribute clause on the same directive + !$omp parallel allocate(omp_default_mem_space : y) firstprivate(x) + do i = 1, N + x = 2 + enddo + !$omp end parallel + + !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive + !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive + !$omp parallel allocate(omp_default_mem_space : x) allocate(omp_default_mem_space : x) + do i = 1, N + x = 2 + enddo + !$omp end parallel + + !ERROR: The ALLOCATE clause requires that 'f' must be listed in a private data-sharing attribute clause on the same directive + !$omp parallel allocate(omp_default_mem_space : f) shared(f) + do i = 1, N + x = 2 + enddo + !$omp end parallel + + !ERROR: The ALLOCATE clause requires that 'q' must be listed in a private data-sharing attribute clause on the same directive + !$omp parallel private(t) allocate(omp_default_mem_space : z, t, q, r) firstprivate(z, r) + do i = 1, N + x = 2 + enddo + !$omp end parallel + + !ERROR: The ALLOCATE clause requires that 'b' must be listed in a private data-sharing attribute clause on the same directive + !ERROR: The ALLOCATE clause requires that 'c' must be listed in a private data-sharing attribute clause on the same directive + !$omp parallel allocate(omp_default_mem_space : a, b, c, d) firstprivate(a, d) + do i = 1, N + x = 2 + enddo + !$omp end parallel +end diff --git a/flang/test/SemanticsChecked/OpenMP/sections01.f90 b/flang/test/SemanticsChecked/OpenMP/sections01.f90 new file mode 100644 index 00000000000000..c26cc88dcc7af7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/sections01.f90 @@ -0,0 +1,15 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 4.5 +! 2.7.2 sections Construct +! Only a single nowait clause can appear on a sections directive. + +program omp_sections + + !$omp sections + !$omp section + print *, "omp section" + !ERROR: At most one NOWAIT clause can appear on the END SECTIONS directive + !$omp end sections nowait nowait + +end program omp_sections diff --git a/flang/test/SemanticsChecked/OpenMP/sections02.f90 b/flang/test/SemanticsChecked/OpenMP/sections02.f90 new file mode 100644 index 00000000000000..ee29922a72c081 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/sections02.f90 @@ -0,0 +1,139 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang %openmp_flags +! OpenMP version 5.0.0 +! 2.8.1 sections construct +! The code enclosed in a sections construct must be a structured block. +program OmpConstructSections01 + use omp_lib + integer :: section_count = 0 + integer, parameter :: NT = 4 + print *, 'section_count', section_count +!ERROR: invalid branch into an OpenMP structured block +!ERROR: invalid branch into an OpenMP structured block +!ERROR: invalid branch into an OpenMP structured block + if (NT) 20, 30, 40 +!ERROR: invalid branch into an OpenMP structured block + goto 20 +!$omp sections + !$omp section + print *, "This is a single statement structured block" + !$omp section + open (10, file="random-file-name.txt", err=30) + !ERROR: invalid branch into an OpenMP structured block + !ERROR: invalid branch leaving an OpenMP structured block + open (10, file="random-file-name.txt", err=40) + !$omp section + section_count = section_count + 1 +20 print *, 'Entering into section' + call calledFromWithinSection() + print *, 'section_count', section_count + !$omp section + section_count = section_count + 1 + print *, 'section_count', section_count + !ERROR: invalid branch leaving an OpenMP structured block + goto 10 + !$omp section +30 print *, "Error in opening file" +!$omp end sections +10 print *, 'Jump from section' + +!$omp sections + !$omp section +40 print *, 'Error in opening file' +!$omp end sections +end program OmpConstructSections01 + +function returnFromSections() + !$omp sections + !$omp section + !ERROR: RETURN statement is not allowed in a SECTIONS construct + RETURN + !$omp end sections +end function + +subroutine calledFromWithinSection() + print *, "I am called from within a 'section' structured block" + return +end subroutine calledFromWithinSection + +subroutine continueWithinSections() + integer i + do i = 1, 10 + print *, "Statement within loop but outside section construct" + !$omp sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: CYCLE to construct outside of SECTIONS construct is not allowed + CYCLE + END IF + !$omp end sections + print *, "Statement within loop but outside section contruct" + end do + + !$omp sections + !$omp section + do i = 1, 10 + CYCLE + end do + !$omp end sections + + !$omp sections + !$omp section + loop_1: do i = 1, 10 + IF (i .EQ. 5) THEN + CYCLE loop_1 + END IF + end do loop_1 + !$omp end sections + + loop_2: do i = 1, 10 + !$omp sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: CYCLE to construct 'loop_2' outside of SECTIONS construct is not allowed + CYCLE loop_2 + END IF + !$omp end sections + end do loop_2 +end subroutine continueWithinSections + +subroutine breakWithinSections() + loop_3: do i = 1, 10 + !$omp sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: EXIT to construct 'loop_3' outside of SECTIONS construct is not allowed + EXIT loop_3 + END IF + !$omp end sections + end do loop_3 + + loop_4: do i = 1, 10 + !$omp sections + !$omp section + IF (i .EQ. 5) THEN + !ERROR: EXIT to construct outside of SECTIONS construct is not allowed + EXIT + END IF + !$omp end sections + end do loop_4 + + !$omp sections + !$omp section + do i = 1, 10 + IF (i .EQ. 5) THEN + EXIT + END IF + end do + !$omp end sections + + !$omp sections + !$omp section + loop_5: do i = 1, 10 + IF (i .EQ. 5) THEN + EXIT loop_5 + END IF + end do loop_5 + !$omp end sections +end subroutine breakWithinSections diff --git a/flang/test/SemanticsChecked/OpenMP/sections03.f90 b/flang/test/SemanticsChecked/OpenMP/sections03.f90 new file mode 100644 index 00000000000000..69775013ea823d --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/sections03.f90 @@ -0,0 +1,27 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +!XFAIL: * +! OpenMP version 5.0.0 +! 2.8.1 sections construct +! Orphaned section directives are prohibited. That is, the section directives must appear within the sections construct and must not be encountered elsewhere in the sections region +!TODO: Error in parsing. Make parser errors more informative. Until then, the test is XFAIL + +program OmpOrphanedSections + use omp_lib + integer counter + counter = 0 + !CHECK: expected 'END' + !CHECK: END PROGRAM statement + !CHECK: in the context: main program + !CHECK: expected 'END PROGRAM' + !CHECK: in the context: END PROGRAM statement + !CHECK: in the context: main program + !$omp section + print *, "An orphaned section containing a single statement" + !$omp section + counter = counter + 1 + print *, "An orphaned section containing multiple statements" +!$omp sections + !$omp section + print *, "Not an orphan structured block" +!$omp end sections +end program OmpOrphanedSections diff --git a/flang/test/SemanticsChecked/OpenMP/simd-aligned.f90 b/flang/test/SemanticsChecked/OpenMP/simd-aligned.f90 new file mode 100644 index 00000000000000..0a9f95833e22e7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/simd-aligned.f90 @@ -0,0 +1,68 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! Semantic error for correct test case + +program omp_simd + integer i, j, k, c, d(100) + integer, allocatable :: a(:), b(:) + common /cmn/ c + + allocate(a(10)) + allocate(b(10)) + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a, a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !ERROR: List item 'b' present at multiple ALIGNED clauses + !$omp simd aligned(a,a) aligned(b) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) aligned(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp simd aligned(a) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) private(a) aligned(a) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + print *, a + + !ERROR: 'c' is a common block name and can not appear in an ALIGNED clause + !$omp simd aligned(c) + do i = 1, 10 + c = 5 + end do + !$omp end simd + + !ERROR: 'd' in ALIGNED clause must be of type C_PTR, POINTER or ALLOCATABLE + !$omp simd aligned(d:100) + do i = 1, 100 + d(i) = i + end do + +end program omp_simd diff --git a/flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90 b/flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90 new file mode 100644 index 00000000000000..a488edd98cdc3f --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90 @@ -0,0 +1,63 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! Semantic error for correct test case + +program omp_simd + integer i, j, k + integer, allocatable :: a(:), b(:) + + allocate(a(10)) + allocate(b(10)) + + !ERROR: List item 'a' present at multiple NONTEMPORAL clauses + !$omp simd nontemporal(a, a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple NONTEMPORAL clauses + !ERROR: List item 'b' present at multiple NONTEMPORAL clauses + !$omp simd nontemporal(a,a) nontemporal(b) nontemporal(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple NONTEMPORAL clauses + !$omp simd nontemporal(a) nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp simd nontemporal(a) nontemporal(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple NONTEMPORAL clauses + !$omp simd nontemporal(a) private(a) nontemporal(a) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple NONTEMPORAL clauses + !ERROR: List item 'b' present at multiple NONTEMPORAL clauses + !$omp simd nontemporal(a,a,b,b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + print *, a + +end program omp_simd diff --git a/flang/test/SemanticsChecked/OpenMP/simd01.f90 b/flang/test/SemanticsChecked/OpenMP/simd01.f90 new file mode 100644 index 00000000000000..1aa2880cda831e --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/simd01.f90 @@ -0,0 +1,40 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 5.0 +! 2.9.3.1 simd Construct +! - A program that branches into or out of a simd region is non-conforming. +! - The associated loops must be structured blocks + +program omp_simd + integer i, j + + !$omp simd + do i = 1, 10 + do j = 1, 10 + print *, "omp simd" + !ERROR: invalid branch leaving an OpenMP structured block + goto 10 + end do + if (i .EQ. 5) THEN + call function1() + else if (i .EQ. 7) THEN + open (10, file="random-file-name.txt", err=20) +20 print *, "Error message doesn't branch out of the loop's structured block" + else + !ERROR: invalid branch leaving an OpenMP structured block + open (10, file="random-file-name.txt", err=10) + end if + end do + !$omp end simd +10 stop + +end program omp_simd + +subroutine function1() + integer i, option + option = 1 + !$omp simd + do i = 1, 10 + print *, "CORRECT SIMD LOOP" + end do + !$omp end simd +end subroutine function1 diff --git a/flang/test/SemanticsChecked/OpenMP/simd02.f90 b/flang/test/SemanticsChecked/OpenMP/simd02.f90 new file mode 100644 index 00000000000000..a627e2ac2d67c7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/simd02.f90 @@ -0,0 +1,21 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! Semantic error for correct test case + +program omp_simd + integer i, j, k + integer, allocatable :: a(:) + + allocate(a(10)) + + !$omp simd aligned(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + print *, a + +end program omp_simd diff --git a/flang/test/SemanticsChecked/OpenMP/simd03.f90 b/flang/test/SemanticsChecked/OpenMP/simd03.f90 new file mode 100644 index 00000000000000..38f45da47748ff --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/simd03.f90 @@ -0,0 +1,26 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp +! XFAIL: * + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! An ordered construct with the simd clause is the only OpenMP construct +! that can be encountered during execution of a simd region. + +program omp_simd + integer i, j, k + integer, allocatable :: a(:) + + allocate(a(10)) + + !$omp simd + do i = 1, 10 + !ERROR: Invalid OpenMP construct inside simd region + !$omp single + a(i) = i + !$omp end single + end do + !$omp end simd + + print *, a + +end program omp_simd diff --git a/flang/test/SemanticsChecked/OpenMP/single01.f90 b/flang/test/SemanticsChecked/OpenMP/single01.f90 new file mode 100644 index 00000000000000..2e40bec56e9c26 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/single01.f90 @@ -0,0 +1,15 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.7.3 single Construct +! Symbol present on multiple clauses + +program omp_single + integer i + i = 10 + + !$omp single private(i) + print *, "omp single", i + !ERROR: COPYPRIVATE variable 'i' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct + !$omp end single copyprivate(i) + +end program omp_single diff --git a/flang/test/SemanticsChecked/OpenMP/single02.f90 b/flang/test/SemanticsChecked/OpenMP/single02.f90 new file mode 100644 index 00000000000000..03cf7fbb6ad380 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/single02.f90 @@ -0,0 +1,17 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! 2.7.3 single Construct +! Copyprivate variable is not thread private or private in outer context + +program omp_single + integer i + i = 10 + + !$omp parallel + !$omp single + print *, "omp single", i + !ERROR: COPYPRIVATE variable 'i' is not PRIVATE or THREADPRIVATE in outer context + !$omp end single copyprivate(i) + !$omp end parallel + +end program omp_single diff --git a/flang/test/SemanticsChecked/OpenMP/struct.f90 b/flang/test/SemanticsChecked/OpenMP/struct.f90 new file mode 100644 index 00000000000000..8ae1fbe4da86f9 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/struct.f90 @@ -0,0 +1,7 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! Check OpenMP compatibility with the DEC STRUCTURE extension + +structure /s/ +end structure + +end diff --git a/flang/test/SemanticsChecked/OpenMP/symbol01.f90 b/flang/test/SemanticsChecked/OpenMP/symbol01.f90 new file mode 100644 index 00000000000000..0b435a9ab9850b --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol01.f90 @@ -0,0 +1,68 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! Test clauses that accept list. +! 2.1 Directive Format +! A list consists of a comma-separated collection of one or more list items. +! A list item is a variable, array section or common block name (enclosed in +! slashes). + +!DEF: /md Module +module md + !DEF: /md/myty PUBLIC DerivedType + type :: myty + !DEF: /md/myty/a ObjectEntity REAL(4) + real :: a + !DEF: /md/myty/b ObjectEntity INTEGER(4) + integer :: b + end type myty +end module md +!DEF: /mm MainProgram +program mm + !REF: /md + use :: md + !DEF: /mm/c CommonBlockDetails + !DEF: /mm/x ObjectEntity REAL(4) + !DEF: /mm/y ObjectEntity REAL(4) + common /c/x, y + !REF: /mm/x + !REF: /mm/y + real x, y + !DEF: /mm/myty Use + !DEF: /mm/t ObjectEntity TYPE(myty) + type(myty) :: t + !DEF: /mm/b ObjectEntity INTEGER(4) + integer b(10) + !REF: /mm/t + !REF: /md/myty/a + t%a = 3.14 + !REF: /mm/t + !REF: /md/myty/b + t%b = 1 + !REF: /mm/b + b = 2 + !DEF: /mm/a (Implicit) ObjectEntity REAL(4) + a = 1.0 + !DEF: /mm/c (Implicit) ObjectEntity REAL(4) + c = 2.0 +!$omp parallel do private(a,t,/c/) shared(c) + !DEF: /mm/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /mm/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4) + !REF: /mm/b + !REF: /mm/OtherConstruct1/i + a = a+b(i) + !DEF: /mm/OtherConstruct1/t (OmpPrivate) HostAssoc TYPE(myty) + !REF: /md/myty/a + !REF: /mm/OtherConstruct1/i + t%a = i + !DEF: /mm/OtherConstruct1/y (OmpPrivate) HostAssoc REAL(4) + y = 0. + !DEF: /mm/OtherConstruct1/x (OmpPrivate) HostAssoc REAL(4) + !REF: /mm/OtherConstruct1/a + !REF: /mm/OtherConstruct1/i + !REF: /mm/OtherConstruct1/y + x = a+i+y + !REF: /mm/c + c = 3.0 + end do +end program diff --git a/flang/test/SemanticsChecked/OpenMP/symbol02.f90 b/flang/test/SemanticsChecked/OpenMP/symbol02.f90 new file mode 100644 index 00000000000000..f6ffc5500d0a44 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol02.f90 @@ -0,0 +1,25 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! 1.4.1 Structure of the OpenMP Memory Model + +! Test implicit declaration in the OpenMP directive enclosing scope +! through clause; also test to avoid creating multiple symbols for +! the same variable + + !DEF: /MainProgram1/b (Implicit) ObjectEntity REAL(4) + b = 2 + !DEF: /MainProgram1/c (Implicit) ObjectEntity REAL(4) + c = 0 + !$omp parallel private(a,b) shared(c,d) + !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4) + a = 3. + !DEF: /MainProgram1/OtherConstruct1/b (OmpPrivate) HostAssoc REAL(4) + b = 4 + !REF: /MainProgram1/c + c = 5 + !DEF: /MainProgram1/d (Implicit) ObjectEntity REAL(4) + d = 6 + !$omp end parallel + !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4) + print *, a +end program diff --git a/flang/test/SemanticsChecked/OpenMP/symbol03.f90 b/flang/test/SemanticsChecked/OpenMP/symbol03.f90 new file mode 100644 index 00000000000000..93e9b7a3eae6be --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol03.f90 @@ -0,0 +1,24 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! 1.4.1 Structure of the OpenMP Memory Model +! In the inner OpenMP region, SHARED `a` refers to the `a` in the outer OpenMP +! region; PRIVATE `b` refers to the new `b` in the same OpenMP region + + !DEF: /MainProgram1/b (Implicit) ObjectEntity REAL(4) + b = 2 + !$omp parallel private(a) shared(b) + !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4) + a = 3. + !REF: /MainProgram1/b + b = 4 + !$omp parallel private(b) shared(a) + !REF: /MainProgram1/OtherConstruct1/a + a = 5. + !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/b (OmpPrivate) HostAssoc REAL(4) + b = 6 + !$omp end parallel + !$omp end parallel + !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4) + !REF: /MainProgram1/b + print *, a, b +end program diff --git a/flang/test/SemanticsChecked/OpenMP/symbol04.f90 b/flang/test/SemanticsChecked/OpenMP/symbol04.f90 new file mode 100644 index 00000000000000..808d1e0dd09bef --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol04.f90 @@ -0,0 +1,23 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! 2.15.3 Data-Sharing Attribute Clauses +! Both PARALLEL and DO (worksharing) directives need to create new scope, +! so PRIVATE `a` will have new symbol in each region + + !DEF: /MainProgram1/a ObjectEntity REAL(8) + real*8 a + !REF: /MainProgram1/a + a = 3.14 + !$omp parallel private(a) + !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(8) + a = 2. + !$omp do private(a) + !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(8) + a = 1. + end do + !$omp end parallel + !REF: /MainProgram1/a + print *, a +end program diff --git a/flang/test/SemanticsChecked/OpenMP/symbol05.f90 b/flang/test/SemanticsChecked/OpenMP/symbol05.f90 new file mode 100644 index 00000000000000..fa0a8f65a42941 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol05.f90 @@ -0,0 +1,40 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! 2.15.2 threadprivate Directive +! The threadprivate directive specifies that variables are replicated, +! with each thread having its own copy. When threadprivate variables are +! referenced in the OpenMP region, we know they are already private to +! their threads, so no new symbol needs to be created. + +!DEF: /mm Module +module mm + !$omp threadprivate (i) +contains + !DEF: /mm/foo PUBLIC (Subroutine) Subprogram + subroutine foo + !DEF: /mm/foo/a ObjectEntity INTEGER(4) + integer :: a = 3 + !$omp parallel + !REF: /mm/foo/a + a = 1 + !DEF: /mm/i PUBLIC (Implicit, OmpThreadprivate) ObjectEntity INTEGER(4) + !REF: /mm/foo/a + i = a + !$omp end parallel + !REF: /mm/foo/a + print *, a + block + !DEF: /mm/foo/BlockConstruct1/i ObjectEntity REAL(4) + real i + !REF: /mm/foo/BlockConstruct1/i + i = 3.14 + end block + end subroutine foo +end module mm +!DEF: /tt MainProgram +program tt + !REF: /mm + use :: mm + !DEF: /tt/foo (Subroutine) Use + call foo +end program tt diff --git a/flang/test/SemanticsChecked/OpenMP/symbol06.f90 b/flang/test/SemanticsChecked/OpenMP/symbol06.f90 new file mode 100644 index 00000000000000..906264eb126422 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol06.f90 @@ -0,0 +1,16 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! 2.15.3 Data-Sharing Attribute Clauses +! A list item that specifies a given variable may not appear in more than +! one clause on the same directive, except that a variable may be specified +! in both firstprivate and lastprivate clauses. + + !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4) + a = 1. + !$omp parallel do firstprivate(a) lastprivate(a) + !DEF: /MainProgram1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /MainProgram1/OtherConstruct1/a (OmpFirstPrivate, OmpLastPrivate) HostAssoc REAL(4) + a = 2. + end do +end program diff --git a/flang/test/SemanticsChecked/OpenMP/symbol07.f90 b/flang/test/SemanticsChecked/OpenMP/symbol07.f90 new file mode 100644 index 00000000000000..e2250f5c7908aa --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol07.f90 @@ -0,0 +1,37 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! Generic tests +! 1. subroutine or function calls should not be fixed for DSA or DMA + +!DEF: /foo (Function) Subprogram REAL(4) +!DEF: /foo/rnum ObjectEntity REAL(4) +function foo(rnum) + !REF: /foo/rnum + real rnum + !REF: /foo/rnum + rnum = rnum+1. +end function foo +!DEF: /function_call_in_region EXTERNAL (Subroutine) Subprogram +subroutine function_call_in_region + implicit none + !DEF: /function_call_in_region/foo (Function) ProcEntity REAL(4) + real foo + !DEF: /function_call_in_region/a ObjectEntity REAL(4) + real :: a = 0. + !DEF: /function_call_in_region/b ObjectEntity REAL(4) + real :: b = 5. + !$omp parallel default(none) private(a) shared(b) + !DEF: /function_call_in_region/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4) + !REF: /function_call_in_region/foo + !REF: /function_call_in_region/b + a = foo(b) + !$omp end parallel + !REF: /function_call_in_region/a + !REF: /function_call_in_region/b + print *, a, b +end subroutine function_call_in_region +!DEF: /mm MainProgram +program mm + !REF: /function_call_in_region + call function_call_in_region +end program mm diff --git a/flang/test/SemanticsChecked/OpenMP/symbol08.f90 b/flang/test/SemanticsChecked/OpenMP/symbol08.f90 new file mode 100644 index 00000000000000..3af85af74ee97c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol08.f90 @@ -0,0 +1,251 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! 2.15.1.1 Predetermined rules for associated do-loops index variable +! a) The loop iteration variable(s) in the associated do-loop(s) of a do, +! parallel do, taskloop, or distribute construct is (are) private. +! b) The loop iteration variable in the associated do-loop of a simd construct +! with just one associated do-loop is linear with a linear-step that is the +! increment of the associated do-loop. +! c) The loop iteration variables in the associated do-loops of a simd +! construct with multiple associated do-loops are lastprivate. +! d) A loop iteration variable for a sequential loop in a parallel or task +! generating construct is private in the innermost such construct that +! encloses the loop. +! - TBD + +! All the tests assume that the do-loops association for collapse/ordered +! clause has been performed (the number of nested do-loops >= n). + +! Rule a) +! TODO: nested constructs (k should be private too) +!DEF: /test_do (Subroutine) Subprogram +subroutine test_do + implicit none + !DEF: /test_do/a ObjectEntity REAL(4) + real a(20,20,20) + !DEF: /test_do/i ObjectEntity INTEGER(4) + !DEF: /test_do/j ObjectEntity INTEGER(4) + !DEF: /test_do/k ObjectEntity INTEGER(4) + integer i, j, k +!$omp parallel + !REF: /test_do/i + i = 99 +!$omp do collapse(2) + !DEF: /test_do/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,5 + !DEF: /test_do/OtherConstruct1/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=6,10 + !REF: /test_do/a + a(1,1,1) = 0. + !DEF: /test_do/OtherConstruct1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=11,15 + !REF: /test_do/a + !REF: /test_do/OtherConstruct1/k + !REF: /test_do/OtherConstruct1/OtherConstruct1/j + !REF: /test_do/OtherConstruct1/OtherConstruct1/i + a(k,j,i) = 1. + end do + end do + end do +!$omp end parallel +end subroutine test_do + +! Rule a) +!DEF: /test_pardo (Subroutine) Subprogram +subroutine test_pardo + implicit none + !DEF: /test_pardo/a ObjectEntity REAL(4) + real a(20,20,20) + !DEF: /test_pardo/i ObjectEntity INTEGER(4) + !DEF: /test_pardo/j ObjectEntity INTEGER(4) + !DEF: /test_pardo/k ObjectEntity INTEGER(4) + integer i, j, k +!$omp parallel do collapse(2) private(k) ordered(2) + !DEF: /test_pardo/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,5 + !DEF: /test_pardo/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=6,10 + !REF: /test_pardo/a + a(1,1,1) = 0. + !DEF: /test_pardo/OtherConstruct1/k (OmpPrivate) HostAssoc INTEGER(4) + do k=11,15 + !REF: /test_pardo/a + !REF: /test_pardo/OtherConstruct1/k + !REF: /test_pardo/OtherConstruct1/j + !REF: /test_pardo/OtherConstruct1/i + a(k,j,i) = 1. + end do + end do + end do +end subroutine test_pardo + +! Rule a) +!DEF: /test_taskloop (Subroutine) Subprogram +subroutine test_taskloop + implicit none + !DEF: /test_taskloop/a ObjectEntity REAL(4) + real a(5,5) + !DEF: /test_taskloop/i ObjectEntity INTEGER(4) + !DEF: /test_taskloop/j ObjectEntity INTEGER(4) + integer i, j +!$omp taskloop private(j) + !DEF: /test_taskloop/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,5 + !DEF: /test_taskloop/OtherConstruct1/j (OmpPrivate) HostAssoc INTEGER(4) + !REF: /test_taskloop/OtherConstruct1/i + do j=1,i + !DEF: /test_taskloop/OtherConstruct1/a (OmpFirstPrivate, OmpImplicit) HostAssoc REAL(4) + !REF: /test_taskloop/OtherConstruct1/j + !REF: /test_taskloop/OtherConstruct1/i + a(j,i) = 3.14 + end do + end do +!$omp end taskloop +end subroutine test_taskloop + +! Rule a); OpenMP 4.5 Examples teams.2.f90 +! TODO: reduction; data-mapping attributes +!DEF: /dotprod (Subroutine) Subprogram +!DEF: /dotprod/b (OmpMapTo) ObjectEntity REAL(4) +!DEF: /dotprod/c (OmpMapTo) ObjectEntity REAL(4) +!DEF: /dotprod/n ObjectEntity INTEGER(4) +!DEF: /dotprod/block_size ObjectEntity INTEGER(4) +!DEF: /dotprod/num_teams ObjectEntity INTEGER(4) +!DEF: /dotprod/block_threads ObjectEntity INTEGER(4) +subroutine dotprod (b, c, n, block_size, num_teams, block_threads) + implicit none + !REF: /dotprod/n + integer n + !REF: /dotprod/b + !REF: /dotprod/n + !REF: /dotprod/c + !DEF: /dotprod/sum (OmpMapToFrom) ObjectEntity REAL(4) + real b(n), c(n), sum + !REF: /dotprod/block_size + !REF: /dotprod/num_teams + !REF: /dotprod/block_threads + !DEF: /dotprod/i ObjectEntity INTEGER(4) + !DEF: /dotprod/i0 ObjectEntity INTEGER(4) + integer block_size, num_teams, block_threads, i, i0 + !REF: /dotprod/sum + sum = 0.0e0 +!$omp target map(to:b,c) map(tofrom:sum) +!$omp teams num_teams(num_teams) thread_limit(block_threads) reduction(+:sum) +!$omp distribute + !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0 (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + !REF: /dotprod/n + !REF: /dotprod/block_size + do i0=1,n,block_size +!$omp parallel do reduction(+:sum) + !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + !REF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0 + !DEF: /dotprod/min ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity + !REF: /dotprod/block_size + !REF: /dotprod/n + do i=i0,min(i0+block_size, n) + !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/sum (OmpReduction) HostAssoc REAL(4) + !REF: /dotprod/b + !REF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/i + !REF: /dotprod/c + sum = sum+b(i)*c(i) + end do + end do +!$omp end teams +!$omp end target + !REF: /dotprod/sum + print *, sum +end subroutine dotprod + +! Rule b) +! TODO: nested constructs (j, k should be private too) +!DEF: /test_simd (Subroutine) Subprogram +subroutine test_simd + implicit none + !DEF: /test_simd/a ObjectEntity REAL(4) + real a(20,20,20) + !DEF: /test_simd/i ObjectEntity INTEGER(4) + !DEF: /test_simd/j ObjectEntity INTEGER(4) + !DEF: /test_simd/k ObjectEntity INTEGER(4) + integer i, j, k +!$omp parallel do simd + !DEF: /test_simd/OtherConstruct1/i (OmpLinear, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,5 + !DEF: /test_simd/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=6,10 + !DEF: /test_simd/OtherConstruct1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=11,15 + !REF: /test_simd/a + !REF: /test_simd/OtherConstruct1/k + !REF: /test_simd/OtherConstruct1/j + !REF: /test_simd/OtherConstruct1/i + a(k,j,i) = 3.14 + end do + end do + end do +end subroutine test_simd + +! Rule c) +!DEF: /test_simd_multi (Subroutine) Subprogram +subroutine test_simd_multi + implicit none + !DEF: /test_simd_multi/a ObjectEntity REAL(4) + real a(20,20,20) + !DEF: /test_simd_multi/i ObjectEntity INTEGER(4) + !DEF: /test_simd_multi/j ObjectEntity INTEGER(4) + !DEF: /test_simd_multi/k ObjectEntity INTEGER(4) + integer i, j, k +!$omp parallel do simd collapse(3) + !DEF: /test_simd_multi/OtherConstruct1/i (OmpLastPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,5 + !DEF: /test_simd_multi/OtherConstruct1/j (OmpLastPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=6,10 + !DEF: /test_simd_multi/OtherConstruct1/k (OmpLastPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=11,15 + !REF: /test_simd_multi/a + !REF: /test_simd_multi/OtherConstruct1/k + !REF: /test_simd_multi/OtherConstruct1/j + !REF: /test_simd_multi/OtherConstruct1/i + a(k,j,i) = 3.14 + end do + end do + end do +end subroutine test_simd_multi + +! Rule d) +!DEF: /test_seq_loop (Subroutine) Subprogram +subroutine test_seq_loop + implicit none + !DEF: /test_seq_loop/i ObjectEntity INTEGER(4) + !DEF: /test_seq_loop/j ObjectEntity INTEGER(4) + integer i, j + !REF: /test_seq_loop/i + i = -1 + !REF: /test_seq_loop/j + j = -1 + !$omp parallel + !REF: /test_seq_loop/i + !REF: /test_seq_loop/j + print *, i, j + !$omp parallel + !REF: /test_seq_loop/i + !DEF: /test_seq_loop/OtherConstruct1/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + print *, i, j + !$omp do + !DEF: /test_seq_loop/OtherConstruct1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !REF: /test_seq_loop/OtherConstruct1/OtherConstruct1/j + do j=1,10 + end do + end do + !REF: /test_seq_loop/i + !REF: /test_seq_loop/OtherConstruct1/OtherConstruct1/j + print *, i, j + !$omp end parallel + !REF: /test_seq_loop/i + !REF: /test_seq_loop/j + print *, i, j + !$omp end parallel + !REF: /test_seq_loop/i + !REF: /test_seq_loop/j + print *, i, j +end subroutine test_seq_loop diff --git a/flang/test/SemanticsChecked/OpenMP/symbol09.f90 b/flang/test/SemanticsChecked/OpenMP/symbol09.f90 new file mode 100644 index 00000000000000..e2250f5c7908aa --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/symbol09.f90 @@ -0,0 +1,37 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! Generic tests +! 1. subroutine or function calls should not be fixed for DSA or DMA + +!DEF: /foo (Function) Subprogram REAL(4) +!DEF: /foo/rnum ObjectEntity REAL(4) +function foo(rnum) + !REF: /foo/rnum + real rnum + !REF: /foo/rnum + rnum = rnum+1. +end function foo +!DEF: /function_call_in_region EXTERNAL (Subroutine) Subprogram +subroutine function_call_in_region + implicit none + !DEF: /function_call_in_region/foo (Function) ProcEntity REAL(4) + real foo + !DEF: /function_call_in_region/a ObjectEntity REAL(4) + real :: a = 0. + !DEF: /function_call_in_region/b ObjectEntity REAL(4) + real :: b = 5. + !$omp parallel default(none) private(a) shared(b) + !DEF: /function_call_in_region/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4) + !REF: /function_call_in_region/foo + !REF: /function_call_in_region/b + a = foo(b) + !$omp end parallel + !REF: /function_call_in_region/a + !REF: /function_call_in_region/b + print *, a, b +end subroutine function_call_in_region +!DEF: /mm MainProgram +program mm + !REF: /function_call_in_region + call function_call_in_region +end program mm diff --git a/flang/test/SemanticsChecked/OpenMP/sync-critical01.f90 b/flang/test/SemanticsChecked/OpenMP/sync-critical01.f90 new file mode 100644 index 00000000000000..b597eb17ea2267 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/sync-critical01.f90 @@ -0,0 +1,41 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 5.0 +! 2.17.1 critical construct +! CRITICAL start and end CRITICAL directive names mismatch +integer function timer_tick_sec() + implicit none + integer t + + !$OMP CRITICAL + t = t + 1 + !$OMP END CRITICAL + + !$OMP CRITICAL (foo) + t = t + 1 + !$OMP END CRITICAL (foo) + + !$OMP CRITICAL (foo) + t = t + 1 + !ERROR: CRITICAL directive names do not match + !$OMP END CRITICAL (bar) + + !$OMP CRITICAL (bar) + t = t + 1 + !ERROR: CRITICAL directive names do not match + !$OMP END CRITICAL (foo) + + !ERROR: CRITICAL directive names do not match + !$OMP CRITICAL (bar) + t = t + 1 + !$OMP END CRITICAL + + !$OMP CRITICAL + t = t + 1 + !ERROR: CRITICAL directive names do not match + !$OMP END CRITICAL (foo) + + timer_tick_sec = t + return + +end function timer_tick_sec diff --git a/flang/test/SemanticsChecked/OpenMP/sync-critical02.f90 b/flang/test/SemanticsChecked/OpenMP/sync-critical02.f90 new file mode 100644 index 00000000000000..1fa9d6ad84f28c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/sync-critical02.f90 @@ -0,0 +1,55 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang %openmp_flags + +! OpenMP Version 5.0 +! 2.17.1 critical construct +! If the hint clause is specified, the critical construct must have a name. +program sample + use omp_lib + integer i, j + !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive + !$omp critical hint(omp_lock_hint_speculative) + j = j + 1 + !$omp end critical + + !$omp critical (foo) hint(omp_lock_hint_speculative) + i = i - 1 + !$omp end critical (foo) + + !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive + !$omp critical hint(omp_lock_hint_nonspeculative) + j = j + 1 + !$omp end critical + + !$omp critical (foo) hint(omp_lock_hint_nonspeculative) + i = i - 1 + !$omp end critical (foo) + + !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive + !$omp critical hint(omp_lock_hint_contended) + j = j + 1 + !$omp end critical + + !$omp critical (foo) hint(omp_lock_hint_contended) + i = i - 1 + !$omp end critical (foo) + + !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive + !$omp critical hint(omp_lock_hint_uncontended) + j = j + 1 + !$omp end critical + + !$omp critical (foo) hint(omp_lock_hint_uncontended) + i = i - 1 + !$omp end critical (foo) + + !$omp critical hint(omp_sync_hint_none) + j = j + 1 + !$omp end critical + + !$omp critical (foo) hint(omp_sync_hint_none) + i = i - 1 + !$omp end critical (foo) + +end program sample diff --git a/flang/test/SemanticsChecked/OpenMP/target-update01.f90 b/flang/test/SemanticsChecked/OpenMP/target-update01.f90 new file mode 100644 index 00000000000000..84dc60dcd75f5c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/target-update01.f90 @@ -0,0 +1,21 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp + +subroutine foo(x) + integer :: x + !ERROR: At least one motion-clause (TO/FROM) must be specified on TARGET UPDATE construct. + !$omp target update + + !ERROR: At least one motion-clause (TO/FROM) must be specified on TARGET UPDATE construct. + !$omp target update nowait + + !$omp target update to(x) nowait + + !ERROR: At most one NOWAIT clause can appear on the TARGET UPDATE directive + !$omp target update to(x) nowait nowait + + !ERROR: A list item ('x') can only appear in a TO or FROM clause, but not in both. + !BECAUSE: 'x' appears in the TO clause. + !BECAUSE: 'x' appears in the FROM clause. + !$omp target update to(x) from(x) + +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/target.f90 b/flang/test/SemanticsChecked/OpenMP/target.f90 new file mode 100644 index 00000000000000..994c04048edffc --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/target.f90 @@ -0,0 +1,11 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror + +! Corner cases in OpenMP target directives + +subroutine empty_target() + integer :: i + + !$omp target map(i) + !$omp end target + +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/target01.f90 b/flang/test/SemanticsChecked/OpenMP/target01.f90 new file mode 100644 index 00000000000000..9836f0112738fe --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/target01.f90 @@ -0,0 +1,58 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp + +subroutine foo(b) +use iso_c_binding +integer :: x,y +type(C_PTR) :: b +!ERROR: Variable 'x' may not appear on both MAP and PRIVATE clauses on a TARGET construct +!$omp target map(x) private(x) + x = x + 1 +!$omp end target + +!ERROR: Variable 'y' in IS_DEVICE_PTR clause must be of type C_PTR +!$omp target map(x) is_device_ptr(y) + x = x + 1 +!$omp end target + +!ERROR: Variable 'b' may not appear on both IS_DEVICE_PTR and HAS_DEVICE_ADDR clauses on a TARGET construct +!$omp target map(x) is_device_ptr(b) has_device_addr(b) + x = x + 1 +!$omp end target + +!ERROR: Variable 'b' may not appear on both IS_DEVICE_PTR and PRIVATE clauses on a TARGET construct +!$omp target map(x) is_device_ptr(b) private(b) + x = x + 1 +!$omp end target + +!ERROR: Variable 'y' may not appear on both HAS_DEVICE_ADDR and FIRSTPRIVATE clauses on a TARGET construct +!$omp target map(x) has_device_addr(y) firstprivate(y) + y = y - 1 +!$omp end target + +end subroutine foo + +subroutine bar(b1, b2, b3) + use iso_c_binding + integer :: y + type(c_ptr) :: c + type(c_ptr), allocatable :: b1 + type(c_ptr), pointer :: b2 + type(c_ptr), value :: b3 + + !WARNING: Variable 'c' in IS_DEVICE_PTR clause must be a dummy argument. This semantic check is deprecated from OpenMP 5.2 and later. + !$omp target is_device_ptr(c) + y = y + 1 + !$omp end target + !WARNING: Variable 'b1' in IS_DEVICE_PTR clause must be a dummy argument that does not have the ALLOCATABLE, POINTER or VALUE attribute. This semantic check is deprecated from OpenMP 5.2 and later. + !$omp target is_device_ptr(b1) + y = y + 1 + !$omp end target + !WARNING: Variable 'b2' in IS_DEVICE_PTR clause must be a dummy argument that does not have the ALLOCATABLE, POINTER or VALUE attribute. This semantic check is deprecated from OpenMP 5.2 and later. + !$omp target is_device_ptr(b2) + y = y + 1 + !$omp end target + !WARNING: Variable 'b3' in IS_DEVICE_PTR clause must be a dummy argument that does not have the ALLOCATABLE, POINTER or VALUE attribute. This semantic check is deprecated from OpenMP 5.2 and later. + !$omp target is_device_ptr(b3) + y = y + 1 + !$omp end target +end subroutine bar diff --git a/flang/test/SemanticsChecked/OpenMP/target02.f90 b/flang/test/SemanticsChecked/OpenMP/target02.f90 new file mode 100644 index 00000000000000..06ce1c0875cc97 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/target02.f90 @@ -0,0 +1,17 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 4.5 + +program p +integer :: y +!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET construct +!$omp target map(y) firstprivate(y) +y = y + 1 +!$omp end target +!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET SIMD construct +!$omp target simd map(y) firstprivate(y) +do i=1,1 + y = y + 1 +end do +!$omp end target simd + +end program p diff --git a/flang/test/SemanticsChecked/OpenMP/task01.f90 b/flang/test/SemanticsChecked/OpenMP/task01.f90 new file mode 100644 index 00000000000000..4dc80d6d70e052 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/task01.f90 @@ -0,0 +1,31 @@ +! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s +! OpenMP Version 4.5 +! 2.9.1 task Construct +! Invalid entry to OpenMP structured block. + +recursive subroutine traverse ( P ) + type Node + type(Node), pointer :: left, right + end type Node + + type(Node) :: P + + !CHECK: invalid branch into an OpenMP structured block + goto 10 + + if (associated(P%left)) then + !$omp task + call traverse(P%left) + !CHECK: In the enclosing TASK directive branched into + 10 stop + !$omp end task + endif + + if (associated(P%right)) then + !$omp task + call traverse(P%right) + !$omp end task + endif + call process ( P ) + + end subroutine traverse diff --git a/flang/test/SemanticsChecked/OpenMP/taskgroup01.f90 b/flang/test/SemanticsChecked/OpenMP/taskgroup01.f90 new file mode 100644 index 00000000000000..9de1df91bf3bdd --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/taskgroup01.f90 @@ -0,0 +1,50 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang %openmp_flags + +use omp_lib + implicit none + integer :: xyz, abc + real :: reduction_var + !$omp parallel num_threads(4) + !$omp single + print *, "The" + !$omp taskgroup + !$omp task + print *, "almighty" + !$omp end task + !$omp task + print *, "sun" + !$omp end task + !$omp end taskgroup + !$omp end single + !$omp end parallel + + !$omp parallel private(xyz) + !$omp taskgroup allocate(xyz) + !$omp task + print *, "The " + !$omp taskgroup allocate(omp_large_cap_mem_space: abc) + !$omp task + print *, "almighty sun" + !$omp end task + !$omp end taskgroup + !$omp end task + !$omp end taskgroup + !$omp end parallel + + !ERROR: PRIVATE clause is not allowed on the TASKGROUP directive + !$omp taskgroup private(abc) + !$omp end taskgroup + + !$omp parallel + !$omp task + !$omp taskgroup task_reduction(+ : reduction_var) + print *, "The " + !$omp taskgroup task_reduction(.or. : reduction_var) task_reduction(.and. : reduction_var) + print *, "almighty sun" + !$omp end taskgroup + !$omp end taskgroup + !$omp end task + !$omp end parallel +end program \ No newline at end of file diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90 new file mode 100644 index 00000000000000..bb7266a52f61e9 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90 @@ -0,0 +1,17 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +! OpenMP Version 5.0 +! 2.10.3 taskloop simd Construct + +program omp_taskloop_simd + integer i , j , k + + !$omp taskloop simd reduction(+:k) + do i=1,10000 + do j=1,i + k = k + 1 + end do + end do + !$omp end taskloop simd + +end program omp_taskloop_simd diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop01.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop01.f90 new file mode 100644 index 00000000000000..6bef584381518f --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/taskloop01.f90 @@ -0,0 +1,23 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.9.2 taskloop Construct + +subroutine parallel_work + integer i + integer j + + !$omp taskgroup + !$omp task + call long_running_task() + !$omp end task + + !$omp taskloop private(j) grainsize(500) nogroup + do i=1,10000 + do j=1,i + call loop_body(i, j) + end do + end do + !$omp end taskloop + !$omp end taskgroup + +end subroutine parallel_work diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop02.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop02.f90 new file mode 100644 index 00000000000000..867ef8a9806d9c --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/taskloop02.f90 @@ -0,0 +1,21 @@ +! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s +! OpenMP Version 4.5 +! 2.9.2 taskloop Construct +! Invalid entry to OpenMP structured block. + +program omp_taskloop + integer i , j + + !CHECK: invalid branch into an OpenMP structured block + goto 10 + + !$omp taskloop private(j) grainsize(500) nogroup + do i=1,10000 + do j=1,i + !CHECK: In the enclosing TASKLOOP directive branched into + 10 call loop_body(i, j) + end do + end do + !$omp end taskloop + +end program omp_taskloop diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop03.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop03.f90 new file mode 100644 index 00000000000000..7e2e426a3fe7e7 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/taskloop03.f90 @@ -0,0 +1,25 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp +! XFAIL: * + +! OpenMP Version 4.5 +! 2.9.2 taskloop Construct +! All loops associated with the taskloop construct must be perfectly nested, +! there must be no intervening code or any OpenMP directive between +! any two loops + +program omp_taskloop + integer i, j + + !$omp taskloop private(j) grainsize(500) nogroup + do i=1, 10000 + do j=1, i + call loop_body(i, j) + end do + !ERROR: Loops associated with !$omp taskloop is not perfectly nested + !$omp single + print *, "omp single" + !$omp end single + end do + !$omp end taskloop + +end program omp_taskloop diff --git a/flang/test/SemanticsChecked/OpenMP/taskwait.f90 b/flang/test/SemanticsChecked/OpenMP/taskwait.f90 new file mode 100644 index 00000000000000..e60051c9da8acb --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/taskwait.f90 @@ -0,0 +1,4 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp + +!$omp taskwait +end diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate01.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate01.f90 new file mode 100644 index 00000000000000..c2cf9ba99ab046 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate01.f90 @@ -0,0 +1,53 @@ +! REQUIRES: openmp_runtime + +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +module thread_private01 + use omp_lib + type my_type(kind_param, len_param) + integer, KIND :: kind_param + integer, LEN :: len_param + integer :: t_i + integer :: t_arr(10) + end type my_type + + type(my_type(2, 4)) :: my_var + integer :: arr(10) + integer(kind=4) :: x + character(len=32) :: w + integer, dimension(:), allocatable :: y + + !$omp threadprivate(my_var) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%t_i) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%t_arr) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%kind_param) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%len_param) + + !$omp threadprivate(arr) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(arr(1)) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(arr(1:2)) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(x%KIND) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(w%LEN) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(y%KIND) +end diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate02.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate02.f90 new file mode 100644 index 00000000000000..7f6e8dcc8e8abf --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate02.f90 @@ -0,0 +1,81 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +program threadprivate02 + integer :: arr1(10) + common /blk1/ a1 + real, save :: eq_a, eq_b, eq_c, eq_d + + !$omp threadprivate(arr1) + + !$omp threadprivate(/blk1/) + + !$omp threadprivate(blk1) + + !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block + !$omp threadprivate(a1) + + equivalence(eq_a, eq_b) + !ERROR: A variable in a THREADPRIVATE directive cannot appear in an EQUIVALENCE statement + !$omp threadprivate(eq_a) + + !ERROR: A variable in a THREADPRIVATE directive cannot appear in an EQUIVALENCE statement + !$omp threadprivate(eq_c) + equivalence(eq_c, eq_d) + +contains + subroutine func() + integer :: arr2(10) + integer, save :: arr3(10) + common /blk2/ a2 + common /blk3/ a3 + save /blk3/ + + !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly + !$omp threadprivate(arr2) + + !$omp threadprivate(arr3) + + !$omp threadprivate(/blk2/) + + !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block + !$omp threadprivate(a2) + + !$omp threadprivate(/blk3/) + + !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block + !$omp threadprivate(a3) + end +end + +module mod4 + integer :: arr4(10) + common /blk4/ a4 + + !$omp threadprivate(arr4) + + !$omp threadprivate(/blk4/) + + !$omp threadprivate(blk4) + + !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block + !$omp threadprivate(a4) +end + +subroutine func5() + integer :: arr5(10) + common /blk5/ a5 + + !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly + !$omp threadprivate(arr5) + + !$omp threadprivate(/blk5/) + + !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly + !$omp threadprivate(blk5) + + !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block + !$omp threadprivate(a5) +end diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate03.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate03.f90 new file mode 100644 index 00000000000000..b466a8e05e9c28 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate03.f90 @@ -0,0 +1,28 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -pedantic +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +module mod1 +end + +program main + use mod1 + integer, parameter :: i = 1 + + !ERROR: The module name or main program name cannot be in a THREADPRIVATE directive + !$omp threadprivate(mod1) + + !PORTABILITY: Name 'main' declared in a main program should not have the same name as the main program + !ERROR: The module name or main program name cannot be in a THREADPRIVATE directive + !$omp threadprivate(main) + + !ERROR: The entity with PARAMETER attribute cannot be in a THREADPRIVATE directive + !$omp threadprivate(i) + +contains + subroutine sub() + !ERROR: The procedure name cannot be in a THREADPRIVATE directive + !$omp threadprivate(sub) + end +end diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate04.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate04.f90 new file mode 100644 index 00000000000000..3d8c7fb8de8fa1 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate04.f90 @@ -0,0 +1,53 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +program main + integer :: i, N = 10 + integer, save :: x1, x2, x3, x4, x5, x6, x7, x8, x9 + common /blk1/ y1, /blk2/ y2, /blk3/ y3, /blk4/ y4, /blk5/ y5 + + !$omp threadprivate(x1, x2, x3, x4, x5, x6, x7, x8, x9) + !$omp threadprivate(/blk1/, /blk2/, /blk3/, /blk4/, /blk5/) + + !$omp parallel num_threads(x1) + !$omp end parallel + + !ERROR: COPYPRIVATE clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive + !$omp single copyprivate(x2, /blk1/) + !$omp end single + + !$omp single + !$omp end single copyprivate(x2, /blk1/) + + !$omp do schedule(static, x3) + do i = 1, N + y1 = x3 + end do + !$omp end do + + !$omp parallel copyin(x4, /blk2/) + !$omp end parallel + + !$omp parallel if(x5 > 1) + !$omp end parallel + + !$omp teams thread_limit(x6) + !$omp end teams + + !ERROR: A THREADPRIVATE variable cannot be in PRIVATE clause + !ERROR: A THREADPRIVATE variable cannot be in PRIVATE clause + !$omp parallel private(x7, /blk3/) + !$omp end parallel + + !ERROR: A THREADPRIVATE variable cannot be in FIRSTPRIVATE clause + !ERROR: A THREADPRIVATE variable cannot be in FIRSTPRIVATE clause + !$omp parallel firstprivate(x8, /blk4/) + !$omp end parallel + + !ERROR: A THREADPRIVATE variable cannot be in SHARED clause + !ERROR: A THREADPRIVATE variable cannot be in SHARED clause + !$omp parallel shared(x9, /blk5/) + !$omp end parallel +end diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate05.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate05.f90 new file mode 100644 index 00000000000000..cdbf3701b70ae5 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate05.f90 @@ -0,0 +1,44 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +module mod0 + integer :: mi + +contains + subroutine subm() + integer, save :: mmi + + !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit + !$omp threadprivate(mi) + mi = 1 + contains + subroutine subsubm() + !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit + !$omp threadprivate(mmi) + end + end +end + +module mod1 + integer :: mod_i +end + +program main + use mod1 + integer, save :: i + integer :: j + + !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit + !$omp threadprivate(mod_i) + +contains + subroutine sub() + !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit + !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit + !$omp threadprivate(i, j) + i = 1 + j = 1 + end +end diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate06.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate06.f90 new file mode 100644 index 00000000000000..f31c38f6f2b248 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate06.f90 @@ -0,0 +1,30 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +program main + call sub1() + print *, 'pass' +end program main + +subroutine sub1() + common /c/ a + !$omp threadprivate(/c/) + integer :: a + + a = 100 + call sub2() + if (a .ne. 101) print *, 'err' + +contains + subroutine sub2() + common /c/ a + !$omp threadprivate(/c/) + integer :: a + + !$omp parallel copyin(/c/) + a = a + 1 + !$omp end parallel + end subroutine +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate07.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate07.f90 new file mode 100644 index 00000000000000..c9a006ca0e0839 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/threadprivate07.f90 @@ -0,0 +1,15 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp + +! Check Threadprivate Directive with local variable of a BLOCK construct. + +program main + call sub1() + print *, 'pass' +end program main + +subroutine sub1() + BLOCK + integer, save :: a + !$omp threadprivate(a) + END BLOCK +end subroutine diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_addr.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_addr.f90 new file mode 100644 index 00000000000000..93a7643b5eb485 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/use_device_addr.f90 @@ -0,0 +1,17 @@ +! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s +! OpenMP Version 5.1 +! 2.14.2 use_device_addr clause +! List item that appears in a use_device_addr clause has corresponding storage +! in the device data environment, references to the list item in the associated +! structured block are converted into references to the corresponding list item. + +subroutine omp_target_data + integer :: a(1024) + !CHECK: b, TARGET size=4096 offset=4096: ObjectEntity type: INTEGER(4) shape: 1_8:1024_8 + integer, target :: b(1024) + a = 1 + !$omp target data map(tofrom: a) use_device_addr(b) + !CHECK: b (OmpUseDeviceAddr): HostAssoc + b = a + !$omp end target data +end subroutine omp_target_data diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90 new file mode 100644 index 00000000000000..867e324b68ad95 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90 @@ -0,0 +1,33 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.0 +! 2.10.1 use_device_ptr clause +! List item in USE_DEVICE_ADDR clause must not be structure element. +! Same list item can not be present multiple times or in multipe +! USE_DEVICE_ADDR clauses. + +subroutine omp_target_data + integer :: a(1024) + integer, target :: b(1024) + type my_type + integer :: my_b(1024) + end type my_type + + type(my_type) :: my_var + a = 1 + + !ERROR: A variable that is part of another variable (structure element) cannot appear on the TARGET DATA USE_DEVICE_ADDR clause + !$omp target data map(tofrom: a) use_device_addr(my_var%my_b) + my_var%my_b = a + !$omp end target data + + !ERROR: List item 'b' present at multiple USE_DEVICE_ADDR clauses + !$omp target data map(tofrom: a) use_device_addr(b,b) + b = a + !$omp end target data + + !ERROR: List item 'b' present at multiple USE_DEVICE_ADDR clauses + !$omp target data map(tofrom: a) use_device_addr(b) use_device_addr(b) + b = a + !$omp end target data + +end subroutine omp_target_data diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90 new file mode 100644 index 00000000000000..64b98cf67961d1 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90 @@ -0,0 +1,21 @@ +! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s +! OpenMP Version 5.0 +! 2.10.1 use_device_ptr clause +! List items that appear in a use_device_ptr clause are converted into device +! pointers to the corresponding list item in the device data environment. + +subroutine omp_target_data + use iso_c_binding + integer :: a(1024) + !CHECK: b size=8 offset=4096: ObjectEntity type: TYPE(c_ptr) + type(C_PTR) :: b + integer, pointer :: arrayB + a = 1 + !$omp target data map(tofrom: a, arrayB) use_device_ptr(b) + !CHECK: b (OmpUseDevicePtr): HostAssoc + allocate(arrayB) + call c_f_pointer(b, arrayB) + a = arrayB + !$omp end target data +end subroutine omp_target_data + diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90 new file mode 100644 index 00000000000000..176fb5f35a8490 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90 @@ -0,0 +1,64 @@ +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.0 +! 2.10.1 use_device_ptr clause +! List item in USE_DEVICE_PTR clause must not be structure element. +! List item in USE_DEVICE_PTR clause must be of type C_PTR. +! List items that appear in a use_device_ptr clause can not appear in +! use_device_addr clause. +! Same list item can not be present multiple times or in multipe +! USE_DEVICE_PTR clauses. + +subroutine omp_target_data + use iso_c_binding + integer :: a(1024) + type(C_PTR) :: b + integer, pointer :: arrayB + type my_type + type(C_PTR) :: my_cptr + end type my_type + + type(my_type) :: my_var + a = 1 + + !ERROR: A variable that is part of another variable (structure element) cannot appear on the TARGET DATA USE_DEVICE_PTR clause + !$omp target data map(tofrom: a, arrayB) use_device_ptr(my_var%my_cptr) + allocate(arrayB) + call c_f_pointer(my_var%my_cptr, arrayB) + a = arrayB + !$omp end target data + + !WARNING: Use of non-C_PTR type 'a' in USE_DEVICE_PTR is deprecated, use USE_DEVICE_ADDR instead + !$omp target data map(tofrom: a) use_device_ptr(a) + a = 2 + !$omp end target data + + !ERROR: List item 'b' present at multiple USE_DEVICE_PTR clauses + !$omp target data map(tofrom: a, arrayB) use_device_ptr(b) use_device_ptr(b) + allocate(arrayB) + call c_f_pointer(b, arrayB) + a = arrayB + !$omp end target data + + !ERROR: List item 'b' present at multiple USE_DEVICE_PTR clauses + !$omp target data map(tofrom: a, arrayB) use_device_ptr(b,b) + allocate(arrayB) + call c_f_pointer(b, arrayB) + a = arrayB + !$omp end target data + + !ERROR: Variable 'b' may not appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR clauses on a TARGET DATA construct + !$omp target data map(tofrom: a, arrayB) use_device_addr(b) use_device_ptr(b) + allocate(arrayB) + call c_f_pointer(b, arrayB) + a = arrayB + !$omp end target data + + !ERROR: Variable 'b' may not appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR clauses on a TARGET DATA construct + !$omp target data map(tofrom: a, arrayB) use_device_ptr(b) use_device_addr(b) + allocate(arrayB) + call c_f_pointer(b, arrayB) + a = arrayB + !$omp end target data + +end subroutine omp_target_data + diff --git a/flang/test/SemanticsChecked/OpenMP/workshare01.f90 b/flang/test/SemanticsChecked/OpenMP/workshare01.f90 new file mode 100644 index 00000000000000..9667a306061c07 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/workshare01.f90 @@ -0,0 +1,33 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.7.4 workshare Construct +! Invalid do construct inside !$omp workshare + +subroutine workshare(aa, bb, cc, dd, ee, ff, n) + integer n, i + real aa(n,n), bb(n,n), cc(n,n), dd(n,n), ee(n,n), ff(n,n) + + !ERROR: The structured block in a WORKSHARE construct may consist of only SCALAR or ARRAY assignments, FORALL or WHERE statements, FORALL, WHERE, ATOMIC, CRITICAL or PARALLEL constructs + !ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only + !$omp workshare + do i = 1, n + print *, "omp workshare" + end do + + !$omp critical + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + aa = bb + !$omp end single + !$omp end critical + + !$omp parallel + !$omp single + cc = dd + !$omp end single + !$omp end parallel + + ee = ff + !$omp end workshare + +end subroutine workshare diff --git a/flang/test/SemanticsChecked/OpenMP/workshare02.f90 b/flang/test/SemanticsChecked/OpenMP/workshare02.f90 new file mode 100644 index 00000000000000..e099ecb9f1e614 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/workshare02.f90 @@ -0,0 +1,65 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.7.4 workshare Construct +! The !omp workshare construct must not contain any user defined +! function calls unless the function is ELEMENTAL. + +module my_mod + contains + integer function my_func() + my_func = 10 + end function my_func +end module my_mod + +subroutine workshare(aa, bb, cc, dd, ee, ff, n) + use my_mod + integer n, i, j + real aa(n), bb(n), cc(n), dd(n), ee(n), ff(n) + + !$omp workshare + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + aa = my_func() + cc = dd + ee = ff + + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + where (aa .ne. my_func()) aa = bb * cc + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + where (dd .lt. 5) dd = aa * my_func() + + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + where (aa .ge. my_func()) + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + cc = aa + my_func() + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + elsewhere (aa .le. my_func()) + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + cc = dd + my_func() + elsewhere + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + cc = ee + my_func() + end where + + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + forall (j = 1:my_func()) aa(j) = aa(j) + bb(j) + + forall (j = 1:10) + aa(j) = aa(j) + bb(j) + + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + where (cc .le. j) cc = cc + my_func() + end forall + + !$omp atomic update + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + j = j + my_func() + + !$omp atomic capture + i = j + !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct + j = j - my_func() + !$omp end atomic + + !$omp end workshare + +end subroutine workshare diff --git a/flang/test/SemanticsChecked/OpenMP/workshare03.f90 b/flang/test/SemanticsChecked/OpenMP/workshare03.f90 new file mode 100644 index 00000000000000..09d46abf42eec8 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/workshare03.f90 @@ -0,0 +1,32 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.7.4 workshare Construct +! All array assignments, scalar assignments, and masked array assignments +! must be intrinsic assignments. + +module defined_assign + interface assignment(=) + module procedure work_assign + end interface + + contains + subroutine work_assign(a,b) + integer, intent(out) :: a + logical, intent(in) :: b(:) + end subroutine work_assign +end module defined_assign + +program omp_workshare + use defined_assign + + integer :: a, aa(10), bb(10) + logical :: l(10) + l = .TRUE. + + !$omp workshare + !ERROR: Defined assignment statement is not allowed in a WORKSHARE construct + a = l + aa = bb + !$omp end workshare + +end program omp_workshare diff --git a/flang/test/SemanticsChecked/OpenMP/workshare04.f90 b/flang/test/SemanticsChecked/OpenMP/workshare04.f90 new file mode 100644 index 00000000000000..0ec635e52d2b73 --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/workshare04.f90 @@ -0,0 +1,50 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.7.4 workshare Construct +! Checks for OpenMP Workshare construct + +subroutine omp_workshare(aa, bb, cc, dd, ee, ff, n) + integer i, j, n, a(10), b(10) + integer, pointer :: p + integer, target :: t + real aa(n,n), bb(n,n), cc(n,n), dd(n,n), ee(n,n), ff(n,n) + + !ERROR: The structured block in a WORKSHARE construct may consist of only SCALAR or ARRAY assignments, FORALL or WHERE statements, FORALL, WHERE, ATOMIC, CRITICAL or PARALLEL constructs + !$omp workshare + p => t + + !$omp parallel + cc = dd + !$omp end parallel + + !ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp parallel workshare + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + ee = ff + !$omp end single + !$omp end parallel workshare + + where (aa .ne. 0) cc = bb / aa + + where (b .lt. 2) b = sum(a) + + where (aa .ge. 2.0) + cc = aa + bb + elsewhere + cc = dd + ee + end where + + forall (i = 1:10, n > i) a(i) = b(i) + + forall (j = 1:10) + a(j) = a(j) + b(j) + end forall + + !$omp atomic update + j = j + sum(a) + + !$omp end workshare + +end subroutine omp_workshare diff --git a/flang/test/SemanticsChecked/OpenMP/workshare05.f90 b/flang/test/SemanticsChecked/OpenMP/workshare05.f90 new file mode 100644 index 00000000000000..b57053e092e67b --- /dev/null +++ b/flang/test/SemanticsChecked/OpenMP/workshare05.f90 @@ -0,0 +1,61 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! OpenMP Version 4.5 +! 2.7.4 workshare Construct +! Checks for OpenMP Parallel constructs enclosed in Workshare constructs + +module workshare_mod + interface assignment(=) + module procedure work_assign + end interface + + contains + subroutine work_assign(a,b) + integer, intent(out) :: a + logical, intent(in) :: b(:) + end subroutine work_assign + + integer function my_func() + my_func = 10 + end function my_func + +end module workshare_mod + +program omp_workshare + use workshare_mod + + integer, parameter :: n = 10 + integer :: i, j, a(10), b(10) + integer, pointer :: p + integer, target :: t + logical :: l(10) + real :: aa(n,n), bb(n,n), cc(n,n), dd(n,n), ee(n,n), ff(n,n) + + !$omp workshare + + !$omp parallel + p => t + a = l + !$omp single + ee = ff + !$omp end single + !$omp end parallel + + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp parallel sections + !$omp section + aa = my_func() + !$omp end parallel sections + + !$omp parallel do + do i = 1, 10 + b(i) = my_func() + i + end do + !$omp end parallel do + + !$omp parallel + where (dd .lt. 5) dd = aa * my_func() + !$omp end parallel + + !$omp end workshare + +end program omp_workshare