Bug 13453 - Case where -O3 seeme broken but -O2 is OK
Summary: Case where -O3 seeme broken but -O2 is OK
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.3.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-12-19 21:45 UTC by Arthur Norman
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: x86_64-suse-linux
Target: x86_64-suse-linux
Build: x86_64-suse-linux
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 Arthur Norman 2003-12-19 21:45:45 UTC
Note that bug1.c has no incvludes and is already preprocessed. Regardless of 
the very dodgy casts etc observe *++stack and *stack-- in it. When compiled 
with -O2 the printf calls show stack returning to its original value. With -O3 
stack does not get reset properly in the path through the conditionally 
executed code and as a result f is not properly restored. The version of gcc 
is as provioded by SuSE 9.0 64-bit and is running on an Athlon64.


File bug1.c

extern long int base, *stack;

extern long int iintern(long int a, int b, long int c, int d);

extern long int cons(long int a, long int b);

int char_to_list(int c, long int f)
{
    long int k, local_base = base;
    printf("INITIAL STACK = %lx f=%lx\n", (long int)stack, (long int)f);
    k = (*(long int *)((char *)(((long int *)(local_base+4))[61]) +
        (sizeof(long int)-6) + (((long int)(c & 0xff))<<3)));
    if (k == local_base)
    { (*((char *)(((long int *)(local_base+4))[60]) +
        (sizeof(long int)-6)+((long int)(0)))) = (char)c;
        *++stack = f;
        k = iintern(((long int *)(local_base+4))[60], 1,
                    ((long int *)(local_base+4))[59], 0);
        f = *stack--;
        local_base = base;
        if ((((int)local_base & 1) != 0)) return 1;
        (*(long int *)((char *)(((long int *)(local_base+4))[61]) +
         (sizeof(long int)-6) + (((long int)(c & 0xff))<<3))) = k;
    }
    *++stack = f;
    k = cons(k, (*(long int *)((char *)(f) + (sizeof(long int)-6) +
                  (((long int)(1))<<3))));
    f = *stack--;
    printf("END stack=%lx f=%lx\n", (long int)stack, (long int)f);
    return 0;
}

/* end of bug1.c */

File bug2.c

#include <stdio.h>

long int base=0, *stack=NULL;

long int iintern(long int a, int b, long int c, int d)
{
    return (long int)printf("iintern %lx %x %lx %x\n", a, b, c, d);
}

long int cons(long int a, long int b)
{
    return (long int)printf("cons %lx %lx\n", a, b);
}

extern int char_to_list(int c, long int f);

long int stack_data[10];
long int base_seg[100];
long int chvec[300];
char chvec1[100];
long int fvec[30] = {0};

int main(int argc, char *argv[])
{
    int ch = 'A', i;
    long int f;
    stack = &stack_data[0];
    base = ((long int)&base_seg[0]) - 4;
    for (i=0; i<100; i++) base_seg[i] = 0x5555aaaa5555aaaaL;
    base_seg[59] = 0x5959595959595959L;
    base_seg[60] = ((long int)&chvec1[0]) - 2;
    base_seg[61] = ((long int)&chvec[0]) - 2;
    f = ((long int)&fvec[0]) - 2;
    for (i=0; i<256; i++) c
    char_to_list(ch, f);
    return 0;
}

/* end of bug2.c */

And the script that I use to demo the bug
#!/bin/bash

gcc -c bug2.c

gcc -O2 bug1.c bug2.o -o bug12
gcc -O2 bug1.c -S -o bug12.s
./bug12

gcc -O3 bug1.c bug2.o -o bug13
gcc -O3 bug1.c -S -o bug13.s
./bug13

and then some output
acn1@gauguin:~/r38/lisp/csl/autolinux64> ./bug
INITIAL STACK = 5019c0 f=500bbe
iintern 500cbe 1 5959595959595959 0
cons 24 0
END stack=5019c0 f=500bbe
INITIAL STACK = 5019c0 f=500bbe
iintern 500cbe 1 5959595959595959 0
cons 24 0
END stack=5019b8 f=0
acn1@gauguin:~/r38/lisp/csl/autolinux64>
Comment 1 Andrew Pinski 2003-12-25 01:34:02 UTC
invalid as you are violating C aliasing rules.
Comment 2 Andrew Pinski 2005-06-05 08:34:26 UTC
Reopening to ...
Comment 3 Andrew Pinski 2005-06-05 08:34:45 UTC
Mark as a dup of bug 21920.

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