diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2016-11-02 09:28:35 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2016-11-02 09:28:35 +0000 |
commit | 4b2c06f49f8d7365e2aa15f32cbc6a726c9ff9fb (patch) | |
tree | 8f619725f7d1a2f96ab4e48798bf97f9f0d98f89 | |
parent | 63e523d6f0853765adc332c7a68a8e6b16971d6b (diff) | |
download | gcc-4b2c06f49f8d7365e2aa15f32cbc6a726c9ff9fb.zip gcc-4b2c06f49f8d7365e2aa15f32cbc6a726c9ff9fb.tar.gz gcc-4b2c06f49f8d7365e2aa15f32cbc6a726c9ff9fb.tar.bz2 |
PR tree-optimization/78170: Truncate sign-extended padding when encoding bitfields
PR tree-optimization/78170
* gimple-ssa-store-merging.c (encode_tree_to_bitpos): Truncate padding
introduced by native_encode_expr on little-endian as well.
* gcc.c-torture/execute/pr78170.c: New test.
From-SVN: r241779
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-ssa-store-merging.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr78170.c | 37 |
4 files changed, 62 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aee2b83..ba76566 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + PR tree-optimization/78170 + * gimple-ssa-store-merging.c (encode_tree_to_bitpos): Truncate padding + introduced by native_encode_expr on little-endian as well. + +2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + PR tree-optimization/78162 * gimple-ssa-store-merging.c (execute): Mark stores with bitpos < 0 as invalid. diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index feba907..f279511 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -432,13 +432,23 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos, contain a sign bit due to sign-extension). */ unsigned int padding = byte_size - ROUND_UP (bitlen, BITS_PER_UNIT) / BITS_PER_UNIT - 1; - if (BYTES_BIG_ENDIAN) + if (padding != 0) { - tmpbuf += padding; + /* On big-endian the padding is at the 'front' so just skip the initial + bytes. */ + if (BYTES_BIG_ENDIAN) + tmpbuf += padding; + byte_size -= padding; if (bitlen % BITS_PER_UNIT != 0) - clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1, - BITS_PER_UNIT - (bitlen % BITS_PER_UNIT)); + { + if (BYTES_BIG_ENDIAN) + clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1, + BITS_PER_UNIT - (bitlen % BITS_PER_UNIT)); + else + clear_bit_region (tmpbuf, bitlen, + byte_size * BITS_PER_UNIT - bitlen); + } } /* Clear the bit region in PTR where the bits from TMPBUF will be diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d979a56..c06c315 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + PR tree-optimization/78170 + * gcc.c-torture/execute/pr78170.c: New test. + +2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + PR tree-optimization/78162 * gcc.c-torture/compile/pr78162.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78170.c b/gcc/testsuite/gcc.c-torture/execute/pr78170.c new file mode 100644 index 0000000..8ef812e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr78170.c @@ -0,0 +1,37 @@ +/* PR tree-optimization/78170. + Check that sign-extended store to a bitfield + doesn't overwrite other fields. */ + +int a, b, d; + +struct S0 +{ + int f0; + int f1; + int f2; + int f3; + int f4; + int f5:15; + int f6:17; + int f7:2; + int f8:30; +} c; + +void fn1 () +{ + d = b = 1; + for (; b; b = a) + { + struct S0 e = { 0, 0, 0, 0, 0, 0, 1, 0, 1 }; + c = e; + c.f6 = -1; + } +} + +int main () +{ + fn1 (); + if (c.f7 != 0) + __builtin_abort (); + return 0; +} |