[gnu.gcc.bug] Bad optimizer example

apratt@AMES.ARC.NASA.GOV (Allan Pratt) (09/26/89)

Here is C source and 68000 assembly output from GCC 1.35 with -O.
In the true part of the if, move.b ax@+,ay@+ would work and be
much better, but the compiler didn't notice that it could be used.
In the false part of the if, move.l ax@+,ay@+ is used correctly.

void
copy(src,dest,count)
long *src, *dest;
short count;
{
    if ((((long)src) & 1) || (((long)dest) & 1)) {
	do {
	    *((char *)dest)++ = *((char *)src)++;
	} while (count--);
    }
    else {
	count /= 4;
	do {
	    *dest++ = *src++;
	} while (count--);
    }
}

****************************************

	.even
.globl _copy
_copy:
	link a6,#0
	moveml #0x30,sp@-
	movel a6@(8),a3
	movel a6@(12),a2
	movew a6@(18),d0
	movel a3,d1
	btst #0,d1
	jne L3
	movel a2,d1
	btst #0,d1
	jeq L2
L3:
L4:
	movel a2,a0
	addqw #1,a2
	movel a3,a1
	addqw #1,a3
	moveb a1@,a0@
	dbra d0,L4
	jra L7
L2:
	tstw d0
	jge L8
	addqw #3,d0
L8:
	asrw #2,d0
L9:
	movel a3@+,a2@+
	dbra d0,L9
L7:
	moveml a6@(-8),#0xc00
	unlk a6
	rts

I mentioned this to James Wilson; this was his reply:

> From: ames!ucbarpa.Berkeley.EDU!wilson (James E. Wilson)
> 
> Gcc seems to generate some really terrible code here.  I can see how this
> is happening in the optimization stages, but the real problem seems to
> be in the rtl generation phase.  Well, this problem is too tough for me
> to solve in 10 minutes, so I suggest you send in a bug report.
> 
> However, in the meantime, you can get the desired code by rewritting the
> loop like this:
>			*((char *)dest) = *((char *)src);	/**/
>			((char *)dest)++;
>			((char *)src)++;
> 
> This is not a hard problem, gcc should be able to handle it. The mshort
> and m68000 options do not matter.  The same problem happens on a VAX.

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt