This is the mail archive of the gcc@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]

pr39339 - invalid testcase or SRA bug?


Hi,
Since r144598, pr39339.c has been failing on picochip. On investigation, it looks to me that the testcase is illegal.


Relevant source code:
struct C
{
  unsigned int c;
  struct D
  {
    unsigned int columns : 4;
    unsigned int fore : 9;
    unsigned int back : 9;
    unsigned int fragment : 1;
    unsigned int standout : 1;
    unsigned int underline : 1;
    unsigned int strikethrough : 1;
    unsigned int reverse : 1;
    unsigned int blink : 1;
    unsigned int half : 1;
    unsigned int bold : 1;
    unsigned int invisible : 1;
    unsigned int pad : 1;
  } attr;
};

struct A
{
  struct C *data;
  unsigned int len;
};

struct B
{
  struct A *cells;
  unsigned char soft_wrapped : 1;
};

struct E
{
  long row, col;
  struct C defaults;
};

__attribute__ ((noinline))
void foo (struct E *screen, unsigned int c, int columns, struct B *row)
{
  struct D attr;
  long col;
  int i;
  col = screen->col;
  attr = screen->defaults.attr;
  attr.columns = columns;
  row->cells->data[col].c = c;
  row->cells->data[col].attr = attr;
  col++;
  attr.fragment = 1;
  for (i = 1; i < columns; i++)
    {
      row->cells->data[col].c = c;
      row->cells->data[col].attr = attr;
      col++;
    }
}

int
main (void)
{
  struct E e = {.row = 5,.col = 0,.defaults =
      {6, {-1, -1, -1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}} };
  struct C c[4];
  struct A a = { c, 4 };
  struct B b = { &a, 1 };
  struct D d;
  __builtin_memset (&c, 0, sizeof c);
  foo (&e, 65, 2, &b);
  d = e.defaults.attr;
  d.columns = 2;
  if (__builtin_memcmp (&d, &c[0].attr, sizeof d))
    __builtin_abort ();
  d.fragment = 1;
  if (__builtin_memcmp (&d, &c[1].attr, sizeof d))
    __builtin_abort ();
  return 0;
}


In picochip, PCC_BITFIELD_TYPE_MATTERS is set and int is 16-bits, so the structure D becomes 6 bytes, with 3-bit padding between fore and back.


At SRA the code becomes

;; Function foo (foo)

foo (struct E * screen, unsigned int c, int columns, struct B * row)
{
  unsigned int attr$B32F16;
  <unnamed-unsigned:6> attr$B26F6;
  <unnamed-unsigned:9> attr$back;
  <unnamed-unsigned:9> attr$fore;
  <unnamed-unsigned:1> attr$fragment;
  int i;
  long int col;
  struct C * D.1267;
  unsigned int D.1266;
  unsigned int D.1265;
  struct C * D.1264;
  struct A * D.1263;
  <unnamed-unsigned:4> D.1262;
  unsigned char D.1261;

<bb 2>:
  col_4 = screen_3(D)->col;
  attr$B32F16_36 = BIT_FIELD_REF <screen_3(D)->defaults.attr, 16, 32>;
  attr$B26F6_37 = BIT_FIELD_REF <screen_3(D)->defaults.attr, 6, 26>;
  attr$back_38 = screen_3(D)->defaults.attr.back;
  attr$fore_39 = screen_3(D)->defaults.attr.fore;
  attr$fragment_40 = screen_3(D)->defaults.attr.fragment;
  D.1261_6 = (unsigned char) columns_5(D);
  D.1262_7 = (<unnamed-unsigned:4>) D.1261_6;
  D.1263_9 = row_8(D)->cells;
  D.1264_10 = D.1263_9->data;
  D.1265_11 = (unsigned int) col_4;
  D.1266_12 = D.1265_11 * 8;
  D.1267_13 = D.1264_10 + D.1266_12;
  D.1267_13->c = c_14(D);
  BIT_FIELD_REF <D.1267_13->attr, 16, 32> = attr$B32F16_36;
  BIT_FIELD_REF <D.1267_13->attr, 6, 26> = attr$B26F6_37;
  D.1267_13->attr.back = attr$back_38;
  D.1267_13->attr.fore = attr$fore_39;
  D.1267_13->attr.fragment = attr$fragment_40;
  D.1267_13->attr.columns = D.1262_7;
  col_20 = col_4 + 1;
  if (columns_5(D) > 1)
    goto <bb 3>;
  else
    goto <bb 4>;

<bb 3>:
  # col_29 = PHI <col_32(3), col_20(2)>
  # i_30 = PHI <i_33(3), 1(2)>
  D.1265_24 = (unsigned int) col_29;
  D.1266_25 = D.1265_24 * 8;
  D.1267_26 = D.1264_10 + D.1266_25;
  D.1267_26->c = c_14(D);
  BIT_FIELD_REF <D.1267_26->attr, 16, 32> = attr$B32F16_36;
  BIT_FIELD_REF <D.1267_26->attr, 6, 26> = attr$B26F6_37;
  D.1267_26->attr.back = attr$back_38;
  D.1267_26->attr.fore = attr$fore_39;
  D.1267_26->attr.fragment = 1;
  D.1267_26->attr.columns = D.1262_7;
  col_32 = col_29 + 1;
  i_33 = i_30 + 1;
  if (columns_5(D) > i_33)
    goto <bb 3>;
  else
    goto <bb 4>;

<bb 4>:
  return;

}



;; Function main (main)

main ()
{
  struct D d;
  struct B b;
  struct A a;
  struct C c[4];
  struct E e;
  int D.1279;
  int D.1276;

<bb 2>:
  e.row = 5;
  e.col = 0;
  e.defaults.c = 6;
  e.defaults.attr.columns = 15;
  e.defaults.attr.fore = 511;
  e.defaults.attr.back = 511;
  e.defaults.attr.fragment = 1;
  e.defaults.attr.standout = 0;
  e.defaults.attr.underline = 1;
  e.defaults.attr.strikethrough = 0;
  e.defaults.attr.reverse = 1;
  e.defaults.attr.blink = 0;
  e.defaults.attr.half = 1;
  e.defaults.attr.bold = 0;
  e.defaults.attr.invisible = 1;
  e.defaults.attr.pad = 0;
  a.data = &c;
  a.len = 4;
  b.cells = &a;
  b.soft_wrapped = 1;
  __builtin_memset (&c, 0, 32);
  foo (&e, 65, 2, &b);
  d = e.defaults.attr;
  d.columns = 2;
  D.1276_1 = __builtin_memcmp (&d, &c[0].attr, 6);
  if (D.1276_1 != 0)
    goto <bb 3>;
  else
    goto <bb 4>;

<bb 3>:
  __builtin_abort ();

<bb 4>:
  d.fragment = 1;
  D.1279_2 = __builtin_memcmp (&d, &c[1].attr, 6);
  if (D.1279_2 != 0)
    goto <bb 5>;
  else
    goto <bb 6>;

<bb 5>:
  __builtin_abort ();

<bb 6>:
  return 0;

}


Note that padding bits (13,16) are not copied over in bb_2 in function foo. main then does a memcmp, which fails because the padding bits are different.


From C99 standards (p328), 265) The contents of ‘‘holes’’ used as padding for purposes of alignment within structure objects are
indeterminate. Strings shorter than their allocated space and unions may also cause problems in comparison.


Is this just that the testcase is illegal on 16-bit targets or is it SRA's responsibility to copy the padding bits?

TIA,
Regards
Hari


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