Optimization produces bad FP code 
Author Message
 Optimization produces bad FP code

/* In this program, optimizing with /O2 causes the parameters to csprintf
 to get messed up on the floating point stack.  This is the complete
program, the compile line, link line, and bad compiler output follow. */

#define VC_EXTRALEAN
#include <afxwin.h>
#include <string>
#include <cmath>

int round(double x)
{ return (int) (x > 0 ? x + 0.5 : x - 0.5); }
double done = 0.6;
double all() { return 100.0 /* * std::sin(1.0) */; }
CString csprintf(const TCHAR * format, ...)
{
   va_list args;
   CString cs;
   va_start(args, format);
   cs.FormatV(format, args);
   va_end(args);
   return cs;

Quote:
}

int main()
{
 AfxTrace(csprintf("%d %d\n", round(done), round(all() - done)));
 int idone = round(done);
 int iremain = round(all() - done);
 AfxTrace(csprintf("%d %d\n", idone, iremain));
 return 0;
Quote:
}

/*
Compile line:
/O2 /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_AFXDLL" /D "_MBCS" /Gm /EHsc
/MDd /GS /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Zi /TP

Link line:
/OUT:"Debug/test.exe" /INCREMENTAL:NO /NOLOGO /DEBUG /PDB:"Debug/test.pdb"
/SUBSYSTEM:CONSOLE /MACHINE:IX86

Output:
0 1
1 99

Change /O2 to /Od, output becomes:
1 99
1 99

Bad disassembly with added comments:
 AfxTrace(csprintf("%d %d\n", round(done), round(all() - done)));

00402436  mov         eax,dword ptr fs:[00000000h]
0040243C  fsub        qword ptr [done (409090h)]        ; subtract done from
all
00402442  push        0FFFFFFFFh
00402444  push        offset $L54336 (4068C0h)
00402449  push        eax

round(diff)
00402450  mov         dword ptr fs:[0],esp
00402457  sub         esp,8
0040245A  fnstsw      ax
0040245C  test        ah,41h
0040245F  jne         main+39h (402469h)

00402467  jmp         main+3Fh (40246Fh)

0040246F  fld         qword ptr [done (409090h)]        ; diff+/- .5 in ST0

is inefficient, but OK
0040247B  fld         qword ptr [done (409090h)]        ;
00402481  fnstsw      ax                ;
00402483  test        ah,41h               ;
00402486  jne         main+60h (402490h)           ;

0040248E  jmp         main+66h (402496h)           ;

done+/-.5 in ST0, diff +/-.5 in ST1
00402496  push        ebx
00402497  fxch        st(1)
00402499  push        ebp
0040249A  fxch        st(2)               ; exchanges are screwy
0040249C  push        esi
0040249D  fxch        st(1)
0040249F  push        edi
004024A0  call        _ftol2 (403170h)  ; done -> int
004024A5  push        eax      ; push round(done) out of order
004024A6  call        _ftol2 (403170h)  ; garbage -> int
004024AB  push        eax      ; push int(garbage)
004024AC  lea         eax,[esp+18h]
004024B0  push        offset string "%d %d\n" (40756Ch)
004024B5  push        eax
004024B6  call        csprintf (402340h)
*/



Tue, 03 Aug 2004 01:57:06 GMT  
 Optimization produces bad FP code
I reproduced the bug and I have reported it to the appropriate developers
here on the optimizer team.

--
Jonathan Caves
Microsoft Corporation

This posting is provided "AS IS" with no warranties, and confers no rights.


Quote:
> /* In this program, optimizing with /O2 causes the parameters to csprintf
>  to get messed up on the floating point stack.  This is the complete
> program, the compile line, link line, and bad compiler output follow. */

> #define VC_EXTRALEAN
> #include <afxwin.h>
> #include <string>
> #include <cmath>

> int round(double x)
> { return (int) (x > 0 ? x + 0.5 : x - 0.5); }
> double done = 0.6;
> double all() { return 100.0 /* * std::sin(1.0) */; }
> CString csprintf(const TCHAR * format, ...)
> {
>    va_list args;
>    CString cs;
>    va_start(args, format);
>    cs.FormatV(format, args);
>    va_end(args);
>    return cs;
> }

> int main()
> {
>  AfxTrace(csprintf("%d %d\n", round(done), round(all() - done)));
>  int idone = round(done);
>  int iremain = round(all() - done);
>  AfxTrace(csprintf("%d %d\n", idone, iremain));
>  return 0;
> }
> /*
> Compile line:
> /O2 /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_AFXDLL" /D "_MBCS" /Gm /EHsc
> /MDd /GS /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Zi /TP

> Link line:
> /OUT:"Debug/test.exe" /INCREMENTAL:NO /NOLOGO /DEBUG /PDB:"Debug/test.pdb"
> /SUBSYSTEM:CONSOLE /MACHINE:IX86

> Output:
> 0 1
> 1 99

> Change /O2 to /Od, output becomes:
> 1 99
> 1 99

> Bad disassembly with added comments:
>  AfxTrace(csprintf("%d %d\n", round(done), round(all() - done)));

> 00402436  mov         eax,dword ptr fs:[00000000h]
> 0040243C  fsub        qword ptr [done (409090h)]        ; subtract done
from
> all
> 00402442  push        0FFFFFFFFh
> 00402444  push        offset $L54336 (4068C0h)
> 00402449  push        eax

> round(diff)
> 00402450  mov         dword ptr fs:[0],esp
> 00402457  sub         esp,8
> 0040245A  fnstsw      ax
> 0040245C  test        ah,41h
> 0040245F  jne         main+39h (402469h)

> 00402467  jmp         main+3Fh (40246Fh)

> 0040246F  fld         qword ptr [done (409090h)]        ; diff+/- .5 in
ST0

> is inefficient, but OK
> 0040247B  fld         qword ptr [done (409090h)]        ;
> 00402481  fnstsw      ax                ;
> 00402483  test        ah,41h               ;
> 00402486  jne         main+60h (402490h)           ;

> 0040248E  jmp         main+66h (402496h)           ;

> done+/-.5 in ST0, diff +/-.5 in ST1
> 00402496  push        ebx
> 00402497  fxch        st(1)
> 00402499  push        ebp
> 0040249A  fxch        st(2)               ; exchanges are screwy
> 0040249C  push        esi
> 0040249D  fxch        st(1)
> 0040249F  push        edi
> 004024A0  call        _ftol2 (403170h)  ; done -> int
> 004024A5  push        eax      ; push round(done) out of order
> 004024A6  call        _ftol2 (403170h)  ; garbage -> int
> 004024AB  push        eax      ; push int(garbage)
> 004024AC  lea         eax,[esp+18h]
> 004024B0  push        offset string "%d %d\n" (40756Ch)
> 004024B5  push        eax
> 004024B6  call        csprintf (402340h)
> */



Tue, 03 Aug 2004 02:04:52 GMT  
 Optimization produces bad FP code
BTW: adding /Op (improve FP consistancy) to /O2 generates the correct
answer.

--
Jonathan Caves
Microsoft Corporation

This posting is provided "AS IS" with no warranties, and confers no rights.



Quote:
> I reproduced the bug and I have reported it to the appropriate developers
> here on the optimizer team.

> --
> Jonathan Caves
> Microsoft Corporation

> This posting is provided "AS IS" with no warranties, and confers no
rights.



> > /* In this program, optimizing with /O2 causes the parameters to
csprintf
> >  to get messed up on the floating point stack.  This is the complete
> > program, the compile line, link line, and bad compiler output follow. */

> > #define VC_EXTRALEAN
> > #include <afxwin.h>
> > #include <string>
> > #include <cmath>

> > int round(double x)
> > { return (int) (x > 0 ? x + 0.5 : x - 0.5); }
> > double done = 0.6;
> > double all() { return 100.0 /* * std::sin(1.0) */; }
> > CString csprintf(const TCHAR * format, ...)
> > {
> >    va_list args;
> >    CString cs;
> >    va_start(args, format);
> >    cs.FormatV(format, args);
> >    va_end(args);
> >    return cs;
> > }

> > int main()
> > {
> >  AfxTrace(csprintf("%d %d\n", round(done), round(all() - done)));
> >  int idone = round(done);
> >  int iremain = round(all() - done);
> >  AfxTrace(csprintf("%d %d\n", idone, iremain));
> >  return 0;
> > }
> > /*
> > Compile line:
> > /O2 /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_AFXDLL" /D "_MBCS" /Gm
/EHsc
> > /MDd /GS /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Zi /TP

> > Link line:
> > /OUT:"Debug/test.exe" /INCREMENTAL:NO /NOLOGO /DEBUG

/PDB:"Debug/test.pdb"

- Show quoted text -

Quote:
> > /SUBSYSTEM:CONSOLE /MACHINE:IX86

> > Output:
> > 0 1
> > 1 99

> > Change /O2 to /Od, output becomes:
> > 1 99
> > 1 99

> > Bad disassembly with added comments:
> >  AfxTrace(csprintf("%d %d\n", round(done), round(all() - done)));

> > 00402436  mov         eax,dword ptr fs:[00000000h]
> > 0040243C  fsub        qword ptr [done (409090h)]        ; subtract done
> from
> > all
> > 00402442  push        0FFFFFFFFh
> > 00402444  push        offset $L54336 (4068C0h)
> > 00402449  push        eax

> > round(diff)
> > 00402450  mov         dword ptr fs:[0],esp
> > 00402457  sub         esp,8
> > 0040245A  fnstsw      ax
> > 0040245C  test        ah,41h
> > 0040245F  jne         main+39h (402469h)

> > 00402467  jmp         main+3Fh (40246Fh)

> > 0040246F  fld         qword ptr [done (409090h)]        ; diff+/- .5 in
> ST0

pop
> > is inefficient, but OK
> > 0040247B  fld         qword ptr [done (409090h)]        ;
> > 00402481  fnstsw      ax                ;
> > 00402483  test        ah,41h               ;
> > 00402486  jne         main+60h (402490h)           ;

> > 0040248E  jmp         main+66h (402496h)           ;

> > done+/-.5 in ST0, diff +/-.5 in ST1
> > 00402496  push        ebx
> > 00402497  fxch        st(1)
> > 00402499  push        ebp
> > 0040249A  fxch        st(2)               ; exchanges are screwy
> > 0040249C  push        esi
> > 0040249D  fxch        st(1)
> > 0040249F  push        edi
> > 004024A0  call        _ftol2 (403170h)  ; done -> int
> > 004024A5  push        eax      ; push round(done) out of order
> > 004024A6  call        _ftol2 (403170h)  ; garbage -> int
> > 004024AB  push        eax      ; push int(garbage)
> > 004024AC  lea         eax,[esp+18h]
> > 004024B0  push        offset string "%d %d\n" (40756Ch)
> > 004024B5  push        eax
> > 004024B6  call        csprintf (402340h)
> > */



Tue, 03 Aug 2004 02:40:12 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. WARNING: VC++ 5.0 generates bad FP code

2. Compiler produces bad code

3. Difference between code optimization and compiler optimization?

4. Incremental Build producing bad exe.

5. Bad optimization in PCC?

6. bad optimization

7. Subject: VC++5.0 generates buggy FP code with /Ot

8. does vc++ .net produce vc++ 6 code?

9. Simple Code Produce "INTERNAL COMPILER ERROR"

10. Compiler produced IL code

11. C pre-processor to produce machine-specific assembler code

12. code produces segmentation fault

 

 
Powered by phpBB® Forum Software