[net.bugs.4bsd] VAX 4.2 c2

jima@nsc.UUCP (Jim Avera) (08/01/85)

This bug is in 4.2BSD c2 optimizer with 
c21.c SCCS ID of "1.83 80/10/16 21:18:22 JFR"

I discovered this bug working with code from a Fortran compiler, but the 
following C program also shows it.  It works correctly only if compiled 
without -O:

static long v2=2, v3=3;
main() {
	printf("checkpoint alpha\n");
	v2 = 5;
	v2 = v3;  /* This statement's effect incorrectly ignored by c2 */
	goto LAB18;
LAB19:	
	printf("should never get here - LAB19\n");
	do {
		printf("should never get here - loop body\n");
LAB18:  
	{ }
	} while (v2 == 5); /* Incorrectly evaluated true by c2 */
	printf("Checkpoint beta\n");
}

The first goto is changed to branch directly to the loop body
(the printf("should never get here")), because v2 is thought to contain 5,
making the conditional branch in the while test always true when reached via
that goto.

Internally, this (incorrect) optimization is done by redunbr(), 
because findrand() thinks that v2==5, because the variable conval,
set by the first assignment to indicate this is the case, is not cleared 
by dest() when the v2=v3 assignement is seen.  The result is that the first 
assignment is still considered valid when redunbr() attempts to evaluate
the conditional test.  This is all in c21.c.

A fix is for dest() to clear conloc[0] for any assignment, not just an 
assignment to an unknown location ("wild store"):

     In c21.c, procedure dest():

	if (!natural(s)) {/* wild store, everything except constants vanishes */
		for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
		/* FIX: MOVED FROM HERE:  conloc[0] = 0; ccloc[0] = 0; */
	} else setcc(s,type); /* natural destinations set condition codes */
	/* TO HERE: */ 
	conloc[0] = 0; ccloc[0] = 0; 
}


Jim Avera (hao!menlo70!nsc!jima) 408/733-2600 x322