Division bug in Intel C++ Compiler 9.0

Division bug in Intel C++ Compiler 9.0

Greetings,

So after three days of our programs behaving completely wrong when compiled as the Release build of Intel C++ Compiler 9.0, I have found a bug.

It occurs when dividing a short/int/double by a float. The return value is the initial short/int/long value. This is only the case when dividing by a float, only when the short/int/long is read of a stored variable, and only under the
release build.

Is Intel aware of this? Is there a fix? A quick search of the forums suggests not. So what is the bug "finder's fee" after three wasted days?

Bellow is the test code I wrote to make sure there was a problem. The code was compiled under different builds and compilers. See bellow.

Regards,

Aristotel Digenis

/*
Intel_vs_VSNET.cpp : Short program proving the following
bug in the Intel C++ compiler 9.0, when dividing a
short/int/double by a float. The return value is the
initial short/int/long value. This is only the case
when dividing by a float, only when the short/int/long
is read of a stored variable, and only under the
RELEASE build.
By : Aristotel Digenis
Date : 11/08/2005
*/

#include
#include
#include
#include

int _tmain(int argc, _TCHAR* argv[])
{
int nValue = 500;
printf("nValue == %d

", nValue);

float fDivResult = nValue / 100.0f;
float fMulResult = nValue * 0.01f;

printf("fDivResult == %f
", fDivResult);
printf("fMulResult == %f", fMulResult);

fDivResult = 500 / 100.f;
fMulResult = 500 * 0.01f;

printf("

fDivResult == %f
", fDivResult);
printf("fMulResult == %f", fMulResult);
return 0;
}

/*********RESULTS********/

/*
Visual Studio.NET Debug
nValue == 500

fDivResult == 5.000000
fMulResult == 5.000000

fDivResult == 5.000000
fMulResult == 5.000000
Visual Studio.NET Release
nValue == 500

fDivResult == 5.000000
fMulResult == 5.000000

fDivResult == 5.000000
fMulResult == 5.000000
Intel C++ 9.0 Debug
nValue == 500

fDivResult == 5.000000
fMulResult == 5.000000

fDivResult == 5.000000
fMulResult == 5.000000
Intel C++ 9.0 Release
nValue == 500

fDivResult == 500.000000 //ERROR!!!
fMulResult == 5.000000

fDivResult == 5.000000
fMulResult == 5.000000
*/

17 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I compled your program (a bit modified in #include and added "
" in the last printf) and got

maverick:~/tmp% icc -v
Version 9.0

maverick:~/tmp% icc -o t t.c
maverick:~/tmp% ./t
nValue == 500

fDivResult == 5.000000
fMulResult == 5.000000

fDivResult == 5.000000
fMulResult == 5.000000

I have nothing strange in it.

for reference, my program is

-----------
#include

int main()
{
int nValue = 500;
printf("nValue == %d

", nValue);

float fDivResult = nValue / 100.0f;
float fMulResult = nValue * 0.01f;

printf("fDivResult == %f
", fDivResult);
printf("fMulResult == %f", fMulResult);

fDivResult = 500 / 100.f;
fMulResult = 500 * 0.01f;

printf("

fDivResult == %f
", fDivResult);
printf("fMulResult == %f
", fMulResult);
return 0;
}

Message Edited by maverick6664 on 08-12-200503:22 AM

Message Edited by maverick6664 on 08-12-2005 03:22 AM

Message Edited by maverick6664 on 08-12-2005 03:23 AM

What is your system? Processor? OS?

I got the bug under P4, WinXP Pro, Visual Studio .NET IDE

Ciao

now I tested on Linux with ICC9.0.024 on P4 Prescott, but I also have ICC9.0.021 for Windows.

EDIT:

I tested on WIndows and got the same results. I compiled and tested in a commandline environment. Used the same source file above in my post, but I compiled it as a C++ source with an extension .cpp.
---------------
nValue == 500

fDivResult == 5.000000
fMulResult == 5.000000

fDivResult == 5.000000
fMulResult == 5.000000

Message Edited by maverick6664 on 08-12-2005 05:16 AM

I have just tried compiling a release build with Intel C++ Compiler 8.1 and the problem goes away.

I am having similar problems with version 9 and have come to the conlusion that with optimization turned on, multiplications and divisions that involves 32-bit floats and certain float orinteger constants doesn't work. Examples of constants thatdoesn't work: 10, 1000, 10010, 0.1f. Constants that do work: 2, 7.27f, 3.1515f.It is pretty scary actually, but Intel are reportedly investigating it.

This is an example of a piece of code that doesn't work:

#include

static float f = 2;

int main(int argc, const char* argv[])
{
printf("%f
", f * 1000.0f);
return 0;
}
Now, look at the machine-code output:

_main:
00000000: 55 push ebp
00000001: 8B EC mov ebp,esp
00000003: 83 EC 03 sub esp,3
00000006: 83 E4 F8 and esp,0FFFFFFF8h
00000009: 83 C4 04 add esp,4
0000000C: 83 EC 40 sub esp,40h
0000000F: 6A 03 push 3
00000011: E8 00 00 00 00 call ___intel_new_proc_init
00000016: D9 05 00 00 00 00 fld dword ptr [?f@@4MA]
0000001C: 83 C4 04 add esp,4 <----- HEY! Something is missing here!
0000001F: DD 5C 24 04 fstp qword ptr [esp+4]
00000023: C7 04 24 00 00 00 mov dword ptr [esp],offset ??_C@_03A@?$CFf?6?$AA@00
0000002A: E8 00 00 00 00 call _printf
0000002F: 33 C0 xor eax,eax
00000031: 83 C4 40 add esp,40h
00000034: 8B E5 mov esp,ebp
00000036: 5D pop ebp
00000037: C3 ret

No multiplication there. Nope. And the output when you run the .exe:

2.000000

Unbelievable... With /Od or /Op it works, but not with any other optimization settings. I just hope to hear from Intel soon, or I may just have to switch to some compiler that works (gcc maybe,or even worse, back to msvc). I have hundreds of 32-bit float constants in my audio code.

/ Magnus Lidstrm

I tried it on Windows with icc 9.0.022, but I cannot reproduce it.
And the results displayed are always 2.000.

For ex, with "icl /Fa", the assembly code created is

_main PROC NEAR
; parameter 1: 8 + ebp
; parameter 2: 12 + ebp
$B1$1: ; Preds $B1$0
push ebp ;7.1
mov ebp, esp ;7.1
sub esp, 3 ;7.1
and esp, -8 ;7.1
add esp, 4 ;7.1
sub esp, 64 ;7.1
push 3 ;7.1
call ___intel_new_proc_init ;7.1
; LOE ebx esi edi
$B1$5: ; Preds $B1$1
fld DWORD PTR _f ;8.18
fmul DWORD PTR _2il0floatpacket$1 ;8.22
add esp, 4 ;7.1
fstp QWORD PTR [esp+4] ;8.22
mov DWORD PTR [esp], OFFSET FLAT: ??_C@_03A@?$CFf?6?$AA@ ;8.10
call _printf ;8.3

Compiled with "icl /Fa /O3" the assembly code is

_main PROC NEAR
; parameter 1: 8 + ebp
; parameter 2: 12 + ebp
$B1$1: ; Preds $B1$0
push ebp ;7.1
mov ebp, esp ;7.1
sub esp, 3 ;7.1
and esp, -8 ;7.1
add esp, 4 ;7.1
sub esp, 64 ;7.1
push 3 ;7.1
call ___intel_new_proc_init ;7.1
; LOE ebx esi edi
$B1$5: ; Preds $B1$1
fld DWORD PTR _f ;8.18
fmul DWORD PTR _2il0floatpacket$1 ;8.22
add esp, 4 ;7.1
fstp QWORD PTR [esp+4] ;8.22
mov DWORD PTR [esp], OFFSET FLAT: ??_C@_03A@?$CFf?6?$AA@ ;8.10
call _printf ;8.3

What is the ICC's build id and what flags do you use?

Message Edited by maverick6664 on 09-04-2005 06:15 AM

Thanks for the reply!

I have tried this on two different systems now with two different 9.0 versions with exactly the same (incorrect) result. Once with 9.0.022 (20050809Z), Win XPand just recently with a fresh copy of the trial version 9.0.019 (20050430Z), Windows 2000. For the last attempt I useda totally clean machine, just installing the linker from the Microsoft Visual C++ Toolkit 2003. Nothing else.

It just never works for me.

I do believe you when you say it works for you (as it apperantly worked for the representative at Intel atfirst). It seems very unlikely that such a blatant bug would have gone through even automatic quality tests at Intel. I think it may be something that is related to specific installations, CPUs, or the phase of the moon, spots on the sun or whatever... It is definitely shaky anyhow.

(And yeah, I just run icl from the command line with no other specific switches than /O. Even default optimization settings, i.e. no switches at all, produce bad code.)

ahh....you are using toolkit.....it may be a problem (but unlikely). When I used ICC8.1 with toolkit in May it had a problem. I don't know about ICC9.0.

I used 9.0.022 w/ VC++ 7.1(.NET 2003) on command line on WinXP. When I have a chance, I'll try with toolkit. I have vmware and can install Windows on many virtual machines as far as the disk space allows.

Message Edited by maverick6664 on 09-04-2005 08:38 AM

I cannot install ICC9.0.021 over VC++ toolkit 2003. ICC has a trouble saying "doesn't know how to handle .hta extension." and I prefer Linux to Windows.

As ICC doesn't support toolkit 2003, IMHO VC++ .net 2003 or something should be necessary. Nowadays it's cheap on eBay.

Funny, I had no problem installing ICC on VC++ Toolkit except that I got a warning that .NET wasn't installed. But you just need a linker to run ICC anyhow, so I see no real reason to install the entire MSVC-environment if you don't need it.

But anyhow. This is not the problem. I just installed VC++ Toolkit to achieve the cleanest possible installation. I have tried version 9.0 with the full installation MSVC V6 and V7 as well, with just the same results.

This is just a wild shoot, but I am thinking that maybe Intel has compiled their own compiler with their own automatic CPU-dispatching. So perhaps this bug only occurs on certain CPUs. I have only tried on Pentium III and Penitum M so far (I am a laptop guy).

What CPU are you using?

P4 Prescott.

Which means that you have SSE3 and I don't. If I am not mistaken this would make a difference if you compile a program with /Q(a)xP. So maybe ICC 9 is compiled with /QaxP and we are simply testing two entirely different pieces of compiler code. :-)

Is anyone else reading this thread using a Pentium Mobile (Centrino) CPU for their compilations (or something similar without SSE3)?

(Damn. Aristotel who started this thread had a P4. So the problem is probably not related to SSE3 either. Sorry for being too quick with conclusions.)

I'm currently facing a similar issue with IC 9.0 on P4 (with and without SSE3)
Howver, the problem shows up only when processor extensions are defined (/QaxP or /QaxN).

Here is the sample code:

#include
#include

int main(int argc, char *argv[])
{
int i, a;

for (i=0; i<1; i++)
{
a = i;
}

float Norm = (1<<14);
float Alpha = 1.5;

printf("Norm:%f, Alpha:%f, Norm*Alpha:%f
", Norm, Alpha, (Norm*Alpha));

return EXIT_SUCCESS;
}

Output:

Norm:16384.000000, Alpha:1.500000, Norm*Alpha:1.500000
Press any key to continue

3remarks:
- if I remove the loop prior to the float multiplication, everything is ok
- if processor extensions are set to "None", erything is ok
- if I go back to compiler 8.0, everything is ok

tested on 2 different setups with IC 9.0 and VS .NET 2003 (P4 D 840, and older P4 2.4GHz).

Does anyone have a clue what is going on ?

Mathieu Picard

Using your test program on a Dell Precsions Pentium D (XP Pro SP2), with compiler 9.0.025, and Visual Studio 2003, I get correct results with QaxN.

Leave a Comment

Please sign in to add a comment. Not a member? Join today