Hi!

The following testcase FAILs on powerpc64le-linux with assembler errors, as we
emit a call to bar.localalias, then .set bar.localalias, bar twice and then
another call to bar.localalias.  The problem is that bar.localalias can be 
created
at various stages and e.g. ipa-pure-const can slightly adjust the original decl,
so that the existing bar.localalias isn't considered usable (different
flags_from_decl_or_type).  In that case, we'd create another bar.localalias, 
which
clashes with the existing name.

Fixed by retrying with another name if it is already present.  The various 
localalias
aliases shouldn't be that many, from different partitions they would be lto_priv
suffixed and in most cases they would already have the same 
type/flags/attributes.

Bootstrapped/regtested on powerpc64{,le}-linux, acked by Honza on IRC,
committed to trunk.

2020-01-30  Jakub Jelinek  <ja...@redhat.com>

        PR lto/93384
        * symtab.c (symtab_node::noninterposable_alias): If localalias
        already exists, but is not usable, append numbers after it until
        a unique name is found.  Formatting fix.

        * gcc.dg/lto/pr93384_0.c: New test.
        * gcc.dg/lto/pr93384_1.c: New file.

--- gcc/symtab.c.jj     2020-01-14 09:23:17.648790352 +0100
+++ gcc/symtab.c        2020-01-30 18:14:00.702919471 +0100
@@ -1864,7 +1864,7 @@ symtab_node::noninterposable_alias (void
   symtab_node *node = ultimate_alias_target ();
   gcc_assert (!node->alias && !node->weakref);
   node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias,
-                                  (void *)&new_node, true);
+                                    (void *)&new_node, true);
   if (new_node)
     return new_node;
 
@@ -1875,7 +1875,17 @@ symtab_node::noninterposable_alias (void
   /* Otherwise create a new one.  */
   new_decl = copy_node (node->decl);
   DECL_DLLIMPORT_P (new_decl) = 0;
-  DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias");
+  tree name = clone_function_name (node->decl, "localalias");
+  if (!flag_wpa)
+    {
+      unsigned long num = 0;
+      /* In the rare case we already have a localalias, but the above
+        node->call_for_symbol_and_aliases call didn't find any suitable,
+        iterate until we find one not used yet.  */
+      while (symtab_node::get_for_asmname (name))
+       name = clone_function_name (node->decl, "localalias", num++);
+    }
+  DECL_NAME (new_decl) = name;
   if (TREE_CODE (new_decl) == FUNCTION_DECL)
     DECL_STRUCT_FUNCTION (new_decl) = NULL;
   DECL_INITIAL (new_decl) = NULL;
--- gcc/testsuite/gcc.dg/lto/pr93384_0.c.jj     2020-01-30 18:18:31.985868078 
+0100
+++ gcc/testsuite/gcc.dg/lto/pr93384_0.c        2020-01-30 18:06:44.784429548 
+0100
@@ -0,0 +1,12 @@
+/* PR lto/93384 */
+/* { dg-lto-do link } */
+/* { dg-require-effective-target fpic } */
+/* { dg-require-effective-target shared } */
+/* { dg-lto-options { { -O2 -flto -ffat-lto-objects -fpic 
-fno-semantic-interposition } } } */
+/* { dg-extra-ld-options { -shared -flto-partition=none } } */
+
+void bar (void);
+__attribute__((noipa)) void quux (int x) { if (x == 5) bar (); }
+__attribute__((noipa, noreturn)) void foo (void) { while (1) ; }
+__attribute__((noinline)) void bar (void) { asm (""); quux (7); foo (); }
+void baz (int x) { if (x) bar (); }
--- gcc/testsuite/gcc.dg/lto/pr93384_1.c.jj     2020-01-30 18:18:35.094821645 
+0100
+++ gcc/testsuite/gcc.dg/lto/pr93384_1.c        2020-01-30 17:58:58.061373326 
+0100
@@ -0,0 +1,2 @@
+extern void bar (void);
+void qux (int x) { if (!x) bar (); }


        Jakub

Reply via email to