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

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
The last testcase shows

  <bb 2> :
  # .MEM_9 = VDEF <.MEM_6(D)>
  D.8527 = S::operator<=> (a_7(D), b_8(D));

  <bb 3> :
  # VUSE <.MEM_9>
  __v$_M_value_21 = D.8527._M_value;
  if (__v$_M_value_21 < 0)
    goto <bb 7>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 4> :
  # .MEM_11 = VDEF <.MEM_9>
  D.8527 = S::operator<=> (a_7(D), b_8(D));

so in this case the result is even the same memory temporary.

Consider

 x = foo(1);
 x.z = 2;
 use (x);
 x = foo(1);

"saving" the result of foo(1) to be re-used the 2nd time would require
a new temporary aggregate.  It's basically lowering to

 _1 = foo (1);
 x = _1;
 x.z = 2;
 use (x);
 x = _1;

with the hope that _1 and x can be coalesced later.

The C++ case can possibly be handled directly in visit_reference_op_call
by looking up with the next VUSE after discovering the same LHS is being
used.  But wiring this into VN itself is a bit difficult.  Figuring
the 2nd store is a redundant one might be easier in this case.

This wouldn't help for the C testcase from comment#4 which uses two
different LHS temporaries.

Reply via email to