https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82569

            Bug ID: 82569
           Summary: [8 regression] failure in 177.mesa cpu2000 test case
                    after r253530
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: seurer at gcc dot gnu.org
  Target Milestone: ---

This failure was notice on a powerpc64 be system.  Specifically, a power6
system.

The test case 177.mesa in the spec2000 test cases began failing with revision
253530 with a segmentation fault.  The failure occurs in "write_color_span" but
I traced it to a bad value in a parameter being passed to an earlier function. 
I noticed this when targeting power6x but the same bad code is generated for
power6.  power7/power8 generate different code.  I only saw the segmentation
fauit when the code was compiled with -O3.

(running in gdb...)
run -frames 1000 -meshfile mesa.in -ppmfile mesa.ppm

Program received signal SIGSEGV, Segmentation fault.
0x000000001006087c in .write_color_span ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.ppc64
(gdb) up
#1  0x00000000100792f4 in .gl_write_texture_span ()
(gdb) up
#2  0x00000000100952f4 in .general_textured_triangle ()
(gdb) x/10i $pc-24
   0x100952dc <.general_textured_triangle+3420>:        std     r16,120(r1)
   0x100952e0 <.general_textured_triangle+3424>:        ld      r5,29104(r1)
   0x100952e4 <.general_textured_triangle+3428>:        ld      r6,29088(r1)
   0x100952e8 <.general_textured_triangle+3432>:        ld      r3,29200(r1)
   0x100952ec <.general_textured_triangle+3436>:        std     r12,29112(r1)
   0x100952f0 <.general_textured_triangle+3440>:        bl      0x10079080
<.gl_write_texture_span>
=> 0x100952f4 <.general_textured_triangle+3444>:        nop
   0x100952f8 <.general_textured_triangle+3448>:        ld      r12,29112(r1)
   0x100952fc <.general_textured_triangle+3452>:        lwz     r9,29148(r1)
   0x10095300 <.general_textured_triangle+3456>:        lwz     r10,29124(r1)

So, if I compare the parameter values at this point in the working (r253529)
and failing (r253530) code r6 holds the bad parm value:

failing:
(gdb) info registers
...
r6             0xfff0000007a    17587891077242

Works:
(gdb) info registers
...
r6             0x7a     122


Why does this happen?  When it fails the value that is computed earlier in the
code for the parameter

  iy = ((fy) >> 11);

is stored via an "stw" and then loaded via a "ld".  If there is any leftover
garbage in the memory it will fail.  It doesn't always fail as sometimes the
memory has 0 in the bytes not stored to via the stw and loaded via the ld.

So, looking at the assembly output:

works:
   0x10094f9c <.general_textured_triangle+2092>:        srawi   r8,r4,11
   0x10094fa0 <.general_textured_triangle+2096>:        std     r8,29256(r1)
...
   0x100952c0 <.general_textured_triangle+2896>:        ld      r10,29256(r1)
   (this is then stored again and loaded into r6 for the function call via
std/ld)

fails:
   0x10094d84 <.general_textured_triangle+2052>:        srawi   r9,r3,11
   0x10094d88 <.general_textured_triangle+2056>:        stw     r9,29268(r1)
...
   0x10095094 <.general_textured_triangle+2836>:        ld      r10,29264(r1)
   (this is then stored again and loaded into r6 for the function call via
std/ld)

Something in this revision causes the (working) std to be replaced by a stw.


The source is really ugly and is a bunch of macros defined in functions that
then #include code that uses the macros.  (Good grief, who wrote this?)  I
haven't been able to whittle down the code much from the original source. 
Trying to duplicate the problem from scratch also hasn't worked; with both
253529 and 253530 the store after the >> is an stw and the parameter load for
the function call is an lwa.

If I generate a .i from the code this is the "bad" part:

# 483 "tritemp.h"
            {
                int subTriangle;
                GLfixed fx, fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge;
                GLfixed fdxOuter;
                int idxOuter;
                float dxOuter;
                GLfixed fError, fdError;
                float adjx, adjy;
                GLfixed fy;
                int iy;
                GLdepth *zRow;
                int dZRowOuter, dZRowInner;
                GLfixed fz, fdzOuter, fdzInner;
                GLfixed fr, fdrOuter, fdrInner;
                GLfixed fg, fdgOuter, fdgInner;
                GLfixed fb, fdbOuter, fdbInner;
                GLfixed fa, fdaOuter, fdaInner;
# 518 "tritemp.h"
                GLfloat sLeft, dsOuter, dsInner;
                GLfloat tLeft, dtOuter, dtInner;
                GLfloat wLeft, dwOuter, dwInner;
                GLfloat uLeft, duOuter, duInner;
                GLfloat vLeft, dvOuter, dvInner;
                for (subTriangle=0;
                        subTriangle<=1;
                        subTriangle++) {
                    EdgeT *eLeft, *eRight;
                    int setupLeft, setupRight;
                    int lines;
                    if (subTriangle==0) {
                        if (ltor) {
                            eLeft = &eMaj;
                            eRight = &eBot;
                            lines = eRight->lines;
                            setupLeft = 1;
                            setupRight = 1;
                        }
                        else {
                            eLeft = &eBot;
                            eRight = &eMaj;
                            lines = eLeft->lines;
                            setupLeft = 1;
                            setupRight = 1;
                        }
                    }
                    else {
                        if (ltor) {
                            eLeft = &eMaj;
                            eRight = &eTop;
                            lines = eRight->lines;
                            setupLeft = 0;
                            setupRight = 1;
                        }
                        else {
                            eLeft = &eTop;
                            eRight = &eMaj;
                            lines = eLeft->lines;
                            setupLeft = 1;
                            setupRight = 0;
                        }
                        if (lines==0) return;
                    }
                    if (setupLeft && eLeft->lines>0) {
                        GLint vLower;
                        GLfixed fsx = eLeft->fsx;
                        fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
                        fError = fx - fsx - 0x00000800;
                        fxLeftEdge = fsx - 1;
                        fdxLeftEdge = eLeft->fdxdy;
                        fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
                        fdError = fdxOuter - fdxLeftEdge + 0x00000800;
                        idxOuter = ((fdxOuter) >> 11);
                        dxOuter = (float) idxOuter;
                        fy = eLeft->fsy;
// ======================================
// The next line is where the improper stw is generated
// ======================================
                        iy = ((fy) >> 11);
                        adjx = (float)(fx - eLeft->fx0);
                        adjy = eLeft->adjy;
                        vLower = eLeft->v0;
# 606 "tritemp.h"
                        {
                            GLfloat z0, tmp;
                            z0 = VB->Win[vLower][2] + ctx->PolygonZoffset;
                            tmp = (z0 * 2048.0f + dzdx * adjx + dzdy * adjy) +
0x00000400;
                            if (tmp < 0xffffffff/2)
                                fz = (GLfixed) tmp;
                            else
                                fz = 0xffffffff/2;
                            fdzOuter = ((GLfixed) ((dzdy + dxOuter * dzdx) *
2048.0f));
                            zRow = ((ctx)->Buffer->Depth + (ctx)->Buffer->Width
* (iy) + (((fxLeftEdge) >> 11)));
                            dZRowOuter = (ctx->Buffer->Width + idxOuter) *
sizeof(GLdepth);
                        }
                        fr = (GLfixed)(((VB->Color[vLower][0]) << 11) + drdx *
adjx + drdy * adjy)
                             + 0x00000400;
                        fdrOuter = ((GLfixed) ((drdy + dxOuter * drdx) *
2048.0f));
                        fg = (GLfixed)(((VB->Color[vLower][1]) << 11) + dgdx *
adjx + dgdy * adjy)
                             + 0x00000400;
                        fdgOuter = ((GLfixed) ((dgdy + dxOuter * dgdx) *
2048.0f));
                        fb = (GLfixed)(((VB->Color[vLower][2]) << 11) + dbdx *
adjx + dbdy * adjy)
                             + 0x00000400;
                        fdbOuter = ((GLfixed) ((dbdy + dxOuter * dbdx) *
2048.0f));
                        fa = (GLfixed)(((VB->Color[vLower][3]) << 11) + dadx *
adjx + dady * adjy)
                             + 0x00000400;
                        fdaOuter = ((GLfixed) ((dady + dxOuter * dadx) *
2048.0f));
# 661 "tritemp.h"
                        {
                            GLfloat w0 = 1.0F / VB->Clip[vLower][3];
                            GLfloat s0, t0, u0, v0;
                            wLeft = w0 + (dwdx * adjx + dwdy * adjy) *
(1.0F/2048.0f);
                            dwOuter = dwdy + dxOuter * dwdx;
                            s0 = VB->TexCoord[vLower][0] * w0;
                            sLeft = s0 + (dsdx * adjx + dsdy * adjy) *
(1.0F/2048.0f);
                            dsOuter = dsdy + dxOuter * dsdx;
                            t0 = VB->TexCoord[vLower][1] * w0;
                            tLeft = t0 + (dtdx * adjx + dtdy * adjy) *
(1.0F/2048.0f);
                            dtOuter = dtdy + dxOuter * dtdx;
                            u0 = VB->TexCoord[vLower][2] * w0;
                            uLeft = u0 + (dudx * adjx + dudy * adjy) *
(1.0F/2048.0f);
                            duOuter = dudy + dxOuter * dudx;
                            v0 = VB->TexCoord[vLower][3];
                            vLeft = v0 + (dvdx * adjx + dvdy * adjy) *
(1.0F/2048.0f);
                            dvOuter = dvdy + dxOuter * dvdx;
                        }
                    }
                    if (setupRight && eRight->lines>0) {
                        fxRightEdge = eRight->fsx - 1;
                        fdxRightEdge = eRight->fdxdy;
                    }
                    if (lines==0) {
                        continue;
                    }
                    dZRowInner = dZRowOuter + sizeof(GLdepth);
                    fdzInner = fdzOuter + fdzdx;
                    fdrInner = fdrOuter + fdrdx;
                    fdgInner = fdgOuter + fdgdx;
                    fdbInner = fdbOuter + fdbdx;
                    fdaInner = fdaOuter + fdadx;
# 721 "tritemp.h"
                    dwInner = dwOuter + dwdx;
                    dsInner = dsOuter + dsdx;
                    dtInner = dtOuter + dtdx;
                    duInner = duOuter + dudx;
                    dvInner = dvOuter + dvdx;
                    while (lines>0) {
                        GLfixed ffz = fz;
                        GLfixed ffr = fr, ffg = fg, ffb = fb;
                        GLfixed ffa = fa;
# 750 "tritemp.h"
                        GLfloat ss = sLeft, tt = tLeft, ww = wLeft;
                        GLfloat uu = uLeft, vv = vLeft;
                        GLint left = ((fxLeftEdge) >> 11);
                        GLint right = ((fxRightEdge) >> 11);
                        {
                            GLfixed ffrend = ffr+(right-left-1)*fdrdx;
                            GLfixed ffgend = ffg+(right-left-1)*fdgdx;
                            GLfixed ffbend = ffb+(right-left-1)*fdbdx;
                            if (ffrend<0) ffr -= ffrend;
                            if (ffgend<0) ffg -= ffgend;
                            if (ffbend<0) ffb -= ffbend;
                            if (ffr<0) ffr = 0;
                            if (ffg<0) ffg = 0;
                            if (ffb<0) ffb = 0;
                        }
                        {
                            GLfixed ffaend = ffa+(right-left-1)*fdadx;
                            if (ffaend<0) ffa -= ffaend;
                            if (ffa<0) ffa = 0;
                        }
                        {   GLint i, n = right-left;
                            GLdepth zspan[1600];
                            GLubyte red[1600], green[1600];
                            GLubyte blue[1600], alpha[1600];
                            GLfloat s[1600], t[1600], u[1600];
                            if (n>0) {
                                if (flat_shade) {
                                    for (i=0;
                                            i<n;
                                            i++) {
                                        GLdouble wwvvInv = 1.0 / (ww*vv);
                                        zspan[i] = ((ffz) >> 11);
                                        red[i] = r;
                                        green[i] = g;
                                        blue[i] = b;
                                        alpha[i] = a;
                                        s[i] = ss*wwvvInv;
                                        t[i] = tt*wwvvInv;
                                        u[i] = uu*wwvvInv;
                                        ffz += fdzdx;
                                        ss += dsdx;
                                        tt += dtdx;
                                        uu += dudx;
                                        vv += dvdx;
                                        ww += dwdx;
                                    }
                                } else {
                                    for (i=0;
                                            i<n;
                                            i++) {
                                        GLdouble wwvvInv = 1.0 / (ww*vv);
                                        zspan[i] = ((ffz) >> 11);
                                        red[i] = ((ffr) >> 11);
                                        green[i] = ((ffg) >> 11);
                                        blue[i] = ((ffb) >> 11);
                                        alpha[i] = ((ffa) >> 11);
                                        s[i] = ss*wwvvInv;
                                        t[i] = tt*wwvvInv;
                                        u[i] = uu*wwvvInv;
                                        ffz += fdzdx;
                                        ffr += fdrdx;
                                        ffg += fdgdx;
                                        ffb += fdbdx;
                                        ffa += fdadx;
                                        ss += dsdx;
                                        tt += dtdx;
                                        uu += dudx;
                                        ww += dwdx;
                                        vv += dvdx;
                                    }
                                }

// ======================================
// This is the function call that blows up because "iy" has a bad value
// ======================================
                                gl_write_texture_span( ctx, n, left, iy, zspan,
s, t, u,
# 783 "tritemp.h" 3 4
                                                       ((void *)0)
# 783 "tritemp.h"
                                                       , red, green, blue,
alpha, GL_POLYGON );
                            }
                        };

Reply via email to