Observed issues › stress/gcc-declare-target-allocatable-component-ice
declare target module variable with an allocatable component used in a target region: internal compiler error
Legality: independently confirmed. One independent reading was uncertain; 2 adjudicating readings that weighed both find the program legal and the result required: gq%v1 is allocated before the enter data map and not reallocated or deallocated while mapped, satisfying the allocation restriction. The target region maps out and host_flag; gq is declare target. Only iteration 1 writes host_flag and each iteration writes a distinct out(i), so there is no race. Acceptance is required, so the ICE is a compiler bug. How this is checked
A module variable of a derived type with an allocatable component, named in a declare target directive and read in a target teams distribute parallel do loop after its component is mapped by target enter data, stops GCC 16.2 with an internal compiler error (lower_omp_target) for both offload targets. Without the declare target directive the program compiles and runs correctly. AFAR, CCE and NVHPC run the stress programs correctly.
Affected variants
| Compiler | MI300A gfx942 unified memory (XNACK 1) | MI300A gfx942 copy (XNACK 0) | MI250X gfx90a copy (XNACK 0) | MI300X gfx942 copy (XNACK 0) | MI350X gfx950 copy (XNACK 0) | A100 sm_80 separate memory | A100 sm_80 managed memory |
|---|---|---|---|---|---|---|---|
| AFAR 24.3.0 | correct | correct | unknown not run | correct | correct | n/a | n/a |
| CCE 19.0.0 | fails another way | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 20.0.2 | fails another way | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.3 | fails another way | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.4 | fails another way | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| NVHPC 25.11 | n/a | n/a | n/a | n/a | n/a | correct | correct |
| NVHPC 26.9 | n/a | n/a | n/a | n/a | n/a | correct | correct |
| GCC 16.2.0 | behaves incorrectly | behaves incorrectly | behaves incorrectly | behaves incorrectly | behaves incorrectly | behaves incorrectly | n/a |
"behaves incorrectly" / "not supported": this issue, confirmed in up to four environments (another build directory, another node, a repeat). "fails another way": a different failure, not counted as this issue. "unknown": not run there, or the runs disagree.
Messages
| Result | Compiler and GPU | Message |
|---|---|---|
| behaves incorrectly | GCC 16.2.0, MI300A unified GCC 16.2.0, MI300A copy | showduring GIMPLE pass: omplower
site-stress--gcc-declare-target-allocatable-component-ice.f90:45:71:
45 | !$omp target teams distribute parallel do map(tofrom: out, host_flag)
| ^
internal compiler error: in lower_omp_target, at omp-low.cc:13204
0x2072e2d internal_error(char const*, ...)
<dir>:787
0x7d943f fancy_abort(char const*, int, char const*) |
| behaves incorrectly | GCC 16.2.0, MI250X | showduring GIMPLE pass: omplower
site-stress--gcc-declare-target-allocatable-component-ice.f90:42:71:
42 | !$omp target teams distribute parallel do map(tofrom: out, host_flag)
| ^
internal compiler error: in lower_omp_target, at omp-low.cc:13204
0x2072e2d internal_error(char const*, ...)
<dir><host>-gcc-src/gcc-16.2.0/gcc/diagnostic-global-context.cc:787
0x7d943f fancy_abort(char const*, int, char const*) |
| behaves incorrectly | GCC 16.2.0, MI300X GCC 16.2.0, MI350X | showduring GIMPLE pass: omplower
site-stress--gcc-declare-target-allocatable-component-ice.f90:45:71:
45 | !$omp target teams distribute parallel do map(tofrom: out, host_flag)
| ^
internal compiler error: in lower_omp_target, at omp-low.cc:13204
0x2083fcd internal_error(char const*, ...)
<home>/<user>/gcc-work/gcc-16.2.0/gcc/diagnostic-global-context.cc:787
0x7cebc6 fancy_abort(char const*, int, char const*) |
| behaves incorrectly | GCC 16.2.0, A100 separate | showduring GIMPLE pass: omplower
site-stress--gcc-declare-target-allocatable-component-ice.f90:42:71:
42 | !$omp target teams distribute parallel do map(tofrom: out, host_flag)
| ^
internal compiler error: in lower_omp_target, at omp-low.cc:13204
0x214aceb internal_error(char const*, ...)
<home>/gcc-build/gcc-16.2.0/gcc/diagnostic-global-context.cc:787
0x7db5a3 fancy_abort(char const*, int, char const*) |
| fails another way | CCE 19.0.0, MI300A unified | showMemory access fault by GPU node-5 (Agent handle: 0x4c80f0) on address (nil). Reason: Unknown. |
| fails another way | CCE 20.0.2, MI300A unified | showMemory access fault by GPU node-4 (Agent handle: 0x4c8090) on address (nil). Reason: Unknown. |
| fails another way | CCE 21.0.3, MI300A unified CCE 21.0.4, MI300A unified | showACC: libcrayacc/acc_hw_amd.c:1927 CRAY_ACC_ERROR - hipStreamSynchronize returned hipErrorIllegalAddress: 'an illegal memory access was encountered' from site-stress--gcc-declare-target-allocatable-co ACC: libcrayacc/acc_hw_amd.c:1476 CRAY_ACC_ERROR - hipDeviceSynchronize returned hipErrorIllegalAddress: 'an illegal memory access was encountered' |
Reproduce
GCC 16.2.0, MI300A unified
export LD_LIBRARY_PATH=$GCC_16_2/lib64:/opt/rocm-7.2.1/lib $GCC_16_2/bin/gfortran -fopenmp -foffload=amdgcn-amdhsa -foffload-options=amdgcn-amdhsa=-march=gfx942 -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
GCC 16.2.0, A100 separate
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=$GCC_16_2/lib64 $GCC_16_2/bin/gfortran -fopenmp -foffload=nvptx-none -foffload-options=nvptx-none=-march=sm_80 -foffload-options=nvptx-none=-latomic -O2 repro.f90 -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
AFAR 24.3.0, MI300A unified (runs correctly)
$AFAR/bin/amdflang -fopenmp --offload-arch=gfx942 -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
Program (53 lines)
! # Finding (GCC 16.2, stress sweeps): a declare target module variable of a derived type with an allocatable component in a
! target region: internal compiler error in lower_omp_target
!
! - toolchains: gcc_g90 (GCC 16.2.0, AMD Instinct MI250X gfx90a, Tioga) and gcc_sm80 (GCC 16.2.0, NVIDIA A100 sm_80, wingtip);
! separate memory only; -O2
! - build: gfortran -fopenmp -foffload=amdgcn-amdhsa -foffload-options=amdgcn-amdhsa=-march=gfx90a -O2 (gcc_g90);
! -foffload=nvptx-none -foffload-options=nvptx-none=-march=sm_80 -foffload-options=nvptx-none=-latomic -O2 (gcc_sm80)
! - failure: ice: internal compiler error: in lower_omp_target
! - observed: `internal compiler error: in lower_omp_target, at omp-low.cc:13204` ("during GIMPLE pass: omplower") at the target
! teams distribute parallel do directive, on both targets (the host compiler fails before any offload code is made)
! - expected: compiles; prints `sum= 6304` and `RESULT ran_on_host=0 check=pass`
! - rule: a variable may appear in a declare target directive in the specification part of a module ("If an extended list item is a
! variable name, the directive must appear in the specification part of a subroutine subprogram, function subprogram, program or
! module", 5.2 §7.8.1 p.206 l.27-28); its allocatable component is mapped by the enter data construct.
! - same-compiler control (compiles; correct, gcc_sm80: mandatory pass 5 of 5; unset pass 5 of 5; gcc_g90: mandatory pass 5 of 5;
! unset pass 5 of 5 (results/parity/<machine>/<tc>/probes.jsonl)): the same program without the declare target directive
! (controls/gcc-declare-target-allocatable-component-control.f90).
! - other families: AFAR, CCE 19/20/21 and NVHPC 25.11/26.9 run the stress programs (template.declared_alloc-omp-8/159/400-1, eight
! allocatable components) correctly in copy mode (results/stress/s1-g5, nv1-omp). The site's finding matrix runs this file on
! every compiler.
! - stress programs (6 cells (3 gcc_g90, 3 gcc_sm80); gate: confirmed 6; the stress kind has no confirmer path):
! template.declared_alloc-omp-159-1, template.declared_alloc-omp-400-1, template.declared_alloc-omp-8-1
! - legality: the stress programs pass the stress gate and the pre-run check (offload.engine.prerun.check: the rules and AFAR's
! front
! end, two witnesses; results/parity/stress-checked); GCC is a compiler under test only and never a legality witness.
module dt_m
implicit none
type :: holder
integer, allocatable :: v1(:)
end type holder
type(holder) :: gq
!$omp declare target(gq)
end module dt_m
program declared_alloc_component
use omp_lib, only: omp_is_initial_device
use dt_m
implicit none
integer :: out(64), i, host_flag
allocate(gq%v1(64))
gq%v1 = [(3*i, i = 1, 64)]
!$omp target enter data map(to: gq%v1)
out = 0
host_flag = 1
!$omp target teams distribute parallel do map(tofrom: out, host_flag)
do i = 1, 64
if (i == 1) host_flag = merge(1, 0, omp_is_initial_device())
out(i) = gq%v1(i) + 1
end do
!$omp target exit data map(delete: gq%v1)
print '(a,i0)', 'sum= ', sum(out)
print '(a,i0,a,a)', 'RESULT ran_on_host=', host_flag, ' check=', merge('pass', 'fail', sum(out) == 3*64*65/2 + 64)
end program declared_alloc_component
Something to add? Dispute its legality · Report it fixed in a newer release · Report a mistake on this page
Expected and observed
Expected
check=pass
Observed where it behaves incorrectly
during GIMPLE pass: omplower
site-stress--gcc-declare-target-allocatable-component-ice.f90:45:71:
45 | !$omp target teams distribute parallel do map(tofrom: out, host_flag)
| ^
internal compiler error: in lower_omp_target, at omp-low.cc:13204
0x2072e2d internal_error(char const*, ...)
<dir>:787
0x7d943f fancy_abort(char const*, int, char const*)What the specification requires
The specification text this program relies on and the compiler is expected to support.
OpenMP 5.2 §7.8.1 p.206 l.27-28
If an extended list item is a variable name, the directive must appear in the specification part of a subroutine subprogram, function subprogram, program or module
Evidence
Same compiler, one change
- the same program without declare target: not run yet
Control program
! Control of stress/gcc-declare-target-allocatable-component-ice.f90: the same program without the declare target ! directive (compiles; correct on gcc_g90 and gcc_sm80). module dt_m implicit none type :: holder integer, allocatable :: v1(:) end type holder type(holder) :: gq end module dt_m program declared_alloc_component use omp_lib, only: omp_is_initial_device use dt_m implicit none integer :: out(64), i, host_flag allocate(gq%v1(64)) gq%v1 = [(3*i, i = 1, 64)] !$omp target enter data map(to: gq%v1) out = 0 host_flag = 1 !$omp target teams distribute parallel do map(tofrom: out, host_flag) do i = 1, 64 if (i == 1) host_flag = merge(1, 0, omp_is_initial_device()) out(i) = gq%v1(i) + 1 end do !$omp target exit data map(delete: gq%v1) print '(a,i0)', 'sum= ', sum(out) print '(a,i0,a,a)', 'RESULT ran_on_host=', host_flag, ' check=', merge('pass', 'fail', sum(out) == 3*64*65/2 + 64) end program declared_alloc_component
Other compilers run it correctly
AFAR 24.3.0, CCE 19.0.0, CCE 20.0.2, CCE 21.0.3, CCE 21.0.4, NVHPC 25.11, NVHPC 26.9