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