public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Backports to 9.4
@ 2020-04-07 19:53 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2020-04-07 19:53 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 157 bytes --]

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

[-- Attachment #2: r10-7229-gcd0b71242738a1901405f421b352e4f6c30ff7c5 --]
[-- Type: text/plain, Size: 8387 bytes --]

From 980a7a0be5a114e285c49ab05ac70881e4f27fc3 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
+
+	Backported from mainline
+	2020-03-17  Jakub Jelinek  <jakub@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  <polacek@redhat.com>
 
 	2020-02-06  Marek Polacek  <polacek@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  <jakub@redhat.com>
+
+	Backported from mainline
+	2020-03-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/90995
+	* g++.dg/cpp0x/enum40.C: New test.
+
 2020-04-07  Jakub Jelinek  <jakub@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


[-- Attachment #3: r10-7230-g046c58907ec85884042d9937ea9c25ef9fe57b1d --]
[-- Type: text/plain, Size: 10837 bytes --]

From 87ce34fa00cd6b87452d747235da40dfe5b6e00f Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
+
+	Backported from mainline
+	2020-03-17  Jakub Jelinek  <jakub@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  <jakub@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


[-- Attachment #4: r10-7274-gc7e9019681857b329bbe4c1e7ec8dec8c736c0fe --]
[-- Type: text/plain, Size: 5340 bytes --]

From 8db876e9c045c57d2dc5bd08a6e250f822efaad0 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
+
+	Backported from mainline
+	2020-03-19  Jakub Jelinek  <jakub@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.tkachov@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-19  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/94211
+	* gcc.dg/pr94211.c: New test.
+
 	2020-03-17  Jakub Jelinek  <jakub@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


[-- Attachment #5: r10-7276-g02f7334ac93f53ed06d881beb611e88be36dc56a --]
[-- Type: text/plain, Size: 6068 bytes --]

From 484206967f958fc47827a71654fe52a98adc95cb Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-19  Jakub Jelinek  <jakub@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  <jakub@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  <jakub@redhat.com>
+
+	Backported from mainline
+	2020-03-19  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/93931
+	* testsuite/libgomp.c++/pr93931.C: New test.
+
 2020-03-17  Jakub Jelinek  <jakub@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


[-- Attachment #6: r10-7281-g9def91e9f2a7051c9c146f16c1a10d1b25d33b47 --]
[-- Type: text/plain, Size: 14004 bytes --]

From 827e5af19a214323c70ee5879dc8f14f4f44ad8d Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-19  Jakub Jelinek  <jakub@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  <jakub@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  <jakub@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


[-- Attachment #7: r10-7343-g5db9e89323cd0a0be16a94f2f984121531ea7772 --]
[-- Type: text/plain, Size: 3582 bytes --]

From f83c2d2991a762f729741a409a1ac7871733ee40 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-23  Jakub Jelinek  <jakub@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  <jakub@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


[-- Attachment #8: r10-7349-g047811579f09048ed538674fd5251b35e5a92025 --]
[-- Type: text/plain, Size: 4043 bytes --]

From 4ac9ab60f06020a24e851ebe3eeacc1b3bffa849 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-24  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
+
 	2020-03-19  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-24  Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/94277
+	* gcc.dg/pr94277.c: New test.
+
 	2020-03-19  Jakub Jelinek  <jakub@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


[-- Attachment #9: r10-7350-ga5a9400a846244d040caa6d1531434eee8fc8ec7 --]
[-- Type: text/plain, Size: 4330 bytes --]

From 4dcfd4e56b0d22af12750372f3e0b49249b1d473 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@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  <jakub@redhat.com>
-
 	2020-03-19  Jakub Jelinek  <jakub@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  <jakub@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


[-- Attachment #10: r10-7365-gc2133167ad58d15c2c2df0cb4fa3a3757603144e --]
[-- Type: text/plain, Size: 3768 bytes --]

From 8ea7970c4968517fb73f42bcca40d316adacf215 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <rguenther@suse.de>
	    Jakub Jelinek  <jakub@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 <rguenther@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-25  Richard Biener  <rguenther@suse.de>
+		    Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/94283
+	* tree-if-conv.c (ifcvt_local_dce): Delete dead statements backwards.
+
+2020-04-07  Jakub Jelinek  <jakub@redhat.com>
+
 	2020-03-24  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-25  Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/94283
+	* gcc.dg/pr94283.c: New test.
+
 	2020-03-24  Jakub Jelinek  <jakub@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


[-- Attachment #11: r10-7368-g5f18995e23edc944af3a401d9d9d3320a9362652 --]
[-- Type: text/plain, Size: 4538 bytes --]

From 56407bab53a514ffcd6ac011965cebdc5eb3ef54 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-25  Jakub Jelinek  <jakub@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  <rguenther@suse.de>
 		    Jakub Jelinek  <jakub@redhat.com>
 
 	PR debug/94283
 	* tree-if-conv.c (ifcvt_local_dce): Delete dead statements backwards.
 
-2020-04-07  Jakub Jelinek  <jakub@redhat.com>
-
 	2020-03-24  Jakub Jelinek  <jakub@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  <jakub@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


[-- Attachment #12: r10-7437-g679becf175c5d7f6b323cd3af0a09c6039b4123d --]
[-- Type: text/plain, Size: 4924 bytes --]

From aa9c08ef97f4df1ebb1fc8d72f2e7f9f8c1045c2 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-28  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
+
 	2020-03-25  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-28  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/94329
+	* gfortran.dg/pr94329.f90: New test.
+
 	2020-03-25  Jakub Jelinek  <jakub@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


[-- Attachment #13: r10-7457-gec919cfcef8d7fcbaab24d0e0d472c65e5329ca6 --]
[-- Type: text/plain, Size: 6037 bytes --]

From 57e276f3e304ef92483763ee1028e5b3e1345e0f Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-30  Jakub Jelinek  <jakub@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  <jakub@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  <jakub@redhat.com>
-
 	2020-03-25  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-30  Jakub Jelinek  <jakub@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  <jakub@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


[-- Attachment #14: r10-7464-g1cb1986cb596336e688c079b821205ec212a46a3 --]
[-- Type: text/plain, Size: 3743 bytes --]

From a6bf0e5fb11cc0e231ac016a1995caaa93fdc4a0 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-30  Jakub Jelinek  <jakub@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  <jakub@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  <jakub@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


[-- Attachment #15: r10-7471-g1dcffc8ddc48f0b45d3d0d2f763ef5870560eb9a --]
[-- Type: text/plain, Size: 4224 bytes --]

From 8f99f9e6ccec167a5ba67dcc08e6c14948595b82 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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.glisse@inria.fr>
	    Jakub Jelinek  <jakub@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.glisse@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-31  Marc Glisse  <marc.glisse@inria.fr>
+		    Jakub Jelinek  <jakub@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  <jakub@redhat.com>
+
 	2020-03-30  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-03-31  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/94412
+	* gcc.c-torture/execute/pr94412.c: New test.
+
 	2020-03-30  Jakub Jelinek  <jakub@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


[-- Attachment #16: r10-7493-g9ecb3ecc8cc0497a2cc815589c59547fd5af8512 --]
[-- Type: text/plain, Size: 3458 bytes --]

From 4486a537f14bc3b05ac552c3cbe18e540e397ed7 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-01  Jakub Jelinek  <jakub@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.glisse@inria.fr>
 		    Jakub Jelinek  <jakub@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  <jakub@redhat.com>
-
 	2020-03-30  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-01  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/94423
+	* gcc.dg/ubsan/pr94423.c: New test.
+
 	2020-03-31  Jakub Jelinek  <jakub@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


[-- Attachment #17: r10-7541-gb8020a5aafd02af1ccf99372d3d8052c40b59725 --]
[-- Type: text/plain, Size: 7660 bytes --]

From dbff1829843180dc2a6c8ce5ce7883146b5cf083 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-03  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
+
 	2020-04-01  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-03  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/94460
+	* gcc.target/i386/avx2-pr94460.c: New test.
+
 	2020-04-01  Jakub Jelinek  <jakub@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


[-- Attachment #18: r10-7547-g0c809f727cd2a6c70c307d9dd53d26dc84bf292a --]
[-- Type: text/plain, Size: 2825 bytes --]

From d1371dbe12214895cda0b13bfc6ff0ed9cbce15d Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-04  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/94477
+	* pt.c (tsubst_expr) <case OMP_MASTER>: Clear
+	omp_parallel_combined_clauses.
+
 	2020-03-30  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-04  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/94477
+	* g++.dg/gomp/pr94477.C: New test.
+
 	2020-04-03  Jakub Jelinek  <jakub@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


[-- Attachment #19: r10-7560-g0be9efad938726721fd8c8c35609b1e1d7d30035 --]
[-- Type: text/plain, Size: 6380 bytes --]

From b5039b7259e64a92f5c077fe4d023556d6b12550 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <ssbssa@yahoo.de>
	    Jakub Jelinek  <jakub@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 <ssbssa@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-04  Hannes Domani  <ssbssa@yahoo.de>
+		    Jakub Jelinek  <jakub@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  <jakub@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  <jakub@redhat.com>
-
 	2020-04-01  Jakub Jelinek  <jakub@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  <jakub@redhat.com>
 
 	Backported from mainline
+	2020-04-04  Hannes Domani  <ssbssa@yahoo.de>
+		    Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/94459
+	* g++.dg/debug/pr94459.C: New test.
+
 	2020-04-04  Jakub Jelinek  <jakub@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


[-- Attachment #20: r10-7584-g7a6588fe65432c0f1a8b5fdefba81700ebf88711 --]
[-- Type: text/plain, Size: 7159 bytes --]

From 7f3ac38b3c765d49a46f65f1e5e9a812fb1da49c Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@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  <jakub@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  <jakub@redhat.com>
 
+	PR target/94488
+	* gcc.c-torture/compile/pr94488.c: New test.
+
 	Backported from mainline
 	2020-04-04  Hannes Domani  <ssbssa@yahoo.de>
 		    Jakub Jelinek  <jakub@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


[-- Attachment #21: r10-7585-g4df50a059fbd4d4a1cb067bd43caccdfca0327a8 --]
[-- Type: text/plain, Size: 3823 bytes --]

From 0490cb0e6113783173f1b986211267fd03415346 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@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  <jakub@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  <jakub@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  <jakub@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  <jakub@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


[-- Attachment #22: r10-7586-gd51af82b4cf4c95c4a7451df2180cc6ebb44856b --]
[-- Type: text/plain, Size: 6472 bytes --]

From 14192f1ed48cb3982b1b3c794e0f313835d0cdcd Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@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  <jakub@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  <jakub@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  <jakub@redhat.com>
-
 	Backported from mainline
 	2020-04-04  Hannes Domani  <ssbssa@yahoo.de>
 		    Jakub Jelinek  <jakub@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  <jakub@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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-04-07 19:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-07 19:53 Backports to 9.4 Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).