* stop IPA wrapping 'main'
@ 2015-12-17 18:39 Nathan Sidwell
2015-12-17 21:01 ` Jan Hubicka
0 siblings, 1 reply; 2+ messages in thread
From: Nathan Sidwell @ 2015-12-17 18:39 UTC (permalink / raw)
To: Jan Hubicka; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 1252 bytes --]
gcc.dg/20031102-1.c now causes some 'surprising' optimization behaviour. It is
essentially
int FooBar(void)
{
... stuff
return 0;
}
int main(void)
{
return FooBar();
}
What happens is that FooBar gets inlined into main, and then ipa-icf notices
FooBar and main have identical bodies. It chooses to have FooBar tail call
main, which results in a surprising call of 'main'. On PTX this is
particularly unfortunate because we have to emit a single prototype for main
with the regular argc and argv arguments (the backend gets around 'int main
(void)' by faking the additional 2 args). But that fails here because the tail
call doesn't match the prototype.
Anyway, picking 'main' as the source function struck me as a poor choice, hence
the attached patch. It picks the second function of a congruent set, if the
first is 'main'. Note that even on, say x86-linux, we emit a tail call rather
than an alias for the included testcase.
I removed the gcc_assert, as the vector indexing operator already checks the
subscript is within range.
Alternatively I could probably just fixup the testcase to make FooBar
uninlinable, as I suspect that might have been the original intent.
tested on x86_64-linux and ptx-none.
nathan
[-- Attachment #2: trunk-ipa.patch --]
[-- Type: text/x-patch, Size: 1857 bytes --]
2015-12-17 Nathan Sidwell <nathan@acm.org>
gcc/
* ipa-icf.c (sem_item_optimizer::merge): Don't pick 'main' as the
source function.
gcc/testsuite/
* gcc.dg/ipa/ipa-icf-merge-1.c: New.
Index: ipa-icf.c
===================================================================
--- ipa-icf.c (revision 231770)
+++ ipa-icf.c (working copy)
@@ -3398,14 +3398,20 @@ sem_item_optimizer::merge_classes (unsig
if (c->members.length () == 1)
continue;
- gcc_assert (c->members.length ());
-
sem_item *source = c->members[0];
- for (unsigned int j = 1; j < c->members.length (); j++)
+ if (MAIN_NAME_P (DECL_NAME (source->decl)))
+ /* If merge via wrappers, picking main as the target can be
+ problematic. */
+ source = c->members[1];
+
+ for (unsigned int j = 0; j < c->members.length (); j++)
{
sem_item *alias = c->members[j];
+ if (alias == source)
+ continue;
+
if (dump_file)
{
fprintf (dump_file, "Semantic equality hit:%s->%s\n",
Index: testsuite/gcc.dg/ipa/ipa-icf-merge-1.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-icf-merge-1.c (revision 0)
+++ testsuite/gcc.dg/ipa/ipa-icf-merge-1.c (working copy)
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -fdump-ipa-icf" } */
+
+/* Picking 'main' as a candiate target for equivalent functios is not a
+ good idea. */
+
+int baz (int);
+
+int foo ()
+{
+ return baz (baz (0));
+}
+
+
+int main ()
+{
+ return baz (baz (0));
+}
+
+/* Notice the two functions are the same. */
+/* { dg-final { scan-ipa-dump "Semantic equality hit:foo->main" "icf" } } */
+
+/* Make sure we don't tail call main. */
+/* { dg-final { scan-ipa-dump-not "= main \\(\\);" "icf" } } */
+
+/* Make sure we tail call foo. */
+/* { dg-final { scan-ipa-dump "= foo \\(\\);" "icf" } } */
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: stop IPA wrapping 'main'
2015-12-17 18:39 stop IPA wrapping 'main' Nathan Sidwell
@ 2015-12-17 21:01 ` Jan Hubicka
0 siblings, 0 replies; 2+ messages in thread
From: Jan Hubicka @ 2015-12-17 21:01 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: Jan Hubicka, GCC Patches
> gcc.dg/20031102-1.c now causes some 'surprising' optimization
> behaviour. It is essentially
>
> int FooBar(void)
> {
> ... stuff
> return 0;
> }
>
> int main(void)
> {
> return FooBar();
> }
>
>
> What happens is that FooBar gets inlined into main, and then
> ipa-icf notices FooBar and main have identical bodies. It chooses
> to have FooBar tail call main, which results in a surprising call
> of 'main'. On PTX this is particularly unfortunate because we have
> to emit a single prototype for main with the regular argc and argv
> arguments (the backend gets around 'int main (void)' by faking the
> additional 2 args). But that fails here because the tail call
> doesn't match the prototype.
>
> Anyway, picking 'main' as the source function struck me as a poor
> choice, hence the attached patch. It picks the second function of a
> congruent set, if the first is 'main'. Note that even on, say
> x86-linux, we emit a tail call rather than an alias for the included
> testcase.
>
> I removed the gcc_assert, as the vector indexing operator already
> checks the subscript is within range.
>
> Alternatively I could probably just fixup the testcase to make
> FooBar uninlinable, as I suspect that might have been the original
> intent.
>
> tested on x86_64-linux and ptx-none.
>
> nathan
> 2015-12-17 Nathan Sidwell <nathan@acm.org>
>
> gcc/
> * ipa-icf.c (sem_item_optimizer::merge): Don't pick 'main' as the
> source function.
>
> gcc/testsuite/
> * gcc.dg/ipa/ipa-icf-merge-1.c: New.
OK, thanks. Indeed we should not introduce new calls to main :)
It contains some magic stuff on x86 targets, too.
Honza
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-12-17 21:01 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-17 18:39 stop IPA wrapping 'main' Nathan Sidwell
2015-12-17 21:01 ` Jan Hubicka
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).