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 ); } };