Community
cancel
Showing results for 
Search instead for 
Did you mean: 
tydeman
Beginner
83 Views

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

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
Black Belt
83 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
TimP
Black Belt
83 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.
tydeman
Beginner
83 Views

I tried your suggest options. It made no difference. if(x==x) still fails to detect a DFP NaN.
jimdempseyatthecove
Black Belt
83 Views

Was the statement optimized out of the code?
tydeman
Beginner
83 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.
Martyn_C_Intel
Employee
83 Views

Please could you attacha small test case, so that we're sure we're reproducing exactly what you see?
jimdempseyatthecove
Black Belt
83 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

tydeman
Beginner
83 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
*/
jimdempseyatthecove
Black Belt
83 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


Martyn_C_Intel
Employee
83 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.