https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71002
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- Hmm, so trying to preserve alias-set zero from the BIT_FIELD_REF folding using a MEM_REF and reference_alias_ptr_type doesn't work as the latter doesn't preserve the langhook effects (duh, that's some interesting thing on its own). Leaves the possibility to not doing the BIT_FIELD_REF producing folding if alias-sets would not agree. The following restores GCC 5 behavior here. Note Boost still is buggy here. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 236032) +++ gcc/fold-const.c (working copy) @@ -117,8 +117,6 @@ static enum tree_code compcode_to_compar static int operand_equal_for_comparison_p (tree, tree, tree); static int twoval_comparison_p (tree, tree *, tree *, int *); static tree eval_subst (location_t, tree, tree, tree, tree, tree); -static tree make_bit_field_ref (location_t, tree, tree, - HOST_WIDE_INT, HOST_WIDE_INT, int, int); static tree optimize_bit_field_compare (location_t, enum tree_code, tree, tree, tree); static tree decode_field_reference (location_t, tree, HOST_WIDE_INT *, @@ -3859,7 +3857,9 @@ optimize_bit_field_compare (location_t l linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode, &lunsignedp, &lreversep, &lvolatilep, false); if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0 - || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR || lvolatilep) + || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR || lvolatilep + /* Make sure we can preserve alias-sets. */ + || get_alias_set (lhs) != get_alias_set (linner)) return 0; if (const_p) @@ -3874,7 +3874,9 @@ optimize_bit_field_compare (location_t l if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize || lunsignedp != runsignedp || lreversep != rreversep || offset != 0 - || TREE_CODE (rinner) == PLACEHOLDER_EXPR || rvolatilep) + || TREE_CODE (rinner) == PLACEHOLDER_EXPR || rvolatilep + /* Make sure we can preserve alias-sets. */ + || get_alias_set (rhs) != get_alias_set (rinner)) return 0; } @@ -5791,7 +5793,10 @@ fold_truth_andor_1 (location_t loc, enum || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp /* Make sure the two fields on the right correspond to the left without being swapped. */ - || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos) + || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos + /* Make sure we can preserve alias-sets. */ + || get_alias_set (ll_arg) != get_alias_set (ll_inner) + || get_alias_set (lr_arg) != get_alias_set (lr_inner)) return 0; first_bit = MIN (lr_bitpos, rr_bitpos); @@ -5921,6 +5926,10 @@ fold_truth_andor_1 (location_t loc, enum } } + /* Make sure we can preserve alias-sets. */ + if (get_alias_set (ll_arg) != get_alias_set (ll_inner)) + return NULL_TREE; + /* Construct the expression we will return. First get the component reference we will make. Unless the mask is all ones the width of that field, perform the mask operation. Then compare with the