From 585334d41d1a255f612d6470ba9b7bd383cdd5e4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 14 Jun 2016 07:26:52 +0000 Subject: [PATCH] re PR middle-end/71310 (Bitfields cause load hit store with smaller store and larger load) 2016-06-14 Richard Biener 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 | 9 +++++++++ gcc/expr.c | 2 +- gcc/expr.h | 4 ++++ gcc/fold-const.c | 17 ++++++++--------- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0077b8d605..40e60a3db34 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-06-14 Richard Biener + + 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 PR tree-optimization/71521 diff --git a/gcc/expr.c b/gcc/expr.c index 2c32b2859ed..6547be1c377 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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, diff --git a/gcc/expr.h b/gcc/expr.h index bd0da5ea364..a77f6e53cd3 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -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); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 26c1435ed0c..3b9500dafe6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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;