diff options
author | Richard Biener <rguenther@suse.de> | 2016-06-14 07:26:52 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-06-14 07:26:52 +0000 |
commit | 585334d41d1a255f612d6470ba9b7bd383cdd5e4 (patch) | |
tree | e7a306bcc65b98f0ce32db3ed56a02f801a9cc08 /gcc/fold-const.c | |
parent | 90b72e84c427d4e735ae98dc06fe84fc1ec8139b (diff) | |
download | gcc-585334d41d1a255f612d6470ba9b7bd383cdd5e4.zip gcc-585334d41d1a255f612d6470ba9b7bd383cdd5e4.tar.gz gcc-585334d41d1a255f612d6470ba9b7bd383cdd5e4.tar.bz2 |
re PR middle-end/71310 (Bitfields cause load hit store with smaller store and larger load)
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 26c1435..3b9500d 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; |