https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101419

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It is the cunrolli pass where things go wrong (it VNs the &u->c for both
__builtin_object_size calls while previously only the first one was &u->c and
the second was &u->i).
Now, objsz2 obviously needs to be done after IPA opts (most importantly
inlining), but what other opt passes we want in between IPA and objsz2 is a
question:
  PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations)
      NEXT_PASS (pass_remove_cgraph_callee_edges);
      /* Initial scalar cleanups before alias computation.
         They ensure memory accesses are not indirect wherever possible.  */
      NEXT_PASS (pass_strip_predict_hints, false /* early_p */);
      NEXT_PASS (pass_ccp, true /* nonzero_p */);
      NEXT_PASS (pass_post_ipa_warn);
      /* After CCP we rewrite no longer addressed locals into SSA
         form if possible.  */
      NEXT_PASS (pass_complete_unrolli);
      NEXT_PASS (pass_backprop);
      NEXT_PASS (pass_phiprop);
      NEXT_PASS (pass_forwprop);
      NEXT_PASS (pass_object_sizes, false /* insert_min_max_p */);
I bet the rewriting no longer addressed locals into SSA form if possible done
for ccp could be sometimes relevant, because when an address is stored into a
previously address taken local and read back, then __bos could see it if in SSA
form and not otherwise.  And in theory the cunrolli could reveal some cases,
though not sure.
So, either do the TODO_update_address_taken sooner (e.g. at end of
pass_remove_cgraph_callee_edges - does ccp itself bring any address taken
removal opportunities?) and then do objsz2, or schedule another objsz pass with
insert_minmax right at the start of pass_all_optimizations?
Out of ideas and it is still just mitigation.

Another way would be change SCCVN to handle it conservatively for __bos (x, 1)
but that could break the rarely used __bos (x, 3) - but it can break randomly
for both now.  E.g. in the
  _8 = &u_5(D)->c;
  use (_8);
...
  _9 = &u_5(D)->i;
  use2 (_9);
case when objsz2 wasn't done yet (check with property) and perhaps if any __bos
(x, 1) are seen (cfun flag propagated conservatively during inlining), compute
__bos (ptr, 1) for both and rewrite the setter to the larger one, i.e. not
optimize into:
  _8 = &u_5(D)->c;
  use (_8);
...
  use2 (_8);
but
  _8 = &u_5(D)->i;
  use (_8);
...
  use2 (_8);

Reply via email to