Folding of bitfield in a union is incorrect on big endian targets. Consider the testcase given in attachment, u.b would be folded to 0x45678 instead of 0x12345.
Created attachment 33298 [details] Testcase: bitfield in a union
I forgot to mention the flag to use: -O1 and whatever flag is necessary to select a big endian target (for instance -mbig-endian if the target is arm little endian by default).
Author: thopre01 Date: Tue Aug 12 02:36:37 2014 New Revision: 213846 URL: https://gcc.gnu.org/viewcvs?rev=213846&root=gcc&view=rev Log: 2014-08-12 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ PR middle-end/62103 * gimple-fold.c (fold_ctor_reference): Don't fold in presence of bitfields, that is when size doesn't match the size of type or the size of the constructor. gcc/testsuite/ PR middle-end/62103 * gcc.c-torture/execute/bitfld-6.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/bitfld-6.c Modified: trunk/gcc/ChangeLog trunk/gcc/gimple-fold.c trunk/gcc/testsuite/ChangeLog
Author: thopre01 Date: Wed Aug 13 09:37:41 2014 New Revision: 213899 URL: https://gcc.gnu.org/viewcvs?rev=213899&root=gcc&view=rev Log: 2014-08-13 Thomas Preud'homme <thomas.preudhomme@arm.com> Backport from mainline 2014-08-12 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ PR middle-end/62103 * gimple-fold.c (fold_ctor_reference): Don't fold in presence of bitfields, that is when size doesn't match the size of type or the size of the constructor. gcc/testsuite/ PR middle-end/62103 * gcc.c-torture/execute/bitfld-6.c: New test. Added: branches/gcc-4_8-branch/gcc/testsuite/gcc.c-torture/execute/bitfld-6.c Modified: branches/gcc-4_8-branch/gcc/ChangeLog branches/gcc-4_8-branch/gcc/gimple-fold.c branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Author: thopre01 Date: Thu Aug 14 06:16:56 2014 New Revision: 213941 URL: https://gcc.gnu.org/viewcvs?rev=213941&root=gcc&view=rev Log: 2014-08-14 Thomas Preud'homme <thomas.preudhomme@arm.com> Backport from mainline 2014-08-12 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ PR middle-end/62103 * gimple-fold.c (fold_ctor_reference): Don't fold in presence of bitfields, that is when size doesn't match the size of type or the size of the constructor. gcc/testsuite/ PR middle-end/62103 * gcc.c-torture/execute/bitfld-6.c: New test. Added: branches/gcc-4_9-branch/gcc/testsuite/gcc.c-torture/execute/bitfld-6.c Modified: branches/gcc-4_9-branch/gcc/ChangeLog branches/gcc-4_9-branch/gcc/gimple-fold.c branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
Fixed in all the branch currently supported
*** Bug 64822 has been marked as a duplicate of this bug. ***
looks like this fix is too conservative. it will disable const fold for bit-field completely. for bitfld-6/little-endian, previously, we can generated main: mov w0, 0 ret while after this patch, we always load from memory. any specific reason for this? shouldn't we fix the code to let big-endian get correct folded constant?
(In reply to Jiong Wang from comment #8) > > while after this patch, we always load from memory. any specific reason for > this? > > shouldn't we fix the code to let big-endian get correct folded constant? and similar bug still exist as 64822
(In reply to Jiong Wang from comment #8) > looks like this fix is too conservative. it will disable const fold for > bit-field completely. for bitfld-6/little-endian, previously, we can > generated > > main: > mov w0, 0 > ret > > while after this patch, we always load from memory. any specific reason for > this? > > shouldn't we fix the code to let big-endian get correct folded constant? We only disable const folding for initialization of bitfields in a union. The rationale was that the fix was much simpler (and could thus be backported) and accessing a bitfield in a union that was initialized with a constant rare enough that it wasn't worth the extra effort anyway. If this latter assumption proves to be wrong I have the beginning of a patch that make double_int::from_buffer and wi::from_buffer work at the bit level. It would need to be extended to do the same to ::to_buffer.
Ok, I have a local fix. The existing testcase didn't catch it because the precision of the bitfield is not a multiple of CHAR_BITS.
Author: thopre01 Date: Wed Feb 4 08:22:45 2015 New Revision: 220390 URL: https://gcc.gnu.org/viewcvs?rev=220390&root=gcc&view=rev Log: 2015-02-04 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ PR middle-end/62103 * tree-ssa-sccvn.c (fully_constant_vn_reference_p): Use TYPE_PRECISION to compute size of referenced value in the constant case. gcc/testsuite/ PR middle-end/62103 * gcc.c-torture/execute/bitfld-7.c: New test adapted from bitfld-6.c to use 24 bits for bitfield b. Added: trunk/gcc/testsuite/gcc.c-torture/execute/bitfld-7.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-sccvn.c
Fixed in all maintained branches.