https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126189
Bug ID: 126189
Summary: Fortran: warn when separate 'target' encloses a
teams/distribute/parallel construct with a 'reduction'
clause (reduction result silently lost)
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libgomp
Assignee: unassigned at gcc dot gnu.org
Reporter: yao2019xm2 at 163 dot com
CC: jakub at gcc dot gnu.org
Target Milestone: ---
Created attachment 64983
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64983&action=edit
Compiled with gfortran -fopenmp -Wall -Wextra warn_repro.f90
Summary:
Fortran: warn when separate 'target' encloses a teams/distribute/parallel
construct with a 'reduction' clause (reduction result silently lost)
Product: gcc
Component: fortran
Keywords: diagnostic, openmp
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109701
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99928
---
Description
When 'target' and a worksharing construct with 'reduction' appear on separate
directives, the scalar reduction variable becomes firstprivate on the target
(per OpenMP 5.0-5.2 §2.19.7), and the reduction result is silently lost.
The implicit map(tofrom:) rule only applies to combined constructs.
Explicitly adding map(tofrom:r) to the inner target directive also fixes it.
GCC compiles all three forms without any diagnostic.
Intel ifx successfully returns the reduction result in the separate form.
This suggests that ifx internally treats the scalar reduction variable as
implicitly mapped (tofrom) even when the target and teams constructs are
not combined — a reasonable extension for compatibility and usability.
Confirmed on x86_64 (GCC 12.2.0, Debian 12) and aarch64 (GCC 15.2.0, macOS 15).
Both are CPU-only environments (no GPU), target regions fall back to host
execution.
Request (priority 1): add a warning (e.g. under -Wopenmp) when a
teams/distribute/parallel construct with a reduction clause appears inside
a separate target region, suggesting either:
(a) use the combined 'target teams distribute parallel do reduction(...)'
(b) or add 'map(tofrom:var)' to the enclosing 'target' directive
Request (priority 2, alternative): consider following ifx's approach —
automatically treat a scalar reduction variable inside a separate
target+teams construct as if it had implicit map(tofrom:). The OpenMP
5.0 spec already has this rule for combined constructs (§2.19.7); extending
it to the separate form would eliminate this class of portability bugs
without breaking any valid code (a reduction result that is intentionally
discarded is nonsensical).
Minimal reproducer — compiles without warning, prints garbage:
--- cut here: warn_repro.f90 ---
program main
implicit none
real :: r
integer :: i
!$omp target data map(from: r)
!$omp target
!$omp teams distribute parallel do reduction(+:r)
do i = 1, 100
r = r + 1.0
end do
!$omp end teams distribute parallel do
!$omp end target
!$omp end target data
print *, "Expected 100.0, got:", r
end program main
--- end ---
$ gfortran -fopenmp warn_repro.f90 && ./a.out
Actual output (garbage, never 100.0):
x86_64 (GCC 12.2.0, Debian 12): non-deterministic, varies between runs
aarch64 (GCC 15.2.0, macOS 15): 1.40129846E-45 (0x00000001)
Suggested warning message:
Warning: reduction variable 'r' in a worksharing construct inside a
separate 'target' region will be firstprivate and its reduced value
will be lost when the target region ends [-Wopenmp]
note: use '!$omp target map(tofrom: r)' or the combined construct
'!$omp target teams distribute parallel do reduction(+:r)' instead