Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Bad optimization for NINT/DBLE

Cross__Mat
Beginner
911 Views

I'm on system

$ uname -a
Linux glasgow 3.1.7-1.fc16.x86_64 #1 SMP Tue Jan 3 19:45:05 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

with

$ ifort -V
Intel Fortran Intel 64 Compiler XE for applications running on Intel 64, Version 12.1.1.256 Build 20111011

For source file

$ cat test.f90
double precision :: rv = 23452123
integer :: iv = 23452123, oiv, nv
logical l
oiv = nint(rv)
nv = nint(dble(iv))
l = (oiv/=nv)
if (l) stop 'ERROR'
end

I see

$ rm a.out ; ifort -O1 test.f90 ; ./a.out
$ rm a.out ; ifort -O2 test.f90 ; ./a.out
ERROR

Note that the value used (for rv and iv) is signficant, and the presence of the lines referencing l are required too for the ERROR to appear.

0 Kudos
7 Replies
TimP
Honored Contributor III
911 Views
Interesting.
I found 2 work-arounds:
1) If you set -fp-model source, you should get a library function call rather than in-line code for nint(), avoiding this apparent round-to-even symptom.
2) If I write real(iv,kind(1d0)) in place of dble(iv) the problem appears to be corrected.
Apparently, dble() is being replaced erroneously by real() with default kind.
0 Kudos
jimdempseyatthecove
Honored Contributor III
911 Views
Try:

double precision :: rv = 23452123_8
or
double precision :: rv = 23452123D+0

The compiler optimization may have removed (double)rv and replaced it with the value of its initializer (float)((int)23452123)). (float==REAL*4)

Jim Dempsey
0 Kudos
mecej4
Honored Contributor III
911 Views
> Apparently, dble() is being replaced erroneously by real() with default kind

That, coupled with the fact that the number in question cannot be represented exactly in single-precision real (23 bit significand), leads to the discrepancy.
0 Kudos
Anonymous66
Valued Contributor I
911 Views
You should replace the function nint with the generic function int.

NINT expects an argument of type REAL(4), so as part of one of the optimizations iv is being treated as type real(4). As Mecej4 notes, 23452123 cannot be represented exactly as a single precision floating point variable. This is whats causing the apparent error.
0 Kudos
Anonymous66
Valued Contributor I
911 Views
Disregard my earlier post. This is an optimization bug. I have escalated it to development. The issue number is DPD200178025. I will post any updates on the issue to this thread.

Regards,
Annalee
0 Kudos
Anonymous66
Valued Contributor I
911 Views
A fix has been found for this issue. We are planning to include it in a release scheduled for later this year.

Regards,
Annalee
0 Kudos
Anonymous66
Valued Contributor I
911 Views
This is issue has been fixed in Intel® Fortran Composer XE for Linux* 2013 which is now available at the Intel® Registration Center. Regards, Annalee Intel Developer Support * Other names and brands may be claimed as the property of others.
0 Kudos
Reply