On 2/22/2022 10:57 AM, Jakub Jelinek via Gcc-patches wrote:
On Tue, Feb 22, 2022 at 12:39:28PM -0500, Andrew MacLeod wrote:
That is EH, then there are calls that might not return because they leave
in some other way (e.g. longjmp), or might loop forever, might exit, might
abort, trap etc.
Generally speaking, calls which do not return should not now be a problem...
as long as they do not transfer control to somewhere else in the current
function.
I thought all of those cases are very relevant to PR104530.
If we have:
_1 = ptr_2(D) == 0;
// unrelated code in the same bb
_3 = *ptr_2(D);
then in light of PR104288, we can optimize ptr_2(D) == 0 into true only if
there are no calls inside of "// unrelated code in the same bb"
or if all calls in "// unrelated code in the same bb" are guaranteed to
return exactly once. Because, if there is a call in there which could
exit (that is the PR104288 testcase), or abort, or trap, or loop forever,
or throw externally, or longjmp or in any other non-UB way
cause the _1 = ptr_2(D) == 0; stmt to be invoked at runtime but
_3 = *ptr_2(D) not being invoked, then we can't optimize the earlier
comparison because ptr_2(D) could be NULL in a valid program.
While if there are no calls (and no problematic inline asms) and no trapping
insns in between, we can and PR104530 is asking that we continue to optimize
that.
Right. This is similar to some of the restrictions we deal with in the
path isolation pass. Essentially we have a path, when traversed, would
result in a *0. We would like to be able to find the edge upon-which
the *0 is control dependent and optimize the test so that it always went
to the valid path rather than the *0 path.
The problem is there may be observable side effects on the *0 path
between the test and the actual *0 -- including calls to nonreturning
functions, setjmp/longjmp, things that could trap, etc. This case is
similar. We can't back-propagate the non-null status through any
statements with observable side effects.
Jeff