re PR tree-optimization/91126 (Incorrect constant propagation of BIT_FIELD_REF)
authorRichard Biener <rguenther@suse.de>
Wed, 10 Jul 2019 13:40:12 +0000 (13:40 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 10 Jul 2019 13:40:12 +0000 (13:40 +0000)
2019-07-10  Richard Biener  <rguenther@suse.de>

PR tree-optimization/91126
* tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust
native encoding offset for BYTES_BIG_ENDIAN.
(vn_reference_lookup_3): Likewise.

* gcc.dg/torture/pr91126.c: New testcase.

From-SVN: r273355

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr91126.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index ac390d65ae7b0ef17e15b7af07682f7ce6089616..9b32482db5f4104feb0a4c35d3c533ac9866c712 100644 (file)
@@ -1,3 +1,10 @@
+2019-07-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91126
+       * tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust
+       native encoding offset for BYTES_BIG_ENDIAN.
+       (vn_reference_lookup_3): Likewise.
+
 2019-07-10  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-sccvn.c (vn_reference_lookup_3): Look at valueized
index 840d9c1f251601a40b82941501920775f8ed78bf..e531f0a3b97215ace403dbdc20367d0dd65ecaac 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91126
+       * gcc.dg/torture/pr91126.c: New testcase.
+
 2019-07-10  Richard Biener  <rguenther@suse.de>
 
        * gcc.dg/torture/ssa-fre-5.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr91126.c b/gcc/testsuite/gcc.dg/torture/pr91126.c
new file mode 100644 (file)
index 0000000..8e34815
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+struct S
+{
+  __INT32_TYPE__ a : 24;
+  __INT32_TYPE__ b : 8;
+} s;
+
+int
+main()
+{
+  s.a = 0xfefefe;
+  s.b = 0xfe;
+  unsigned char c;
+  c = ((unsigned char *)&s)[0];
+  if (c != 0xfe)
+    __builtin_abort ();
+  c = ((unsigned char *)&s)[1];
+  if (c != 0xfe)
+    __builtin_abort ();
+  c = ((unsigned char *)&s)[2];
+  if (c != 0xfe)
+    __builtin_abort ();
+  c = ((unsigned char *)&s)[3];
+  if (c != 0xfe)
+    __builtin_abort ();
+  return 0;
+}
index 777cf58e43b7ca5e8fc0dfe029e896cdb38672d0..73c77d1df4b24e92f528f088e8fa4a62a6300082 100644 (file)
@@ -1832,10 +1832,20 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse,
                            0, MIN ((HOST_WIDE_INT)sizeof (buffer), pd.size));
                  else
                    {
+                     unsigned pad = 0;
+                     if (BYTES_BIG_ENDIAN
+                         && is_a <scalar_mode> (TYPE_MODE (TREE_TYPE (pd.rhs))))
+                       {
+                         /* On big-endian the padding is at the 'front' so
+                            just skip the initial bytes.  */
+                         fixed_size_mode mode = as_a <fixed_size_mode>
+                                              (TYPE_MODE (TREE_TYPE (pd.rhs)));
+                         pad = GET_MODE_SIZE (mode) - pd.size;
+                       }
                      len = native_encode_expr (pd.rhs,
                                                buffer + MAX (0, pd.offset),
                                                sizeof (buffer - MAX (0, pd.offset)),
-                                               MAX (0, -pd.offset));
+                                               MAX (0, -pd.offset) + pad);
                      if (len <= 0
                          || len < (pd.size - MAX (0, -pd.offset)))
                        {
@@ -2588,9 +2598,20 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
              tree rhs = gimple_assign_rhs1 (def_stmt);
              if (TREE_CODE (rhs) == SSA_NAME)
                rhs = SSA_VAL (rhs);
+             unsigned pad = 0;
+             if (BYTES_BIG_ENDIAN
+                 && is_a <scalar_mode> (TYPE_MODE (TREE_TYPE (rhs))))
+               {
+                 /* On big-endian the padding is at the 'front' so
+                    just skip the initial bytes.  */
+                 fixed_size_mode mode
+                   = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (rhs)));
+                 pad = GET_MODE_SIZE (mode) - size2i / BITS_PER_UNIT;
+               }
              len = native_encode_expr (rhs,
                                        buffer, sizeof (buffer),
-                                       (offseti - offset2i) / BITS_PER_UNIT);
+                                       ((offseti - offset2i) / BITS_PER_UNIT
+                                        + pad));
              if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
                {
                  tree type = vr->type;