re PR tree-optimization/86034 (wrong code for bit-field manipulation at -Os)
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 3 Jun 2018 11:51:10 +0000 (11:51 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 3 Jun 2018 11:51:10 +0000 (11:51 +0000)
PR tree-optimization/86034
* gimple-ssa-store-merging.c (output_merged_store): Convert the RHS to
the unsigned bitfield type in a bit insertion sequence if it does not
have a larger precision than the bitfield size.
(process_store): Also bypass widening conversions for BIT_INSERT_EXPR.

From-SVN: r261128

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

index 0dc3091bf1c66c15d6b1a0983418b553fa91d049..4faeadc8a47e9fcb1110301380591d0fec9e0778 100644 (file)
@@ -1,3 +1,11 @@
+2018-06-03  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR tree-optimization/86034
+       * gimple-ssa-store-merging.c (output_merged_store): Convert the RHS to
+       the unsigned bitfield type in a bit insertion sequence if it does not
+       have a larger precision than the bitfield size.
+       (process_store): Also bypass widening conversions for BIT_INSERT_EXPR.
+
 2018-06-03  Kito Cheng  <kito.cheng@gmail.com>
 
        * config/nds32/nds32-peephole2.md: Add new patterns for code size.
index 3c63e75fcf6ccf3ea6d8d8d3d4f27e3c104e05ae..b972f9bef8488561736711616f5185c7d6d89ee0 100644 (file)
@@ -3778,7 +3778,14 @@ imm_store_chain_info::output_merged_store (merged_store_group *group)
                  const HOST_WIDE_INT end_gap
                    = (try_bitpos + try_size) - (info->bitpos + info->bitsize);
                  tree tem = info->ops[0].val;
-                 if ((BYTES_BIG_ENDIAN ? start_gap : end_gap) > 0)
+                 if (TYPE_PRECISION (TREE_TYPE (tem)) <= info->bitsize)
+                   {
+                     tree bitfield_type
+                       = build_nonstandard_integer_type (info->bitsize,
+                                                         UNSIGNED);
+                     tem = gimple_convert (&seq, loc, bitfield_type, tem);
+                   }
+                 else if ((BYTES_BIG_ENDIAN ? start_gap : end_gap) > 0)
                    {
                      const unsigned HOST_WIDE_INT imask
                        = (HOST_WIDE_INT_1U << info->bitsize) - 1;
@@ -4270,13 +4277,12 @@ pass_store_merging::process_store (gimple *stmt)
              || !multiple_p (bitpos, BITS_PER_UNIT))
          && const_bitsize <= 64)
        {
-         /* Bypass a truncating conversion to the bit-field type.  */
+         /* Bypass a conversion to the bit-field type.  */
          if (is_gimple_assign (def_stmt) && CONVERT_EXPR_CODE_P (rhs_code))
            {
              tree rhs1 = gimple_assign_rhs1 (def_stmt);
              if (TREE_CODE (rhs1) == SSA_NAME
-                 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
-                 && const_bitsize <= TYPE_PRECISION (TREE_TYPE (rhs1)))
+                 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
                rhs = rhs1;
            }
          rhs_code = BIT_INSERT_EXPR;
index 084c231960e984036f644a33d8aa8951af1763e2..1367ca6882c562d077449708ce4dfbf277673f18 100644 (file)
@@ -1,3 +1,7 @@
+2018-06-03  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.dg/torture/pr86034.c: New test.
+
 2018-06-03  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/36497
diff --git a/gcc/testsuite/gcc.dg/torture/pr86034.c b/gcc/testsuite/gcc.dg/torture/pr86034.c
new file mode 100644 (file)
index 0000000..247428c
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR tree-optimization/86034 */
+/* Testcase by  Zhendong Su  <su@cs.ucdavis.edu> */
+
+/* { dg-do run } */
+
+struct A
+{
+  int b;
+  int c:24;
+  int d:10;
+  int e;
+} f;
+
+int g; 
+
+void h ()
+{
+  struct A i = { 0, 0, -1, 0 };
+L:
+  f = i;
+  i.d = 0;
+  if (g < 0)
+    goto L;
+}
+
+int main (void)
+{
+  h ();
+  if (f.e != 0) 
+    __builtin_abort ();
+  return 0; 
+}