re PR middle-end/71310 (Bitfields cause load hit store with smaller store and larger...
authorRichard Biener <rguenther@suse.de>
Tue, 14 Jun 2016 07:26:52 +0000 (07:26 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 14 Jun 2016 07:26:52 +0000 (07:26 +0000)
2016-06-14  Richard Biener  <rguenther@suse.de>

PR middle-end/71310
PR bootstrap/71510
* expr.h (get_bit_range): Declare.
* expr.c (get_bit_range): Export.
* fold-const.c (optimize_bit_field_compare): Use get_bit_range and
word_mode again to constrain the bitfield access.

From-SVN: r237426

gcc/ChangeLog
gcc/expr.c
gcc/expr.h
gcc/fold-const.c

index f0077b8d605e9821827bdc14a21200c26e7fb4b5..40e60a3db344d652b74e8d58125939a9f470e078 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-14  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/71310
+       PR bootstrap/71510
+       * expr.h (get_bit_range): Declare.
+       * expr.c (get_bit_range): Export.
+       * fold-const.c (optimize_bit_field_compare): Use get_bit_range and
+       word_mode again to constrain the bitfield access.
+
 2016-06-14  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/71521
index 2c32b2859ed9a0643b2895a23ced2c97e8b1fc1b..6547be1c377c77aae8aa89a1366a707f666bd30d 100644 (file)
@@ -4795,7 +4795,7 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
    If the access does not need to be restricted, 0 is returned in both
    *BITSTART and *BITEND.  */
 
-static void
+void
 get_bit_range (unsigned HOST_WIDE_INT *bitstart,
               unsigned HOST_WIDE_INT *bitend,
               tree exp,
index bd0da5ea36413974889582e939f506d3c93a5d38..a77f6e53cd345b11d825f4ee832c683f37ce87c1 100644 (file)
@@ -242,6 +242,10 @@ extern rtx push_block (rtx, int, int);
 extern bool emit_push_insn (rtx, machine_mode, tree, rtx, unsigned int,
                            int, rtx, int, rtx, rtx, int, rtx, bool);
 
+/* Extract the accessible bit-range from a COMPONENT_REF.  */
+extern void get_bit_range (unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
+                          tree, HOST_WIDE_INT *, tree *);
+
 /* Expand an assignment that stores the value of FROM into TO.  */
 extern void expand_assignment (tree, tree, bool);
 
index 26c1435ed0c50b2d2f21844ac92fe07295ad9a55..3b9500dafe65a79cffc1a7c64c941b86c4e568c0 100644 (file)
@@ -3902,24 +3902,23 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
        return 0;
    }
 
-  /* Don't use a larger mode for reading the bit field than we will
-     use in other places accessing the bit field.  */
-  machine_mode largest_mode = word_mode;
+  /* Honor the C++ memory model and mimic what RTL expansion does.  */
+  unsigned HOST_WIDE_INT bitstart = 0;
+  unsigned HOST_WIDE_INT bitend = 0;
   if (TREE_CODE (lhs) == COMPONENT_REF)
     {
-      tree field = TREE_OPERAND (lhs, 1);
-      tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
-      if (repr)
-       largest_mode = DECL_MODE (repr);
+      get_bit_range (&bitstart, &bitend, lhs, &lbitpos, &offset);
+      if (offset != NULL_TREE)
+       return 0;
     }
 
   /* See if we can find a mode to refer to this field.  We should be able to,
      but fail if we can't.  */
-  nmode = get_best_mode (lbitsize, lbitpos, 0, 0,
+  nmode = get_best_mode (lbitsize, lbitpos, bitstart, bitend,
                         const_p ? TYPE_ALIGN (TREE_TYPE (linner))
                         : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
                                TYPE_ALIGN (TREE_TYPE (rinner))),
-                        largest_mode, false);
+                        word_mode, false);
   if (nmode == VOIDmode)
     return 0;