On Wed, 9 Dec 2020, Jakub Jelinek wrote: > Hi! > > With the bit_cast changes, I have added support for bitfields which don't > have scalar representatives. For bit_cast it works fine, as when mask > is non-NULL, off is asserted to be 0. But when native_encode_initializer > is called e.g. from sccvn with off > 0 (i.e. we are interested in encoding > just a few bytes out of it somewhere from the middle or at the end), the > following computations are incorrect. > pos is a byte position from the start of the constructor, repr_size is the > size in bytes of the bit-field representative and len is the length > of the buffer. If the buffer is offsetted by positive off, those numbers > are uncomparable though, we need to add off to len to make both > count bytes from the start of the constructor, and o is a utility temporary > set to off != -1 ? off : 0 (because off -1 also means start at offset 0 > and just force special behavior). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. > 2020-12-09 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/98199 > * fold-const.c (native_encode_initializer): Fix handling bit-fields > when off > 0. > > * gcc.c-torture/compile/pr98199.c: New test. > > --- gcc/fold-const.c.jj 2020-12-08 12:42:53.000000000 +0100 > +++ gcc/fold-const.c 2020-12-08 15:26:43.055445045 +0100 > @@ -8320,11 +8320,11 @@ native_encode_initializer (tree init, un > return 0; > HOST_WIDE_INT repr_size = int_size_in_bytes (repr_type); > gcc_assert (repr_size > 0 && repr_size <= len); > - if (pos + repr_size <= len) > + if (pos + repr_size <= o + len) > rpos = pos; > else > { > - rpos = len - repr_size; > + rpos = o + len - repr_size; > gcc_assert (rpos <= pos); > } > } > --- gcc/testsuite/gcc.c-torture/compile/pr98199.c.jj 2020-12-08 > 15:37:15.082465022 +0100 > +++ gcc/testsuite/gcc.c-torture/compile/pr98199.c 2020-12-08 > 15:36:51.032730617 +0100 > @@ -0,0 +1,7 @@ > +/* PR tree-optimization/98199 */ > + > +struct A { long a; short d; int c, f, e, g; }; > +struct B { int a, i; short j; struct A k; signed : 20; int e, g; } > __attribute__((packed)); > +struct C { short a; unsigned i, k; struct B d; const int : 30; signed e : > 20; signed : 18; }; > +const struct C l = { 1, 6, 0, {}, 0 }; > +int foo (void) { return l.e || 0; } > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)