Hello,
the following sample is reduced from a larger application and crashes at runtime when compiled with “-O -tp haswell”:
! Crashes when compiled with -O -tp haswell:
module bug
implicit none
type t_ray
real :: var = 0
end type t_ray
type t_obs_err
real :: s = 0
end type t_obs_err
type(t_obs_err), pointer :: obs_err(:) => NULL ()
type(t_obs_err), target :: dummy ! Workaround for nvfortran-24.9 bug
integer :: modify_obs_err = 1
namelist /GPS_RO/ modify_obs_err ! works when commented out
contains
subroutine set_obs_err (rays)
type(t_ray) ,pointer :: rays (:)
integer :: k
real :: new_var
type(t_obs_err), pointer :: e
if (modify_obs_err > 1) then
e => obs_err(1)
else
e => NULL()
! e => dummy ! workaround for optimization bug
end if
if (modify_obs_err > 0) then
do k=1, size (rays) ! <<< may crash here
if (modify_obs_err <= 1) then
new_var = 1
else
new_var = e% s ! works when commented out
end if
rays(k)% var = new_var ! works when commented out
enddo
endif
end subroutine set_obs_err
end module
program main
use bug
implicit none
type(t_ray), pointer :: rays(:)
allocate (rays(10))
call set_obs_err (rays)
deallocate (rays)
print *, "PASS"
end program main
Changing any of the indicated places, changing the optimization level (e.g. to -O0) may let the reduced testcase pass.
There is no issue with previous releases. E.g. 24.7 works fine, as do other compilers.
Running under gdb points to the loop entry when the segfault happens.
The regression appears not fully fixed here. Adding a few more lines from the original code let the crash reappear with 24.11:
! Crashes when compiled with -O -tp haswell:
module bug
implicit none
type t_ray
real :: var = 0
end type t_ray
type t_obs_err
integer :: x = -99
real :: s = 0
end type t_obs_err
type(t_obs_err), pointer :: obs_err(:) => NULL ()
type(t_obs_err), target :: dummy ! Workaround for nvfortran-24.9 bug
integer :: modify_obs_err = 1
namelist /GPS_RO/ modify_obs_err ! works when commented out
contains
subroutine set_obs_err (rays)
type(t_ray) ,pointer :: rays (:)
integer :: k
real :: new_var
type(t_obs_err), pointer :: e
if (modify_obs_err > 1) then
e => obs_err(1)
else
e => NULL()
! e => dummy ! workaround for optimization bug
end if
if (modify_obs_err > 0) then
do k=1, size (rays) ! <<< may crash here
if (modify_obs_err <= 1) then
new_var = 1
else
new_var = e% s ! works when commented out
if (e% x > 0) new_var = 2*new_var ! works when commented out
end if
select case (modify_obs_err)
case (1)
rays(k)% var = new_var * 3
case default
rays(k)% var = new_var
end select
enddo
endif
end subroutine set_obs_err
end module
program main
use bug
implicit none
type(t_ray), pointer :: rays(:)
allocate (rays(10))
call set_obs_err (rays)
deallocate (rays)
print *, "PASS"
end program main
This crashes in the same place with 24.11 as with 24.9; 24.7 passes.
The issue may be very sensitive to small code perturbations.
I assume there is no compiler directive to reduce optimization for a single loop (nest), right?
Ok, I reopened the report and attached the updated example.
Different directives have different scopes, but the “opt” directive has either file or routine scoping.
Though here, the crash only occurs at the default “-O” (which is between -O1 and -O2), if you specify any other optimization, -O0, -01, -O2, -O3, -Ofast, then it’s fine. It’s an odd error that way, but you should be ok by picking a higher or low opt flag.