PR tree-optimization/78170: Truncate sign-extended padding when encoding bitfields
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Wed, 2 Nov 2016 09:28:35 +0000 (09:28 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Wed, 2 Nov 2016 09:28:35 +0000 (09:28 +0000)
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

gcc/ChangeLog
gcc/gimple-ssa-store-merging.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr78170.c [new file with mode: 0644]

index aee2b83f8b3acfd6ea33e2156b4b22521aaf8fd4..ba76566850df5c696bcb9ddc7c033808b4b6d832 100644 (file)
@@ -1,3 +1,9 @@
+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
index feba907559f766a9cbedb9dcf9c933bc0acc84a5..f279511e1c60bd45f6c232b72a6fda271c02c04e 100644 (file)
@@ -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
index d979a56fcf7525530a497c7266d3ccff4f51bb5a..c06c315821e252aad96778856dfc8234cbd20f5e 100644 (file)
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78170.c b/gcc/testsuite/gcc.c-torture/execute/pr78170.c
new file mode 100644 (file)
index 0000000..8ef812e
--- /dev/null
@@ -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;
+}