hidden text to trigger early load of fonts ПродукцияПродукцияПродукцияПродукция Các sản phẩmCác sản phẩmCác sản phẩmCác sản phẩm المنتجاتالمنتجاتالمنتجاتالمنتجات מוצריםמוצריםמוצריםמוצרים
Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29064 Discussions

Incorrect results using -O2 or -O3 in ifx. Minimal example attached.

RagnarVdB
Beginner
466 Views
Hello


When upgrading from ifort to ifx 2025.1.0 recently, We ran into a strange issue when compiling a specific piece of code with optimizations enabled. Running on Rocky Linux 9.5 with Intel Xeon Gold 6248 CPU. Below is a minimal working example:


program test
  real(kind=8) :: A(13)
  real(kind=8) :: B(13)
  integer :: i
  open(8,file='table.txt')
  DO i=1,13
    read (8,*) B(i)
    A(i) = B(i)
  ENDDO
  print *, "compare", A(1), B(1)
end program test


'table.txt' is a text file containing one number per line, and is longer than 13 elements. An example is attached.

When compiling this small program with -O2 or -03 optimizations, the assignment A(i) = B(i) is not performed correctly, and A contains all zeroes, i.e. the program prints
compare 0.000000000000000E+000 20.0000000000000
When compiling with -O1 or -O0, behavior is normal, and the program prints
compare 20.0000000000000 20.0000000000000.
We have the same issue with ifx 2024.0.0, whereas the program works correctly in ifort or gfortran.

We inspected the assembly generated by ifx, and found that the instructions corresponding to the assignment A(i) = B(i) are all moved to the beginning of the loop and done in vectorized form. The assignments are therefore done before the file is read, and A remains all zeroes. It seems that the compiler is simply ignoring the fact that B is being written to in the read operation.
 
Small changes to the code can also affect whether this incorrect optimization is being done or not. For example, when looping 12 or fewer iterations (instead of 13 or more), or when adding print *, i inside the loop, the program works as intended again. When we add print *, "compare", A(i), B(i) inside the loop, after the assignment, the code still works incorrectly with ifx 2025.0.4, but correctly in 2024.0.0.

It is easy to fix the issue in this case, by moving the assignments after the loop for example, but there are many other places in our code with similar structures, where a bug like this might go unnoticed. We would therefore like to know what the cause of the problem is, and whether we could solve it on the compiler level without falling back to -O1 optimizations.
 
Thanks in advance!
0 Kudos
5 Replies
garraleta_fortran
412 Views

It's true
W11
VS 2022

Compiling with Intel® Fortran Compiler 2025.1.0 [Intel(R) 64]...
ifx /nologo /O3 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads /c /Qlocation,link,"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64" /Qm64 "B:\FORO20\P.F90"
Linking...
Link /OUT:"x64\Release\FORO20.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"x64\Release\FORO20.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /IMPLIB:"B:\FORO20\x64\Release\FORO20.lib" -qnextgen -qm64 "x64\Release\P.obj"
Embedding manifest...
mt.exe /nologo /outputresource:"B:\FORO20\x64\Release\FORO20.exe;#1" /manifest "x64\Release\FORO20.exe.intermediate.manifest"

FORO20 - 0 error(s), 0 warning(s)

Program

program test
real(kind=8) :: A(13)
real(kind=8) :: B(13)
integer :: i
open(8,file='table.txt')
DO i=1,13
read (8,*) B(i)
A(i) = B(i)
!WRITE(*,*)A(I),B(I)
ENDDO
DO I=1,13
WRITE(*,*)A(I),B(I)
ENDDO
end program test

Result
0.000000000000000E+000 20.0000000000000
0.000000000000000E+000 40.0000000000000
0.000000000000000E+000 60.0000000000000
0.000000000000000E+000 80.0000000000000
0.000000000000000E+000 100.000000000000
0.000000000000000E+000 120.000000000000
0.000000000000000E+000 140.000000000000
0.000000000000000E+000 160.000000000000
0.000000000000000E+000 180.000000000000
0.000000000000000E+000 200.000000000000
0.000000000000000E+000 220.000000000000
0.000000000000000E+000 240.000000000000
0.000000000000000E+000 260.000000000000

 

0 Kudos
MarcGrodent
Novice
397 Views

Hello @RagnarVdB 

 

I found the same results as you with ifx compiler from oneapi 2024.0 under linux. The code gives correct results for -O1, but starts failing for -O2 and -O3. I've tried various compiler flags but none of them solves the issue. Maybe an Intel specialist can recommend the appropriate flag. However there is definitely something going wrong here and this can be quite tricky to detect in a large code.

 

Regards

 

  Marc

 

garraleta_fortran
263 Views

The problem posed by RagnarVdB
Incorrect results using -O2 or -O3 in ifx.
I think it's very important

Why are there no answers? 

0 Kudos
Devorah_H_Intel
Moderator
162 Views

Our support team will respond to this.  Meanwhile, please check out the Priority Support option for fast turnaround. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
191 Views

>>It seems that the compiler is simply ignoring the fact that B is being written to in the read operation.

That sounds like a correct diagnosis of a compiler optimization bug.

Jim Dempsey

 

0 Kudos
Reply