[net.bugs.4bsd] /lib/c2 bug fix

jte (06/21/82)

The 4.1bsd C optimizer breaks when float-to-int conversions are
combined with bit masks. The following program
	main(){
		printf("%d %d\n", (short)(3.4), ( (short)(3.4) ) & 077);
	}
prints "3 25" instead of "3 3".

The compiler constructs a convert/bitmask series of instructions
	cvtdl	L19,r0
	bicl2	$-64,r0
for the latter expression. The optimizer first changes the BIC into an EXT
	cvtdl	L19,r0
	extzv	$0,$6,r0,r0
(anyone know why?). It then thinks that the EXTZV is doing a conversion
to a long already, so it deletes the CVT! This is fine when converting
from a byte or short to a long, but fails on floating point.
	extzv	$0,$6,L19,r0
L19 is masked directly, and the resulting garbage used.

This one kept one of our programmers running in circles for an entire day
looking for a (nonexistant) bug in his (*huge*) program...

-------
Changes to /usr/src/cmd/c2/c21.c
-------
			delnode(p->back);
		}
	}
#ifndef BUGFIX
	if (p->back->op==CVT || p->back->op==MOVZ) {/* greedy, aren't we? */
#else
/*
 * Yes, too greedy. For now, leave extra CVT's in.
 * We should really examine each case as the optimization is usually ok.
 */
	if (0) {
#endif BUGFIX
		splitrand(p->back); cp1=regs[RT1]; cp2=regs[RT2];
		if (equstr(src,cp2) && okio(cp1) && !indexa(cp1)
		  && 0<=(r=isreg(cp2)) && r<NUSE
-------

James Ellis  (mcnc!jte)
Microelectronics Center of North Carolina