EGCS Optimization bug on HPUX

John David Anglin dave@hiauly1.hia.nrc.ca
Fri Apr 30 23:15:00 GMT 1999


> 
> Reply-To: ddsinc09@ix.netcom.com
> 
> 
> The following code fragment appears in AutoGen's evalExpr_SHSTR
> routine in src/agExpr.c:
> 
> > >     *(pz++) = '"';
> > >     for (;;) {
> > >         switch (*(pz++) = *(pzDta++)) {
> > >         case NUL:
> > >             goto loopDone2;
> > >
> > >         case '"':
> > >         case '\\':
> > >             pz[-1]  = '\\';
> > >             *(pz++) = pzDta[-1];
> > >         }
> > >     } loopDone2:;
> > >     pz[-1] = '"';
> > >     *pz    = NUL;
> 
> AutoGen is available from:
> 
>    ftp://sourceware.cygnus.com/pub/egcs/infrastructure/autogen.tar.gz
> 
> Under optimization levels 2 and above, the value for "pzDta" is
> apparently stored in both a register and in memory _AND_ they are
> not kept in sync.  Here is an example from autogen/tests/evalstr.test:

I believe the above observation is essentially correct.  However, it
is the synchronization between two registers rather than register and
memory.  At -O2 and above, additional registers are used to hold pz-1
and pzDta-1.  These registers are not properly kept in sync with the
registers used for pz and pzDta.

I created this test program:

#define NUL 0
void loop (char * pz, char * pzDta)
{
    for (;;) {
        switch (*(pz++) = *(pzDta++)) {
        case NUL:
  	    goto loopDone2;

	case '"':
	case '\\':
	    pz[-1]  = '\\';
            *(pz++) = pzDta[-1];
	}
    } loopDone2:;
}

Here is the assembler code at -O1:

	.SPACE $PRIVATE$
	.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
	.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
	.SPACE $TEXT$
	.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
	.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
	.IMPORT $global$,DATA
	.IMPORT $$dyncall,MILLICODE
; gcc_compiled.:
	.SPACE $TEXT$
	.SUBSPA $CODE$

	.align 4
	.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
	.EXPORT loop,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR
loop
	.PROC
	.CALLINFO FRAME=0,NO_CALLS
	.ENTRY
	ldi 34,%r21
	ldi 92,%r20
L$0002
	ldbs,ma 1(0,%r25),%r19
L$0013
	stbs,ma %r19,1(0,%r26)
L$0015
	extrs %r19,31,8,%r19
	comb,=,n %r21,%r19,L$0009
	comb,<,n %r21,%r19,L$0012
	comib,=,n 0,%r19,L$0007
	ldbs,ma 1(0,%r25),%r19
	bl L$0015,0
	stbs,ma %r19,1(0,%r26)
L$0012
	comb,<>,n %r20,%r19,L$0013
	ldbs,ma 1(0,%r25),%r19
L$0009
	stb %r20,-1(0,%r26)
	ldb -1(0,%r25),%r19
	bl L$0002,0
	stbs,ma %r19,1(0,%r26)
L$0007
	bv,n 0(%r2)
	.EXIT
	.PROCEND

Here is the assembler code at -O3:

	.SPACE $PRIVATE$
	.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
	.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
	.SPACE $TEXT$
	.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
	.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
	.IMPORT $global$,DATA
	.IMPORT $$dyncall,MILLICODE
; gcc_compiled.:
	.SPACE $TEXT$
	.SUBSPA $CODE$

	.align 4
	.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
	.EXPORT loop,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR
loop
	.PROC
	.CALLINFO FRAME=0,NO_CALLS
	.ENTRY
	ldi 34,%r23
	ldi 92,%r22
	ldo -1(%r26),%r21
	ldo -1(%r25),%r24
L$0002
	ldbs,ma 1(0,%r25),%r19
L$0013
	ldo 1(%r21),%r21
L$0015
	extrs %r19,31,8,%r20
	comb,= %r23,%r20,L$0009
	stbs,ma %r19,1(0,%r26)
	comb,<,n %r23,%r20,L$0012
	comib,=,n 0,%r20,L$0007
	ldbs,ma 1(0,%r25),%r19
	bl L$0015,0
	ldo 1(%r21),%r21
L$0012
	comb,<>,n %r22,%r20,L$0013
	ldbs,ma 1(0,%r25),%r19
L$0009
	stbs,ma %r22,1(0,%r21)
	ldbs,mb 1(0,%r24),%r19
	bl L$0002,0
	stbs,ma %r19,1(0,%r26)
L$0007
	bv,n 0(%r2)
	.EXIT
	.PROCEND

It can be seen that the -O3 code uses r21 for pz-1 and r24 for pzDta-1.

-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)



More information about the Gcc-bugs mailing list