Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-25 Thread Jakub Jelinek
On Wed, Jan 24, 2018 at 06:51:54PM +0100, Richard Biener wrote:
> >Well, "omp declare simd" is a part of the ABI just for the original
> >exported
> >functions, for everything else it is a pure optimization, but I'm not
> >sure
> >if we want to deoptimize e.g. callers of these functions outside of
> >loops
> >by disabling the signature changing cloning for those.  For calls from
> >within OpenMP simd regions or other loops where we try hard to
> >vectorize
> >them, it might make sense not to change those callers, for callers from
> >other loops, a question.
> 
> Until we can distinguish the cases I think not changing the signature by
> default might be a good thing.

Done thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.

2018-01-25  Jakub Jelinek  

PR middle-end/83977
* ipa-fnsummary.c (compute_fn_summary): Clear can_change_signature
on functions with #pragma omp declare simd or functions with simd
attribute.
* omp-simd-clone.c (expand_simd_clones): Revert 2018-01-24 change.
* config/i386/i386.c (ix86_simd_clone_compute_vecsize_and_simdlen):
Remove trailing \n from warning_at calls.

* c-c++-common/gomp/pr83977-1.c: Add -w to dg-options.

--- gcc/ipa-fnsummary.c.jj  2018-01-25 12:13:06.651327787 +0100
+++ gcc/ipa-fnsummary.c 2018-01-25 12:14:22.282340706 +0100
@@ -2467,7 +2467,11 @@ compute_fn_summary (struct cgraph_node *
 info->inlinable = tree_inlinable_function_p (node->decl);
 
/* Type attributes can use parameter indices to describe them.  */
-   if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
+   if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))
+  /* Likewise for #pragma omp declare simd functions or functions
+ with simd attribute.  */
+  || lookup_attribute ("omp declare simd",
+   DECL_ATTRIBUTES (node->decl)))
 node->local.can_change_signature = false;
else
 {
--- gcc/omp-simd-clone.c.jj 2018-01-25 12:13:06.624327783 +0100
+++ gcc/omp-simd-clone.c2018-01-25 12:14:22.282340706 +0100
@@ -1574,10 +1574,6 @@ expand_simd_clones (struct cgraph_node *
   tree attr = lookup_attribute ("omp declare simd",
DECL_ATTRIBUTES (node->decl));
   if (attr == NULL_TREE
-  /* Ignore artificial decls with an abstract origin, results of function
-cloning, versioning etc.  We want to handle certain builtins
-with simd attribute, like __builtin_sin.  */
-  || (DECL_ARTIFICIAL (node->decl) && DECL_ABSTRACT_ORIGIN (node->decl))
   || node->global.inlined_to
   || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
 return;
--- gcc/config/i386/i386.c.jj   2018-01-24 23:41:33.714031847 +0100
+++ gcc/config/i386/i386.c  2018-01-25 12:16:02.231357778 +0100
@@ -50224,7 +50224,7 @@ ix86_simd_clone_compute_vecsize_and_simd
break;
   default:
warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
-   "unsupported return type %qT for simd\n", ret_type);
+   "unsupported return type %qT for simd", ret_type);
return 0;
   }
 
@@ -50246,7 +50246,7 @@ ix86_simd_clone_compute_vecsize_and_simd
break;
   default:
warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
-   "unsupported argument type %qT for simd\n", TREE_TYPE (t));
+   "unsupported argument type %qT for simd", TREE_TYPE (t));
return 0;
   }
 
--- gcc/testsuite/c-c++-common/gomp/pr83977-1.c.jj  2018-01-24 
17:26:25.217357997 +0100
+++ gcc/testsuite/c-c++-common/gomp/pr83977-1.c 2018-01-25 12:18:34.196383735 
+0100
@@ -1,6 +1,6 @@
 /* PR middle-end/83977 */
 /* { dg-do compile } */
-/* { dg-additional-options "-O2" } */
+/* { dg-additional-options "-O2 -w" } */
 
 struct S { int a, b, c; };
 


Jakub


Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Richard Biener
On January 24, 2018 6:51:54 PM GMT+01:00, Richard Biener  
wrote:
>On January 24, 2018 6:40:25 PM GMT+01:00, Jakub Jelinek
> wrote:
>>On Wed, Jan 24, 2018 at 06:36:02PM +0100, Martin Jambor wrote:
>>> > I think there's already a set of attributes that prevent cloning
>>and
>>> > or are adjusted by the IPA param machinery. The Martins or Honza
>>> > should know better.
>>> 
>>> I am not sure I understand the problem but if
>>> tree_versionable_function_p returns false, the local.versionable bit
>>is
>>> not set and no cloning for that function happens.
>>> 
>>> If it is sufficient that IPA-CP and other IPA passes do not change
>>the
>>> function type in any way (in practice that they don't remove
>>> parameters), it is sufficient to clear the
>local.can_change_signature
>>> cgraph flag in compute_fn_summary() in ipa-fnsummary.c.  That is how
>>we
>>> handle, or rather avoid handling, fnspec attributes.
>>
>>Well, "omp declare simd" is a part of the ABI just for the original
>>exported
>>functions, for everything else it is a pure optimization, but I'm not
>>sure
>>if we want to deoptimize e.g. callers of these functions outside of
>>loops
>>by disabling the signature changing cloning for those.  For calls from
>>within OpenMP simd regions or other loops where we try hard to
>>vectorize
>>them, it might make sense not to change those callers, for callers
>from
>>other loops, a question.
>
>Until we can distinguish the cases I think not changing the signature
>by default might be a good thing. 

Otoh cloning for ipa cp and then inlining is OK. Not sure how the mitigation 
mechanism works. 

Richard. 

>Richard. 
>
>>  Jakub



Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Richard Biener
On January 24, 2018 6:40:25 PM GMT+01:00, Jakub Jelinek  
wrote:
>On Wed, Jan 24, 2018 at 06:36:02PM +0100, Martin Jambor wrote:
>> > I think there's already a set of attributes that prevent cloning
>and
>> > or are adjusted by the IPA param machinery. The Martins or Honza
>> > should know better.
>> 
>> I am not sure I understand the problem but if
>> tree_versionable_function_p returns false, the local.versionable bit
>is
>> not set and no cloning for that function happens.
>> 
>> If it is sufficient that IPA-CP and other IPA passes do not change
>the
>> function type in any way (in practice that they don't remove
>> parameters), it is sufficient to clear the local.can_change_signature
>> cgraph flag in compute_fn_summary() in ipa-fnsummary.c.  That is how
>we
>> handle, or rather avoid handling, fnspec attributes.
>
>Well, "omp declare simd" is a part of the ABI just for the original
>exported
>functions, for everything else it is a pure optimization, but I'm not
>sure
>if we want to deoptimize e.g. callers of these functions outside of
>loops
>by disabling the signature changing cloning for those.  For calls from
>within OpenMP simd regions or other loops where we try hard to
>vectorize
>them, it might make sense not to change those callers, for callers from
>other loops, a question.

Until we can distinguish the cases I think not changing the signature by 
default might be a good thing. 

Richard. 

>   Jakub




Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Jakub Jelinek
On Wed, Jan 24, 2018 at 06:36:02PM +0100, Martin Jambor wrote:
> > I think there's already a set of attributes that prevent cloning and
> > or are adjusted by the IPA param machinery. The Martins or Honza
> > should know better.
> 
> I am not sure I understand the problem but if
> tree_versionable_function_p returns false, the local.versionable bit is
> not set and no cloning for that function happens.
> 
> If it is sufficient that IPA-CP and other IPA passes do not change the
> function type in any way (in practice that they don't remove
> parameters), it is sufficient to clear the local.can_change_signature
> cgraph flag in compute_fn_summary() in ipa-fnsummary.c.  That is how we
> handle, or rather avoid handling, fnspec attributes.

Well, "omp declare simd" is a part of the ABI just for the original exported
functions, for everything else it is a pure optimization, but I'm not sure
if we want to deoptimize e.g. callers of these functions outside of loops
by disabling the signature changing cloning for those.  For calls from
within OpenMP simd regions or other loops where we try hard to vectorize
them, it might make sense not to change those callers, for callers from
other loops, a question.

Jakub


Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Martin Jambor
On Wed, Jan 24 2018, Richard Biener wrote:
> On January 24, 2018 5:16:45 PM GMT+01:00, Jakub Jelinek  
> wrote:
>>On Wed, Jan 24, 2018 at 05:08:10PM +0100, Richard Biener wrote:
>>> >The "omp declare simd" attribute refers to argument numbers of the
>>> >functions, so trying to apply it on versioned functions that can
>>> >perhaps
>>> >have different number and types of arguments results in ICEs or
>>> >wrong-code.
>>> >Unfortunately, if simd attribute or #pragma omp declare simd is used
>>> >on C++ ctors or dtors, those have DECL_ABSTRACT_ORIGIN of something
>>> >that
>>> >really doesn't exist, abstract ctor or dtor, so checking if
>>> >the types of node->decl and its DECL_ABSTRACT_ORIGIN are compatible
>>> >function
>>> >types doesn't work.
>>> 
>>> So if the attribute is on the decl we clone it should be in the list
>>of things that cloning adjusts or blocks cloning. 
>>
>>Yeah, guess I could move the attribute removal code from omp-low.c to
>>some
>>helper function and in tree_function_versioning check if the attribute
>>is
>>present and if yes and the old/new function types don't match, drop the
>>attribute.  Or, add some flag to cgraph whether the attribute should be
>>honored or not, and clear it in tree_function_versioning and
>>omp_create_child_function instead of removing the attribute.
>
> I think there's already a set of attributes that prevent cloning and
> or are adjusted by the IPA param machinery. The Martins or Honza
> should know better.

I am not sure I understand the problem but if
tree_versionable_function_p returns false, the local.versionable bit is
not set and no cloning for that function happens.

If it is sufficient that IPA-CP and other IPA passes do not change the
function type in any way (in practice that they don't remove
parameters), it is sufficient to clear the local.can_change_signature
cgraph flag in compute_fn_summary() in ipa-fnsummary.c.  That is how we
handle, or rather avoid handling, fnspec attributes.

Martin



Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Richard Biener
On January 24, 2018 5:16:45 PM GMT+01:00, Jakub Jelinek  
wrote:
>On Wed, Jan 24, 2018 at 05:08:10PM +0100, Richard Biener wrote:
>> >The "omp declare simd" attribute refers to argument numbers of the
>> >functions, so trying to apply it on versioned functions that can
>> >perhaps
>> >have different number and types of arguments results in ICEs or
>> >wrong-code.
>> >Unfortunately, if simd attribute or #pragma omp declare simd is used
>> >on C++ ctors or dtors, those have DECL_ABSTRACT_ORIGIN of something
>> >that
>> >really doesn't exist, abstract ctor or dtor, so checking if
>> >the types of node->decl and its DECL_ABSTRACT_ORIGIN are compatible
>> >function
>> >types doesn't work.
>> 
>> So if the attribute is on the decl we clone it should be in the list
>of things that cloning adjusts or blocks cloning. 
>
>Yeah, guess I could move the attribute removal code from omp-low.c to
>some
>helper function and in tree_function_versioning check if the attribute
>is
>present and if yes and the old/new function types don't match, drop the
>attribute.  Or, add some flag to cgraph whether the attribute should be
>honored or not, and clear it in tree_function_versioning and
>omp_create_child_function instead of removing the attribute.

I think there's already a set of attributes that prevent cloning and or are 
adjusted by the IPA param machinery. The Martins or Honza should know better. 

>I'd prefer to defer that to GCC9 though at this point.

Sure. 

>   Jakub



Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Jakub Jelinek
On Wed, Jan 24, 2018 at 05:08:10PM +0100, Richard Biener wrote:
> >The "omp declare simd" attribute refers to argument numbers of the
> >functions, so trying to apply it on versioned functions that can
> >perhaps
> >have different number and types of arguments results in ICEs or
> >wrong-code.
> >Unfortunately, if simd attribute or #pragma omp declare simd is used
> >on C++ ctors or dtors, those have DECL_ABSTRACT_ORIGIN of something
> >that
> >really doesn't exist, abstract ctor or dtor, so checking if
> >the types of node->decl and its DECL_ABSTRACT_ORIGIN are compatible
> >function
> >types doesn't work.
> 
> So if the attribute is on the decl we clone it should be in the list of 
> things that cloning adjusts or blocks cloning. 

Yeah, guess I could move the attribute removal code from omp-low.c to some
helper function and in tree_function_versioning check if the attribute is
present and if yes and the old/new function types don't match, drop the
attribute.  Or, add some flag to cgraph whether the attribute should be
honored or not, and clear it in tree_function_versioning and
omp_create_child_function instead of removing the attribute.

I'd prefer to defer that to GCC9 though at this point.

Jakub


Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Richard Biener
On January 24, 2018 4:47:06 PM GMT+01:00, Jakub Jelinek  
wrote:
>Hi!
>
>The "omp declare simd" attribute refers to argument numbers of the
>functions, so trying to apply it on versioned functions that can
>perhaps
>have different number and types of arguments results in ICEs or
>wrong-code.
>Unfortunately, if simd attribute or #pragma omp declare simd is used
>on C++ ctors or dtors, those have DECL_ABSTRACT_ORIGIN of something
>that
>really doesn't exist, abstract ctor or dtor, so checking if
>the types of node->decl and its DECL_ABSTRACT_ORIGIN are compatible
>function
>types doesn't work.

So if the attribute is on the decl we clone it should be in the list of things 
that cloning adjusts or blocks cloning. 

>The following patch just keeps optimizing only the original functions,
>not
>any versioned copies of them, but still allows simd attribute handling
>on
>e.g. __builtin_sin.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux.
>
>Richard, is the first hunk ok, the rest is OpenMP related and I can ack
>myself.

Yes. 

>2018-01-24  Jakub Jelinek  
>
>   PR middle-end/83977
>   * tree.c (free_lang_data_in_decl): Don't clear DECL_ABSTRACT_ORIGIN
>   here.
>   * omp-low.c (create_omp_child_function): Remove "omp declare simd"
>   attributes from DECL_ATTRIBUTES (decl) without affecting
>   DECL_ATTRIBUTES (current_function_decl).
>   * omp-simd-clone.c (expand_simd_clones): Ignore DECL_ARTIFICIAL
>   functions with non-NULL DECL_ABSTRACT_ORIGIN.
>
>   * c-c++-common/gomp/pr83977-1.c: New test.
>   * c-c++-common/gomp/pr83977-2.c: New test.
>   * c-c++-common/gomp/pr83977-3.c: New test.
>   * gfortran.dg/gomp/pr83977.f90: New test.
>
>--- gcc/tree.c.jj  2018-01-23 14:48:50.216265866 +0100
>+++ gcc/tree.c 2018-01-24 11:40:30.845519905 +0100
>@@ -5329,16 +5329,6 @@ free_lang_data_in_decl (tree decl)
>At this point, it is not needed anymore.  */
>   DECL_SAVED_TREE (decl) = NULL_TREE;
> 
>-  /* Clear the abstract origin if it refers to a method.
>- Otherwise dwarf2out.c will ICE as we splice functions out of
>- TYPE_FIELDS and thus the origin will not be output
>- correctly.  */
>-  if (DECL_ABSTRACT_ORIGIN (decl)
>-&& DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
>-&& RECORD_OR_UNION_TYPE_P
>- (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl
>-  DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
>-
>  /* Sometimes the C++ frontend doesn't manage to transform a temporary
>DECL_VINDEX referring to itself into a vtable slot number as it
>should.  Happens with functions that are copied and then forgotten
>--- gcc/omp-low.c.jj   2018-01-04 00:43:16.106702767 +0100
>+++ gcc/omp-low.c  2018-01-24 12:59:37.566218901 +0100
>@@ -1585,6 +1585,23 @@ create_omp_child_function (omp_context *
>   DECL_INITIAL (decl) = make_node (BLOCK);
>   BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
>   DECL_ATTRIBUTES (decl) = DECL_ATTRIBUTES (current_function_decl);
>+  /* Remove omp declare simd attribute from the new attributes.  */
>+  if (tree a = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES
>(decl)))
>+{
>+  while (tree a2 = lookup_attribute ("omp declare simd",
>TREE_CHAIN (a)))
>+  a = a2;
>+  a = TREE_CHAIN (a);
>+  for (tree *p = _ATTRIBUTES (decl); *p != a;)
>+  if (is_attribute_p ("omp declare simd", get_attribute_name (*p)))
>+*p = TREE_CHAIN (*p);
>+  else
>+{
>+  tree chain = TREE_CHAIN (*p);
>+  *p = copy_node (*p);
>+  p = _CHAIN (*p);
>+  *p = chain;
>+}
>+}
>   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
> = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (current_function_decl);
>   DECL_FUNCTION_SPECIFIC_TARGET (decl)
>--- gcc/omp-simd-clone.c.jj2018-01-23 14:48:47.275261492 +0100
>+++ gcc/omp-simd-clone.c   2018-01-24 11:45:28.484494749 +0100
>@@ -1574,6 +1574,10 @@ expand_simd_clones (struct cgraph_node *
>   tree attr = lookup_attribute ("omp declare simd",
>   DECL_ATTRIBUTES (node->decl));
>   if (attr == NULL_TREE
>+  /* Ignore artificial decls with an abstract origin, results of
>function
>+   cloning, versioning etc.  We want to handle certain builtins
>+   with simd attribute, like __builtin_sin.  */
>+  || (DECL_ARTIFICIAL (node->decl) && DECL_ABSTRACT_ORIGIN
>(node->decl))
>   || node->global.inlined_to
>   || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
> return;
>--- gcc/testsuite/c-c++-common/gomp/pr83977-1.c.jj 2018-01-24
>11:46:00.946492004 +0100
>+++ gcc/testsuite/c-c++-common/gomp/pr83977-1.c2018-01-24
>11:46:29.181489615 +0100
>@@ -0,0 +1,19 @@
>+/* PR middle-end/83977 */
>+/* { dg-do compile } */
>+/* { dg-additional-options "-O2" } */
>+
>+struct S { int a, b, c; };
>+
>+#pragma omp declare simd uniform(z) linear(v:1)

[PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)

2018-01-24 Thread Jakub Jelinek
Hi!

The "omp declare simd" attribute refers to argument numbers of the
functions, so trying to apply it on versioned functions that can perhaps
have different number and types of arguments results in ICEs or wrong-code.
Unfortunately, if simd attribute or #pragma omp declare simd is used
on C++ ctors or dtors, those have DECL_ABSTRACT_ORIGIN of something that
really doesn't exist, abstract ctor or dtor, so checking if
the types of node->decl and its DECL_ABSTRACT_ORIGIN are compatible function
types doesn't work.

The following patch just keeps optimizing only the original functions, not
any versioned copies of them, but still allows simd attribute handling on
e.g. __builtin_sin.

Bootstrapped/regtested on x86_64-linux and i686-linux.

Richard, is the first hunk ok, the rest is OpenMP related and I can ack
myself.

2018-01-24  Jakub Jelinek  

PR middle-end/83977
* tree.c (free_lang_data_in_decl): Don't clear DECL_ABSTRACT_ORIGIN
here.
* omp-low.c (create_omp_child_function): Remove "omp declare simd"
attributes from DECL_ATTRIBUTES (decl) without affecting
DECL_ATTRIBUTES (current_function_decl).
* omp-simd-clone.c (expand_simd_clones): Ignore DECL_ARTIFICIAL
functions with non-NULL DECL_ABSTRACT_ORIGIN.

* c-c++-common/gomp/pr83977-1.c: New test.
* c-c++-common/gomp/pr83977-2.c: New test.
* c-c++-common/gomp/pr83977-3.c: New test.
* gfortran.dg/gomp/pr83977.f90: New test.

--- gcc/tree.c.jj   2018-01-23 14:48:50.216265866 +0100
+++ gcc/tree.c  2018-01-24 11:40:30.845519905 +0100
@@ -5329,16 +5329,6 @@ free_lang_data_in_decl (tree decl)
 At this point, it is not needed anymore.  */
   DECL_SAVED_TREE (decl) = NULL_TREE;
 
-  /* Clear the abstract origin if it refers to a method.
- Otherwise dwarf2out.c will ICE as we splice functions out of
- TYPE_FIELDS and thus the origin will not be output
- correctly.  */
-  if (DECL_ABSTRACT_ORIGIN (decl)
- && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
- && RECORD_OR_UNION_TYPE_P
-  (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl
-   DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
-
   /* Sometimes the C++ frontend doesn't manage to transform a temporary
  DECL_VINDEX referring to itself into a vtable slot number as it
 should.  Happens with functions that are copied and then forgotten
--- gcc/omp-low.c.jj2018-01-04 00:43:16.106702767 +0100
+++ gcc/omp-low.c   2018-01-24 12:59:37.566218901 +0100
@@ -1585,6 +1585,23 @@ create_omp_child_function (omp_context *
   DECL_INITIAL (decl) = make_node (BLOCK);
   BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
   DECL_ATTRIBUTES (decl) = DECL_ATTRIBUTES (current_function_decl);
+  /* Remove omp declare simd attribute from the new attributes.  */
+  if (tree a = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl)))
+{
+  while (tree a2 = lookup_attribute ("omp declare simd", TREE_CHAIN (a)))
+   a = a2;
+  a = TREE_CHAIN (a);
+  for (tree *p = _ATTRIBUTES (decl); *p != a;)
+   if (is_attribute_p ("omp declare simd", get_attribute_name (*p)))
+ *p = TREE_CHAIN (*p);
+   else
+ {
+   tree chain = TREE_CHAIN (*p);
+   *p = copy_node (*p);
+   p = _CHAIN (*p);
+   *p = chain;
+ }
+}
   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
 = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (current_function_decl);
   DECL_FUNCTION_SPECIFIC_TARGET (decl)
--- gcc/omp-simd-clone.c.jj 2018-01-23 14:48:47.275261492 +0100
+++ gcc/omp-simd-clone.c2018-01-24 11:45:28.484494749 +0100
@@ -1574,6 +1574,10 @@ expand_simd_clones (struct cgraph_node *
   tree attr = lookup_attribute ("omp declare simd",
DECL_ATTRIBUTES (node->decl));
   if (attr == NULL_TREE
+  /* Ignore artificial decls with an abstract origin, results of function
+cloning, versioning etc.  We want to handle certain builtins
+with simd attribute, like __builtin_sin.  */
+  || (DECL_ARTIFICIAL (node->decl) && DECL_ABSTRACT_ORIGIN (node->decl))
   || node->global.inlined_to
   || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
 return;
--- gcc/testsuite/c-c++-common/gomp/pr83977-1.c.jj  2018-01-24 
11:46:00.946492004 +0100
+++ gcc/testsuite/c-c++-common/gomp/pr83977-1.c 2018-01-24 11:46:29.181489615 
+0100
@@ -0,0 +1,19 @@
+/* PR middle-end/83977 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O2" } */
+
+struct S { int a, b, c; };
+
+#pragma omp declare simd uniform(z) linear(v:1)
+__attribute__((noinline)) static int
+foo (int x, int y, struct S z, int u, int v)
+{
+  return x + y + z.a;
+}
+
+int
+bar (int x, int y, int z)
+{
+  struct S s = { z, 1, 1 };
+  return foo (x, y, s, 0, 0);
+}
--- gcc/testsuite/c-c++-common/gomp/pr83977-2.c.jj  2018-01-24 
11:46:42.259488509 +0100
+++