Bug 33999

Summary: g++ optimizer(-O2) generates wrong code in 32bit mode on x86_64
Product: gcc Reporter: Michael Yan <myan>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: attardi, cdfrey, chiabaut, Dries.Decock, gcc-bugs, gcc2eran, hans.buchmann.wantuch, honza, lucifer_ww, mihai.dontu, myan, rosenfeld, sb, schendel, sorenj, stillzhang, takahisa.yokota, tompa-l
Priority: P3    
Version: 3.4.6   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Attachments: A small test file shows the problem.

Description Michael Yan 2007-11-05 22:13:49 UTC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// g++ optimizer(-O2) generates wrong code on 32bit x86_64
//
// g++ 3.2.3 is ok
// g++ 3.4.6 & 4.1.1 are wrong
//
// platform Redhat AS4, x86_64
//
// g++ -g -O2 -m32 foo.cpp

typedef struct _GUID
{
	unsigned int Data1;
	unsigned short Data2;
	unsigned short Data3;
	unsigned char Data4[ 8 ];
} 
GUID;

inline bool IsGUIDNULL(const ::GUID& irGUID)
{
	return (
		(reinterpret_cast<const int*>(&irGUID))[0] == 0 &&
		(reinterpret_cast<const int*>(&irGUID))[1] == 0 &&
		(reinterpret_cast<const int*>(&irGUID))[2] == 0 &&
		(reinterpret_cast<const int*>(&irGUID))[3] == 0);
}

/* objdump result of the following bar() function

08048450 <_Z3barv>:
 8048450:       55                      push   %ebp
 8048451:       31 c0                   xor    %eax,%eax
 8048453:       89 e5                   mov    %esp,%ebp
 8048455:       83 ec 28                sub    $0x28,%esp
 8048458:       8b 55 ec                mov    0xffffffec(%ebp),%edx
 804845b:       c7 45 e8 00 00 00 00    movl   $0x0,0xffffffe8(%ebp)
 8048462:       66 c7 45 ec 00 00       movw   $0x0,0xffffffec(%ebp)
 8048468:       66 c7 45 ee 00 00       movw   $0x0,0xffffffee(%ebp)
 804846e:       c6 45 f0 00             movb   $0x0,0xfffffff0(%ebp)
 8048472:       c6 45 f1 00             movb   $0x0,0xfffffff1(%ebp)
 8048476:       85 d2                   test   %edx,%edx
 8048478:       c6 45 f2 00             movb   $0x0,0xfffffff2(%ebp)
 804847c:       c6 45 f3 00             movb   $0x0,0xfffffff3(%ebp)
 8048480:       c6 45 f4 00             movb   $0x0,0xfffffff4(%ebp)
 8048484:       c6 45 f5 00             movb   $0x0,0xfffffff5(%ebp)
 8048488:       c6 45 f6 00             movb   $0x0,0xfffffff6(%ebp)
 804848c:       c6 45 f7 00             movb   $0x0,0xfffffff7(%ebp)
 8048490:       75 10                   jne    80484a2 <_Z3barv+0x52>
 8048492:       8b 4d f0                mov    0xfffffff0(%ebp),%ecx
 8048495:       85 c9                   test   %ecx,%ecx
 8048497:       75 09                   jne    80484a2 <_Z3barv+0x52>
 8048499:       8b 55 f4                mov    0xfffffff4(%ebp),%edx
 804849c:       85 d2                   test   %edx,%edx
 804849e:       75 02                   jne    80484a2 <_Z3barv+0x52>
 80484a0:       b0 01                   mov    $0x1,%al
 80484a2:       85 c0                   test   %eax,%eax
 80484a4:       74 02                   je     80484a8 <_Z3barv+0x58>
 80484a6:       c9                      leave
 80484a7:       c3                      ret
 80484a8:       c7 44 24 04 bc 85 04    movl   $0x80485bc,0x4(%esp)
 80484af:       08
 80484b0:       a1 5c 97 04 08          mov    0x804975c,%eax
 80484b5:       89 04 24                mov    %eax,(%esp)
 80484b8:       e8 af fe ff ff          call   804836c <fprintf@plt>
 80484bd:       c9                      leave
 80484be:       c3                      ret
 80484bf:       90                      nop
*/

void bar()
{
	GUID guid;

	guid.Data1 = 0;
	guid.Data2 = 0;
	guid.Data3 = 0;
	guid.Data4[0] = 0;
	guid.Data4[1] = 0;
	guid.Data4[2] = 0;
	guid.Data4[3] = 0;
	guid.Data4[4] = 0;
	guid.Data4[5] = 0;
	guid.Data4[6] = 0;
	guid.Data4[7] = 0;

	if (!IsGUIDNULL(guid))
	{
		// Fails here
		fprintf(stderr, "test failed\n");
	}
}

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

	bar();

	return i;
}
Comment 1 Michael Yan 2007-11-05 22:15:55 UTC
Created attachment 14487 [details]
A small test file shows the problem.

The attached source file has all the information of this bug report.
Comment 2 Andrew Pinski 2007-11-05 22:25:53 UTC
This is one of the most obvious violations of C/C++ aliasing rules.
You are accessing a _GUID as an int.  Either use -fno-strict-aliasing, an union or memcpy to get around the aliasing violation

*** This bug has been marked as a duplicate of 21920 ***