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.