archiel@hercules.UUCP (Archie Lachner) (09/27/84)
There in a bug in the way the 4.2bsd C compiler treats bit fields under some circumstances when optimization is turned on. If there is a bit field 16 bits long that falls on a byte boundary, the optimizer issues a "cvtwl," "movwl," or "movzwl" instruction instead of an "extv" or "extzv" instruction when extracting the field, since the former are more efficient than the latter. However, the address used for the field in any of the former is incorrect. I have short program that documents this bug, if anyone is interested. I don't know if this bug is present on other versions of UNIX, since I only have 4.2 available to me. -- Archie Lachner Logic Design Systems Division Tektronix, Inc. uucp: {ucbvax,decvax,pur-ee,cbosg,ihnss}!tektronix!teklds!archiel CSnet: archiel@tek ARPAnet: archiel.tek@csnet-relay
chris@umcp-cs.UUCP (Chris Torek) (09/29/84)
(Does this REALLY need to go to net.lang.c? Oh well...) Guy Harris posted a fix for this one long ago. It seems that Berkeley never picked up the fix since the bug is still there in the 4.2BSD /lib/c2. Here's RCS diffs. (Thanks, Guy.) [This first one is just to make it use the 4.2 stdio buffering, which means /tmp will (hopefully) have less disk activity] RCS file: RCS/c20.c,v retrieving revision 1.1 diff -b -c1 -r1.1 c20.c *** /tmp/,RCSt1001443 Sat Sep 29 11:49:05 1984 --- c20.c Mon Aug 6 15:57:42 1984 *************** *** 57,59 } ! setbuf(stdin,_sibuf); ++infound; } else if (freopen(*argv, "w", stdout) ==NULL) { --- 57,60 ----- } ! /* setbuf(stdin,_sibuf); */ ! ++infound; } else if (freopen(*argv, "w", stdout) ==NULL) { *************** *** 62,64 } ! setbuf(stdout,_sobuf); argc--; argv++; --- 63,65 ----- } ! /* setbuf(stdout,_sobuf); */ argc--; argv++; [and here's the real fixes] RCS file: RCS/c21.c,v retrieving revision 1.1 diff -b -c1 -r1.1 c21.c *** /tmp/,RCSt1001448 Sat Sep 29 11:49:19 1984 --- c21.c Mon Aug 6 13:43:32 1984 *************** *** 277,279 ** extv $n*8,$8,A,B > cvtbl n+A,B ! ** extv $n*16,$16,A,B > cvtwl n+A,B ** extzv $n*8,$8,A,B > movzbl n+A,B --- 277,279 ----- ** extv $n*8,$8,A,B > cvtbl n+A,B ! ** extv $n*16,$16,A,B > cvtwl 2n+A,B ** extzv $n*8,$8,A,B > movzbl n+A,B *************** *** 279,281 ** extzv $n*8,$8,A,B > movzbl n+A,B ! ** extzv $n*16,$16,A,B > movzwl n+A,B */ --- 279,281 ----- ** extzv $n*8,$8,A,B > movzbl n+A,B ! ** extzv $n*16,$16,A,B > movzwl 2n+A,B */ *************** *** 324,326 else ! sprintf(regs[RT1], "%d%s%s", coff, regs[RT3][0]=='(' ? "":"+", regs[RT3]); --- 324,328 ----- else ! sprintf(regs[RT1], "%d%s%s", ! (flen == 8 ? coff : 2*coff), ! (regs[RT3][0] == '(' ? "" : "+"), regs[RT3]); *************** *** 790,791 register char *cp1,*cp2; int r; char src[C2_ASIZE]; --- 792,794 ----- register char *cp1,*cp2; int r; + int lhssiz, subop; char src[C2_ASIZE]; *************** *** 806,807 } if (p->back->op==CVT || p->back->op==MOVZ) {/* greedy, aren't we? */ --- 809,824 ----- } + /* + * 'pos', 'siz' known; find out the size of the + * left-hand operand of what the bicl will turn into. + */ + if (pos==0) { + if (siz==8) + lhssiz = BYTE;/* movzbl */ + else if (siz==16) + lhssiz = WORD;/* movzwl */ + else + lhssiz = BYTE;/* extzvl */ + } + else + lhssiz = BYTE;/* extzvl */ if (p->back->op==CVT || p->back->op==MOVZ) {/* greedy, aren't we? */ *************** *** 808,810 splitrand(p->back); cp1=regs[RT1]; cp2=regs[RT2]; ! if (equstr(src,cp2) && okio(cp1) && !indexa(cp1) && 0<=(r=isreg(cp2)) && r<NUSE --- 825,840 ----- splitrand(p->back); cp1=regs[RT1]; cp2=regs[RT2]; ! /* ! * If indexa(cp1) || autoid(cp1), the fold may ! * still be OK if the CVT/MOVZ has the same ! * size operand on its left size as what we ! * will turn the bicl into. ! * However, if the CVT is from a float or ! * double, forget it! ! */ ! subop = p->back->subop&0xF;/* type of LHS of ! CVT/MOVZ */ ! if (equstr(src,cp2) && okio(cp1) ! && subop != FFLOAT && subop != DFLOAT ! && subop != GFLOAT && subop != HFLOAT ! && ((!indexa(cp1) && !autoid(cp1)) || lhssiz == subop) && 0<=(r=isreg(cp2)) && r<NUSE *************** *** 810,812 && 0<=(r=isreg(cp2)) && r<NUSE ! && bitsize[p->back->subop&0xF]>=(pos+siz) && bitsize[p->back->subop>>4]>=(pos+siz)) {/* good CVT */ --- 840,842 ----- && 0<=(r=isreg(cp2)) && r<NUSE ! && bitsize[subop]>=(pos+siz) && bitsize[p->back->subop>>4]>=(pos+siz)) {/* good CVT */ *************** *** 818,821 splitrand(p); /* retrieve destination of BICL */ ! if (siz==8 && pos==0) { ! p->combop = T(MOVZ,U(BYTE,LONG)); sprintf(line,"%s,%s",src,lastrand); --- 848,851 ----- splitrand(p); /* retrieve destination of BICL */ ! if ((siz==8 || siz == 16) && pos==0) { ! p->combop = T(MOVZ,U(lhssiz,LONG)); sprintf(line,"%s,%s",src,lastrand); *************** *** 1363,1364 while (*p) if (*p++=='[') return(1); return(0); --- 1393,1402 ----- while (*p) if (*p++=='[') return(1); + return(0); + } + + autoid(p) register char *p; { /* 1-> uses autoincrement/autodecrement; + 0-> doesn't */ + if (*p == '-' && *(p+1) == '(') return(1); + while (*p) p++; + if (*--p == '+' && *--p == ')') return(1); return(0); -- (This page accidently left blank.) In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690 UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
guy@rlgvax.UUCP (Guy Harris) (09/30/84)
> (Does this REALLY need to go to net.lang.c? Oh well...) Guy Harris > posted a fix for this one long ago. It seems that Berkeley never > picked up the fix since the bug is still there in the 4.2BSD /lib/c2. > Here's RCS diffs. (Thanks, Guy.) That diff listing actually includes about 3 bug fixes. To be fair, the only one that's actually mine is the one which keeps the optimizer from merging cvtwl (r11)+,r0 movzbl r0,r0 into movzbl (r11)+,r0 which sequence gets generated by code like register short *sp; register int c; c = (*sp++)&0377; The other fixes are the one to the "extzv" instructions, and one that kept the compiler from merging floating and non-floating convert instructions. I'm told lots of other fixes posted to net.bugs.4bsd but not mailed to 4bsd-bugs@berkeley haven't been picked up by Berkeley yet. These bugs exist in the System III version of the optimizer as well, and some of them might even still be around in System V Release 2. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy