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