https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123252

            Bug ID: 123252
           Summary: OpenACC: derived-type scalar component has wrong value
                    in device kernel when only array component is mapped
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: albert at tugraz dot at
  Target Milestone: ---

current trunk; repo base upstream/master at
769041822723208bf85a91ac409b9b0bdae3fff0 (2025-12-22)

  COLLECT_GCC=/opt/gcc16/bin/gfortran
 
COLLECT_LTO_WRAPPER=/opt/gcc16/libexec/gcc/x86_64-pc-linux-gnu/16.0.0/lto-wrapper
  OFFLOAD_TARGET_NAMES=nvptx-none
  Target: x86_64-pc-linux-gnu
  Configured with: ../../gcc/configure --prefix=/opt/gcc16
--enable-languages=c,c++,fortran,lto --disable-multilib --disable-nls
--enable-checking=release
  --disable-bootstrap --enable-offload-targets=nvptx-none CFLAGS='-O2 -pipe'
CXXFLAGS='-O2 -pipe' : (reconfigured) ../../gcc/configure --prefix=/opt/gcc16
  --disable-multilib --disable-nls --enable-checking=release
--disable-bootstrap --enable-offload-targets=nvptx-none CFLAGS='-O2 -pipe'
CXXFLAGS='-O2 -pipe'
  --enable-languages=c,c++,fortran,lto --no-create --no-recursion
  Thread model: posix
  Supported LTO compression algorithms: zlib zstd
  gcc version 16.0.0 20251222 (experimental) (GCC)

If only an allocatable array component of a derived type is mapped with !$acc
enter data copyin(c%arr(…)), then a later OpenACC kernel reading a scalar
component c%flag can observe the wrong value on the device (behaves as
false/garbage), even though c%flag is .true. on the host.

Reproducer:

program mre
    use, intrinsic :: iso_fortran_env, only: dp => real64
    implicit none

    type :: container_t
      real(dp), allocatable :: arr(:)
      logical :: flag
      integer :: n
    end type container_t

    type(container_t) :: c
    real(dp), allocatable :: result(:)
    integer :: i
    real(dp) :: diff

    c%n = 100
    c%flag = .true.
    allocate(c%arr(c%n))
    do i = 1, c%n
      c%arr(i) = real(i, dp)
    end do

    !$acc enter data copyin(c%arr(1:c%n))

    allocate(result(c%n))
    result = 0.0_dp

    !$acc data copy(result)
    !$acc parallel loop present(c%arr)
    do i = 1, c%n
      if (c%flag) then
        result(i) = c%arr(i) * 2.0_dp
      else
        result(i) = c%arr(i)
      end if
    end do
    !$acc end parallel loop
    !$acc end data

  diff = maxval(abs(result - 2.0_dp * c%arr))
    if (diff > 1.0e-10_dp) then
      print *, "FAIL: max diff = ", diff
      stop 1
    end if
    print *, "PASS"
  end program mre


gfortran -v -save-temps -O2 -cpp -fopenacc -foffload=nvptx-none mre.F90 -o mre
ACC_DEVICE_TYPE=nvidia ./mre

The OpenACC regions are lowered with maps that include map(struct:c [len: 1])
and the array component, but the device kernel still reads flag incorrectly.

#pragma omp target oacc_enter_data map(struct:c [len: 1]) map(to:c.arr [pointer
set, len: 64]) ...
#pragma omp target oacc_parallel map(struct:c [len: 1]) map(to:c.arr [pointer
set, len: 64]) ...
...
D.4871 = D.4960->flag;
if (D.4871 != 0) goto ...

Reply via email to