public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/2] tree-optimization/104530 - proposed re-evaluation.
@ 2022-02-22 16:39 Andrew MacLeod
  2022-02-22 16:56 ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew MacLeod @ 2022-02-22 16:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Aldy Hernandez, Jakub Jelinek

  I'd like to get clarification on some subtle terminology. I find I am 
conflating calls that don't return with calls that may throw, and I 
think they have different considerations.

My experiments with calls that can throw indicate that they always end a 
basic block.  This makes sense to me as there is the outgoing fall-thru 
edge and an outgoing EH edge.  Are there any conditions under which this 
is not the case? (other than non-call exceptions)

If that supposition is true, that leaves us with calls in the middle of 
the block which may not return.  This prevents us from allowing later 
calculations from impacting anything which happens before the call.

I believe the following 2 small patches could then resolve this.
  1 - Export global names to SSA_NAME_RANGE_INFO during the statement 
walk instead of at the end of the pass
  2 - Use the existing lazy recomputation machinery to recompute any 
globals which are defined in the block where a dependent value becomes 
non-null.

More details in each patch.  Neither is very large.  We could add this 
to this release or wait for stage 1.

Andrew


^ permalink raw reply	[flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] tree-optimization/104530 - proposed re-evaluation.
@ 2022-02-23 21:23 Martin Uecker
  0 siblings, 0 replies; 9+ messages in thread
From: Martin Uecker @ 2022-02-23 21:23 UTC (permalink / raw)
  To: jeffreyalaw; +Cc: gcc-patches

> 
> 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.

There are cases with volatile accesses where
this is currently not the case.

Also there is a proposal for C++ to require
an explicit std::observable fence to make sure
observable side effects are not undone by
later UB. (see the discussion about "reordering
of trapping operations and volatile" in
Janunary on the gcc list)

In my opinion it is much better if a compiler
makes sure to preserve observable side effects
even in code path with later UB (because the
behavior may otherwise be surprising and existing
code may be broken in a subtle way).  If I
understand you correctly, GCC intends to do
this.

Can we then also agree that the remaining volatile
cases used be fixed?


Martin






^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-02-23 21:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-22 16:39 [PATCH 0/2] tree-optimization/104530 - proposed re-evaluation Andrew MacLeod
2022-02-22 16:56 ` Jakub Jelinek
2022-02-22 17:39   ` Andrew MacLeod
2022-02-22 17:57     ` Jakub Jelinek
2022-02-22 18:07       ` Jeff Law
2022-02-22 19:18         ` Andrew MacLeod
2022-02-23  7:48           ` Richard Biener
2022-02-23 16:30             ` Andrew MacLeod
2022-02-23 21:23 Martin Uecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).