Re: [PATCH] Fix ICEs with "omp declare simd" attribute on versioned fns or omp_fn* (PR middle-end/83977)
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 JelinekPR 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)
On January 24, 2018 6:51:54 PM GMT+01:00, Richard Bienerwrote: >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)
On January 24, 2018 6:40:25 PM GMT+01:00, Jakub Jelinekwrote: >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)
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)
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)
On January 24, 2018 5:16:45 PM GMT+01:00, Jakub Jelinekwrote: >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)
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)
On January 24, 2018 4:47:06 PM GMT+01:00, Jakub Jelinekwrote: >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)
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 JelinekPR 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 +++