Hi! I've backported following 21 commits from trunk to 9.4, bootstrapped/regtested on x86_64-linux and i686-linux and committed to 9 branch.
Jakub
>From 980a7a0be5a114e285c49ab05ac70881e4f27fc3 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 17 Mar 2020 21:21:16 +0100 Subject: [PATCH] c++: Fix parsing of invalid enum specifiers [PR90995] The testcase shows some accepts-invalid (the ones without alignas) and ice-on-invalid-code (the ones with alignas) cases. If the enum doesn't have an underlying type and is not a definition, the caller retries to parse it as elaborated type specifier. E.g. for enum struct S s it will then pedwarn that elaborated type specifier shouldn't have the struct/class keywords. The problem is if the enum specifier is not followed by { when it has underlying type. In that case we have already called cp_parser_parse_definitely to end the tentative parsing started at the beginning of cp_parser_enum_specifier. But the cp_parser_error (parser, "expected %<;%> or %<{%>"); doesn't emit any error because the whole function is called from yet another tentative parse and the caller starts parsing the elaborated type specifier where the cp_parser_enum_specifier stopped (i.e. after the underlying type token(s)). The ultimate caller than commits the tentative parsing (and even if it wouldn't, it wouldn't know what kind of error to report). I think after seeing enum {,struct,class} : type not being followed by { or ;, there is no reason not to report it right away, as it can't be valid C++, which is what the patch does. Not sure if we shouldn't also return error_mark_node instead of NULL_TREE, so that the caller doesn't try to parse it as elaborated type specifier (the patch doesn't do that right now). Furthermore, while reading the code, I've noticed that parser->colon_corrects_to_scope_p is saved and set to false at the start of the function, but not restored back in some cases. Don't have a testcase where this would be a problem, but it just seems wrong. Either we can in the two spots replace return NULL_TREE; with { type = NULL_TREE; goto out; } or we could perhaps abuse warning_sentinel or create a special class with dtor to clean the flag up. And lastly, I've fixed some formatting issues in the function while reading it. 2020-03-17 Jakub Jelinek <ja...@redhat.com> PR c++/90995 * parser.c (cp_parser_enum_specifier): Use temp_override for parser->colon_corrects_to_scope_p, replace goto out with return. If scoped enum or enum with underlying type is not followed by { or ;, call cp_parser_commit_to_tentative_parse before calling cp_parser_error and make sure to return error_mark_node instead of NULL_TREE. Formatting fixes. * g++.dg/cpp0x/enum40.C: New test. --- gcc/cp/ChangeLog | 13 ++++++++ gcc/cp/parser.c | 52 ++++++++++++----------------- gcc/testsuite/ChangeLog | 8 +++++ gcc/testsuite/g++.dg/cpp0x/enum40.C | 26 +++++++++++++++ 4 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum40.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e247069b96..8afe6aca339 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2020-04-07 Jakub Jelinek <ja...@redhat.com> + + Backported from mainline + 2020-03-17 Jakub Jelinek <ja...@redhat.com> + + PR c++/90995 + * parser.c (cp_parser_enum_specifier): Use temp_override for + parser->colon_corrects_to_scope_p, replace goto out with return. + If scoped enum or enum with underlying type is not followed by + { or ;, call cp_parser_commit_to_tentative_parse before calling + cp_parser_error and make sure to return error_mark_node instead of + NULL_TREE. Formatting fixes. + 2020-04-05 Marek Polacek <pola...@redhat.com> 2020-02-06 Marek Polacek <pola...@redhat.com> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e1c02d7b718..0219920be8f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18705,9 +18705,7 @@ cp_parser_enum_specifier (cp_parser* parser) bool is_unnamed = false; tree underlying_type = NULL_TREE; cp_token *type_start_token = NULL; - bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; - - parser->colon_corrects_to_scope_p = false; + temp_override<bool> cleanup (parser->colon_corrects_to_scope_p, false); /* Parse tentatively so that we can back up if we don't find a enum-specifier. */ @@ -18747,24 +18745,24 @@ cp_parser_enum_specifier (cp_parser* parser) push_deferring_access_checks (dk_no_check); nested_name_specifier - = cp_parser_nested_name_specifier_opt (parser, - /*typename_keyword_p=*/true, - /*check_dependency_p=*/false, - /*type_p=*/false, - /*is_declaration=*/false); + = cp_parser_nested_name_specifier_opt (parser, + /*typename_keyword_p=*/true, + /*check_dependency_p=*/false, + /*type_p=*/false, + /*is_declaration=*/false); if (nested_name_specifier) { tree name; identifier = cp_parser_identifier (parser); - name = cp_parser_lookup_name (parser, identifier, - enum_type, - /*is_template=*/false, - /*is_namespace=*/false, - /*check_dependency=*/true, - /*ambiguous_decls=*/NULL, - input_location); + name = cp_parser_lookup_name (parser, identifier, + enum_type, + /*is_template=*/false, + /*is_namespace=*/false, + /*check_dependency=*/true, + /*ambiguous_decls=*/NULL, + input_location); if (name && name != error_mark_node) { type = TREE_TYPE (name); @@ -18844,23 +18842,21 @@ cp_parser_enum_specifier (cp_parser* parser) { if (cxx_dialect < cxx11 || (!scoped_enum_p && !underlying_type)) { + if (has_underlying_type) + cp_parser_commit_to_tentative_parse (parser); cp_parser_error (parser, "expected %<{%>"); if (has_underlying_type) - { - type = NULL_TREE; - goto out; - } + return error_mark_node; } /* An opaque-enum-specifier must have a ';' here. */ if ((scoped_enum_p || underlying_type) && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { + if (has_underlying_type) + cp_parser_commit_to_tentative_parse (parser); cp_parser_error (parser, "expected %<;%> or %<{%>"); if (has_underlying_type) - { - type = NULL_TREE; - goto out; - } + return error_mark_node; } } @@ -18876,9 +18872,7 @@ cp_parser_enum_specifier (cp_parser* parser) push_scope (nested_name_specifier); } else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL) - { - push_nested_namespace (nested_name_specifier); - } + push_nested_namespace (nested_name_specifier); } /* Issue an error message if type-definitions are forbidden here. */ @@ -19038,12 +19032,8 @@ cp_parser_enum_specifier (cp_parser* parser) pop_scope (nested_name_specifier); } else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL) - { - pop_nested_namespace (nested_name_specifier); - } + pop_nested_namespace (nested_name_specifier); } - out: - parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; return type; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf0d5d76f2d..c10d50b623b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2020-04-07 Jakub Jelinek <ja...@redhat.com> + + Backported from mainline + 2020-03-17 Jakub Jelinek <ja...@redhat.com> + + PR c++/90995 + * g++.dg/cpp0x/enum40.C: New test. + 2020-04-07 Jakub Jelinek <ja...@redhat.com> PR target/94500 diff --git a/gcc/testsuite/g++.dg/cpp0x/enum40.C b/gcc/testsuite/g++.dg/cpp0x/enum40.C new file mode 100644 index 00000000000..cfdf2a4a18a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum40.C @@ -0,0 +1,26 @@ +// PR c++/90995 +// { dg-do compile { target c++11 } } + +void +foo () +{ + enum : int a alignas; // { dg-error "expected" } +} + +void +bar () +{ + enum : int a; // { dg-error "expected" } +} + +void +baz () +{ + enum class a : int b alignas; // { dg-error "expected" } +} + +void +qux () +{ + enum class a : int b; // { dg-error "expected" } +} -- 2.20.1
>From 87ce34fa00cd6b87452d747235da40dfe5b6e00f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 17 Mar 2020 22:32:34 +0100 Subject: [PATCH] c: Handle C_TYPE_INCOMPLETE_VARS even for ENUMERAL_TYPEs [PR94172] The following testcases ICE, because they contain extern variable declarations with incomplete enum types that is later completed and after that those variables are accessed. The ICEs are because the vars then may have incorrect DECL_MODE etc., e.g. in the first case the var has SImode DECL_MODE (the guessed mode for the enum), but the enum then actually has DImode because its enumerators don't fit into unsigned int. The following patch fixes it by using C_TYPE_INCOMPLETE_VARS not just on incomplete struct/union types, but also incomplete enum types. TYPE_VFIELD can't be used as it is TYPE_MIN_VALUE on ENUMERAL_TYPE, thankfully TYPE_LANG_SLOT_1 has been used in the C FE only on FUNCTION_TYPEs. 2020-03-17 Jakub Jelinek <ja...@redhat.com> PR c/94172 * c-tree.h (C_TYPE_INCOMPLETE_VARS): Define to TYPE_LANG_SLOT_1 instead of TYPE_VFIELD, and support it on {RECORD,UNION,ENUMERAL}_TYPE. (TYPE_ACTUAL_ARG_TYPES): Check that it is only used on FUNCTION_TYPEs. * c-decl.c (pushdecl): Push C_TYPE_INCOMPLETE_VARS also to ENUMERAL_TYPEs. (finish_incomplete_vars): New function, moved from finish_struct. Use relayout_decl instead of layout_decl. (finish_struct): Remove obsolete comment about C_TYPE_INCOMPLETE_VARS being TYPE_VFIELD. Use finish_incomplete_vars. (finish_enum): Clear C_TYPE_INCOMPLETE_VARS. Call finish_incomplete_vars. * c-typeck.c (c_build_qualified_type): Clear C_TYPE_INCOMPLETE_VARS also on ENUMERAL_TYPEs. * gcc.dg/pr94172-1.c: New test. * gcc.dg/pr94172-2.c: New test. --- gcc/c/ChangeLog | 20 +++++++++++++ gcc/c/c-decl.c | 50 +++++++++++++++++--------------- gcc/c/c-tree.h | 12 +++++--- gcc/c/c-typeck.c | 3 +- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/pr94172-1.c | 12 ++++++++ gcc/testsuite/gcc.dg/pr94172-2.c | 19 ++++++++++++ 7 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr94172-1.c create mode 100644 gcc/testsuite/gcc.dg/pr94172-2.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c38f1d73605..1c3ca1b4709 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,23 @@ +2020-04-07 Jakub Jelinek <ja...@redhat.com> + + Backported from mainline + 2020-03-17 Jakub Jelinek <ja...@redhat.com> + + PR c/94172 + * c-tree.h (C_TYPE_INCOMPLETE_VARS): Define to TYPE_LANG_SLOT_1 + instead of TYPE_VFIELD, and support it on {RECORD,UNION,ENUMERAL}_TYPE. + (TYPE_ACTUAL_ARG_TYPES): Check that it is only used on FUNCTION_TYPEs. + * c-decl.c (pushdecl): Push C_TYPE_INCOMPLETE_VARS also to + ENUMERAL_TYPEs. + (finish_incomplete_vars): New function, moved from finish_struct. Use + relayout_decl instead of layout_decl. + (finish_struct): Remove obsolete comment about C_TYPE_INCOMPLETE_VARS + being TYPE_VFIELD. Use finish_incomplete_vars. + (finish_enum): Clear C_TYPE_INCOMPLETE_VARS. Call + finish_incomplete_vars. + * c-typeck.c (c_build_qualified_type): Clear C_TYPE_INCOMPLETE_VARS + also on ENUMERAL_TYPEs. + 2020-03-12 Release Manager * GCC 9.3.0 released. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 859a6241258..350e08e22c2 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -3272,7 +3272,8 @@ pushdecl (tree x) element = TREE_TYPE (element); element = TYPE_MAIN_VARIANT (element); - if (RECORD_OR_UNION_TYPE_P (element) + if ((RECORD_OR_UNION_TYPE_P (element) + || TREE_CODE (element) == ENUMERAL_TYPE) && (TREE_CODE (x) != TYPE_DECL || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE) && !COMPLETE_TYPE_P (element)) @@ -8141,6 +8142,26 @@ field_decl_cmp (const void *x_p, const void *y_p) return 1; } +/* If this structure or union completes the type of any previous + variable declaration, lay it out and output its rtl. */ +static void +finish_incomplete_vars (tree incomplete_vars, bool toplevel) +{ + for (tree x = incomplete_vars; x; x = TREE_CHAIN (x)) + { + tree decl = TREE_VALUE (x); + if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + layout_array_type (TREE_TYPE (decl)); + if (TREE_CODE (decl) != TYPE_DECL) + { + relayout_decl (decl); + if (c_dialect_objc ()) + objc_check_decl (decl); + rest_of_decl_compilation (decl, toplevel, 0); + } + } +} + /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. LOC is the location of the RECORD_TYPE or UNION_TYPE's definition. FIELDLIST is a chain of FIELD_DECL nodes for the fields. @@ -8399,13 +8420,6 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, warning_at (loc, 0, "union cannot be made transparent"); } - /* Note: C_TYPE_INCOMPLETE_VARS overloads TYPE_VFIELD which is used - in dwarf2out via rest_of_decl_compilation below and means - something totally different. Since we will be clearing - C_TYPE_INCOMPLETE_VARS shortly after we iterate through them, - clear it ahead of time and avoid problems in dwarf2out. Ideally, - C_TYPE_INCOMPLETE_VARS should use some language specific - node. */ tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)); for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) { @@ -8426,21 +8440,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, /* Finish debugging output for this type. */ rest_of_type_compilation (t, toplevel); - /* If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ - for (x = incomplete_vars; x; x = TREE_CHAIN (x)) - { - tree decl = TREE_VALUE (x); - if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - layout_array_type (TREE_TYPE (decl)); - if (TREE_CODE (decl) != TYPE_DECL) - { - layout_decl (decl, 0); - if (c_dialect_objc ()) - objc_check_decl (decl); - rest_of_decl_compilation (decl, toplevel, 0); - } - } + finish_incomplete_vars (incomplete_vars, toplevel); /* If we're inside a function proper, i.e. not file-scope and not still parsing parameters, then arrange for the size of a variable sized type @@ -8719,8 +8719,10 @@ finish_enum (tree enumtype, tree values, tree attributes) TYPE_LANG_SPECIFIC (enumtype) = lt; /* Fix up all variant types of this enum type. */ + tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (enumtype)); for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem)) { + C_TYPE_INCOMPLETE_VARS (tem) = NULL_TREE; if (tem == enumtype) continue; TYPE_VALUES (tem) = TYPE_VALUES (enumtype); @@ -8739,6 +8741,8 @@ finish_enum (tree enumtype, tree values, tree attributes) /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, toplevel); + finish_incomplete_vars (incomplete_vars, toplevel); + /* If this enum is defined inside a struct, add it to struct_types. */ if (warn_cxx_compat diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 7e35ab1f0bc..147a7e867aa 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -38,9 +38,12 @@ along with GCC; see the file COPYING3. If not see nonzero if the definition of the type has already started. */ #define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE) -/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable - declarations whose type would be completed by completing that type. */ -#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE) +/* In an incomplete RECORD_TYPE, UNION_TYPE or ENUMERAL_TYPE, a list of + variable declarations whose type would be completed by completing + that type. */ +#define C_TYPE_INCOMPLETE_VARS(TYPE) \ + TYPE_LANG_SLOT_1 (TREE_CHECK4 (TYPE, RECORD_TYPE, UNION_TYPE, \ + QUAL_UNION_TYPE, ENUMERAL_TYPE)) /* In an IDENTIFIER_NODE, nonzero if this identifier is actually a keyword. C_RID_CODE (node) is then the RID_* value of the keyword. */ @@ -111,7 +114,8 @@ along with GCC; see the file COPYING3. If not see /* For FUNCTION_TYPE, a hidden list of types of arguments. The same as TYPE_ARG_TYPES for functions with prototypes, but created for functions without prototypes. */ -#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE) +#define TYPE_ACTUAL_ARG_TYPES(NODE) \ + TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE)) /* For a CONSTRUCTOR, whether some initializer contains a subexpression meaning it is not a constant expression. */ diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index c0582a54c93..24106c126cd 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -14965,7 +14965,8 @@ c_build_qualified_type (tree type, int type_quals, tree orig_qual_type, : build_qualified_type (type, type_quals)); /* A variant type does not inherit the list of incomplete vars from the type main variant. */ - if (RECORD_OR_UNION_TYPE_P (var_type) + if ((RECORD_OR_UNION_TYPE_P (var_type) + || TREE_CODE (var_type) == ENUMERAL_TYPE) && TYPE_MAIN_VARIANT (var_type) != var_type) C_TYPE_INCOMPLETE_VARS (var_type) = 0; return var_type; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c10d50b623b..18025a5fa58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,10 @@ Backported from mainline 2020-03-17 Jakub Jelinek <ja...@redhat.com> + PR c/94172 + * gcc.dg/pr94172-1.c: New test. + * gcc.dg/pr94172-2.c: New test. + PR c++/90995 * g++.dg/cpp0x/enum40.C: New test. diff --git a/gcc/testsuite/gcc.dg/pr94172-1.c b/gcc/testsuite/gcc.dg/pr94172-1.c new file mode 100644 index 00000000000..12f84af42dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94172-1.c @@ -0,0 +1,12 @@ +/* PR c/94172 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern enum E e; +enum E { l = 0x100000000ULL }; + +unsigned long long +foo (void) +{ + return e; +} diff --git a/gcc/testsuite/gcc.dg/pr94172-2.c b/gcc/testsuite/gcc.dg/pr94172-2.c new file mode 100644 index 00000000000..bb7b060d7b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94172-2.c @@ -0,0 +1,19 @@ +/* PR c/94172 */ +/* { dg-do compile } */ +/* { dg-options "-Os -g -fshort-enums" } */ + +extern enum E e; +extern void bar (int a); +enum E { F }; + +void +foo (int a) +{ + int l = e; + if (a) + { + __asm volatile ("nop"); + l = 0; + } + bar (l); +} -- 2.20.1
>From 8db876e9c045c57d2dc5bd08a6e250f822efaad0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Thu, 19 Mar 2020 10:24:16 +0100 Subject: [PATCH] phiopt: Avoid -fcompare-debug bug in phiopt [PR94211] Two years ago, I've added support for up to 2 simple preparation statements in value_replacement, but the - && estimate_num_insns (assign, &eni_time_weights) + && estimate_num_insns (bb_seq (middle_bb), &eni_time_weights) change, meant that we compute the cost of all those statements rather than just the single assign that has been the single supported non-debug statement in the bb before, doesn't do what I thought would do, gimple_seq is just gimple * and thus it can't be really overloaded depending on whether we pass a single gimple * or a whole sequence. Which means in the last two years it doesn't count all the statements, but only the first one. With -g that happens to be a DEBUG_STMT, or it could be e.g. the first preparation statement which could be much cheaper than the actual assign. 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/94211 * tree-ssa-phiopt.c (value_replacement): Use estimate_num_insns_seq instead of estimate_num_insns for bb_seq (middle_bb). Rename emtpy_or_with_defined_p variable to empty_or_with_defined_p, adjust all uses. * gcc.dg/pr94211.c: New test. --- gcc/ChangeLog | 11 +++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr94211.c | 12 ++++++++++++ gcc/tree-ssa-phiopt.c | 10 +++++----- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr94211.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc1a903cf47..2cd4b81ebe9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2020-04-07 Jakub Jelinek <ja...@redhat.com> + + Backported from mainline + 2020-03-19 Jakub Jelinek <ja...@redhat.com> + + PR tree-optimization/94211 + * tree-ssa-phiopt.c (value_replacement): Use estimate_num_insns_seq + instead of estimate_num_insns for bb_seq (middle_bb). Rename + emtpy_or_with_defined_p variable to empty_or_with_defined_p, adjust + all uses. + 2020-04-07 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR target/94518 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 18025a5fa58..7b15ef6a938 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-19 Jakub Jelinek <ja...@redhat.com> + + PR tree-optimization/94211 + * gcc.dg/pr94211.c: New test. + 2020-03-17 Jakub Jelinek <ja...@redhat.com> PR c/94172 diff --git a/gcc/testsuite/gcc.dg/pr94211.c b/gcc/testsuite/gcc.dg/pr94211.c new file mode 100644 index 00000000000..3e160e457fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94211.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/94211 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcompare-debug" } */ + +long +foo (long a, long b) +{ + if (__builtin_expect (b == 1, 1)) + return a; + int e = a + 1; + return a / b; +} diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 19b37b43b8e..47227dc16dc 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1040,7 +1040,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, gimple *cond; edge true_edge, false_edge; enum tree_code code; - bool emtpy_or_with_defined_p = true; + bool empty_or_with_defined_p = true; /* If the type says honor signed zeros we cannot do this optimization. */ @@ -1059,7 +1059,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, { if (gimple_code (stmt) != GIMPLE_PREDICT && gimple_code (stmt) != GIMPLE_NOP) - emtpy_or_with_defined_p = false; + empty_or_with_defined_p = false; continue; } /* Now try to adjust arg0 or arg1 according to the computation @@ -1069,7 +1069,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, && jump_function_from_stmt (&arg0, stmt)) || (lhs == arg1 && jump_function_from_stmt (&arg1, stmt))) - emtpy_or_with_defined_p = false; + empty_or_with_defined_p = false; } cond = last_stmt (cond_bb); @@ -1121,7 +1121,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, /* If the middle basic block was empty or is defining the PHI arguments and this is a single phi where the args are different for the edges e0 and e1 then we can remove the middle basic block. */ - if (emtpy_or_with_defined_p + if (empty_or_with_defined_p && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)), e0, e1) == phi) { @@ -1239,7 +1239,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, && profile_status_for_fn (cfun) != PROFILE_ABSENT && EDGE_PRED (middle_bb, 0)->probability < profile_probability::even () /* If assign is cheap, there is no point avoiding it. */ - && estimate_num_insns (bb_seq (middle_bb), &eni_time_weights) + && estimate_num_insns_seq (bb_seq (middle_bb), &eni_time_weights) >= 3 * estimate_num_insns (cond, &eni_time_weights)) return 0; -- 2.20.1
>From 484206967f958fc47827a71654fe52a98adc95cb Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Thu, 19 Mar 2020 12:22:47 +0100 Subject: [PATCH] c++: Fix up handling of captured vars in lambdas in OpenMP clauses [PR93931] Without the parser.c change we were ICEing on the testcase, because while the uses of the captured vars inside of the constructs were replaced with capture proxy decls, we didn't do that for decls in OpenMP clauses. With that fixed, we don't ICE anymore, but the testcase is miscompiled and FAILs at runtime. This is because the capture proxy decls have DECL_VALUE_EXPR and during gimplification we were gimplifying those to their DECL_VALUE_EXPRs. That is fine for shared vars, but for privatized ones we must not do that. So that is what the cp-gimplify.c changes do. Had to add a DECL_CONTEXT check before calling is_capture_proxy because some VAR_DECLs don't have DECL_CONTEXT set (yet) and is_capture_proxy relies on that being non-NULL always. 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR c++/93931 * parser.c (cp_parser_omp_var_list_no_open): Call process_outer_var_ref on outer_automatic_var_p decls. * cp-gimplify.c (cxx_omp_disregard_value_expr): Return true also for capture proxy decls. * testsuite/libgomp.c++/pr93931.C: New test. --- gcc/cp/ChangeLog | 8 ++ gcc/cp/cp-gimplify.c | 17 ++-- gcc/cp/parser.c | 2 + libgomp/ChangeLog | 8 ++ libgomp/testsuite/libgomp.c++/pr93931.C | 120 ++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c++/pr93931.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8afe6aca339..d11c4c62ddf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,14 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-19 Jakub Jelinek <ja...@redhat.com> + + PR c++/93931 + * parser.c (cp_parser_omp_var_list_no_open): Call process_outer_var_ref + on outer_automatic_var_p decls. + * cp-gimplify.c (cxx_omp_disregard_value_expr): Return true also for + capture proxy decls. + 2020-03-17 Jakub Jelinek <ja...@redhat.com> PR c++/90995 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 4be45abca88..0e15b1c8147 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2192,12 +2192,17 @@ cxx_omp_finish_clause (tree c, gimple_seq *) bool cxx_omp_disregard_value_expr (tree decl, bool shared) { - return !shared - && VAR_P (decl) - && DECL_HAS_VALUE_EXPR_P (decl) - && DECL_ARTIFICIAL (decl) - && DECL_LANG_SPECIFIC (decl) - && DECL_OMP_PRIVATIZED_MEMBER (decl); + if (shared) + return false; + if (VAR_P (decl) + && DECL_HAS_VALUE_EXPR_P (decl) + && DECL_ARTIFICIAL (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl)) + return true; + if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl)) + return true; + return false; } /* Fold expression X which is used as an rvalue if RVAL is true. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0219920be8f..00e950d2e93 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -32563,6 +32563,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, token->location); } } + if (outer_automatic_var_p (decl)) + decl = process_outer_var_ref (decl, tf_warning_or_error); if (decl == error_mark_node) ; else if (kind != 0) diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index f4aa8c63481..ee18a994590 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,11 @@ +2020-04-07 Jakub Jelinek <ja...@redhat.com> + + Backported from mainline + 2020-03-19 Jakub Jelinek <ja...@redhat.com> + + PR c++/93931 + * testsuite/libgomp.c++/pr93931.C: New test. + 2020-03-17 Jakub Jelinek <ja...@redhat.com> Backported from mainline diff --git a/libgomp/testsuite/libgomp.c++/pr93931.C b/libgomp/testsuite/libgomp.c++/pr93931.C new file mode 100644 index 00000000000..4d4232ef340 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr93931.C @@ -0,0 +1,120 @@ +// PR c++/93931 +// { dg-do run } +// { dg-options "-O2 -std=c++14" } + +extern "C" void abort (); + +void +sink (int &x) +{ + int *volatile p; + p = &x; + (*p)++; +} + +int +foo () +{ + int r = 0; + [&r] () { +#pragma omp parallel for reduction(+ : r) + for (int i = 0; i < 1024; ++i) + r += i; + } (); + return r; +} + +int +bar () +{ + int l = 0; + [&l] () { +#pragma omp parallel for lastprivate (l) + for (int i = 0; i < 1024; ++i) + l = i; + } (); + return l; +} + +void +baz () +{ + int f = 18; + [&f] () { +#pragma omp parallel for firstprivate (f) + for (int i = 0; i < 1024; ++i) + { + sink (f); + f += 3; + sink (f); + if (f != 23) + abort (); + sink (f); + f -= 7; + sink (f); + } + } (); + if (f != 18) + abort (); +} + +int +qux () +{ + int r = 0; + [&] () { +#pragma omp parallel for reduction(+ : r) + for (int i = 0; i < 1024; ++i) + r += i; + } (); + return r; +} + +int +corge () +{ + int l = 0; + [&] () { +#pragma omp parallel for lastprivate (l) + for (int i = 0; i < 1024; ++i) + l = i; + } (); + return l; +} + +void +garply () +{ + int f = 18; + [&] () { +#pragma omp parallel for firstprivate (f) + for (int i = 0; i < 1024; ++i) + { + sink (f); + f += 3; + sink (f); + if (f != 23) + abort (); + sink (f); + f -= 7; + sink (f); + } + } (); + if (f != 18) + abort (); +} + +int +main () +{ + if (foo () != 1024 * 1023 / 2) + abort (); + if (bar () != 1023) + abort (); + baz (); + if (qux () != 1024 * 1023 / 2) + abort (); + if (corge () != 1023) + abort (); + garply (); +} -- 2.20.1
>From 827e5af19a214323c70ee5879dc8f14f4f44ad8d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Thu, 19 Mar 2020 22:56:20 +0100 Subject: [PATCH] c: Fix up cfun->function_end_locus from the C FE [PR94029] On the following testcase we ICE because while DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus = c_parser_peek_token (parser)->location; and similarly DECL_SOURCE_LOCATION (fndecl) is set from some token's location, the end is set as: /* Store the end of the function, so that we get good line number info for the epilogue. */ cfun->function_end_locus = input_location; and the thing is that input_location is only very rarely set in the C FE (the primary spot that changes it is the cb_line_change/fe_file_change). Which means, e.g. for pretty much all C functions that are on a single line, function_start_locus column is > than function_end_locus column, and the testcase even has smaller line in function_end_locus because cb_line_change isn't performed while parsing multi-line arguments of a function-like macro. Attached are two possible fixes to achieve what the C++ FE does, in particular that cfun->function_end_locus is the locus of the closing } of the function. The first one updates input_location when we see a closing } of a compound statement (though any, not just the function body) and thus input_location in the finish_function call is what we need. The second instead propagates the location_t from the parsing of the outermost compound statement (the function body) to finish_function. The second one is this version. 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR gcov-profile/94029 * c-tree.h (finish_function): Add location_t argument defaulted to input_location. * c-parser.c (c_parser_compound_statement): Add endlocp argument and set it to the locus of closing } if non-NULL. (c_parser_compound_statement_nostart): Return locus of closing }. (c_parser_parse_rtl_body): Likewise. (c_parser_declaration_or_fndef): Propagate locus of closing } to finish_function. * c-decl.c (finish_function): Add end_loc argument, use it instead of input_location to set function_end_locus. * gcc.misc-tests/gcov-pr94029.c: New test. --- gcc/c/ChangeLog | 14 ++++++ gcc/c/c-decl.c | 4 +- gcc/c/c-parser.c | 51 ++++++++++++--------- gcc/c/c-tree.h | 2 +- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/gcc.misc-tests/gcov-pr94029.c | 14 ++++++ 6 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr94029.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 1c3ca1b4709..4ff242de551 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,6 +1,20 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-19 Jakub Jelinek <ja...@redhat.com> + + PR gcov-profile/94029 + * c-tree.h (finish_function): Add location_t argument defaulted to + input_location. + * c-parser.c (c_parser_compound_statement): Add endlocp argument and + set it to the locus of closing } if non-NULL. + (c_parser_compound_statement_nostart): Return locus of closing }. + (c_parser_parse_rtl_body): Likewise. + (c_parser_declaration_or_fndef): Propagate locus of closing } to + finish_function. + * c-decl.c (finish_function): Add end_loc argument, use it instead of + input_location to set function_end_locus. + 2020-03-17 Jakub Jelinek <ja...@redhat.com> PR c/94172 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 350e08e22c2..caa2b75ac6d 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -9597,7 +9597,7 @@ temp_pop_parm_decls (void) This is called after parsing the body of the function definition. */ void -finish_function (void) +finish_function (location_t end_loc) { tree fndecl = current_function_decl; @@ -9693,7 +9693,7 @@ finish_function (void) /* Store the end of the function, so that we get good line number info for the epilogue. */ - cfun->function_end_locus = input_location; + cfun->function_end_locus = end_loc; /* Finalize the ELF visibility for the function. */ c_determine_visibility (fndecl); diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index aafe8d1740b..5ffa61935a4 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1402,8 +1402,8 @@ static struct c_expr c_parser_braced_init (c_parser *, tree, bool, static void c_parser_initelt (c_parser *, struct obstack *); static void c_parser_initval (c_parser *, struct c_expr *, struct obstack *); -static tree c_parser_compound_statement (c_parser *); -static void c_parser_compound_statement_nostart (c_parser *); +static tree c_parser_compound_statement (c_parser *, location_t * = NULL); +static location_t c_parser_compound_statement_nostart (c_parser *); static void c_parser_label (c_parser *); static void c_parser_statement (c_parser *, bool *, location_t * = NULL); static void c_parser_statement_after_labels (c_parser *, bool *, @@ -1498,8 +1498,7 @@ static void c_parser_objc_at_synthesize_declaration (c_parser *); static void c_parser_objc_at_dynamic_declaration (c_parser *); static bool c_parser_objc_diagnose_bad_element_prefix (c_parser *, struct c_declspecs *); - -static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass); +static location_t c_parser_parse_rtl_body (c_parser *, char *); /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9). @@ -2323,12 +2322,13 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_finish_oacc_routine (oacc_routine_data, current_function_decl, true); DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus = c_parser_peek_token (parser)->location; + location_t endloc; /* If the definition was marked with __RTL, use the RTL parser now, consuming the function body. */ if (specs->declspec_il == cdil_rtl) { - c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); + endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); /* Normally, store_parm_decls sets next_is_function_body, anticipating a function body. We need a push_scope/pop_scope @@ -2337,7 +2337,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, push_scope (); pop_scope (); - finish_function (); + finish_function (endloc); return; } /* If the definition was marked with __GIMPLE then parse the @@ -2349,9 +2349,11 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass, specs->declspec_il); in_late_binary_op = saved; + struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); + endloc = fun->function_start_locus; } else - fnbody = c_parser_compound_statement (parser); + fnbody = c_parser_compound_statement (parser, &endloc); tree fndecl = current_function_decl; if (nested) { @@ -2362,7 +2364,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ DECL_STATIC_CHAIN (decl) = 1; add_stmt (fnbody); - finish_function (); + finish_function (endloc); c_pop_function_context (); add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); } @@ -2370,7 +2372,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, { if (fnbody) add_stmt (fnbody); - finish_function (); + finish_function (endloc); } /* Get rid of the empty stmt list for GIMPLE/RTL. */ if (specs->declspec_il != cdil_none) @@ -4965,7 +4967,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after, cancellation-point-directive */ static tree -c_parser_compound_statement (c_parser *parser) +c_parser_compound_statement (c_parser *parser, location_t *endlocp) { tree stmt; location_t brace_loc; @@ -4979,7 +4981,9 @@ c_parser_compound_statement (c_parser *parser) return error_mark_node; } stmt = c_begin_compound_stmt (true); - c_parser_compound_statement_nostart (parser); + location_t end_loc = c_parser_compound_statement_nostart (parser); + if (endlocp) + *endlocp = end_loc; return c_end_compound_stmt (brace_loc, stmt, true); } @@ -4988,7 +4992,7 @@ c_parser_compound_statement (c_parser *parser) used for parsing both compound statements and statement expressions (which follow different paths to handling the opening). */ -static void +static location_t c_parser_compound_statement_nostart (c_parser *parser) { bool last_stmt = false; @@ -4997,9 +5001,10 @@ c_parser_compound_statement_nostart (c_parser *parser) location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { - add_debug_begin_stmt (c_parser_peek_token (parser)->location); + location_t endloc = c_parser_peek_token (parser)->location; + add_debug_begin_stmt (endloc); c_parser_consume_token (parser); - return; + return endloc; } mark_valid_location_for_stdc_pragma (true); if (c_parser_next_token_is_keyword (parser, RID_LABEL)) @@ -5040,8 +5045,9 @@ c_parser_compound_statement_nostart (c_parser *parser) { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); c_parser_error (parser, "expected declaration or statement"); + location_t endloc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); - return; + return endloc; } while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) { @@ -5122,7 +5128,7 @@ c_parser_compound_statement_nostart (c_parser *parser) { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); c_parser_error (parser, "expected declaration or statement"); - return; + return c_parser_peek_token (parser)->location; } else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) { @@ -5130,7 +5136,7 @@ c_parser_compound_statement_nostart (c_parser *parser) { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); error_at (loc, "expected %<}%> before %<else%>"); - return; + return c_parser_peek_token (parser)->location; } else { @@ -5152,9 +5158,11 @@ c_parser_compound_statement_nostart (c_parser *parser) } if (last_label) error_at (label_loc, "label at end of compound statement"); + location_t endloc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); /* Restore the value we started with. */ mark_valid_location_for_stdc_pragma (save_valid_for_pragma); + return endloc; } /* Parse all consecutive labels. */ @@ -19920,13 +19928,13 @@ c_parse_file (void) Take ownership of START_WITH_PASS, if non-NULL. */ -void +location_t c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) { if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) { free (start_with_pass); - return; + return c_parser_peek_token (parser)->location; } location_t start_loc = c_parser_peek_token (parser)->location; @@ -19948,7 +19956,7 @@ c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) case CPP_EOF: error_at (start_loc, "no closing brace"); free (start_with_pass); - return; + return c_parser_peek_token (parser)->location; default: break; } @@ -19966,7 +19974,7 @@ c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) if (!read_rtl_function_body_from_file_range (start_loc, end_loc)) { free (start_with_pass); - return; + return end_loc; } /* If a pass name was provided for START_WITH_PASS, run the backend @@ -19974,6 +19982,7 @@ c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) ownership of START_WITH_PASS. */ if (start_with_pass) run_rtl_passes (start_with_pass); + return end_loc; } #include "gt-c-c-parser.h" diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 147a7e867aa..4642d682452 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -562,7 +562,7 @@ extern bool c_check_switch_jump_warnings (struct c_spot_bindings *, location_t, location_t); extern void finish_decl (tree, location_t, tree, tree, tree); extern tree finish_enum (tree, tree, tree); -extern void finish_function (void); +extern void finish_function (location_t = input_location); extern tree finish_struct (location_t, tree, tree, tree, struct c_struct_parse_info *); extern struct c_arg_info *build_arg_info (void); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b15ef6a938..650b8683387 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ Backported from mainline 2020-03-19 Jakub Jelinek <ja...@redhat.com> + PR gcov-profile/94029 + * gcc.misc-tests/gcov-pr94029.c: New test. + PR tree-optimization/94211 * gcc.dg/pr94211.c: New test. diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr94029.c b/gcc/testsuite/gcc.misc-tests/gcov-pr94029.c new file mode 100644 index 00000000000..84d9b9b2749 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcov-pr94029.c @@ -0,0 +1,14 @@ +/* PR gcov-profile/94029 */ +/* { dg-options "-ftest-coverage" } */ +/* { dg-do compile } */ + +#define impl_test(name) void test_##name() { } +impl_test(t1 +) impl_test(t2) + +int main() +{ + return 0; +} + +/* { dg-final { run-gcov remove-gcda gcov-pr94029.c } } */ -- 2.20.1
>From f83c2d2991a762f729741a409a1ac7871733ee40 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Mon, 23 Mar 2020 19:44:58 +0100 Subject: [PATCH] c: Fix up cfun->function_end_locus on invalid function bodies [PR94239] Unfortunately the patch broke +FAIL: gcc.dg/pr20245-1.c (internal compiler error) +FAIL: gcc.dg/pr20245-1.c (test for excess errors) +FAIL: gcc.dg/pr28419.c (internal compiler error) +FAIL: gcc.dg/pr28419.c (test for excess errors) on some targets (and under valgrind on the rest of them). Those functions don't have the opening { and so c_parser_compound_statement returned error_mark_node before initializing *endlocp. So, either we can initialize it in that case too: --- gcc/c/c-parser.c 2020-03-20 22:09:39.659411721 +0100 +++ gcc/c/c-parser.c 2020-03-21 09:36:44.455705261 +0100 @@ -5611,6 +5611,8 @@ c_parser_compound_statement (c_parser *p if we have just prepared to enter a function body. */ stmt = c_begin_compound_stmt (true); c_end_compound_stmt (brace_loc, stmt, true); + if (endlocp) + *endlocp = brace_loc; return error_mark_node; } stmt = c_begin_compound_stmt (true); or perhaps simpler initialize it to the function_start_locus at the beginning and have those functions without { have function_start_locus == function_end_locus like the __GIMPLE functions (where propagating the closing } seemed too difficult). 2020-03-23 Jakub Jelinek <ja...@redhat.com> PR gcov-profile/94029 PR c/94239 * c-parser.c (c_parser_declaration_or_fndef): Initialize endloc to the function_start_locus location. Don't do that afterwards for the __GIMPLE body parsing. --- gcc/c/ChangeLog | 8 ++++++++ gcc/c/c-parser.c | 7 +++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 4ff242de551..1bfcefb875b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,6 +1,14 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-23 Jakub Jelinek <ja...@redhat.com> + + PR gcov-profile/94029 + PR c/94239 + * c-parser.c (c_parser_declaration_or_fndef): Initialize endloc to + the function_start_locus location. Don't do that afterwards for the + __GIMPLE body parsing. + 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR gcov-profile/94029 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 5ffa61935a4..042ae876d1c 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2320,9 +2320,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, omp_declare_simd_clauses); if (oacc_routine_data) c_finish_oacc_routine (oacc_routine_data, current_function_decl, true); + location_t startloc = c_parser_peek_token (parser)->location; DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus - = c_parser_peek_token (parser)->location; - location_t endloc; + = startloc; + location_t endloc = startloc; /* If the definition was marked with __RTL, use the RTL parser now, consuming the function body. */ @@ -2349,8 +2350,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass, specs->declspec_il); in_late_binary_op = saved; - struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); - endloc = fun->function_start_locus; } else fnbody = c_parser_compound_statement (parser, &endloc); -- 2.20.1
>From 4ac9ab60f06020a24e851ebe3eeacc1b3bffa849 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 24 Mar 2020 09:33:17 +0100 Subject: [PATCH] cgraphunit: Avoid code generation differences based on -w/TREE_NO_WARNING [PR94277] The following testcase FAILs with -fcompare-debug, but not because -g vs. -g0 would make a difference, but because the second compilation is done with -w in order not to emit warnings twice and -w seems to affect the *.gkd dump content. This is because TREE_NO_WARNING flag, or warn_unused_function does affect not just whether a warning/pedwarn is printed, but also whether we set TREE_PUBLIC on such decls. The following patch makes sure we set it regardless of anything warning related (TREE_NO_WARNING or warn_unused_function). 2020-03-24 Jakub Jelinek <ja...@redhat.com> PR debug/94277 * cgraphunit.c (check_global_declaration): For DECL_EXTERNAL and non-TREE_PUBLIC non-DECL_ARTIFICIAL FUNCTION_DECLs, set TREE_PUBLIC regardless of whether TREE_NO_WARNING is set on it or whether warn_unused_function is true or not. * gcc.dg/pr94277.c: New test. --- gcc/ChangeLog | 10 ++++++++++ gcc/cgraphunit.c | 12 ++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr94277.c | 11 +++++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr94277.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2cd4b81ebe9..356e7c14e3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,16 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-24 Jakub Jelinek <ja...@redhat.com> + + PR debug/94277 + * cgraphunit.c (check_global_declaration): For DECL_EXTERNAL and + non-TREE_PUBLIC non-DECL_ARTIFICIAL FUNCTION_DECLs, set TREE_PUBLIC + regardless of whether TREE_NO_WARNING is set on it or whether + warn_unused_function is true or not. + +2020-04-07 Jakub Jelinek <ja...@redhat.com> + 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/94211 diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 4a27867b82c..0f933bdc758 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -967,15 +967,15 @@ check_global_declaration (symtab_node *snode) && DECL_INITIAL (decl) == 0 && DECL_EXTERNAL (decl) && ! DECL_ARTIFICIAL (decl) - && ! TREE_NO_WARNING (decl) - && ! TREE_PUBLIC (decl) - && (warn_unused_function - || snode->referred_to_p (/*include_self=*/false))) + && ! TREE_PUBLIC (decl)) { - if (snode->referred_to_p (/*include_self=*/false)) + if (TREE_NO_WARNING (decl)) + ; + else if (snode->referred_to_p (/*include_self=*/false)) pedwarn (input_location, 0, "%q+F used but never defined", decl); else - warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl); + warning (OPT_Wunused_function, "%q+F declared %<static%> but never " + "defined", decl); /* This symbol is effectively an "extern" declaration now. */ TREE_PUBLIC (decl) = 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 650b8683387..a43da5200a2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-24 Jakub Jelinek <ja...@redhat.com> + + PR debug/94277 + * gcc.dg/pr94277.c: New test. + 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR gcov-profile/94029 diff --git a/gcc/testsuite/gcc.dg/pr94277.c b/gcc/testsuite/gcc.dg/pr94277.c new file mode 100644 index 00000000000..dfe38e401a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94277.c @@ -0,0 +1,11 @@ +/* PR debug/94277 */ +/* { dg-do compile } */ +/* { dg-options "-fcompare-debug" } */ + +static void foo (void); /* { dg-warning "used but never defined" } */ + +void +bar (void) +{ + foo (); +} -- 2.20.1
>From 4dcfd4e56b0d22af12750372f3e0b49249b1d473 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 20:57:37 +0200 Subject: [PATCH] if-conv: Fix -fcompare-debug bugs in ifcvt_local_dce [PR94283] The following testcase shows -fcompare-debug bugs in ifcvt_local_dce, where the decisions what statements are needed is based also on debug stmt operands, which is wrong. So, this patch makes sure to never add debug stmt to the worklist, or never add an assign to worklist just because it is used in a debug stmt in another bb. 2020-03-24 Jakub Jelinek <ja...@redhat.com> PR debug/94283 * tree-if-conv.c (ifcvt_local_dce): For gimple debug stmts, just set GF_PLF_2, but don't add them to worklist. Don't add an assigment to worklist or set GF_PLF_2 just because it is used in a debug stmt in another bb. Formatting improvements. * gcc.target/i386/pr94283.c: New test. --- gcc/ChangeLog | 8 ++++++-- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/i386/pr94283.c | 5 +++++ gcc/tree-if-conv.c | 14 ++++++++------ 4 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr94283.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 356e7c14e3b..95b7cc8f7ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,14 +3,18 @@ Backported from mainline 2020-03-24 Jakub Jelinek <ja...@redhat.com> + PR debug/94283 + * tree-if-conv.c (ifcvt_local_dce): For gimple debug stmts, just set + GF_PLF_2, but don't add them to worklist. Don't add an assigment to + worklist or set GF_PLF_2 just because it is used in a debug stmt in + another bb. Formatting improvements. + PR debug/94277 * cgraphunit.c (check_global_declaration): For DECL_EXTERNAL and non-TREE_PUBLIC non-DECL_ARTIFICIAL FUNCTION_DECLs, set TREE_PUBLIC regardless of whether TREE_NO_WARNING is set on it or whether warn_unused_function is true or not. -2020-04-07 Jakub Jelinek <ja...@redhat.com> - 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/94211 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a43da5200a2..30ce191dfef 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ Backported from mainline 2020-03-24 Jakub Jelinek <ja...@redhat.com> + PR debug/94283 + * gcc.target/i386/pr94283.c: New test. + PR debug/94277 * gcc.dg/pr94277.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr94283.c b/gcc/testsuite/gcc.target/i386/pr94283.c new file mode 100644 index 00000000000..4982f7d01d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr94283.c @@ -0,0 +1,5 @@ +/* PR debug/94283 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fcompare-debug -mavx2" } */ + +#include "../../gcc.dg/fold-bopcond-1.c" diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 2780a4b243f..8a6e2415d7c 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -2913,9 +2913,12 @@ ifcvt_local_dce (basic_block bb) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { stmt = gsi_stmt (gsi); - if (gimple_store_p (stmt) - || gimple_assign_load_p (stmt) - || is_gimple_debug (stmt)) + if (is_gimple_debug (stmt)) + { + gimple_set_plf (stmt, GF_PLF_2, true); + continue; + } + if (gimple_store_p (stmt) || gimple_assign_load_p (stmt)) { gimple_set_plf (stmt, GF_PLF_2, true); worklist.safe_push (stmt); @@ -2936,7 +2939,7 @@ ifcvt_local_dce (basic_block bb) FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) { stmt1 = USE_STMT (use_p); - if (gimple_bb (stmt1) != bb) + if (!is_gimple_debug (stmt1) && gimple_bb (stmt1) != bb) { gimple_set_plf (stmt, GF_PLF_2, true); worklist.safe_push (stmt); @@ -2959,8 +2962,7 @@ ifcvt_local_dce (basic_block bb) if (TREE_CODE (use) != SSA_NAME) continue; stmt1 = SSA_NAME_DEF_STMT (use); - if (gimple_bb (stmt1) != bb - || gimple_plf (stmt1, GF_PLF_2)) + if (gimple_bb (stmt1) != bb || gimple_plf (stmt1, GF_PLF_2)) continue; gimple_set_plf (stmt1, GF_PLF_2, true); worklist.safe_push (stmt1); -- 2.20.1
>From 8ea7970c4968517fb73f42bcca40d316adacf215 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Wed, 25 Mar 2020 08:08:04 +0100 Subject: [PATCH] if-conv: Delete dead stmts backwards in ifcvt_local_dce [PR94283] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > > This patch caused: > > > > gcc > > /home/marxin/Programming/gcc/gcc/testsuite/gcc.c-torture/compile/990625-2.c > > -O3 -g -fno-tree-dce -c > > during GIMPLE pass: ifcvt > > /home/marxin/Programming/gcc/gcc/testsuite/gcc.c-torture/compile/990625-2.c: > > In function ‘broken030599’: > > /home/marxin/Programming/gcc/gcc/testsuite/gcc.c-torture/compile/990625-2.c:2:1: > > internal compiler error: Segmentation fault > > Likely > > /* Delete dead statements. */ > gsi = gsi_start_bb (bb); > while (!gsi_end_p (gsi)) > { > > needs to instead work back-to-front for debug stmt adjustment to work Indeed, that seems to work. 2020-03-25 Richard Biener <rguent...@suse.de> Jakub Jelinek <ja...@redhat.com> PR debug/94283 * tree-if-conv.c (ifcvt_local_dce): Delete dead statements backwards. * gcc.dg/pr94283.c: New test. Co-authored-by: Richard Biener <rguent...@suse.de> --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr94283.c | 16 ++++++++++++++++ gcc/tree-if-conv.c | 7 +++++-- 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr94283.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95b7cc8f7ca..e52fcf6707b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,14 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-25 Richard Biener <rguent...@suse.de> + Jakub Jelinek <ja...@redhat.com> + + PR debug/94283 + * tree-if-conv.c (ifcvt_local_dce): Delete dead statements backwards. + +2020-04-07 Jakub Jelinek <ja...@redhat.com> + 2020-03-24 Jakub Jelinek <ja...@redhat.com> PR debug/94283 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 30ce191dfef..a36c7d85fae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-25 Jakub Jelinek <ja...@redhat.com> + + PR debug/94283 + * gcc.dg/pr94283.c: New test. + 2020-03-24 Jakub Jelinek <ja...@redhat.com> PR debug/94283 diff --git a/gcc/testsuite/gcc.dg/pr94283.c b/gcc/testsuite/gcc.dg/pr94283.c new file mode 100644 index 00000000000..ac162d6ac7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94283.c @@ -0,0 +1,16 @@ +/* PR debug/94283 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-tree-dce -fcompare-debug" } */ + +void +foo (int *n) +{ + for (int i = 0; i < 32; i++) + { + int x = 0; + x++; + if (i & 4) + x++; + x++; + } +} diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 8a6e2415d7c..699b48b8124 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -2969,13 +2969,15 @@ ifcvt_local_dce (basic_block bb) } } /* Delete dead statements. */ - gsi = gsi_start_bb (bb); + gsi = gsi_last_bb (bb); while (!gsi_end_p (gsi)) { + gimple_stmt_iterator gsiprev = gsi; + gsi_prev (&gsiprev); stmt = gsi_stmt (gsi); if (gimple_plf (stmt, GF_PLF_2)) { - gsi_next (&gsi); + gsi = gsiprev; continue; } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2985,6 +2987,7 @@ ifcvt_local_dce (basic_block bb) } gsi_remove (&gsi, true); release_defs (stmt); + gsi = gsiprev; } } -- 2.20.1
>From 56407bab53a514ffcd6ac011965cebdc5eb3ef54 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 20:59:37 +0200 Subject: [PATCH] varasm: Fix output_constructor where a RANGE_EXPR index needs to skip some elts [PR94303] The following testcase is miscompiled, because output_constructor doesn't output the initializer correctly. The FE creates {[1...2] = 9} in this case, and we emit .long 9; long 9; .zero 8 instead of the expected .zero 8; .long 9; .long 9. If the CONSTRUCTOR is {[1] = 9, [2] = 9}, output_constructor_regular_field has code to notice that the current location (local->total_bytes) is smaller than the location we want to write to (1*sizeof(elt)) and will call assemble_zeros to skip those. But RANGE_EXPRs are handled by a different function which didn't do this, so for RANGE_EXPRs we emitted them properly only if local->total_bytes was always equal to the location where the RANGE_EXPR needs to start. 2020-03-25 Jakub Jelinek <ja...@redhat.com> PR middle-end/94303 * varasm.c (output_constructor_array_range): If local->index RANGE_EXPR doesn't start at the current location in the constructor, skip needed number of bytes using assemble_zeros or assert we don't go backwards. PR middle-end/94303 * g++.dg/torture/pr94303.C: New test. --- gcc/ChangeLog | 10 ++++++++-- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/torture/pr94303.C | 17 +++++++++++++++++ gcc/varasm.c | 20 ++++++++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr94303.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e52fcf6707b..4e84e4a69fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,14 +1,20 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-25 Jakub Jelinek <ja...@redhat.com> + + PR middle-end/94303 + * varasm.c (output_constructor_array_range): If local->index + RANGE_EXPR doesn't start at the current location in the constructor, + skip needed number of bytes using assemble_zeros or assert we don't + go backwards. + 2020-03-25 Richard Biener <rguent...@suse.de> Jakub Jelinek <ja...@redhat.com> PR debug/94283 * tree-if-conv.c (ifcvt_local_dce): Delete dead statements backwards. -2020-04-07 Jakub Jelinek <ja...@redhat.com> - 2020-03-24 Jakub Jelinek <ja...@redhat.com> PR debug/94283 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a36c7d85fae..d0c4d510280 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ Backported from mainline 2020-03-25 Jakub Jelinek <ja...@redhat.com> + PR middle-end/94303 + * g++.dg/torture/pr94303.C: New test. + PR debug/94283 * gcc.dg/pr94283.c: New test. diff --git a/gcc/testsuite/g++.dg/torture/pr94303.C b/gcc/testsuite/g++.dg/torture/pr94303.C new file mode 100644 index 00000000000..45b90a2249d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr94303.C @@ -0,0 +1,17 @@ +// PR middle-end/94303 +// { dg-do run } + +struct A { + int d = 9; + A () = default; + A (int x) : d(x) {} + void foo () { if (d < 1) __builtin_abort (); } +}; + +A a[3] = { 1 }; + +int +main () +{ + a[2].foo (); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 8f006dcff67..8d87e28cc7c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5136,6 +5136,26 @@ struct oc_local_state { static void output_constructor_array_range (oc_local_state *local) { + /* Perform the index calculation in modulo arithmetic but + sign-extend the result because Ada has negative DECL_FIELD_OFFSETs + but we are using an unsigned sizetype. */ + unsigned prec = TYPE_PRECISION (sizetype); + offset_int idx = wi::sext (wi::to_offset (TREE_OPERAND (local->index, 0)) + - wi::to_offset (local->min_index), prec); + tree valtype = TREE_TYPE (local->val); + HOST_WIDE_INT fieldpos + = (idx * wi::to_offset (TYPE_SIZE_UNIT (valtype))).to_short_addr (); + + /* Advance to offset of this element. */ + if (fieldpos > local->total_bytes) + { + assemble_zeros (fieldpos - local->total_bytes); + local->total_bytes = fieldpos; + } + else + /* Must not go backwards. */ + gcc_assert (fieldpos == local->total_bytes); + unsigned HOST_WIDE_INT fieldsize = int_size_in_bytes (TREE_TYPE (local->type)); -- 2.20.1
>From aa9c08ef97f4df1ebb1fc8d72f2e7f9f8c1045c2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Sat, 28 Mar 2020 10:21:52 +0100 Subject: [PATCH] reassoc: Fix -fcompare-debug bug in reassociate_bb [PR94329] The following testcase FAILs with -fcompare-debug, because reassociate_bb mishandles the case when the last stmt in a bb has zero uses. In that case reassoc_remove_stmt (like gsi_remove) moves the iterator to the next stmt, i.e. gsi_end_p is true, which means the code sets the iterator back to gsi_last_bb. The problem is that the for loop does gsi_prev on that before handling the next statement, which means the former penultimate stmt, now last one, is not processed by reassociate_bb. Now, with -g, if there is at least one debug stmt at the end of the bb, reassoc_remove_stmt moves the iterator to that following debug stmt and we just do gsi_prev and continue with the former penultimate non-debug stmt, now last non-debug stmt. The following patch fixes that by not doing the gsi_prev in this case; there are too many continue; cases, so I didn't want to copy over the gsi_prev to all of them, so this patch uses a bool for that instead. The second gsi_end_p check isn't needed anymore, because when we don't do the undesirable gsi_prev after gsi = gsi_last_bb, the loop !gsi_end_p (gsi) condition will catch the removal of the very last stmt from a bb. 2020-03-28 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/94329 * tree-ssa-reassoc.c (reassociate_bb): When calling reassoc_remove_stmt on the last stmt in a bb, make sure gsi_prev isn't done immediately after gsi_last_bb. * gfortran.dg/pr94329.f90: New test. --- gcc/ChangeLog | 9 +++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr94329.f90 | 12 ++++++++++++ gcc/tree-ssa-reassoc.c | 14 +++++++------- 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr94329.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e84e4a69fa..68c2acdc576 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,15 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-28 Jakub Jelinek <ja...@redhat.com> + + PR tree-optimization/94329 + * tree-ssa-reassoc.c (reassociate_bb): When calling reassoc_remove_stmt + on the last stmt in a bb, make sure gsi_prev isn't done immediately + after gsi_last_bb. + +2020-04-07 Jakub Jelinek <ja...@redhat.com> + 2020-03-25 Jakub Jelinek <ja...@redhat.com> PR middle-end/94303 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0c4d510280..9d2a2a49791 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-28 Jakub Jelinek <ja...@redhat.com> + + PR tree-optimization/94329 + * gfortran.dg/pr94329.f90: New test. + 2020-03-25 Jakub Jelinek <ja...@redhat.com> PR middle-end/94303 diff --git a/gcc/testsuite/gfortran.dg/pr94329.f90 b/gcc/testsuite/gfortran.dg/pr94329.f90 new file mode 100644 index 00000000000..9efcf4b6524 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr94329.f90 @@ -0,0 +1,12 @@ +! PR tree-optimization/94329 +! { dg-do compile } +! { dg-options "-O1 -fno-tree-loop-optimize -fwrapv -fcompare-debug" } + +subroutine pr94329 (s, t) + real :: s, t(:,:) + do i = 1,3 + do j = 1,3 + s = t(i,j) + end do + end do +end diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 6794fbde29e..9bb04d65387 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -5872,8 +5872,11 @@ reassociate_bb (basic_block bb) if (stmt && !gimple_visited_p (stmt)) cfg_cleanup_needed |= maybe_optimize_range_tests (stmt); - for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) + bool do_prev = false; + for (gsi = gsi_last_bb (bb); + !gsi_end_p (gsi); do_prev ? gsi_prev (&gsi) : (void) 0) { + do_prev = true; stmt = gsi_stmt (gsi); if (is_gimple_assign (stmt) @@ -5899,15 +5902,12 @@ reassociate_bb (basic_block bb) release_defs (stmt); /* We might end up removing the last stmt above which places the iterator to the end of the sequence. - Reset it to the last stmt in this case which might - be the end of the sequence as well if we removed - the last statement of the sequence. In which case - we need to bail out. */ + Reset it to the last stmt in this case and make sure + we don't do gsi_prev in that case. */ if (gsi_end_p (gsi)) { gsi = gsi_last_bb (bb); - if (gsi_end_p (gsi)) - break; + do_prev = false; } } continue; -- 2.20.1
>From 57e276f3e304ef92483763ee1028e5b3e1345e0f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 21:00:28 +0200 Subject: [PATCH] Fix vextract* masked patterns [PR93069] The AVX512F documentation clearly states that in instructions where the destination is a memory only merging-masking is possible, not zero-masking, and the assembler enforces that. The testcase in this patch fails to assemble because of Error: unsupported masking for `vextracti32x8' on vextracti32x8 $0x0, %zmm1, -64(%rsp){%k1}{z} For the vector extraction patterns, we apparently have 7 *_maskm patterns that only accept memory destinations and rtx_equal_p merge-masking source for it, 7 *<mask_name> corresponding patterns that allow memory destination only for the non-masked cases (through <store_mask_constraint>), then 2 *<mask_name> patterns (lo ssehalf V16FI and lo ssehalf VI8F_256 ones) which do allow memory destination even for masked cases and are the cause of the testsuite failure, because we must not allow C constraint if the destination is m, and finally one pair of patterns (separate * and *_mask, hi ssehalf VI4F_256), which has another issue (for which I don't have a testcase though), where if it would match zero-masking with register destination, it wouldn't emit the needed {z} into assembly. The attached patch fixes those 3 issues only, perhaps more suitable for backporting. 2020-03-30 Jakub Jelinek <ja...@redhat.com> PR target/93069 * config/i386/sse.md (vec_extract_lo_<mode><mask_name>): Use <store_mask_constraint> instead of m in output operand constraint. (vec_extract_hi_<mode><mask_name>): Use <mask_operand2> instead of %{%3%}. * gcc.target/i386/avx512vl-pr93069.c: New test. * gcc.dg/vect/pr93069.c: New test. --- gcc/ChangeLog | 10 ++++++++-- gcc/config/i386/sse.md | 8 +++++--- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/vect/pr93069.c | 10 ++++++++++ gcc/testsuite/gcc.target/i386/avx512vl-pr93069.c | 12 ++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr93069.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-pr93069.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68c2acdc576..ed82d0694b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,14 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-30 Jakub Jelinek <ja...@redhat.com> + + PR target/93069 + * config/i386/sse.md (vec_extract_lo_<mode><mask_name>): Use + <store_mask_constraint> instead of m in output operand constraint. + (vec_extract_hi_<mode><mask_name>): Use <mask_operand2> instead of + %{%3%}. + 2020-03-28 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/94329 @@ -8,8 +16,6 @@ on the last stmt in a bb, make sure gsi_prev isn't done immediately after gsi_last_bb. -2020-04-07 Jakub Jelinek <ja...@redhat.com> - 2020-03-25 Jakub Jelinek <ja...@redhat.com> PR middle-end/94303 diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 18cc39ae521..a8b879bcdc4 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -8288,7 +8288,8 @@ }) (define_insn "vec_extract_lo_<mode><mask_name>" - [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=v,v,m") + [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" + "=v,v,<store_mask_constraint>") (vec_select:<ssehalfvecmode> (match_operand:V16FI 1 "<store_mask_predicate>" "v,<store_mask_constraint>,v") @@ -8345,7 +8346,8 @@ }) (define_insn "vec_extract_lo_<mode><mask_name>" - [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=v,v,m") + [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" + "=v,v,<store_mask_constraint>") (vec_select:<ssehalfvecmode> (match_operand:VI8F_256 1 "<store_mask_predicate>" "v,<store_mask_constraint>,v") @@ -8355,7 +8357,7 @@ && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))" { if (<mask_applied>) - return "vextract<shuffletype>64x2\t{$0x0, %1, %0%{%3%}|%0%{%3%}, %1, 0x0}"; + return "vextract<shuffletype>64x2\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}"; else return "#"; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9d2a2a49791..4a1b7fd3e8a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,12 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-30 Jakub Jelinek <ja...@redhat.com> + + PR target/93069 + * gcc.target/i386/avx512vl-pr93069.c: New test. + * gcc.dg/vect/pr93069.c: New test. + 2020-03-28 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/94329 diff --git a/gcc/testsuite/gcc.dg/vect/pr93069.c b/gcc/testsuite/gcc.dg/vect/pr93069.c new file mode 100644 index 00000000000..45c740dbe9e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr93069.c @@ -0,0 +1,10 @@ +/* PR target/93069 */ +/* { dg-do assemble { target vect_simd_clones } } */ +/* { dg-options "-O2 -fopenmp-simd" } */ + +#pragma omp declare simd +int +foo (int x, int y) +{ + return x == 0 ? x : y; +} diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-pr93069.c b/gcc/testsuite/gcc.target/i386/avx512vl-pr93069.c new file mode 100644 index 00000000000..b38b5ad32bb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-pr93069.c @@ -0,0 +1,12 @@ +/* PR target/93069 */ +/* { dg-do assemble { target vect_simd_clones } } */ +/* { dg-options "-O2 -fopenmp-simd -mtune=skylake-avx512" } */ +/* { dg-additional-options "-mavx512vl" { target avx512vl } } */ +/* { dg-additional-options "-mavx512dq" { target avx512dq } } */ + +#pragma omp declare simd +int +foo (int x, int y) +{ + return x == 0 ? x : y; +} -- 2.20.1
>From a6bf0e5fb11cc0e231ac016a1995caaa93fdc4a0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Mon, 30 Mar 2020 22:55:36 +0200 Subject: [PATCH] c++: Fix handling of internal fn calls in statement expressions [PR94385] The following testcase ICEs, because the FE when processing the statement expression changes the .VEC_CONVERT internal fn CALL_EXPR into .PHI call. That is because the internal fn call is recorded in the base.u.ifn field, which overlaps base.u.bits.lang_flag_1 which is used for STMT_IS_FULL_EXPR_P, so this essentially does ifn |= 2 on little-endian. STMT_IS_FULL_EXPR_P bit is used in: cp-gimplify.c- if (STATEMENT_CODE_P (code)) cp-gimplify.c- { cp-gimplify.c- saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); cp-gimplify.c- current_stmt_tree ()->stmts_are_full_exprs_p cp-gimplify.c: = STMT_IS_FULL_EXPR_P (*expr_p); cp-gimplify.c- } and pt.c- if (STATEMENT_CODE_P (TREE_CODE (t))) pt.c: current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t); so besides being wrong on some other codes, it actually isn't beneficial at all to set it on anything else, so the following patch restricts it to trees with STATEMENT_CODE_P TREE_CODE. 2020-03-30 Jakub Jelinek <ja...@redhat.com> PR c++/94385 * semantics.c (add_stmt): Only set STMT_IS_FULL_EXPR_P on trees with STATEMENT_CODE_P code. * c-c++-common/pr94385.c: New test. --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/semantics.c | 3 ++- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/c-c++-common/pr94385.c | 12 ++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/c-c++-common/pr94385.c diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d11c4c62ddf..324e133a125 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,12 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-30 Jakub Jelinek <ja...@redhat.com> + + PR c++/94385 + * semantics.c (add_stmt): Only set STMT_IS_FULL_EXPR_P on trees with + STATEMENT_CODE_P code. + 2020-03-19 Jakub Jelinek <ja...@redhat.com> PR c++/93931 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4bfb5d15293..559e38dbc14 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -380,7 +380,8 @@ add_stmt (tree t) /* When we expand a statement-tree, we must know whether or not the statements are full-expressions. We record that fact here. */ - STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); + if (STATEMENT_CODE_P (TREE_CODE (t))) + STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); } if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4a1b7fd3e8a..c32e6a86b8b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ Backported from mainline 2020-03-30 Jakub Jelinek <ja...@redhat.com> + PR c++/94385 + * c-c++-common/pr94385.c: New test. + PR target/93069 * gcc.target/i386/avx512vl-pr93069.c: New test. * gcc.dg/vect/pr93069.c: New test. diff --git a/gcc/testsuite/c-c++-common/pr94385.c b/gcc/testsuite/c-c++-common/pr94385.c new file mode 100644 index 00000000000..0611921295c --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr94385.c @@ -0,0 +1,12 @@ +/* PR c++/94385 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef int V __attribute__((__vector_size__(16))); +typedef float W __attribute__((__vector_size__(16))); + +void +foo (W *x, V *y) +{ + *y = (({ __builtin_convertvector (*x, V); })); +} -- 2.20.1
>From 8f99f9e6ccec167a5ba67dcc08e6c14948595b82 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 31 Mar 2020 11:06:43 +0200 Subject: [PATCH] fold-const: Fix division folding with vector operands [PR94412] The following testcase is miscompiled since 4.9, we treat unsigned vector types as if they were signed and "optimize" negations across it. 2020-03-31 Marc Glisse <marc.gli...@inria.fr> Jakub Jelinek <ja...@redhat.com> PR middle-end/94412 * fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P. * gcc.c-torture/execute/pr94412.c: New test. Co-authored-by: Marc Glisse <marc.gli...@inria.fr> --- gcc/ChangeLog | 9 ++++++ gcc/fold-const.c | 8 +++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.c-torture/execute/pr94412.c | 28 +++++++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94412.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ed82d0694b8..e3e5d86275b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,15 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-31 Marc Glisse <marc.gli...@inria.fr> + Jakub Jelinek <ja...@redhat.com> + + PR middle-end/94412 + * fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use + ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P. + +2020-04-07 Jakub Jelinek <ja...@redhat.com> + 2020-03-30 Jakub Jelinek <ja...@redhat.com> PR target/93069 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c717f24501e..64273c1c6bc 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10376,11 +10376,11 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, /* Convert -A / -B to A / B when the type is signed and overflow is undefined. */ - if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) + if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) && TREE_CODE (op0) == NEGATE_EXPR && negate_expr_p (op1)) { - if (INTEGRAL_TYPE_P (type)) + if (ANY_INTEGRAL_TYPE_P (type)) fold_overflow_warning (("assuming signed overflow does not occur " "when distributing negation across " "division"), @@ -10390,11 +10390,11 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, TREE_OPERAND (arg0, 0)), negate_expr (op1)); } - if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) + if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) && TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (op0)) { - if (INTEGRAL_TYPE_P (type)) + if (ANY_INTEGRAL_TYPE_P (type)) fold_overflow_warning (("assuming signed overflow does not occur " "when distributing negation across " "division"), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c32e6a86b8b..0c09c9ee12f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-03-31 Jakub Jelinek <ja...@redhat.com> + + PR middle-end/94412 + * gcc.c-torture/execute/pr94412.c: New test. + 2020-03-30 Jakub Jelinek <ja...@redhat.com> PR c++/94385 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94412.c b/gcc/testsuite/gcc.c-torture/execute/pr94412.c new file mode 100644 index 00000000000..6c806bbd90c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr94412.c @@ -0,0 +1,28 @@ +/* PR middle-end/94412 */ + +typedef unsigned V __attribute__ ((__vector_size__ (sizeof (unsigned) * 2))); + +void +foo (V *v, V *w) +{ + *w = -*v / 11; +} + +void +bar (V *v, V *w) +{ + *w = -18 / -*v; +} + +int +main () +{ + V a = (V) { 1, 0 }; + V b = (V) { 3, __INT_MAX__ }; + V c, d; + foo (&a, &c); + bar (&b, &d); + if (c[0] != -1U / 11 || c[1] != 0 || d[0] != 0 || d[1] != -18U / -__INT_MAX__) + __builtin_abort (); + return 0; +} -- 2.20.1
>From 4486a537f14bc3b05ac552c3cbe18e540e397ed7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 21:01:06 +0200 Subject: [PATCH] objsz: Don't call replace_uses_by on SSA_NAME_OCCURS_IN_ABNORMAL_PHI [PR94423] The following testcase ICEs because the objsz pass calls replace_uses_by on SSA_NAME_OCCURS_IN_ABNORMAL_PHI SSA_NAME. The following patch instead of that calls replace_call_with_value, which will turn it into xyz_123(ab) = 234; 2020-04-01 Jakub Jelinek <ja...@redhat.com> PR middle-end/94423 * tree-object-size.c (pass_object_sizes::execute): Don't call replace_uses_by for SSA_NAME_OCCURS_IN_ABNORMAL_PHI lhs, instead call replace_call_with_value. * gcc.dg/ubsan/pr94423.c: New test. --- gcc/ChangeLog | 9 +++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/ubsan/pr94423.c | 17 +++++++++++++++++ gcc/tree-object-size.c | 5 ++++- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ubsan/pr94423.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3e5d86275b..4cb05e922e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,13 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-01 Jakub Jelinek <ja...@redhat.com> + + PR middle-end/94423 + * tree-object-size.c (pass_object_sizes::execute): Don't call + replace_uses_by for SSA_NAME_OCCURS_IN_ABNORMAL_PHI lhs, instead + call replace_call_with_value. + 2020-03-31 Marc Glisse <marc.gli...@inria.fr> Jakub Jelinek <ja...@redhat.com> @@ -8,8 +15,6 @@ * fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P. -2020-04-07 Jakub Jelinek <ja...@redhat.com> - 2020-03-30 Jakub Jelinek <ja...@redhat.com> PR target/93069 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c09c9ee12f..78f4b5119d8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-01 Jakub Jelinek <ja...@redhat.com> + + PR middle-end/94423 + * gcc.dg/ubsan/pr94423.c: New test. + 2020-03-31 Jakub Jelinek <ja...@redhat.com> PR middle-end/94412 diff --git a/gcc/testsuite/gcc.dg/ubsan/pr94423.c b/gcc/testsuite/gcc.dg/ubsan/pr94423.c new file mode 100644 index 00000000000..76f831f26e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/pr94423.c @@ -0,0 +1,17 @@ +/* PR middle-end/94423 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsanitize=object-size" } */ + +void foo (void); +typedef struct { long buf[22]; } jmp_buf[1]; +extern int sigsetjmp (jmp_buf, int) __attribute__ ((__nothrow__)); +jmp_buf buf; + +void +bar (int *c) +{ + while (*c) + foo (); + while (*c) + sigsetjmp (buf, 0); +} diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 25c5ced57b7..6450cae371d 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -1369,7 +1369,10 @@ pass_object_sizes::execute (function *fun) } /* Propagate into all uses and fold those stmts. */ - replace_uses_by (lhs, result); + if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) + replace_uses_by (lhs, result); + else + replace_call_with_value (&i, result); } } -- 2.20.1
>From dbff1829843180dc2a6c8ce5ce7883146b5cf083 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Fri, 3 Apr 2020 19:44:42 +0200 Subject: [PATCH] i386: Fix vph{add,subs?}[wd] 256-bit AVX2 RTL patterns [PR94460] The following testcase is miscompiled, because the AVX2 patterns don't describe correctly what the insn does. E.g. vphaddd with %ymm* operands (the second pattern) instruction as per: https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_hadd_epi32&expand=2941 does { a0+a1, a2+a3, b0+b1, b2+b3, a4+a5, a6+a7, b4+b5, b6+b7 } but our RTL pattern did { a0+a1, a2+a3, a4+a5, a6+a7, b0+b1, b2+b3, b4+b5, b6+b7 } where the first and last 64 bits are the same and two middle 64 bits swapped. https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_hadd_epi16&expand=2939 similarly, insn does: { a0+a1, a2+a3, a4+a5, a6+a7, b0+b1, b2+b3, b4+b5, b6+b7, a8+a9, a10+a11, a12+a13, a14+a15, b8+b9, b10+b11, b12+b13, b14+b15 } but RTL pattern did { a0+a1, a2+a3, a4+a5, a6+a7, a8+a9, a10+a11, a12+a13, a14+a15, b0+b1, b2+b3, b4+b5, b6+b7, b8+b9, b10+b11, b12+b13, b14+b15 } again, first and last 64 bits are the same and the two middle 64 bits swapped. 2020-04-03 Jakub Jelinek <ja...@redhat.com> PR target/94460 * config/i386/sse.md (avx2_ph<plusminus_mnemonic>wv16hi3, avx2_ph<plusminus_mnemonic>dv8si3): Fix up RTL pattern to do second half of first lane from first lane of second operand and first half of second lane from second lane of first operand. * gcc.target/i386/avx2-pr94460.c: New test. --- gcc/ChangeLog | 10 ++++ gcc/config/i386/sse.md | 52 ++++++++++---------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/i386/avx2-pr94460.c | 31 ++++++++++++ 4 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx2-pr94460.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4cb05e922e9..022d71e9e73 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,16 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-03 Jakub Jelinek <ja...@redhat.com> + + PR target/94460 + * config/i386/sse.md (avx2_ph<plusminus_mnemonic>wv16hi3, + avx2_ph<plusminus_mnemonic>dv8si3): Fix up RTL pattern to do + second half of first lane from first lane of second operand and + first half of second lane from second lane of first operand. + +2020-04-07 Jakub Jelinek <ja...@redhat.com> + 2020-04-01 Jakub Jelinek <ja...@redhat.com> PR middle-end/94423 diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index a8b879bcdc4..618fc231c40 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -15540,22 +15540,6 @@ (ssse3_plusminus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 6)])) (vec_select:HI (match_dup 1) (parallel [(const_int 7)]))))) - (vec_concat:V4HI - (vec_concat:V2HI - (ssse3_plusminus:HI - (vec_select:HI (match_dup 1) (parallel [(const_int 8)])) - (vec_select:HI (match_dup 1) (parallel [(const_int 9)]))) - (ssse3_plusminus:HI - (vec_select:HI (match_dup 1) (parallel [(const_int 10)])) - (vec_select:HI (match_dup 1) (parallel [(const_int 11)])))) - (vec_concat:V2HI - (ssse3_plusminus:HI - (vec_select:HI (match_dup 1) (parallel [(const_int 12)])) - (vec_select:HI (match_dup 1) (parallel [(const_int 13)]))) - (ssse3_plusminus:HI - (vec_select:HI (match_dup 1) (parallel [(const_int 14)])) - (vec_select:HI (match_dup 1) (parallel [(const_int 15)])))))) - (vec_concat:V8HI (vec_concat:V4HI (vec_concat:V2HI (ssse3_plusminus:HI @@ -15572,7 +15556,23 @@ (vec_select:HI (match_dup 2) (parallel [(const_int 5)]))) (ssse3_plusminus:HI (vec_select:HI (match_dup 2) (parallel [(const_int 6)])) - (vec_select:HI (match_dup 2) (parallel [(const_int 7)]))))) + (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))) + (vec_concat:V8HI + (vec_concat:V4HI + (vec_concat:V2HI + (ssse3_plusminus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 8)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 9)]))) + (ssse3_plusminus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 10)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 11)])))) + (vec_concat:V2HI + (ssse3_plusminus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 12)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 13)]))) + (ssse3_plusminus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 14)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 15)]))))) (vec_concat:V4HI (vec_concat:V2HI (ssse3_plusminus:HI @@ -15686,14 +15686,6 @@ (plusminus:SI (vec_select:SI (match_dup 1) (parallel [(const_int 2)])) (vec_select:SI (match_dup 1) (parallel [(const_int 3)])))) - (vec_concat:V2SI - (plusminus:SI - (vec_select:SI (match_dup 1) (parallel [(const_int 4)])) - (vec_select:SI (match_dup 1) (parallel [(const_int 5)]))) - (plusminus:SI - (vec_select:SI (match_dup 1) (parallel [(const_int 6)])) - (vec_select:SI (match_dup 1) (parallel [(const_int 7)]))))) - (vec_concat:V4SI (vec_concat:V2SI (plusminus:SI (vec_select:SI @@ -15702,7 +15694,15 @@ (vec_select:SI (match_dup 2) (parallel [(const_int 1)]))) (plusminus:SI (vec_select:SI (match_dup 2) (parallel [(const_int 2)])) - (vec_select:SI (match_dup 2) (parallel [(const_int 3)])))) + (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))) + (vec_concat:V4SI + (vec_concat:V2SI + (plusminus:SI + (vec_select:SI (match_dup 1) (parallel [(const_int 4)])) + (vec_select:SI (match_dup 1) (parallel [(const_int 5)]))) + (plusminus:SI + (vec_select:SI (match_dup 1) (parallel [(const_int 6)])) + (vec_select:SI (match_dup 1) (parallel [(const_int 7)])))) (vec_concat:V2SI (plusminus:SI (vec_select:SI (match_dup 2) (parallel [(const_int 4)])) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 78f4b5119d8..963a1af39be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-03 Jakub Jelinek <ja...@redhat.com> + + PR target/94460 + * gcc.target/i386/avx2-pr94460.c: New test. + 2020-04-01 Jakub Jelinek <ja...@redhat.com> PR middle-end/94423 diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr94460.c b/gcc/testsuite/gcc.target/i386/avx2-pr94460.c new file mode 100644 index 00000000000..75b7a7bf313 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-pr94460.c @@ -0,0 +1,31 @@ +/* PR target/94460 */ +/* { dg-do run { target { avx2 && int128 } } } */ +/* { dg-options "-O2 -mavx2" } */ + +#include <x86intrin.h> +#include "avx2-check.h" + +typedef __int128 v2ti __attribute__ ((__vector_size__ (32))); + +static inline v2ti +foo (__v16hi b) +{ + return (v2ti) _mm256_hsub_epi16 ((__m256i) b, (__m256i) b); +} + +static inline v2ti +bar (__v8si b) +{ + return (v2ti) _mm256_hsub_epi32 ((__m256i) b, (__m256i) b); +} + +static void +avx2_test (void) +{ + v2ti x = foo ((__v16hi) { 1 }); + if (x[0] != ((__int128)1 << 64 | 1) || x[1] != 0) + abort (); + x = bar ((__v8si) { 1 }); + if (x[0] != ((__int128)1 << 64 | 1) || x[1] != 0) + abort (); +} -- 2.20.1
>From d1371dbe12214895cda0b13bfc6ff0ed9cbce15d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Sat, 4 Apr 2020 00:35:41 +0200 Subject: [PATCH] openmp: Fix ICE on #pragma omp parallel master in template [PR94477] The following testcase ICEs, because for parallel combined with some other construct we initialize the omp_parallel_combined_clauses pointer and expect the construct combined with it to clear it after it no longer needs it, but OMP_MASTER didn't do that. 2020-04-04 Jakub Jelinek <ja...@redhat.com> PR c++/94477 * pt.c (tsubst_expr) <case OMP_MASTER>: Clear omp_parallel_combined_clauses. * g++.dg/gomp/pr94477.C: New test. --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 4 +++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/gomp/pr94477.C | 18 ++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/gomp/pr94477.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 324e133a125..ae33956b867 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,12 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-04 Jakub Jelinek <ja...@redhat.com> + + PR c++/94477 + * pt.c (tsubst_expr) <case OMP_MASTER>: Clear + omp_parallel_combined_clauses. + 2020-03-30 Jakub Jelinek <ja...@redhat.com> PR c++/94385 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bc572ac51fb..7f51f70c71a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17882,8 +17882,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, add_stmt (t); break; - case OMP_SECTION: case OMP_MASTER: + omp_parallel_combined_clauses = NULL; + /* FALLTHRU */ + case OMP_SECTION: stmt = push_stmt_list (); RECUR (OMP_BODY (t)); stmt = pop_stmt_list (stmt); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 963a1af39be..306380907ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-04 Jakub Jelinek <ja...@redhat.com> + + PR c++/94477 + * g++.dg/gomp/pr94477.C: New test. + 2020-04-03 Jakub Jelinek <ja...@redhat.com> PR target/94460 diff --git a/gcc/testsuite/g++.dg/gomp/pr94477.C b/gcc/testsuite/g++.dg/gomp/pr94477.C new file mode 100644 index 00000000000..e7fdc23d6d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr94477.C @@ -0,0 +1,18 @@ +// PR c++/94477 +// { dg-do compile } + +void foo (); + +template <int> +void +bar () +{ + #pragma omp parallel master + foo (); +} + +void +baz () +{ + bar<0> (); +} -- 2.20.1
>From b5039b7259e64a92f5c077fe4d023556d6b12550 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 21:01:40 +0200 Subject: [PATCH] debug: Improve debug info of c++14 deduced return type [PR94459] On the following testcase, in gdb ptype S<long>::m1 prints long as return type, but all the other methods show void instead. PR53756 added code to add_type_attribute if the return type is auto/decltype(auto), but we actually should look through references, pointers and qualifiers. Haven't included there DW_TAG_atomic_type, because I think at least ATM one can't use that in C++. Not sure about DW_TAG_array_type or what else could be deduced. > http://eel.is/c++draft/dcl.spec.auto#3 says it has to appear as a > decl-specifier. > > http://eel.is/c++draft/temp.deduct.type#8 lists the forms where a template > argument can be deduced. > > Looks like you are missing arrays, pointers to members, and function return > types. 2020-04-04 Hannes Domani <ssb...@yahoo.de> Jakub Jelinek <ja...@redhat.com> PR debug/94459 * dwarf2out.c (gen_subprogram_die): Look through references, pointers, arrays, pointer-to-members, function types and qualifiers when checking if in-class DIE had an 'auto' or 'decltype(auto)' return type to emit type again on definition. * g++.dg/debug/pr94459.C: New test. Co-Authored-By: Hannes Domani <ssb...@yahoo.de> --- gcc/ChangeLog | 11 +++++- gcc/dwarf2out.c | 15 ++++++- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/debug/pr94459.C | 58 ++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/debug/pr94459.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 022d71e9e73..4f3708cb39b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,15 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-04 Hannes Domani <ssb...@yahoo.de> + Jakub Jelinek <ja...@redhat.com> + + PR debug/94459 + * dwarf2out.c (gen_subprogram_die): Look through references, pointers, + arrays, pointer-to-members, function types and qualifiers when + checking if in-class DIE had an 'auto' or 'decltype(auto)' return type + to emit type again on definition. + 2020-04-03 Jakub Jelinek <ja...@redhat.com> PR target/94460 @@ -9,8 +18,6 @@ second half of first lane from first lane of second operand and first half of second lane from second lane of first operand. -2020-04-07 Jakub Jelinek <ja...@redhat.com> - 2020-04-01 Jakub Jelinek <ja...@redhat.com> PR middle-end/94423 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 30c4c7007ee..9ea109b3b61 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -23011,11 +23011,22 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) != (unsigned) s.column)) add_AT_unsigned (subr_die, DW_AT_decl_column, s.column); - /* If the prototype had an 'auto' or 'decltype(auto)' return type, - emit the real type on the definition die. */ + /* If the prototype had an 'auto' or 'decltype(auto)' in + the return type, emit the real type on the definition die. */ if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE) { dw_die_ref die = get_AT_ref (old_die, DW_AT_type); + while (die + && (die->die_tag == DW_TAG_reference_type + || die->die_tag == DW_TAG_rvalue_reference_type + || die->die_tag == DW_TAG_pointer_type + || die->die_tag == DW_TAG_const_type + || die->die_tag == DW_TAG_volatile_type + || die->die_tag == DW_TAG_restrict_type + || die->die_tag == DW_TAG_array_type + || die->die_tag == DW_TAG_ptr_to_member_type + || die->die_tag == DW_TAG_subroutine_type)) + die = get_AT_ref (die, DW_AT_type); if (die == auto_die || die == decltype_auto_die) add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), TYPE_UNQUALIFIED, false, context_die); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 306380907ee..5561d7f2ee8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,12 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline + 2020-04-04 Hannes Domani <ssb...@yahoo.de> + Jakub Jelinek <ja...@redhat.com> + + PR debug/94459 + * g++.dg/debug/pr94459.C: New test. + 2020-04-04 Jakub Jelinek <ja...@redhat.com> PR c++/94477 diff --git a/gcc/testsuite/g++.dg/debug/pr94459.C b/gcc/testsuite/g++.dg/debug/pr94459.C new file mode 100644 index 00000000000..ebc0cf45cc6 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/pr94459.C @@ -0,0 +1,58 @@ +// PR debug/94459 +// { dg-do compile { target c++14 } } +// { dg-options "-g -dA" } + +template <typename T> +struct S +{ + T v; + T w[2]; + S () : v (0), w { 0, 0 } {} + static auto baz () { return (T) 0; } + auto m1 () { return v; } + auto &m2 () { return v; } + auto &&m3 () { return (T&&)v; } + const auto m4 () { return v; } + const auto &m5 () { return v; } + const auto &&m6 () { return (T&&)v; } + volatile auto m7 () { return v; } + volatile auto &m8 () { return v; } + volatile auto &&m9 () { return (T&&)v; } + volatile const auto m10 () { return v; } + volatile const auto &m11 () { return v; } + volatile const auto &&m12 () { return (T&&)v; } + const volatile auto m13 () { return v; } + const volatile auto &m14 () { return v; } + const volatile auto &&m15 () { return (T&&)v; } +#ifndef __STRICT_ANSI__ + __restrict const volatile auto &&m16 () { return (T&&)v; } + const __restrict auto &m17 () { return v; } +#endif + auto *m18 () { return &v; } + auto (S::* (m19 ())) () { return &S::m1; } + auto (S::* (m20 ())) { return &S::v; } + auto (*m21 ()) () { return S::baz; } +}; + +S<long> s, u, v; + +long +foo () +{ + auto x = s.m19 (); + auto y = s.m20 (); + auto z = s.m21 (); + return s.m1 () + s.m2 () + s.m3 () + s.m4 () + s.m5 () + + s.m6 () + s.m7 () + s.m8 () + s.m9 () + s.m10 () + + s.m11 () + s.m12 () + s.m13 () + s.m14 () + s.m15 () +#ifndef __STRICT_ANSI__ + + u.m16 () + v.m17 () +#endif + + *s.m18 () + (s.*x) () + s.*y + z (); +} + +int +main () +{ + return foo (); +} -- 2.20.1
>From 7f3ac38b3c765d49a46f65f1e5e9a812fb1da49c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 10:01:16 +0200 Subject: [PATCH] aarch64: Fix {ash[lr],lshr}<mode>3 expanders [PR94488] The following testcase ICEs on aarch64 apparently since the introduction of the aarch64 port. The reason is that the {ashl,ashr,lshr}<mode>3 expanders completely unnecessarily FAIL; if operands[2] is something other than a CONST_INT or REG or MEM and the middle-end code can't cope with the pattern giving up in these cases. All the expanders use general_operand predicate for the shift amount operand, but then have just a special case for CONST_INT (if in-bound, emit an immediate shift, otherwise force into REG), or MEM (force into REG), or REG (that is the case it handles). In the testcase, operands[2] is a lowpart SUBREG of a REG, which is valid general_operand. I don't see any reason what is magic about MEMs that it should be forced into REG and others like SUBREGs that it shouldn't, there isn't even a reason to check for !REG_P because force_reg will do nothing if the operand is already a REG, and otherwise can handle general_operand just fine. 2020-04-07 Jakub Jelinek <ja...@redhat.com> PR target/94488 * config/aarch64/aarch64-simd.md (ashl<mode>3, lshr<mode>3, ashr<mode>3): Force operands[2] into reg whenever it is not CONST_INT. Assume it is a REG after that instead of testing it and doing FAIL otherwise. Formatting fix. * gcc.c-torture/compile/pr94488.c: New test. --- gcc/ChangeLog | 8 ++ gcc/config/aarch64/aarch64-simd.md | 100 ++++++------------ gcc/testsuite/ChangeLog | 3 + gcc/testsuite/gcc.c-torture/compile/pr94488.c | 22 ++++ 4 files changed, 64 insertions(+), 69 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr94488.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f3708cb39b..7c873296c56 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-04-07 Jakub Jelinek <ja...@redhat.com> + + PR target/94488 + * config/aarch64/aarch64-simd.md (ashl<mode>3, lshr<mode>3, + ashr<mode>3): Force operands[2] into reg whenever it is not CONST_INT. + Assume it is a REG after that instead of testing it and doing FAIL + otherwise. Formatting fix. + 2020-04-07 Jakub Jelinek <ja...@redhat.com> Backported from mainline diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 0b09fd8320d..f413575cfc9 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1012,31 +1012,17 @@ tmp)); DONE; } - else - { - operands[2] = force_reg (SImode, operands[2]); - } - } - else if (MEM_P (operands[2])) - { - operands[2] = force_reg (SImode, operands[2]); } - if (REG_P (operands[2])) - { - rtx tmp = gen_reg_rtx (<MODE>mode); - emit_insn (gen_aarch64_simd_dup<mode> (tmp, - convert_to_mode (<VEL>mode, - operands[2], - 0))); - emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1], - tmp)); - DONE; - } - else - FAIL; -} -) + operands[2] = force_reg (SImode, operands[2]); + + rtx tmp = gen_reg_rtx (<MODE>mode); + emit_insn (gen_aarch64_simd_dup<mode> (tmp, convert_to_mode (<VEL>mode, + operands[2], + 0))); + emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1], tmp)); + DONE; +}) (define_expand "lshr<mode>3" [(match_operand:VDQ_I 0 "register_operand" "") @@ -1059,31 +1045,19 @@ tmp)); DONE; } - else - operands[2] = force_reg (SImode, operands[2]); - } - else if (MEM_P (operands[2])) - { - operands[2] = force_reg (SImode, operands[2]); } - if (REG_P (operands[2])) - { - rtx tmp = gen_reg_rtx (SImode); - rtx tmp1 = gen_reg_rtx (<MODE>mode); - emit_insn (gen_negsi2 (tmp, operands[2])); - emit_insn (gen_aarch64_simd_dup<mode> (tmp1, - convert_to_mode (<VEL>mode, - tmp, 0))); - emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], - operands[1], - tmp1)); - DONE; - } - else - FAIL; -} -) + operands[2] = force_reg (SImode, operands[2]); + + rtx tmp = gen_reg_rtx (SImode); + rtx tmp1 = gen_reg_rtx (<MODE>mode); + emit_insn (gen_negsi2 (tmp, operands[2])); + emit_insn (gen_aarch64_simd_dup<mode> (tmp1, + convert_to_mode (<VEL>mode, tmp, 0))); + emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], operands[1], + tmp1)); + DONE; +}) (define_expand "ashr<mode>3" [(match_operand:VDQ_I 0 "register_operand" "") @@ -1106,31 +1080,19 @@ tmp)); DONE; } - else - operands[2] = force_reg (SImode, operands[2]); - } - else if (MEM_P (operands[2])) - { - operands[2] = force_reg (SImode, operands[2]); } - if (REG_P (operands[2])) - { - rtx tmp = gen_reg_rtx (SImode); - rtx tmp1 = gen_reg_rtx (<MODE>mode); - emit_insn (gen_negsi2 (tmp, operands[2])); - emit_insn (gen_aarch64_simd_dup<mode> (tmp1, - convert_to_mode (<VEL>mode, - tmp, 0))); - emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], - operands[1], - tmp1)); - DONE; - } - else - FAIL; -} -) + operands[2] = force_reg (SImode, operands[2]); + + rtx tmp = gen_reg_rtx (SImode); + rtx tmp1 = gen_reg_rtx (<MODE>mode); + emit_insn (gen_negsi2 (tmp, operands[2])); + emit_insn (gen_aarch64_simd_dup<mode> (tmp1, convert_to_mode (<VEL>mode, + tmp, 0))); + emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], operands[1], + tmp1)); + DONE; +}) (define_expand "vashl<mode>3" [(match_operand:VDQ_I 0 "register_operand" "") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5561d7f2ee8..660def73d7f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> + PR target/94488 + * gcc.c-torture/compile/pr94488.c: New test. + Backported from mainline 2020-04-04 Hannes Domani <ssb...@yahoo.de> Jakub Jelinek <ja...@redhat.com> diff --git a/gcc/testsuite/gcc.c-torture/compile/pr94488.c b/gcc/testsuite/gcc.c-torture/compile/pr94488.c new file mode 100644 index 00000000000..6e20a4168de --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr94488.c @@ -0,0 +1,22 @@ +/* PR target/94488 */ + +typedef unsigned long V __attribute__((__vector_size__(16))); +typedef long W __attribute__((__vector_size__(16))); + +void +foo (V *x, unsigned long y) +{ + *x = *x >> (unsigned int) y; +} + +void +bar (V *x, unsigned long y) +{ + *x = *x << (unsigned int) y; +} + +void +baz (W *x, unsigned long y) +{ + *x = *x >> (unsigned int) y; +} -- 2.20.1
>From 0490cb0e6113783173f1b986211267fd03415346 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 14:30:53 +0200 Subject: [PATCH] openmp: Fix parallel master error recovery [PR94512] We need to set OMP_PARALLEL_COMBINED only if the parsing of omp_master succeeded, because otherwise there is no nested master construct in the parallel. 2020-04-07 Jakub Jelinek <ja...@redhat.com> PR c++/94512 * c-parser.c (c_parser_omp_parallel): Set OMP_PARALLEL_COMBINED if c_parser_omp_master succeeded. * parser.c (cp_parser_omp_parallel): Set OMP_PARALLEL_COMBINED if cp_parser_omp_master succeeded. * g++.dg/gomp/pr94512.C: New test. --- gcc/c/ChangeLog | 4 ++++ gcc/c/c-parser.c | 2 +- gcc/cp/ChangeLog | 4 ++++ gcc/cp/parser.c | 2 +- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/gomp/pr94512.C | 18 ++++++++++++++++++ 6 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gomp/pr94512.C diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 1bfcefb875b..3439f6d4e65 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,5 +1,9 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> + PR c++/94512 + * c-parser.c (c_parser_omp_parallel): Set OMP_PARALLEL_COMBINED + if c_parser_omp_master succeeded. + Backported from mainline 2020-03-23 Jakub Jelinek <ja...@redhat.com> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 042ae876d1c..d0139ab4b86 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -17631,9 +17631,9 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, stmt = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], block); - OMP_PARALLEL_COMBINED (stmt) = 1; if (ret == NULL) return ret; + OMP_PARALLEL_COMBINED (stmt) = 1; return stmt; } else if (!flag_openmp) /* flag_openmp_simd */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ae33956b867..cb49aeccafa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> + PR c++/94512 + * parser.c (cp_parser_omp_parallel): Set OMP_PARALLEL_COMBINED + if cp_parser_omp_master succeeded. + Backported from mainline 2020-04-04 Jakub Jelinek <ja...@redhat.com> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 00e950d2e93..db0276eb04f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -37820,9 +37820,9 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok, cp_parser_end_omp_structured_block (parser, save); stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], block); - OMP_PARALLEL_COMBINED (stmt) = 1; if (ret == NULL_TREE) return ret; + OMP_PARALLEL_COMBINED (stmt) = 1; return stmt; } else if (!flag_openmp) /* flag_openmp_simd */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 660def73d7f..7aed8e289c1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> + PR c++/94512 + * g++.dg/gomp/pr94512.C: New test. + PR target/94488 * gcc.c-torture/compile/pr94488.c: New test. diff --git a/gcc/testsuite/g++.dg/gomp/pr94512.C b/gcc/testsuite/g++.dg/gomp/pr94512.C new file mode 100644 index 00000000000..8ba0e65795f --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr94512.C @@ -0,0 +1,18 @@ +// PR c++/94512 + +void +foo (); + +template <int> +void +bar () +{ +#pragma omp parallel master taskloop + foo (); // { dg-error "for statement expected before" } +} + +void +baz () +{ + bar<0> (); +} -- 2.20.1
>From 14192f1ed48cb3982b1b3c794e0f313835d0cdcd Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <ja...@redhat.com> Date: Tue, 7 Apr 2020 14:39:24 +0200 Subject: [PATCH] i386: Fix V{64QI,32HI}mode constant permutations [PR94509] The following testcases are miscompiled, because expand_vec_perm_pshufb incorrectly thinks it can use vpshufb instruction for the permutations when it can't. The if (vmode == V32QImode) { /* vpshufb only works intra lanes, it is not possible to shuffle bytes in between the lanes. */ for (i = 0; i < nelt; ++i) if ((d->perm[i] ^ i) & (nelt / 2)) return false; } intra-lane check which is correct has been copied and adjusted for 64-byte modes into: if (vmode == V64QImode) { /* vpshufb only works intra lanes, it is not possible to shuffle bytes in between the lanes. */ for (i = 0; i < nelt; ++i) if ((d->perm[i] ^ i) & (nelt / 4)) return false; } which is not correct, because 64-byte modes have 4 lanes rather than just two and the above is only testing that the permutation grabs even lane elts from even lanes and odd lane elts from odd lanes, but not that they are from the same 256-bit half. The following patch fixes it by using 3 * nelt / 4 instead of nelt / 4, so we actually check the most significant 2 bits rather than just one. 2020-04-07 Jakub Jelinek <ja...@redhat.com> PR target/94509 * config/i386/i386-expand.c (expand_vec_perm_pshufb): Fix the check for inter-lane permutation for 64-byte modes. * gcc.target/i386/avx512bw-pr94509-1.c: New test. * gcc.target/i386/avx512bw-pr94509-2.c: New test. --- gcc/ChangeLog | 6 ++- gcc/config/i386/i386.c | 2 +- gcc/testsuite/ChangeLog | 4 ++ .../gcc.target/i386/avx512bw-pr94509-1.c | 30 +++++++++++++++ .../gcc.target/i386/avx512bw-pr94509-2.c | 38 +++++++++++++++++++ 5 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512bw-pr94509-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512bw-pr94509-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c873296c56..9d077ed6e18 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,13 +1,15 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> + PR target/94509 + * config/i386/i386.c (expand_vec_perm_pshufb): Fix the check + for inter-lane permutation for 64-byte modes. + PR target/94488 * config/aarch64/aarch64-simd.md (ashl<mode>3, lshr<mode>3, ashr<mode>3): Force operands[2] into reg whenever it is not CONST_INT. Assume it is a REG after that instead of testing it and doing FAIL otherwise. Formatting fix. -2020-04-07 Jakub Jelinek <ja...@redhat.com> - Backported from mainline 2020-04-04 Hannes Domani <ssb...@yahoo.de> Jakub Jelinek <ja...@redhat.com> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c9c33a8fd62..5d12d82db5b 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -46675,7 +46675,7 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d) /* vpshufb only works intra lanes, it is not possible to shuffle bytes in between the lanes. */ for (i = 0; i < nelt; ++i) - if ((d->perm[i] ^ i) & (nelt / 4)) + if ((d->perm[i] ^ i) & (3 * nelt / 4)) return false; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7aed8e289c1..605cd2e1c73 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2020-04-07 Jakub Jelinek <ja...@redhat.com> + PR target/94509 + * gcc.target/i386/avx512bw-pr94509-1.c: New test. + * gcc.target/i386/avx512bw-pr94509-2.c: New test. + PR c++/94512 * g++.dg/gomp/pr94512.C: New test. diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr94509-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr94509-1.c new file mode 100644 index 00000000000..6cd79b7443f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr94509-1.c @@ -0,0 +1,30 @@ +/* PR target/94509 */ +/* { dg-do run { target avx512bw } } */ +/* { dg-options "-O2 -mavx512bw" } */ + +#define AVX512BW +#include "avx512f-helper.h" + +typedef unsigned short __attribute__ ((__vector_size__ (64))) V; + +__attribute__((noipa)) V +foo (V x) +{ + return __builtin_shuffle (x, (V) { 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15 }); +} + +static void +TEST (void) +{ + V v = foo ((V) { 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32 }); + unsigned int i; + for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + if (v[i] != ((i & 8) ? 16 : 1)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr94509-2.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr94509-2.c new file mode 100644 index 00000000000..089e3f211b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr94509-2.c @@ -0,0 +1,38 @@ +/* PR target/94509 */ +/* { dg-do run { target avx512bw } } */ +/* { dg-options "-O2 -mavx512bw" } */ + +#define AVX512BW +#include "avx512f-helper.h" + +typedef unsigned char __attribute__ ((__vector_size__ (64))) V; + +__attribute__((noipa)) V +foo (V x) +{ + return __builtin_shuffle (x, (V) { 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31 }); +} + +static void +TEST (void) +{ + V v = foo ((V) { 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64 }); + unsigned int i; + for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + if (v[i] != ((i & 16) ? 31 : 1) + (i & 1)) + abort (); +} -- 2.20.1