Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29575 Diskussionen

Possible IFX 2025.2.0 optimization bug (-O2 vs -O1)

cfried
Einsteiger
131Aufrufe

I believe I have found a compiler bug in IFX 2025.2.0. The problem occurs with -O2 but not with -O1.

The following reproducer stops with

STOP "slice element 1 incorrect"

when compiled with -O2, but runs correctly with -O1.

program test
   use iso_fortran_env, only : real64
   implicit none

   integer, parameter :: n = 49
   complex(real64), allocatable :: a(:,:,:,:) ! Works for an automatic array
   complex(real64) :: tmp(2)

   integer :: i,j,k

   allocate(a(-n:n,-n:n,-n:n,2))
   a = (0.0_real64,0.0_real64)

   a(0,0,0,1) = (1.0_real64,0.0_real64)
   a(0,0,0,2) = (2.0_real64,0.0_real64)

   tmp = a(0,0,0,:)

   print *, "scalar 1 =", a(0,0,0,1)
   print *, "scalar 2 =", a(0,0,0,2)
   print *, "slice    =", tmp

   if (tmp(1) /= a(0,0,0,1)) stop "slice element 1 incorrect"
   if (tmp(2) /= a(0,0,0,2)) stop "slice element 2 incorrect"

   deallocate(a)

end program

Observations:

  • The problem is reproducible with an allocatable array.

  • The problem disappears when using an automatic (stack) array instead.

  • The array has non-unit lower bounds.

  • The problem occurs only with -O2; -O1 behaves correctly.

In addition, I encountered two possibly related issues in a larger application:

  1. Array section passed as actual argument

A call of the form

call potential_coul(..., dpw(:,:,:,:nspin), ...)

caused a segmentation fault when running under Valgrind.

Replacing it by

call potential_coul(..., dpw, ...)

eliminated the crash.

In this case the two forms are semantically equivalent because the full array extent is passed.

  1. Automatic character length

The declaration

character(len_trim(string)) :: str

triggered a Valgrind warning:

Conditional jump or move depends on uninitialised value(s)

inside the Intel runtime library.

Changing the declaration to

character(len(string)) :: str

eliminated the warning.

I do not know whether these three observations are related, but they all involve compiler-generated descriptors/temporaries and all occurred with IFX 2025.2.0.

Has anyone seen similar issues, or can this be reproduced by Intel?

0 Kudos
1 Lösung
Shiquan_Su
Moderator
1Aufruf

We tested your reproducer against our latest oneapi 2026.0 release. The issue goes away. Please upgrade your oneapi version to 2026.0 to fix the issue.

 

$ cat runme.sh

#!/bin/bash

module purge

module load intel/oneapi/2026.0

ifx -O2 test.f90

./a.out

$ cat test.f90

program test

  use iso_fortran_env, only : real64

  implicit none

 

  integer, parameter :: n = 49

  complex(real64), allocatable :: a(:,:,:,:) ! Works for an automatic array

  complex(real64) :: tmp(2)

 

  integer :: i,j,k

 

  allocate(a(-n:n,-n:n,-n:n,2))

  a = (0.0_real64,0.0_real64)

 

  a(0,0,0,1) = (1.0_real64,0.0_real64)

  a(0,0,0,2) = (2.0_real64,0.0_real64)

 

  tmp = a(0,0,0,:)

 

  print *, "scalar 1 =", a(0,0,0,1)

  print *, "scalar 2 =", a(0,0,0,2)

  print *, "slice  =", tmp

 

  if (tmp(1) /= a(0,0,0,1)) stop "slice element 1 incorrect"

  if (tmp(2) /= a(0,0,0,2)) stop "slice element 2 incorrect"

 

  deallocate(a)

 

end program

$ . ./runme.sh

 scalar 1 = (1.00000000000000,0.000000000000000E+000)

 scalar 2 = (2.00000000000000,0.000000000000000E+000)

 slice  = (1.00000000000000,0.000000000000000E+000)

 (2.00000000000000,0.000000000000000E+000)

Lösung in ursprünglichem Beitrag anzeigen

1 Antworten
Shiquan_Su
Moderator
2Aufrufe

We tested your reproducer against our latest oneapi 2026.0 release. The issue goes away. Please upgrade your oneapi version to 2026.0 to fix the issue.

 

$ cat runme.sh

#!/bin/bash

module purge

module load intel/oneapi/2026.0

ifx -O2 test.f90

./a.out

$ cat test.f90

program test

  use iso_fortran_env, only : real64

  implicit none

 

  integer, parameter :: n = 49

  complex(real64), allocatable :: a(:,:,:,:) ! Works for an automatic array

  complex(real64) :: tmp(2)

 

  integer :: i,j,k

 

  allocate(a(-n:n,-n:n,-n:n,2))

  a = (0.0_real64,0.0_real64)

 

  a(0,0,0,1) = (1.0_real64,0.0_real64)

  a(0,0,0,2) = (2.0_real64,0.0_real64)

 

  tmp = a(0,0,0,:)

 

  print *, "scalar 1 =", a(0,0,0,1)

  print *, "scalar 2 =", a(0,0,0,2)

  print *, "slice  =", tmp

 

  if (tmp(1) /= a(0,0,0,1)) stop "slice element 1 incorrect"

  if (tmp(2) /= a(0,0,0,2)) stop "slice element 2 incorrect"

 

  deallocate(a)

 

end program

$ . ./runme.sh

 scalar 1 = (1.00000000000000,0.000000000000000E+000)

 scalar 2 = (2.00000000000000,0.000000000000000E+000)

 slice  = (1.00000000000000,0.000000000000000E+000)

 (2.00000000000000,0.000000000000000E+000)

Antworten