https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70623
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- "Patch" in testing. Note that the issue seems to be oscillating values because of bitmap_set_and only taking expressions from 'dest', pruning out those for which the value-and removed their value. But mem_ref<0B>,addr_expr<&av>}@.MEM_5 (0005) mem_ref<0B>,av.0_8}@.MEM_7(D) (0006) _9 (0006) and with only 0006 in the value-and but mem_ref<0B>,av.0_8}@.MEM_7(D) (0006) in the expr-set we get 0006 dropped in clean (). In a different iteration mem_ref<0B>,av.0_8}@.MEM_7(D) gets exchanged for _9 (0006) and it re-appears. The solution seems to be to union the expr-sets in bitmap_set_and before pruning expressions no longer in the value-intersection. But then clean () uses bitmap_remove_from_set which does unsigned int val = get_expr_value_id (expr); if (!value_id_constant_p (val)) { bitmap_clear_bit (&set->values, val); bitmap_clear_bit (&set->expressions, get_expression_id (expr)); } and thus seems to rely on there being exactly one expression for each value in a bitmap-set. bitmap_find_leader does if (bitmap_set_contains_value (set, val)) { unsigned int i; bitmap_iterator bi; bitmap exprset = value_expressions[val]; EXECUTE_IF_AND_IN_BITMAP (exprset, &set->expressions, 0, i, bi) return expression_for_id (i); so kind-of would agree with that.