delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/04/18/17:02:12

Message-Id: <m0wIEv7-000S1oC@natacha.inti.edu.ar>
Comments: Authenticated sender is <salvador AT natacha DOT inti DOT edu DOT ar>
From: "Salvador Eduardo Tropea (SET)" <salvador AT inti DOT edu DOT ar>
Organization: INTI
To: djgpp AT delorie DOT com
Date: Fri, 18 Apr 1997 18:01:58 +0000
MIME-Version: 1.0
Subject: GCC 2.7.2 BUGS, be carefull, not scared

Hi all:

   I'm very sad to communicate to all of you the following :-(

   That's a report of 2 bugs in GCC 2.7.2 that can affect to djgpp
programs.


*** Bug 1 ***


Description: -funroll-loops generates bad code in do-while statements usin=
g
wrap-around exit conditions.

Example to test the bug:
/* Compile with -O2 -funroll-loops
 *
 */

unsigned char S[256];

int main(int argc, char **argv)
{
  unsigned char i =3D 0;
  do S[i] =3D i; while (++i);
  return i;
}
/**** End of example *****/

Compile with: -O2 -funroll-loops

Effect: The loop will never end (press ^Break to stop it), compiling with
only -O2 works OK.

Detailed explanation: The code generated by GCC for this loop is:

	.file	"pp.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
	.align 2
.globl _main
_main:
	pushl %ebp
	movl %esp,%ebp
	call ___main
	movb $0,_S        <=3D=3D=3D=3D=3D=3D=3D=3D That's an optimization for th=
e S[0]=3D0
	movb $1,%cl       <=3D=3D=3D=3D=3D=3D=3D=3D CL starts with 1 and is the c=
ounter
	testb %cl,%cl     <=3D=3D=3D=3D=3D=3D=3D=3D This line an the 2 next lines=
 are a redundant
	je L6                       code. Shows a fail in the optimizer but not
	.align 2,0x90               serious.
L2:
	movzbl %cl,%eax    <=3D=3D=3D=3D=3D=3D=3D That's the unrolled loop :-P
	movb %cl,_S(%eax)
	movb %cl,%dl
	incb %dl
	movzbl %dl,%eax
	movb %dl,_S(%eax)
	movb %cl,%dl
	addb $2,%dl
	movzbl %dl,%eax
	movb %dl,_S(%eax)
	movb %cl,%dl
	addb $3,%dl
	movzbl %dl,%eax
	movb %dl,_S(%eax)
	addb $4,%cl        <***BUG*** Here CL have 4*n added so NEVER will be 0!
                                 because CL started with 1.
	jne L2             <=3D=3D=3D=3D=3D=3D=3D=3D=3D So here we have an infini=
te loop.
L6:
	movzbl %cl,%eax
	leave
	ret
.comm _S,256

Reported to bug-gcc by: nisse AT lysator DOT liu DOT se (Niels M=F7ller)

Analized by SET.

--------------------------------------------------------------------------
*** Bug 2 ***


Description: The scheduler for assigments of the compiler fails using -O
             under some complex situations.

Example to test the bug:
/* bugs/gcc.2722.386.c
 * This program triggers a code generation bug in gcc 2.7.2.2 for
 * Intel 386 (and later) processors.
 * The bug has been present at least since gcc 2.6.3.
 *
 * When compiled correctly, the program should produce no output.
 * Any output on the form "X is Y, should be Z" indicates an error.
 * On the Intel 386, the erroneous output is:
 *
 *	SP[3] is 0x0000000B, should be 0x00000061
 *
 * In the `update()' function below, gcc schedules the load of A1 at 2a
 * and store at 2b BEFORE the load of SP1 at 1a and store at 1b.
 * The store at 2b CLOBBERS the original value of SP1, causing the
 * load at 1a to pick up the wrong value, and consequently store
 * the wrong value at 1b.
 */
#include <stdio.h>

struct state {
    unsigned *SP;
    unsigned ARG0;
    unsigned ARG1;
    unsigned STACK[100];
};

void update(struct state *state) 
{
    unsigned *SP =3D state->SP;
    unsigned SP1 =3D SP[1];	/*1a*/
    unsigned SP2 =3D SP[2];
    unsigned SP3 =3D SP[3];
    unsigned A0 =3D state->ARG0;
    unsigned A1 =3D state->ARG1;	/*2a*/
    SP[3] =3D SP1;		/*1b*/
    SP[2] =3D SP3;
    SP[1] =3D A1;			/*2b*/
    SP[0] =3D SP2;
    state->ARG1 =3D A0;
    state->ARG0 =3D SP3;
}

void check(const char *name, unsigned now, unsigned expected)
{
    if( now !=3D expected )
	fprintf(stderr, "%s is 0x%08X, should be 0x%08X\n",
		name, now, expected);
}

int main(void)
{ 
    struct state state;
    state.STACK[99] =3D 99;
    state.STACK[98] =3D 98;
    state.STACK[97] =3D 97;
    state.STACK[96] =3D 96;
    state.SP =3D &state.STACK[96];
    state.ARG1 =3D 11;
    state.ARG0 =3D 10;
    update(&state);
    check("SP[3]", state.SP[3], 97);
    check("SP[2]", state.SP[2], 99);
    check("SP[1]", state.SP[1], 11);
    check("SP[0]", state.SP[0], 98);
    check("ARG1", state.ARG1, 10);
    check("ARG0", state.ARG0, 99);
    return 0;
}
/**** End of example *****/

Compile with: -O

Effect: GCC assigns a wrong value to SP[3] because he destroyed the right
        value when reordering the instructions. See comments in the source=
.

To test it better you can use a debugger and you'll see how gcc reorders t=
he
assigments and fails.

There are an unofitial patch for it.

Reported to bug-gcc by Mikael Pettersson <mpe AT ida DOT liu DOT se>.
--------------------------------------------------------------------------

SET


------------------------------------ 0 --------------------------------
Visit my home page: http://www.geocities.com/SiliconValley/Vista/6552
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA
TE: +(541) 759 0013

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019