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

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2
                 CC|                            |law at redhat dot com
           Assignee|unassigned at gcc dot gnu.org      |mliska at suse dot cz

--- Comment #3 from Jeffrey A. Law <law at redhat dot com> ---
Darwin does not support weak aliases.  As a result the ICF code has to be more
conservative in how it transforms the resulting code when an ICF opportunity
exists.

Normally (if we have weak aliases), recurser_void1 will be made a weak alias to
recurser_void2.  That in turn exposes recurser_void2 as self recursion which
gets optimized into an appropriate loop by the 2nd tail call optimizer.  And
(of course) the test passes with ICF enabled.  For darwin, we don't have weak
aliases, so none of this applies.

For darwin, in the non-ICF case we ultimately determine that both recurser
functions are local and we can change their signature.  And they're both
changed to use register passing for some arguments.  As a result when it comes
time to try a tail call sequence, neither function has a need for parameters on
the stack, so that test passes and ultimately we emit the optimized tail call
sequence.

In the ICF case, recurser_void2 has the right bits (local/signature changeable)
and it's changed to use register passing conventions (ie, no stack space). 
However recurser_void1 doesn't have the "local" bit set and thus it's not
considered eligible for register passing conventions (arguments on the stack).

This mismatch in stack handling for parameters ultimately means that we can't
use a tail call for the call from recurser_void2 to recurser_void1 and the test
fails.

It's unclear to me if the ICF bits should be setting flags in the cgraph nodes
when it merges functions or if those bits should be set elsewhere.  It may also
be possible to fix this in the x86 backend perhaps if there's a way to
recognize the alias/thunk nature of recurser_void1 and follow that to
recurser_void2 and use the flags from the latter for determining the calling
conventions for the former.

Assigning to mliksa for further analysis.

Reply via email to