On Tue, Mar 10, 2009 at 2:44 PM, Hariharan Sandanagobalane <harihar...@picochip.com> wrote: > 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?
The memcmp assumes the bitfield is packed. Does the testcase work for you if you make the structure so? Richard. > TIA, > Regards > Hari >