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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
The bisected rev. does not change the underlying logic, it just exposes more
paths to DSE, so if the issue is in DSE it was latent before.  I assume
we are talking about struct A D.5736

-  D.5736.f_ = cb;
-  D.5736.p_ = &b.q;
-  D.5736.a_ = 8;

in make_widget.isra since the DSE of b.q = 0B is obvious from the IL:

-  b.q = 0B;
   b ={v} {CLOBBER(eob)};
   b ={v} {CLOBBER(eos)};

--

<L0>:
  # .MEM_17 = VDEF <.MEM_15>
  # USE = nonlocal null { D.5581 D.5591 D.5794 D.5795 } (nonlocal, escaped,
escaped heap, interposable)
  # CLB = nonlocal null { D.5581 D.5591 D.5794 D.5795 } (nonlocal, escaped,
escaped heap, interposable)
  operator delete (_33, &D.5736, &g_r.D.5569);

does not use D.5736 and the object does not escape either, but we
definitely call this operator and the operator does read from D.5736:

__attribute__((noinline))
void operator delete (void * p, const struct A & a, struct R & r)
{
  # PT = nonlocal
  void * p_5(D) = p;
  # PT = nonlocal
  # ALIGN = 8, MISALIGN = 0
  const struct A & a_4(D) = a;
  # PT = nonlocal
  struct R & r_6(D) = r;
  void * _3;
  void * * _10;

  <bb 2> [local count: 1073741824]:
  # PT = nonlocal null
  # USE = nonlocal null
  _3 = __builtin_return_address (0);
  # PT = nonlocal escaped null
  _10 = MEM[(void * * *)a_4(D) + 8B];
  # USE = nonlocal escaped null
  # CLB = nonlocal escaped null
  destroy.isra (_10, p_5(D), _3, r_6(D)); [tail call]


PTA does

      /* If the call is to a replaceable operator delete and results
         from a delete expression as opposed to a direct call to
         such operator, then the effects for PTA (in particular
         the escaping of the pointer) can be ignored.  */
      else if (fndecl
               && DECL_IS_OPERATOR_DELETE_P (fndecl)
               && gimple_call_from_new_or_delete (t))
        ;

and completely ignores the delete operator.

Adding && DECL_IS_REPLACEABLE_OPERATOR (fndecl) fixes the testcase.

r11-3612-g4f4ced28826ece replaced the former use of
DECL_IS_REPLACEABLE_OPERATOR_DELETE_P with DECL_IS_OPERATOR_DELETE_P
(throughout the code base).  Jason, what's this about?   I suppose
DECL_IS_REPLACEABLE_OPERATOR will just never be set on delete?

Reply via email to