Hi!

When a cgraph clone is created for simd clones, it is forced
make_decl_local, but for the simd clones we actually want to preserve their
visibility, weak, comdat etc. (except that we want to use a separate comdat
group).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk, queued for 6.2.

2016-08-08  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/68762
        * omp-simd-clone.c: Include varasm.h.
        (simd_clone_create): Copy over DECL_COMDAT, DECL_WEAK, DECL_EXTERNAL,
        DECL_VISIBILITY, DECL_VISIBILITY_SPECIFIED, DECL_DLLIMPORT_P and for
        DECL_ONE_ONLY call make_decl_one_only.  Fix up spelling in comment and
        update function name.

        * g++.dg/vect/pr68762-1.cc: New test.
        * g++.dg/vect/pr68762-2.cc: New test.
        * g++.dg/vect/pr68762.h: New file.

--- gcc/omp-simd-clone.c.jj     2016-05-20 09:05:08.000000000 +0200
+++ gcc/omp-simd-clone.c        2016-08-08 11:44:51.081423066 +0200
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
 #include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-eh.h"
+#include "varasm.h"
 
 
 /* Allocate a fresh `simd_clone' and return it.  NARGS is the number
@@ -435,9 +436,18 @@ simd_clone_create (struct cgraph_node *o
     return new_node;
 
   TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
+  DECL_COMDAT (new_node->decl) = DECL_COMDAT (old_node->decl);
+  DECL_WEAK (new_node->decl) = DECL_WEAK (old_node->decl);
+  DECL_EXTERNAL (new_node->decl) = DECL_EXTERNAL (old_node->decl);
+  DECL_VISIBILITY_SPECIFIED (new_node->decl)
+    = DECL_VISIBILITY_SPECIFIED (old_node->decl);
+  DECL_VISIBILITY (new_node->decl) = DECL_VISIBILITY (old_node->decl);
+  DECL_DLLIMPORT_P (new_node->decl) = DECL_DLLIMPORT_P (old_node->decl);
+  if (DECL_ONE_ONLY (old_node->decl))
+    make_decl_one_only (new_node->decl, DECL_ASSEMBLER_NAME (new_node->decl));
 
-  /* The function cgraph_function_versioning () will force the new
-     symbol local.  Undo this, and inherit external visability from
+  /* The method cgraph_version_clone_with_body () will force the new
+     symbol local.  Undo this, and inherit external visibility from
      the old node.  */
   new_node->local.local = old_node->local.local;
   new_node->externally_visible = old_node->externally_visible;
--- gcc/testsuite/g++.dg/vect/pr68762-1.cc.jj   2016-08-08 11:35:32.767418789 
+0200
+++ gcc/testsuite/g++.dg/vect/pr68762-1.cc      2016-08-08 11:33:49.590711603 
+0200
@@ -0,0 +1,26 @@
+// PR middle-end/68762
+// { dg-require-effective-target vect_simd_clones }
+// { dg-additional-options "-fopenmp-simd -fno-inline" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-additional-sources "pr68762-2.cc" }
+
+#include "pr68762.h"
+
+double v[64];
+
+double
+bar ()
+{
+  double sum = 0.0;
+  #pragma omp simd reduction (+: sum)
+  for (int i = 0; i < 64; i++)
+    sum += foo (v[i]);
+  return sum;
+}
+
+int
+main ()
+{
+  if (bar () != 0.0)
+    __builtin_abort ();
+}
--- gcc/testsuite/g++.dg/vect/pr68762-2.cc.jj   2016-08-08 11:35:35.815380598 
+0200
+++ gcc/testsuite/g++.dg/vect/pr68762-2.cc      2016-08-08 11:35:07.589734268 
+0200
@@ -0,0 +1,17 @@
+// PR middle-end/68762
+// { dg-do compile }
+
+#include "pr68762.h"
+
+#pragma omp declare simd
+double
+baz (double x)
+{
+  return x;
+}
+
+double
+fn (double x)
+{
+  return foo (x);
+}
--- gcc/testsuite/g++.dg/vect/pr68762.h.jj      2016-08-08 11:35:38.827342858 
+0200
+++ gcc/testsuite/g++.dg/vect/pr68762.h 2016-08-08 11:33:00.381328200 +0200
@@ -0,0 +1,11 @@
+// PR middle-end/68762
+
+#pragma omp declare simd
+double baz (double x);
+
+#pragma omp declare simd
+inline double
+foo (double d)
+{
+  return baz (d);
+}

        Jakub

Reply via email to