[comp.lang.c] pcc optimizer strangeness?

pardo@june.cs.washington.edu (David Keppel) (01/25/88)

I have a program that compiles some (to me) strange code under pcc even
with the (presumed peephole) optimzer turned on  (Ultrix).  I'm led to
wonder if this is even legal C.  Basically I'm trying to create an array
of range (-1..1) instead of (0..2):

	main()
	{
	    static int	foo[3];
	    static int	*bar = &foo;

	    bar[-1] =  1;
	    bar[ 0] =  0;
	    bar[ 1] = -1;

	    exit(bar[-1]+bar[1]);	/* wierd */
	}

For the /* wierd */ part, the resulting unoptimized code is:
	movl	L17,r0
	movl	L17,r1
	addl3	4(r1),-4(r0),r0
	pushl	r0

The resulting optimized code is:
	movl	L17,r0
	movl	r0,r1
	addl3	4(r1),-4(r0),-(sp)

And it all works just hunky-dory when I change it to
	movl	L17,r0
	addl3	4(r0),-4(r0),-(sp)

So my questions are:

(a) is this legal C?
(b) is this lack of optimization worth telling anybody about?

	;-D on  (I want a float-indexed array !-)  Pardo
	pardo@cs.washington.edu    ucbvax!uw-beaver!uw-june!pardo

chris@mimsy.UUCP (Chris Torek) (01/25/88)

[long and largely boring]

In article <4061@june.cs.washington.edu> pardo@june.cs.washington.edu
(David Keppel) writes:
>	main()
>	{
>	    static int	foo[3];
>	    static int	*bar = &foo;

The correct form is `... = foo', or `= &foo[0]'; except:

>	    bar[-1] =  1;

this writes in foo[-1], which, since it does not exist, is
clobbering something at random.  As it happens, it is clobbering
the place where the exit value will be stored on the stack,
which is unused at the time.

If you really want to do this, you should set bar = &foo[1],
so that bar[-1] is the same as foo[0].

On to the peephole optimiser:

>	    exit(bar[-1]+bar[1]);	/* wierd */
>
>For the /* wierd */ part, the resulting unoptimized code is:
>	movl	L17,r0
>	movl	L17,r1
>	addl3	4(r1),-4(r0),r0

I.e., bar[-1], -4(r0), plus bar[1], 4(r1), into temporary...

>	pushl	r0

and onto a stack...

>The resulting optimized code is:
>	movl	L17,r0
>	movl	r0,r1
>	addl3	4(r1),-4(r0),-(sp)

... which saves computing the value of `bar' twice, and merges the
add and the push.

>And it all works just hunky-dory when I change it to
>	movl	L17,r0
>	addl3	4(r0),-4(r0),-(sp)

Naturally.  The optimiser simply missed the fact that since r0==r1
and r1 is not used later, it could replace occurrences of `r1' with
`r0' and eliminate stores to r1.

>So my questions are:
>
>(a) is this legal C?

No, unless you change the `bar = &foo' to `bar = &foo[1]'.

>(b) is this lack of optimization worth telling anybody about?

You might complain to DEC.  They will probably tell you to buy
their Ultrix version of VMS C.  Or you could try to get a *real*
optimising compiler, which would replace the whole thing with
`main() { exit(0); }'.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris