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.

Reply via email to