[gnu.gcc.bug] possible bug fix for Sun-3's w/ FPA and -O

vern@HELIOS.EE.LBL.GOV (Vern Paxson) (10/22/88)

This is regarding the following bug:

	Script started on Sat Oct 22 01:25:03 1988
	yak 1 % cat bug.c
	a()
	{
	double b;
	b == 0.0;
	}
	yak 2 % gcc -v -mfpa -O -c !$
	gcc -v -mfpa -O -c bug.c
	gcc version 1.29
	 /usr/local/lib/gcc-cpp -v -undef -D__GNU__ -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__OPTIMIZE__ -D__HAVE_68881__ -Dmc68020 bug.c /tmp/cca21305.cpp
	GNU CPP version 1.29
	 /usr/local/lib/gcc-cc1 /tmp/cca21305.cpp -quiet -dumpbase bug.c -mfpa -O -version -o /tmp/cca21305.s
	GNU C version 1.29 (68k, MIT syntax) compiled by GNU C version 1.29.
	gcc: Program cc1 got fatal signal 6.
	yak 3 % exit
	script done on Sat Oct 22 01:25:30 1988

I don't understand gcc's internals nearly well enough to fully understand
the problem, but from what I can tell what's happening is that the compare
operator generates an instruction which both "birth"'s and "kills" the
2nd pseudo-register.  There's special-case code to recognize this occurrence
which then decrements the register's "birth" to make sure that it doesn't
conflict with any of the operands to the instruction.  In some cases this
makes the birth quantity be 0, which is later interpreted to mean "no birth",
leading to an abort().  The following appears to fix the problem:

	Script started on Sat Oct 22 01:29:45 1988
	yak 1 % rcsdiff -c local-alloc.c
	RCS file: RCS/local-alloc.c,v
	retrieving revision 1.3
	diff -c -r1.3 local-alloc.c
	*** /tmp/,RCSt1a21324   Sat Oct 22 01:29:53 1988
	--- local-alloc.c       Sat Oct 22 01:21:40 1988
	***************
	*** 937,943 ****
		 assume that this register is used before all the inputs of the
		 insn are dead.  So this register must not conflict with any of them.
		 Mark it as born at the previous insn.  */
	!       qty_birth[reg_qty[regno]]--;
		/* It should also conflict with this insn's outputs.  */
		qty_death[reg_qty[regno]]++;
	      }
	--- 937,947 ----
		 assume that this register is used before all the inputs of the
		 insn are dead.  So this register must not conflict with any of them.
		 Mark it as born at the previous insn.  */
	!       /* hack - if we push its birth back before the beginning of the
	!          block it gets regarded as not having a quantity at all and
	!          we subsequently abort().  */
	!       if (qty_birth[reg_qty[regno]] > 1)
	!         qty_birth[reg_qty[regno]]--;
		/* It should also conflict with this insn's outputs.  */
		qty_death[reg_qty[regno]]++;
	      }
	yak 2 % exit
	script done on Sat Oct 22 01:30:11 1988

		Vern

	Vern Paxson				vern@lbl-csam.arpa
	Real Time Systems			ucbvax!lbl-csam.arpa!vern
	Lawrence Berkeley Laboratory		(415) 486-6411