Nvfortran-24.9 Regression: runtime segfault with optimization

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.

Thanks,
Harald

Thanks Harald. I’ve filed TPR#36571 and sent it engineering for review.

It’s interesting that it only fails with -O, so the work around would be to add an opt level like “-O2” or “-O3”.

-Mat

Hi Harald,

FYI, this regression, TPR #36571, was fixed in our 24.11 release.

Thanks again for the report.

Mat

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?

Harald

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.

Hi Harold,

We’ve got the second issue fix in 25.1 if you want to give it a try.

% nvfortran -O -V24.11 test2.F90 ; a.out
Segmentation fault (core dumped)
% nvfortran -O -V25.1 test2.F90 ; a.out
 PASS

I’m going to close the report, but if you find anything else, please let us know.

Thanks,
Mat