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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2023-01-27
                 CC|                            |hubicka at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
  <bb 2> [local count: 1073741824]:
  _4 = operator new (4);
  MEM[(int *)_4] = 10;
  a ={v} {CLOBBER};
  if (_4 != 0B)
    goto <bb 3>; [53.47%]
  else
    goto <bb 4>; [46.53%]

I suspect 'operator new' is not returns_nonnull for the variant that isn't
noexcept.  That would be my first stab at improving things.  Not sure
what the standard guarantees and where we can adjust things here?  We
currently rely on VRP assumptions to derive _4 != 0 from the store
preceeding it, but value-numbering doesn't (yet) have any of that wired in.

The issue with the CSE of MEM[(int *)_28] is that _28 escapes through
passing 'b' to the not inlined shared_ptr::~shared_ptr (&b) DTOR.  It
looks like modref is not powerful enough to see that this DTOR doesn't
make *this or **this escape (it "escapes" to operator delete maybe).
The late modref sees

modref analyzing 'shared_ptr::~shared_ptr()/7' (ipa=0)
Past summary:
  loads:
    Every base
  stores:
    Every base
  kills:
     Parm 0 param offset:0 offset:0 size:128 max_size:128
  Side effects
  Nondeterministic
  Global memory read
  Global memory written
  parm 0 flags: no_direct_escape

  Analyzing stmt: _10 = this_6(D)->data_;
    Analyzing flags of ssa name: _10
      Analyzing stmt: operator delete (_10, 4); [tail call]
      current flags of _10 no_direct_escape no_indirect_escape
not_returned_directly not_returned_indirectly
      Analyzing stmt: if (_10 != 0B)
      current flags of _10 no_direct_escape no_indirect_escape
not_returned_directly not_returned_indirectly
    flags of ssa name _10 no_direct_escape no_indirect_escape
not_returned_directly not_returned_indirectly
  current flags of this_6(D) no_direct_clobber no_direct_escape
no_indirect_escape not_returned_directly not_returned_indirectly

good!  But:

  Analyzing stmt: _1 = this_6(D)->counter_;
    Analyzing flags of ssa name: _1
      Analyzing stmt: operator delete (_1, 4);
      current flags of _1 no_direct_escape no_indirect_escape
not_returned_directly not_returned_indirectly
      Analyzing stmt: *_1 = _3;
      current flags of _1 no_direct_escape no_indirect_escape
not_returned_directly not_returned_indirectly
      Analyzing stmt: _2 = *_1;
        Analyzing flags of ssa name: _2
          Analyzing stmt: _3 = _2 + -1;
            Analyzing flags of ssa name: _3
              Analyzing stmt: if (_3 == 0)
              current flags of _3 no_direct_clobber no_indirect_clobber
no_direct_escape no_indirect_escape not_returned_directly
not_returned_indirectly no_direct_read no_indirect_read
              Analyzing stmt: *_1 = _3;
              ssa name saved to memory
              current flags of _3
            flags of ssa name _3
          current flags of _2
        flags of ssa name _2
      current flags of _1 no_direct_escape not_returned_directly
      Analyzing stmt: if (_1 != 0B)
      current flags of _1 no_direct_escape not_returned_directly
    flags of ssa name _1 no_direct_escape not_returned_directly
  current flags of this_6(D) no_direct_clobber no_direct_escape
not_returned_directly

not sure what it makes dropping he no_indirect_escape - it seems the
'ssa name saved to memory', but that should affect _3 which only
"escapes" to where it was loaded from?

With the modref analysis fixed points-to done before PRE should
improve and thus PRE VN should perform the desired transform earlier.

Reply via email to