User account creation filtered due to spam.

Bug 30208 - program was compiled wrong when use GCC O2 or O3 option
Summary: program was compiled wrong when use GCC O2 or O3 option
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.3.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-12-14 04:34 UTC by Zeguang.Zhao
Modified: 2006-12-14 04:53 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zeguang.Zhao 2006-12-14 04:34:16 UTC
On such platforms:
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
gcc version 3.3.3 (SuSE Linux)

Source Code:
void func(unsigned char *buf)
{
	unsigned short *p, a, b, c, d;
	unsigned int *q, m, n;
	unsigned int i1 = 0x1111;
	unsigned int i2 = 0x2222;
	unsigned int i3 = 0x3333;
	unsigned int i4 = 0x4444;
	unsigned int mod1 = 0x5555;
	unsigned int mod2 = 0x6666;
	unsigned int mod3 = 0x7777;
	unsigned int mod4 = 0x8888;

	p = (unsigned short *)buf;
	a = *p;
	b = *(p + 2);
	c = *(p + 4);
	d = *(p + 6);

	c = d^0x1234;
	b = c^0x2345;
	a = b^0x3456;

	*p = a;
	*(p + 2) = b;
	*(p + 4) = c;

	q = (unsigned int *)buf;
	m = *q;
	*q = ((*q * i1) % mod1) ^ 0xabcd;
	q++;
	n = *q;
	*q = ((*q * i2) % mod2) ^ 0xbcde ^ (m & 0xffff);
	q++;
	m = *q;
	*q = ((*q * i3) % mod3) ^ 0xcdef ^ (n & 0xffff);
	q++;
	*q = ((*q * i4) % mod4) ^ 0xdef1 ^ (m & 0xffff);
	return;	
}

when compiled with O2 or O3 options, such as "gcc -O2 a.c", the problem is:
when "m" was assigned first, buf[0] & buf[1] was NOT updated by "a".
the asm code like this:
...
xor 0x3456, eax; <- a
mov [ebx], esi; <- m was assigned value of OLD buf[0 ~ 3]
mov ax, [ebx]; <- buf[0] & buf[1] was updated by a
imul 0x1111, esi;
...

as a constrast, when compiled with O1 or none options, such like "gcc -O1 a.c" or "gcc a.c", the asm code like this:
...
xor 0x3456, eax;
mov ax, [ebx]; 
mov [ebx], esi;
imul 0x1111, esi;
...

when change the order of "*p = a; *(p + 2) = b; *(p + 4) =c" 
to "*(p + 4) = c; *(p + 2) = b; *p = a",
compiled with O2 or O3 option, the result was correct too.
Comment 1 Andrew Pinski 2006-12-14 04:53:34 UTC
You are violating C aliasing rules.
C aliasing rules say you can only access a variable (or an array) by the orginal type (signed or unsigned version) or a character type (or qualified types of those).

You have an access to a variable via both a short and an int which automatically violates C aliasing rules.


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

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