aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2016-11-02 09:28:35 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2016-11-02 09:28:35 +0000
commit4b2c06f49f8d7365e2aa15f32cbc6a726c9ff9fb (patch)
tree8f619725f7d1a2f96ab4e48798bf97f9f0d98f89
parent63e523d6f0853765adc332c7a68a8e6b16971d6b (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/gimple-ssa-store-merging.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr78170.c37
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;
+}