Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: MSVC .NET 2003 optimization bug [O.T]

Author: Dann Corbit

Date: 15:24:04 04/09/04

Go up one level in this thread


On April 09, 2004 at 18:04:10, Russell Reagan wrote:

>I'm posting this here because I know that some of the programmers here use MSVC
>.NET 2003, and in hopes that Eugene will read this :)
>
>Today I had a problem with a program I was writing, and I came across what I
>believe is an optimization bug. I wrote this little program to reproduce the
>bug. If I compile with optimizations set to "Disabled", there is no problem. If
>I compile with optimzations set to anything else (Maximize Speed, Minimize Size,
>Full Optimizations), the program crashes due to a loop never terminating. The
>source code is at the end of this message. The line where the problem occurs is:
>
>for (row = 11; row < 12; row--)
>
>The problem is the comparison: row < 12
>
>When optimizations are turned off, this is the assembly output for that
>comparison:
>
>cmp DWORD PTR _row$[ebp], 12
>
>If optimizations are turned on, this is the assembly output:
>
>cmp ebx, OFFSET FLAT:_a+576
>
>I'm no assembly expert, but that looks like it is comparing the address of two
>pointers to me, and has nothing to do with comparing two values.
>
>Here is the example C source code. I compiled it under GCC with and without
>optimizations and it ran fine. Another person with MSVC .NET 2003 ran this code
>and he reported the same problem of crashing with optimizations turned on.
>
>Is this really an optimization bug, or is it possible that I am doing something
>wrong with the compiler settings? If this is indeed an optimization bug, how can
>I find out if Microsoft is already aware of it? If they are not aware of it, how
>can I report it to them?
>
>#include <stdio.h>
>
>unsigned int a[144];
>
>void init ()
>{
>    unsigned int i;
>    for (i = 0; i < 144; i++)
>        a[i] = rand();
>}
>
>void dump ()
>{
>    unsigned int row, col;
>    for (row = 11; row < 12; row--)     // <--- PROBLEM: row < 12
>    {
>        for (col = 0; col < 12; col++)
>            printf("%u ", a[(row * 12) + col]);
>        putchar('\n');
>    }
>}
>
>int main ()
>{
>    init();
>    dump();
>    return 0;
>}

It's definitely a serious bug.  Here is the assembly output.  It looks to me
like the optimizer noticed that the loop only iterates once and yet we branch
back up anyway.  I think the mov is fine, it's just putting an 11 into the
register.

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

	TITLE	.\bug.cpp
	.386P
include listing.inc
if @Version gt 510
.model FLAT
else
;	COMDAT ??_C@_03IOOJPBPG@?$CFu?5?$AA@
CONST	SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST	ENDS
;	COMDAT ?init@@YAXXZ
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT ?dump@@YAXXZ
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _main
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
FLAT	GROUP _DATA, CONST, _BSS
	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

PUBLIC	??_C@_03IOOJPBPG@?$CFu?5?$AA@			; `string'
PUBLIC	?a@@3PAIA					; a
EXTRN	__iob:BYTE
EXTRN	__flsbuf:NEAR
EXTRN	_rand:NEAR
EXTRN	_printf:NEAR
?a@@3PAIA DD	090H DUP (?)				; a
;	COMDAT ??_C@_03IOOJPBPG@?$CFu?5?$AA@
CONST	SEGMENT
??_C@_03IOOJPBPG@?$CFu?5?$AA@ DB '%u ', 00H		; `string'
CONST	ENDS
PUBLIC	?dump@@YAXXZ					; dump
; Function compile flags: /Ogty
; File c:\tmp\bug.cpp
;	COMDAT ?dump@@YAXXZ
_TEXT	SEGMENT
?dump@@YAXXZ PROC NEAR					; dump, COMDAT

; 13   : {

  00000	53		 push	 ebx
  00001	56		 push	 esi
  00002	57		 push	 edi

; 14   :     unsigned int row, col;
; 15   :     for (row = 11; row < 12; row--)     // <--- PROBLEM: row < 12

  00003	bb 10 02 00 00	 mov	 ebx, OFFSET FLAT:?a@@3PAIA+528
  00008	eb 06 8d 9b 00
	00 00 00	 npad	 8
$L980:

; 16   :     {
; 17   :         for (col = 0; col < 12; col++)

  00010	8b f3		 mov	 esi, ebx
  00012	bf 0c 00 00 00	 mov	 edi, 12			; 0000000cH
$L983:

; 18   :             printf("%u ", a[(row * 12) + col]);

  00017	8b 06		 mov	 eax, DWORD PTR [esi]
  00019	50		 push	 eax
  0001a	68 00 00 00 00	 push	 OFFSET FLAT:??_C@_03IOOJPBPG@?$CFu?5?$AA@
  0001f	e8 00 00 00 00	 call	 _printf
  00024	83 c4 08	 add	 esp, 8
  00027	83 c6 04	 add	 esi, 4
  0002a	4f		 dec	 edi
  0002b	75 ea		 jne	 SHORT $L983

; 19   :         putchar('\n');

  0002d	ff 0d 24 00 00
	00		 dec	 DWORD PTR __iob+36
  00033	78 11		 js	 SHORT $L1000
  00035	8b 0d 20 00 00
	00		 mov	 ecx, DWORD PTR __iob+32
  0003b	c6 01 0a	 mov	 BYTE PTR [ecx], 10	; 0000000aH
  0003e	ff 05 20 00 00
	00		 inc	 DWORD PTR __iob+32
  00044	eb 0f		 jmp	 SHORT $L981
$L1000:
  00046	68 20 00 00 00	 push	 OFFSET FLAT:__iob+32
  0004b	6a 0a		 push	 10			; 0000000aH
  0004d	e8 00 00 00 00	 call	 __flsbuf
  00052	83 c4 08	 add	 esp, 8
$L981:
  00055	83 eb 30	 sub	 ebx, 48			; 00000030H
  00058	81 fb 40 02 00
	00		 cmp	 ebx, OFFSET FLAT:?a@@3PAIA+576
  0005e	72 b0		 jb	 SHORT $L980
  00060	5f		 pop	 edi
  00061	5e		 pop	 esi
  00062	5b		 pop	 ebx

; 20   :     }
; 21   : }

  00063	c3		 ret	 0
?dump@@YAXXZ ENDP					; dump
_TEXT	ENDS
PUBLIC	?init@@YAXXZ					; init
; Function compile flags: /Ogty
;	COMDAT ?init@@YAXXZ
_TEXT	SEGMENT
?init@@YAXXZ PROC NEAR					; init, COMDAT

; 6    : {

  00000	56		 push	 esi

; 7    :     unsigned int i;
; 8    :     for (i = 0; i < 144; i++)

  00001	33 f6		 xor	 esi, esi
$L973:

; 9    :         a[i] = rand();

  00003	e8 00 00 00 00	 call	 _rand
  00008	89 86 00 00 00
	00		 mov	 DWORD PTR ?a@@3PAIA[esi], eax
  0000e	83 c6 04	 add	 esi, 4
  00011	81 fe 40 02 00
	00		 cmp	 esi, 576		; 00000240H
  00017	72 ea		 jb	 SHORT $L973
  00019	5e		 pop	 esi

; 10   : }

  0001a	c3		 ret	 0
?init@@YAXXZ ENDP					; init
_TEXT	ENDS
PUBLIC	_main
; Function compile flags: /Ogty
;	COMDAT _main
_TEXT	SEGMENT
_main	PROC NEAR					; COMDAT

; 24   : {

  00000	56		 push	 esi

; 25   :     init();

  00001	33 f6		 xor	 esi, esi
$L1017:
  00003	e8 00 00 00 00	 call	 _rand
  00008	89 86 00 00 00
	00		 mov	 DWORD PTR ?a@@3PAIA[esi], eax
  0000e	83 c6 04	 add	 esi, 4
  00011	81 fe 40 02 00
	00		 cmp	 esi, 576		; 00000240H
  00017	72 ea		 jb	 SHORT $L1017

; 26   :     dump();

  00019	e8 00 00 00 00	 call	 ?dump@@YAXXZ		; dump

; 27   :     return 0;

  0001e	33 c0		 xor	 eax, eax
  00020	5e		 pop	 esi

; 28   : }

  00021	c3		 ret	 0
_main	ENDP
_TEXT	ENDS
END



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.