Bug 202952 - Optimizer problem in gcc with -O2 or -O3
Optimizer problem in gcc with -O2 or -O3
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: gcc (Show other bugs)
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Depends On:
  Show dependency treegraph
Reported: 2006-08-17 10:06 EDT by Tom Fredian
Modified: 2007-11-16 20:14 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2006-08-17 11:30:04 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description Tom Fredian 2006-08-17 10:06:18 EDT
Description of problem:

The gcc compiler seems to be changing the order of execution of statements 
such that pointers to memory are being dereferenced before the contents of the 
memory is initialized when using the -O2 or -O3 options.

Version-Release number of selected component (if applicable):

gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)

How reproducible:

Very reproducible

Steps to Reproduce:
1. Run the program below first using -O1 and then using -O2

#define N 5
int main()
  int in[N];
  int out[N];
  short *optr=(short *)out;
  short *iptr=(short *)in;
  int i,j;
  printf("Uninitialized in=%x,%x,%x,%x,%x\n\n",in[0],in[1],in[2],in[3],in[4]);
  for (i=0;i<N;i++) {
  for (i=0;i<N;i++) 
    printf("in[%d]=%x, out[%d]=%x\n",i,in[i],i,out[i]);
  return 0;
Actual results:

With -O2 you get the following output:

Uninitialized in=80483ec,80495ec,bff37748,804828d,0

in[0]=0, out[0]=80483ec
in[1]=1, out[1]=80495ec
in[2]=2, out[2]=bff37748
in[3]=3, out[3]=804828d
in[4]=4, out[4]=0

Note that the output array contains the uninitialized values of the in array.

Expected results:

Compiled with -O1 you get the expected results where the output array contains 
the same values as the input array.

Uninitialized in=80483f4,80495f4,bfe21068,804828d,0

in[0]=0, out[0]=0
in[1]=1, out[1]=1
in[2]=2, out[2]=2
in[3]=3, out[3]=3
in[4]=4, out[4]=4

Additional info:

Obviously, this sample program does not represent the real use case where the 
problem was first detected. The original code was swapping the low 16-bits 
with the high 16-bits of a 32-bit integer and was not in doing this in a loop.
Comment 1 Jakub Jelinek 2006-08-17 11:30:04 EDT
The testcase is invalid C, violates the aliasing requirements of the ISO C
Search info gcc on -fstrict-aliasing or read directly the ISO C99 standard.
-O2 and above turns by default the -fstrict-aliasing option, as a workaround
for broken code you can use -fno-strict-aliasing, but better just fix the code
to conform to the standard.

Note You need to log in before you can comment on or make changes to this bug.