Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7953 Discussions

if( x == x ) does wrong thing for decimal FP NaN

tydeman
Beginner
641 Views
The test for equality (x == x) is supposed to fail for NaN (Not-a-Number) for both binary FP and decimal FP.
It works correctly for binary FP, but does the wrong thing for decimal FP in icc 11.1 on Linux Fedora Core 10
on a Pentium 4 in IA-32. The isnan() macro works as expected for both BFP and DFP.
0 Kudos
10 Replies
jimdempseyatthecove
Honored Contributor III
641 Views
The compiler may have optimized that statement out of the code.

Open a Dissassembly window and see if the test is present and/or see if the test is using integer compares. If it is using integer compares then there may be an optimization switch that permits the integer compare.

Jim
0 Kudos
TimP
Honored Contributor III
641 Views
You would set options -fp-model strict -fp-speculation=strict if you wished to persuade icc to take the possibility of NaN into account. Even then, isnan() is preferred.
0 Kudos
tydeman
Beginner
641 Views
I tried your suggest options. It made no difference. if(x==x) still fails to detect a DFP NaN.
0 Kudos
jimdempseyatthecove
Honored Contributor III
641 Views
Was the statement optimized out of the code?
0 Kudos
tydeman
Beginner
641 Views
Command line options:
-fp-model strict -fp-speculation=strict -O0 -S -fcode-asm -fsource-asm -fverbose-asm
if( ld10 != ld10 )
xorl %eax,%eax
testl %eax,%eax
je label

So, it appears that a DFP compare is done as integer compare (which will not detect a NaN).
In addition, since a _Decimal128 is 128 bits, a 32-bit integer compare is not looking at all the bits.
0 Kudos
Martyn_C_Intel
Employee
641 Views
Please could you attacha small test case, so that we're sure we're reproducing exactly what you see?
0 Kudos
jimdempseyatthecove
Honored Contributor III
641 Views
Quoting tydeman
Command line options:
-fp-model strict -fp-speculation=strict -O0 -S -fcode-asm -fsource-asm -fverbose-asm
if( ld10 != ld10 )
xorl %eax,%eax
testl %eax,%eax
je label

So, it appears that a DFP compare is done as integer compare (which will not detect a NaN).
In addition, since a _Decimal128 is 128 bits, a 32-bit integer compare is not looking at all the bits.


The assembly code would seem to indicate that variable "ld10" is an uninitialized integer variable. Do you have IMPLICIT NONE?
IOW this looks like you are not using IMPLICIT NONE and have not declared variable LD10.

Ignore this post, I just got off the Fortran forum

The xorl "%eax, %eax" is used to zero a register (value of variable in register). Look at the code leading into this section and possibly do something with variable ld10 (e.g. copy it) make sure the type (typedef) is correct. What little code you sent implies ld10 is in eax, but for some reason is also being zeroed. Are you zeroing ld10 immediately before or after the if(...)?

Jim Dempsey

0 Kudos
tydeman
Beginner
641 Views
In creating a small test case, the generated assembly changed. It still is wrong.
Testing as a 32-bit integer is not the same as testing a 128-bit decimal FP value.

/*
* Hardware: Intel Pentium 4 in 32-bit mode
* O.S: Linux (Fedora Core 10) in 32-bit mode
* Software: Intel icc 11.1 (072) in C99 mode
* Command: icc -msse3 -O0 -fmath-errno -fp-model strict -fp-speculation=strict -H test73.c
*/
#define __STDC_WANT_DEC_FP__ /* Tell implementation that we want Decimal FP */
#include
int main(void){
_Decimal128 ld10;
ld10 -= ld10; /* zero */
ld10 /= ld10; /* NaN */
if( ld10 == ld10 ){
printf("Bad\n");
}else{
printf("OK\n");
}
return 0;
}
/*
;;; if( ld10 == ld10 ){
movl $1, %eax #test73.c:13.3
testl %eax, %eax #test73.c:13.3
je ..B1.3 # Prob 100% #test73.c:13.3
*/
0 Kudos
jimdempseyatthecove
Honored Contributor III
641 Views
_Decimal128 ld10;
ld10 -= ld10; /* zero */

ld10 -= ;

Try explicitly setting ld10 to 0.0 _prior_ to use
Or set it to any valid number, then use ld10 -= ld10

Jim Dempsey


0 Kudos
Martyn_C_Intel
Employee
641 Views
This issue was pursued separately through Intel Premier Support. It was fixed in update 2 toversion 12.0 of the Intel C++compiler, l_cprof_p_12.0.2.137 on Linux.
Two NaNs no longer compare as equal in decimal floating-point arithmetic, provided that you compile with -fp-model precise or -fp-model strict.
0 Kudos
Reply