+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
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,
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);
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;