https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106715
Bug ID: 106715 Summary: [OpenMP][5.2] Permit 'order' clause with 'for simd'/'do simd' + improve error message Product: gcc Version: 13.0 Status: UNCONFIRMED Keywords: diagnostic, openmp, rejects-valid Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: burnus at gcc dot gnu.org CC: jakub at gcc dot gnu.org Target Milestone: --- In OpenMP 5.1's 2.11.5.2, there is the restriction for worksharing-loop SIMD constructs: "* No ordered clause with a parameter can be specified." This is gone with OpenMP 5.2. However, 5.2 does have the following restriction (from 17.1 Nesting of Regions): "An ordered region that corresponds to an ordered construct without the simd clause specified must be closely nested inside a worksharing-loop region." So, this is now allowed: integer :: i, n, a(0:5) n = 5 !$omp do ordered(1) do i=1,n a(i) = a(i) + 1 end do end and this would also be allowed: integer :: i, n, a(0:5) n = 5 !$omp do simd ordered(1) do i=1,n a(i) = a(i) + 1 end do end ------------------------- Remark: Both Fortran snippets are already accepted; as is the C/C++ version of the first example. However, the C/C++ version of the second is rejected by GCC: foo44.c:4:31: error: ‘ordered’ clause with parameter may not be specified on ‘#pragma omp for simd’ construct 4 | #pragma omp for simd ordered(1) ------------------------ void foo() { int i, n = 5, a[5]; #pragma omp for simd ordered(1) for(i=0; i < n; i++) a[i] += 1; } ------------------------ However, this would not be allowed: integer :: i, n, a(0:5) n = 5 !$omp do simd ordered(1) do i=1,n !$omp ordered depend(sink:i-1) ! 'depend' -> 'doaccross' in 5.2 a(i) = a(i) + a(i-1) !$omp ordered depend(source) ! 'depend' -> 'doaccross' in 5.2 end do end ------------ Remark: GCC outputs the following: Error: ‘ordered’ construct with ‘depend’ clause must be closely nested inside a loop with ‘ordered’ clause with a parameter Printing an error is fine. However, I think this message is a bit misleading as 'ordered' construct is closely nested in a loop - and that loop has an 'ordered' clause with a parameter. It is just that the "for simd" is internally a "for" + "simd" and the 'ordered' is only only the outer 'for' bit. Likewise for the C/C++ version of the latter (same error diagnostic): void foo() { int i, n = 5, a[5]; #pragma omp for ordered(1) for(i=0; i < n; i++) { #pragma omp ordered depend(sink:i-1) a[i] += 1; #pragma omp ordered depend(source) } }