M68k Codegen Bug with -frerun-loop-opt, various EGCS versions

Melissa O'Neill oneill@cs.sfu.ca
Fri Oct 23 13:06:00 GMT 1998

		Sorry if this message has appeared more than once. I've
		been having some problems with my mailer software --
		hopefully they're resoved now. If this is the third time
		you're seeing this message, please let me know.

I have discovered a bad code generation bug in EGCS. In egcs-9981012,
this bug manifests itself as, for example, accesses to `jp[39 * m]' when
the source said `jp[14 * m]', or accesses to `kp[45 * m]' when the source
said `kp[9 * m]'. It seems to be due to the compiler getting confused
about what's in registers.

I discovered the bug compiling a fast fourier transform program that's
provided as an example in the Cilk language distribution. I could pinpoint
the problem, but because since I didn't write the code in question myself
(in fact, much of it was machine generated), I wasn't able to make a
short runnable test case. So, I've included two C files, one that can
be run from the command line, and one that just contains an example of
bad code. For the latter, I carefully traced through the code and
annotated the assembler output. I also attempted to determine which
part(s) of the optimizer were to blame.

In all recent m68k versions of egcs I tried (1.1b, 19980921, 19981012),
using `-O2' generated bad code. However, the exact culprit seemed to
vary between versions:

  981012    the bug seems to be caused by the `rerun-loop-opt' optimization,
	    since `-O -frerun-loop-opt' makes bad code and `-O2
	    -fno-rerun-loop-opt' makes good code

  1.1b      an interaction between several optimizations seems to be
  	    involved, since the following all make good code:
	    	-O2 -fno-strength-reduce
		-O2 -fno-optimize-register-move
		-O2 -fno-regmove
		-O2 -fno-rerun-loop-opt
	    and `-O -fstrength-reduce -foptimize-register-move -fregmove
	    -frerun-loop-opt' makes bad code.

I've enclosed code, both for a runnable program (fft.c -- test with `fft
-n 16384') and a single function from that program where bad code is
generated (fft_twiddle_16.c).  For the latter, I've also included my
annotations on the egcs-9981012 compiler's output for `-O -frerun-loop-opt'
(fft_twiddle_16-O-rlo-annotated.s).  Due to the sizes of these files,
they're enclosed as a compressed tar archive.


P.S. Even when the code did work, I wasn't very happy about the quality
of the `-O2' optimized code; it's as if peephole optimizer isn't running,
or something.  It was littered with redundant loads, stores and register
moves (stack temporaries were routinely initialized and then almost
immediately overwritten, without their value being read in the meantime).
Curiously, this did not happen with the `-O -frerun-loop-opt' code.


Here's the segment of erroneous code, with my annotations. For more
details, look in the tar file.

	lea a5@(a5:l:4),a5	$a5 = m * 5
	movel a5,d3		$d3 = m * 5
	movel d3,d5		$d5 = m * 5
	lsll #4,d5		$d5 = m * 80
	movel d5,a6@(-136)	_tmp34 = m * 80
	movel d1,d5		$d5 = m * 5
	lsll #4,d5		$d5 = m * 80
	movel d5,a6@(-140)	_tmp35 = m * 80
	movel a6@(36),d2	$d2 = m
	lsll #3,d2		$d2 = m * 8
	subl a5,d2		$d2 = m * 3
#######	^----------- bad code? (does the compiler think $a5 = m here too?)
	movel d2,d5		$d5 = m * 3
	lsll #4,d5		$d5 = m * 48
	movel d5,a6@(-144)	_tmp36 = m * 48
	lea a5@(a5:l:8),a5	$a5 = m * 45
#######	^----------- compiler thinks $a5 = m, but $a5 = m * 5		!!!!!!!
	movel a5,d0		$d0 = m * 45
	lsll #3,d0		$d0 = m * 360
	movel d0,a6@(-176)	_tmp44 = m * 360
#######	^----------- bad code, $d0 = m * 360, should be m * 72		!!!!!!!

Here's the tar file with full source:

-------------- next part --------------
A non-text attachment was scrubbed...
Name: egcs-loop-opt-bug.tar.gz
Type: application/x-gzip
Size: 26030 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-bugs/attachments/19981023/ae4e0c96/attachment.bin>

More information about the Gcc-bugs mailing list