[gnu.gcc.bug] interaction between -fstrength-reduce and -finline-functions

mark@comp.vuw.ac.nz (Mark Davies) (05/26/89)

In compiling the attached file w2.c (yes it is part of an X server)
with both -fstrength-reduce and -finline-functions gcc 1.35 fails to
calculate the correct loop termination value for the outer loop in the
function CreateWindow.  If either option is used by itself valid output is produced.

version info:
gcc 1.35 running on an hp9000s370 running MORE/bsd

compiler options used:
gcc -v -O -fstrength-reduce -finline-functions -S w2.c
gcc version 1.35
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dhp300 -Dunix
-D__mc68000__ -D__hp300__ -D__unix__ -D__OPTIMIZE__ -D__HAVE_FPU__ w2.c
/tmp/cc026825.cpp
GNU CPP version 1.35
 /usr/local/lib/gcc-cc1 /tmp/cc026825.cpp -quiet -dumpbase w2.c
-fstrength-reduce -finline-functions -O -version -o w2.s
GNU C version 1.35 (68k, MIT syntax) compiled by GNU C version 1.35.

------start-of-w2.c--------
typedef unsigned long VisualID;

typedef struct _Depth  *DepthPtr;
typedef struct _Screen *ScreenPtr;
 
typedef struct _DDXPoint *DDXPointPtr;
typedef struct _Box *BoxPtr;
 
typedef struct _Region *RegionPtr;
    
typedef struct _Depth {
    int		depth;
    int		numVids;
    unsigned long	*vids;     
  } DepthRec;

typedef struct _Screen {
    int			myNum;	 
    short		numDepths;
    DepthPtr       	allowedDepths;
    int (* Intersect)();		 
    RegionPtr (* RegionCreate)(); 	 
    void (* RegionCopy)();		 
    BoxPtr (*RegionExtents)(); 		 
    void (* RegionReset)();		 

} ScreenRec;
 
typedef struct _Window *WindowPtr;

typedef struct _DrawInfo {
    short	type;
    ScreenPtr	pScreen;     
    int         depth;           
    unsigned long        serialNumber;
} DrawableRec;

typedef struct _DDXPoint {
    short x, y;
} DDXPointRec;

typedef struct _Box {
    short x1, y1, x2, y2;
} BoxRec;

typedef struct _Window {

	DrawableRec drawable;		 

	VisualID visual;

	struct _Window *parent;	         
	struct _Window *nextSib;	         
	struct _Window *prevSib;	         
	struct _Window *firstChild;	 
	struct _Window *lastChild;	 

	RegionPtr winSize;                 
	RegionPtr borderSize;              
	DDXPointRec  absCorner;
} WindowRec;

ClippedRegionFromBox(pWin, Rgn, x, y, w, h)
    register WindowPtr pWin;
    RegionPtr Rgn;
    int x, y, w, h;
{
    register ScreenPtr pScreen = pWin->drawable.pScreen;
    BoxRec box;

    box = *((* pScreen->RegionExtents)(pWin->winSize));
     
    if (x > box.x1)
	box.x1 = x;
    if (y > box.y1)
	box.y1 = y;
    x += w;
    if (x < box.x2)
	box.x2 = x;
    y += h;
    if (y < box.y2)
	box.y2 = y;
    if (box.x1 > box.x2)
	box.x2 = box.x1;
    if (box.y1 > box.y2)
	box.y2 = box.y1;
    (* pScreen->RegionReset)(Rgn, &box);
    (* pScreen->Intersect)(Rgn, Rgn, pWin->winSize);
}

WindowPtr
CreateWindow( pParent, w, h, bw, class, depth, visual)
    WindowPtr pParent;     
    unsigned short w, h, bw;
    unsigned short class;
    int depth;
    VisualID visual;
{
    WindowPtr pWin;
    ScreenPtr pScreen;
    int idepth, ivisual;
    DepthPtr pDepth;

    pScreen = pParent->drawable.pScreen;
     
    for(idepth = 0; idepth < pScreen->numDepths; idepth++)
    {
	pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
	if ((depth == pDepth->depth) || (depth == 0))
	{
	    for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
	    {
		if (visual == pDepth->vids[ivisual])
		{
		    break;
		}
	    }
	}
    }

    ClippedRegionFromBox(pParent, pWin->winSize,
			 pWin->absCorner.x, pWin->absCorner.y, (int)w, (int)h);
    pWin->borderSize = (* pScreen->RegionCreate)(((void *)0) , 1);
    if (bw)
	ClippedRegionFromBox(pParent, pWin->borderSize,
		pWin->absCorner.x - (int)bw, pWin->absCorner.y - (int)bw,
		(int)(w + (bw<<1)), (int)(h + (bw<<1)));
    else
	(* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);
    return pWin;
}

------end-of-w2.c--------

The following assembler is produced:

	:
	:
	.even
.globl _CreateWindow
_CreateWindow:
	link a6,#-32
	moveml #0x3f3c,sp@-
	movel a6@(8),d7
	movew a6@(14),a6@(-18)
	movew a6@(18),a6@(-20)
	movew a6@(22),a6@(-22)
	movel a6@(28),d4
	movel a6@(32),d5
	movel d7,a4
	movel a4@(2),a6@(-26)
	movel a6@(-26),a4
	movew a4@(4),a0	   <--- uses a4
	subl a2,a2            /
	movel a4@(6),d2    <-
	lea a0@(a0:l:2),a4 <---- clobbers a4
	movel a4,d0
	movel d0,d3
	asll #2,d3
	addl a4@(6),d3   <--- tries to use old a4 value
	jra L16
L26:
	:
	:

mark
--
Domainised:  mark@comp.vuw.ac.nz	Bang form: ...!uunet!vuwcomp!mark