optimization/6475: zlib miscompilation with gcc-3.1

Jakub Jelinek jakub@redhat.com
Fri Apr 26 11:06:00 GMT 2002


Reduced testcase below, it segfaults when run.
The problem seems to be stack slot reusal and new memattr code:

Reload decides to spill off (reg/f:SI 219) into:
($ebp - 272 [27 p S4 A8]), (reg/v/f: SI 78) into
($ebp - 224 [17 p S4 A8]) and (reg/v/f:SI 82) into
($ebp - 272 [27 xx S4 A8]) (ie. reusing slot for pseudo 219).
All uses of pseudo 219 are before all uses of pseudo 82, so this
doesn't look like something reload cannot do (I'll leave now the
question why pseudo 219 was ever created, it is some GCSE silliness
which apparently does consider ((frame + const_int) + const_int)
as good candidate for elimination and increases register preasure
when it is always cheaper to recompute it when needed).
When scheduler is run, it compares ($ebp - 272 [27 p S4 A8])
with ($ebp - 272 [27 xx S4 A8]) and since they are for different
variables, thinks they are independent and swaps them.
Any ideas what to do here?

lreg:
(insn 358 356 363 (set (mem/s:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -188 [0xffffff44])) [3 x+4 S4 A32])
        (const_int 0 [0x0])) 45 {*movsi_1} (nil)
    (nil))

(insn 363 358 368 (set (reg/v/f:SI 78)
        (reg/f:SI 219)) 45 {*movsi_1} (nil)
    (expr_list:REG_DEAD (reg/f:SI 219)
        (nil)))

(insn 368 363 1098 (parallel[
            (set (reg/v/f:SI 82)
                (plus:SI (reg/f:SI 20 frame)
                    (const_int -184 [0xffffff48])))
            (clobber (reg:CC 17 flags))
        ] ) 207 {*addsi_1} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))

greg:
(insn 358 356 1411 (set (mem/s:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int -196 [0xffffff3c])) [3 x+4 S4 A32])
        (const_int 0 [0x0])) 45 {*movsi_1} (nil)
    (nil))

(insn 1411 358 363 (set (reg:SI 1 edx)
        (mem:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int -272 [0xfffffef0])) [27 p S4 A8])) 45 {*movsi_1} (nil)
    (nil))

(insn 363 1411 368 (set (mem:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int -224 [0xffffff20])) [17 p S4 A8])
        (reg:SI 1 edx)) 45 {*movsi_1} (nil)
    (nil))

(insn 368 363 1414 (parallel[
            (set (reg:SI 2 ecx)
                (plus:SI (reg/f:SI 6 ebp)
                    (const_int -192 [0xffffff40])))
            (clobber (reg:CC 17 flags))
        ] ) 207 {*addsi_1} (nil)
    (nil))

(insn 1414 368 1098 (set (mem:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int -272 [0xfffffef0])) [27 xx S4 A8])
        (reg:SI 2 ecx)) 45 {*movsi_1} (nil)
    (nil))

sched2:
(insn:TI 1414 368 1768 (set (mem:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int -272 [0xfffffef0])) [27 xx S4 A8])
        (reg:SI 2 ecx)) 45 {*movsi_1} (insn_list 368 (nil))
    (expr_list:REG_DEAD (reg:SI 2 ecx)
        (nil)))

(insn:TI 1768 1414 1411 (parallel[
            (set (reg:SI 0 eax [133])
                (plus:SI (reg:SI 0 eax [133])
                    (reg:SI 1 edx)))
            (clobber (reg:CC 17 flags))
        ] ) 207 {*addsi_1} (insn_list 1767 (nil))
    (expr_list:REG_DEAD (reg:SI 1 edx)
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))

(insn 1411 1768 353 (set (reg:SI 1 edx)
        (mem:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int -272 [0xfffffef0])) [27 p S4 A8])) 45 {*movsi_1} (insn_list...))

typedef struct
{
  union
  {
    struct
    {
      unsigned char a3;
      unsigned char a4;
    } a2;
    unsigned int a5;
  } a0;
  unsigned int a1;
} A;

static int
foo (unsigned int *b, unsigned int n, unsigned int s, const unsigned int *d,
     const unsigned int *e, A **t, unsigned int *m, A *hp, unsigned int *hn,
     unsigned int *v)
{
  unsigned int a, c[15 + 1], f;
  int g, h;
  unsigned int i, j, k;
  int l;
  unsigned int ee;
  unsigned int *p;
  A *q, r, *u[15];
  int w;
  unsigned int x[15 + 1], *xx;
  int y;
  unsigned int z;
  p = c;
  *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0;
  *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0;
  *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0;
  *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0;
  p = b;
  i = n;
  do
    c[*p++]++;
  while (--i);
  if (c[0] == n)
    {
      *t = (A *) 0;
      *m = 0;
      return 0;
    }
  l = *m;
  for (j = 1; j <= 15; j++)
    if (c[j])
      break;
  k = j;
  if ((unsigned int) l < j)
    l = j;
  for (i = 15; i; i--)
    if (c[i])
      break;
  g = i;
  if ((unsigned int) l > i)
    l = i;
  *m = l;
  for (y = 1 << j; j < i; j++, y <<= 1)
    if ((y -= c[j]) < 0)
      return -3;
  if ((y -= c[i]) < 0)
    return -3;
  c[i] += y;
  x[1] = j = 0;
  p = c + 1;
  xx = x + 2;
  while (--i)
    *xx++ = (j += *p++);
  p = b;
  i = 0;
  do
    if ((j = *p++) != 0)
      v[x[j]++] = i;
  while (++i < n);
  n = x[g];
  x[0] = i = 0;
  p = v;
  h = -1;
  w = -l;
  u[0] = (A *) 0;
  q = (A *) 0;
  z = 0;
  for (; k <= g; k++)
    {
      a = c[k];
      while (a--)
        {
          while (k > w + l)
            {
              h++;
              w += l;
              z = g - w;
              z = z > (unsigned int) l ? l : z;
              if ((f = 1 << (j = k - w)) > a + 1)
                {
                  f -= a + 1;
                  xx = c + k;
                  if (j < z)
                    while (++j < z)
                      {
                        if ((f <<= 1) <= *++xx)
                          break;
                        f -= *xx;
                      }
                }
              z = 1 << j;
              if (*hn + z > 1440)
                return -3;
              u[h] = q = hp + *hn;
              *hn += z;
              if (h)
                {
                  x[h] = i;
                  r.a0.a2.a4 = (unsigned char) l;
                  r.a0.a2.a3 = (unsigned char) j;
                  j = i >> (w - l);
                  r.a1 = (unsigned int) (q - u[h - 1] - j);
                  u[h - 1][j] = r;
                }
              else
                *t = q;
            }
          r.a0.a2.a4 = (unsigned char) (k - w);
          if (p >= v + n)
            r.a0.a2.a3 = 128 + 64;
          else if (*p < s)
            {
              r.a0.a2.a3 = (unsigned char) (*p < 256 ? 0 : 32 + 64);
              r.a1 = *p++;
            }
          else
            {
              r.a0.a2.a3 = (unsigned char) (e[*p - s] + 16 + 64);
              r.a1 = d[*p++ - s];
            }
          f = 1 << (k - w);
          for (j = i >> w; j < z; j += f)
            q[j] = r;
          for (j = 1 << (k - 1); i & j; j >>= 1)
            i ^= j;
          i ^= j;
          ee = (1 << w) - 1;
          while ((i & ee) != x[h])
            {
              h--;
              w -= l;
              ee = (1 << w) - 1;
            }
        }
    }
  return y != 0 && g != 1 ? (-5) : 0;
}

int a[19] = { 3, 4, 0, 2, 2,[17] = 3, 3 };
int d[19];
A h[1440];

int
main (void)
{
  int b = 0, c = 0;
  A *e = 0;
  foo (a, 19, 19, 0, 0, &e, &b, h, &c, d);
}

	Jakub



More information about the Gcc-bugs mailing list