This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Reload bug & SRA oddness


Alexandre Oliva wrote:
> On Apr 20, 2007, Bernd Schmidt <bernds_cb1@t-online.de> wrote:
> 
>> Bootstrap completed, and no check-gcc regressions on i686-linux.  Can
>> you send me a testcase that fails when this change is made?
> 
> Native configuration is x86_64-pc-linux-gnu
> FAIL: gcc.c-torture/execute/20040709-2.c execution,  -O3 -g 

Okay, I've set up an x86-64 install and debugged this a little further.
 I've attached a reduced testcase for this.

What's happening is that in esra, the following happens to function retmeA:
retmeA (x)                              retmeA (x)
{                                       {
                                  >       <unnamed-unsigned:11> x$k;
                                  >       unsigned char x$B0F5;
  struct A D.2000;                        struct A D.2000;

<bb 2>:                                 <bb 2>:
  D.2000 = x;                     |       x$k_1 = x.k;
                                  >       x$B0F5_2 = BIT_FIELD_REF <x,
                                  >       D.2000.k = x$k_1;
                                  >       BIT_FIELD_REF <D.2000, 5, 0>
  return D.2000;                          return D.2000;

}                                       }

It is then inlined into fn1A, where esra runs again, and when scanning
the function, we run into the new BIT_FIELD_REFs.  When it tries to deal
with the following stmt:

   BIT_FIELD_REF <D.4935, 5, 0> = BIT_FIELD_REF <x$B0F5_11, 5, 0>;

it just calls scalarize_use with D.4935 and is_output==true, causing us
to insert two additional stmts:

+  D.4935.k = SR.282_16;
   BIT_FIELD_REF <D.4935, 5, 0> = BIT_FIELD_REF <x$B0F5_11, 5, 0>;
+  SR.282_17 = D.4935.k;

Both of these are unnecessary (and inefficient), as the BIT_FIELD_REF
does not touch "k".  With my patch to restore is_output behaviour, we
only eliminate the first, but not the second.

IMO the real problem is that SRA doesn't know how to deal with these
BIT_FIELD_REFs properly - possibly something similar to how we deal with
ARRAY_RANGE_REF could be used?  I'll keep investigating this, but for
the moment there are two more points I'd like to make:

 * 20040709-2.c (which is very bitfield intensive) at -O3 has a pretty
large code size regression at least on x86-64 when compared to before
your SRA patch.
 * I've seen no serious attempt to investigate or fix the regressions
Andrew Pinski has reported.

As a consequence of all these problems, I'd like to see this patch
reverted for now until it we know how to do it properly.


Bernd
-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
extern void abort (void);
extern void exit (int);

unsigned int
myrnd (void)
{
  static unsigned int s = 1388815473;
  s *= 1103515245;
  s += 12345;
  return (s / 65536) % 2048;
}

struct __attribute__ ((packed)) A
{
  unsigned short i:1, l:1, j:3, k:11;
};
struct A sA;
struct A
retmeA (struct A x)
{
  return x;
}
unsigned int
fn1A (unsigned int x)
{
  struct A y = sA;
  y.k += x;
  y = retmeA (y);
  return y.k;
}
unsigned int
fn2A (unsigned int x)
{
  struct A y = sA;
  y.k += x;
  y.k %= 15;
  return y.k;
}
unsigned int
retitA (void)
{
  return sA.k;
}
unsigned int
fn3A (unsigned int x)
{
  sA.k += x;
  return retitA ();
}

void
testA (void)
{
  int i;
  unsigned int mask, v, a, r;
  struct A x;
  char *p = (char *) &sA;
  for (i = 0; i < sizeof (sA); ++i)
    *p++ = myrnd ();
  if (__builtin_classify_type (sA.l) == 8)
    sA.l = 5.25;
  sA.k = -1;
  mask = sA.k;
  v = myrnd ();
  a = myrnd ();
  sA.k = v;
  x = sA;
  r = fn1A (a);
  if (x.i != sA.i || x.j != sA.j || x.k != sA.k || x.l != sA.l
      || ((v + a) & mask) != r)
    abort ();
  v = myrnd ();
  a = myrnd ();
  sA.k = v;
  x = sA;
  r = fn2A (a);
  if (x.i != sA.i || x.j != sA.j || x.k != sA.k || x.l != sA.l
      || ((((v + a) & mask) % 15) & mask) != r)
    abort ();
  v = myrnd ();
  a = myrnd ();
  sA.k = v;
  x = sA;
  r = fn3A (a);
  if (x.i != sA.i || x.j != sA.j || sA.k != r || x.l != sA.l
      || ((v + a) & mask) != r)
    abort ();
}

int
main (void)
{
  testA ();
  exit (0);
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]