public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Backports to 8.3
@ 2018-09-05  7:25 Jakub Jelinek
  0 siblings, 0 replies; 3+ messages in thread
From: Jakub Jelinek @ 2018-09-05  7:25 UTC (permalink / raw)
  To: gcc-patches

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

Hi!

I've bootstrapped/regtested the following backports on gcc-8-branch
on x86_64-linux and i686-linux and committed.

	Jakub

[-- Attachment #2: r263293 --]
[-- Type: text/plain, Size: 1065 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-08-03  Jason Merrill  <jason@redhat.com>

	PR c++/86706
	* class.c (build_base_path): Use currently_open_class.

	* g++.dg/template/pr86706.C: New test.

--- gcc/cp/class.c	(revision 263292)
+++ gcc/cp/class.c	(revision 263293)
@@ -278,6 +278,9 @@ build_base_path (enum tree_code code,
   probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
   if (want_pointer)
     probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
+  if (dependent_type_p (probe))
+    if (tree open = currently_open_class (probe))
+      probe = open;
 
   if (code == PLUS_EXPR
       && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
--- gcc/testsuite/g++.dg/template/pr86706.C	(nonexistent)
+++ gcc/testsuite/g++.dg/template/pr86706.C	(revision 263293)
@@ -0,0 +1,16 @@
+// PR c++/86706
+// { dg-do compile }
+
+class A { int b; };
+
+template <class, typename>
+class C : A { C (); static C *f; };
+
+template <class T, typename U>
+C<T, U> *C<T, U>::f;
+
+template <class T, typename U>
+C<T, U>::C ()
+{
+  f->b;
+}

[-- Attachment #3: r263390 --]
[-- Type: text/plain, Size: 1665 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-08-08  Jakub Jelinek  <jakub@redhat.com>

	PR c++/86738
	* constexpr.c (cxx_eval_binary_expression): For arithmetics involving
	NULL pointer set *non_constant_p to true.
	(cxx_eval_component_reference): For dereferencing of a NULL pointer,
	set *non_constant_p to true and return t.

	* g++.dg/opt/pr86738.C: New test.

--- gcc/cp/constexpr.c	(revision 263389)
+++ gcc/cp/constexpr.c	(revision 263390)
@@ -2082,6 +2082,7 @@ cxx_eval_binary_expression (const conste
     {
       if (!ctx->quiet)
 	error ("arithmetic involving a null pointer in %qE", lhs);
+      *non_constant_p = true;
       return t;
     }
   else if (code == POINTER_PLUS_EXPR)
@@ -2522,9 +2523,13 @@ cxx_eval_component_reference (const cons
 					     lval,
 					     non_constant_p, overflow_p);
   if (INDIRECT_REF_P (whole)
-      && integer_zerop (TREE_OPERAND (whole, 0))
-      && !ctx->quiet)
-    error ("dereferencing a null pointer in %qE", orig_whole);
+      && integer_zerop (TREE_OPERAND (whole, 0)))
+    {
+      if (!ctx->quiet)
+	error ("dereferencing a null pointer in %qE", orig_whole);
+      *non_constant_p = true;
+      return t;
+    }
 
   if (TREE_CODE (whole) == PTRMEM_CST)
     whole = cplus_expand_constant (whole);
--- gcc/testsuite/g++.dg/opt/pr86738.C	(nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr86738.C	(revision 263390)
@@ -0,0 +1,12 @@
+// PR c++/86738
+// { dg-do compile }
+
+struct S { int s; };
+unsigned char a[20];
+unsigned char *p = &a[(__UINTPTR_TYPE__) &((S *) 0)->s];
+
+void
+foo ()
+{
+  __builtin_memcpy (&a[15], &a[(__UINTPTR_TYPE__) &((S *) 0)->s], 2);
+}

[-- Attachment #4: r263391 --]
[-- Type: text/plain, Size: 2611 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-08-08  Jakub Jelinek  <jakub@redhat.com>

	PR c++/86836
	* pt.c (tsubst_expr): For structured bindings, call tsubst_decomp_names
	before tsubst_init, not after it.

	* g++.dg/cpp1z/decomp46.C: New test.

--- gcc/cp/pt.c	(revision 263390)
+++ gcc/cp/pt.c	(revision 263391)
@@ -16740,7 +16740,17 @@ tsubst_expr (tree t, tree args, tsubst_f
 		else
 		  {
 		    int const_init = false;
+		    unsigned int cnt = 0;
+		    tree first = NULL_TREE, ndecl = error_mark_node;
 		    maybe_push_decl (decl);
+
+		    if (VAR_P (decl)
+			&& DECL_DECOMPOSITION_P (decl)
+			&& TREE_TYPE (pattern_decl) != error_mark_node)
+		      ndecl = tsubst_decomp_names (decl, pattern_decl, args,
+						   complain, in_decl, &first,
+						   &cnt);
+
 		    if (VAR_P (decl)
 			&& DECL_PRETTY_FUNCTION_P (decl))
 		      {
@@ -16756,23 +16766,14 @@ tsubst_expr (tree t, tree args, tsubst_f
 		    if (VAR_P (decl))
 		      const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
 				    (pattern_decl));
-		    if (VAR_P (decl)
-			&& DECL_DECOMPOSITION_P (decl)
-			&& TREE_TYPE (pattern_decl) != error_mark_node)
-		      {
-			unsigned int cnt;
-			tree first;
-			tree ndecl
-			  = tsubst_decomp_names (decl, pattern_decl, args,
-						 complain, in_decl, &first, &cnt);
-			if (ndecl != error_mark_node)
-			  cp_maybe_mangle_decomp (ndecl, first, cnt);
-			cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
-			if (ndecl != error_mark_node)
-			  cp_finish_decomp (ndecl, first, cnt);
-		      }
-		    else
-		      cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+
+		    if (ndecl != error_mark_node)
+		      cp_maybe_mangle_decomp (ndecl, first, cnt);
+
+		    cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+
+		    if (ndecl != error_mark_node)
+		      cp_finish_decomp (ndecl, first, cnt);
 		  }
 	      }
 	  }
--- gcc/testsuite/g++.dg/cpp1z/decomp46.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp1z/decomp46.C	(revision 263391)
@@ -0,0 +1,25 @@
+// PR c++/86836
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A {
+  int operator*();
+  void operator++();
+  bool operator!=(A);
+};
+template <typename> class map {
+public:
+  A begin();
+  A end();
+};
+
+template <typename T> void mergemap(map<T> orig, map<T> toadd) {
+  for (auto p : toadd)
+    auto [orig] = orig;		// { dg-error "use of 'orig' before deduction of 'auto'" }
+}				// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+
+int
+main() {
+  map<double> x, y;
+  mergemap(x, y);
+}

[-- Attachment #5: r263487 --]
[-- Type: text/plain, Size: 2607 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-08-11  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/86835
	* tree-ssa-math-opts.c (insert_reciprocals): Even when inserting
	new_stmt after def_gsi, make sure to insert new_square_stmt after
	that stmt, not 2 stmts before it.

	* gcc.dg/pr86835.c: New test.

--- gcc/tree-ssa-math-opts.c	(revision 263486)
+++ gcc/tree-ssa-math-opts.c	(revision 263487)
@@ -422,6 +422,8 @@ insert_reciprocals (gimple_stmt_iterator
 	    gsi_next (&gsi);
 
 	  gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
+	  if (should_insert_square_recip)
+	    gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
 	}
       else if (def_gsi && occ->bb == def_gsi->bb)
 	{
@@ -429,21 +431,19 @@ insert_reciprocals (gimple_stmt_iterator
 	     never happen if the definition statement can throw, because in
 	     that case the sole successor of the statement's basic block will
 	     dominate all the uses as well.  */
-	  gsi = *def_gsi;
 	  gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
+	  if (should_insert_square_recip)
+	    gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT);
 	}
       else
 	{
 	  /* Case 3: insert in a basic block not containing defs/uses.  */
 	  gsi = gsi_after_labels (occ->bb);
 	  gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
+	  if (should_insert_square_recip)
+	    gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
 	}
 
-      /* Regardless of which case the reciprocal as inserted in,
-	 we insert the square immediately after the reciprocal.  */
-      if (should_insert_square_recip)
-	gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
-
       reciprocal_stats.rdivs_inserted++;
 
       occ->recip_def_stmt = new_stmt;
--- gcc/testsuite/gcc.dg/pr86835.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr86835.c	(revision 263487)
@@ -0,0 +1,29 @@
+/* PR tree-optimization/86835 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ffast-math -Wuninitialized" } */
+
+__attribute__((noipa)) void
+foo (int n, double *x, double *y)
+{		/* { dg-bogus "is used uninitialized in this function" "" { target *-*-* } 0 } */
+  int i;
+  double b = y[4];
+  for (i = 0; i < n; ++i)
+    y[3] += __builtin_sin (x[i] / b);
+  y[0] /= b;
+  y[1] /= b * b;
+  y[2] /= b;
+}
+
+int
+main ()
+{
+  double y[] = { 16.0, 64.0, 128.0, 0.0, 2.0 };
+  foo (0, y, y);
+  if (__builtin_fabs (y[0] - 8.0) > 0.0001
+      || __builtin_fabs (y[1] - 16.0) > 0.0001
+      || __builtin_fabs (y[2] - 64.0) > 0.0001
+      || y[3] != 0.0
+      || y[4] != 2.0)
+    __builtin_abort ();
+  return 0;
+}

[-- Attachment #6: r263967 --]
[-- Type: text/plain, Size: 1546 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-08-29  Jakub Jelinek  <jakub@redhat.com>

	PR c++/87095
	* decl.c (begin_destructor_body): If current_class_type has
	virtual bases and the primary base is nearly empty virtual base,
	voidify clearing of vptr and make it conditional on in-charge
	argument.

	* g++.dg/ubsan/vptr-13.C: New test.

--- gcc/cp/decl.c	(revision 263966)
+++ gcc/cp/decl.c	(revision 263967)
@@ -15698,6 +15698,18 @@ begin_destructor_body (void)
 	    tree stmt = cp_build_modify_expr (input_location, vtbl_ptr,
 					      NOP_EXPR, vtbl,
 					      tf_warning_or_error);
+	    /* If the vptr is shared with some virtual nearly empty base,
+	       don't clear it if not in charge, the dtor of the virtual
+	       nearly empty base will do that later.  */
+	    if (CLASSTYPE_VBASECLASSES (current_class_type)
+		&& CLASSTYPE_PRIMARY_BINFO (current_class_type)
+		&& BINFO_VIRTUAL_P
+			  (CLASSTYPE_PRIMARY_BINFO (current_class_type)))
+	      {
+		stmt = convert_to_void (stmt, ICV_STATEMENT,
+					tf_warning_or_error);
+		stmt = build_if_in_charge (stmt);
+	      }
 	    finish_decl_cleanup (NULL_TREE, stmt);
 	  }
 	else
--- gcc/testsuite/g++.dg/ubsan/vptr-13.C	(nonexistent)
+++ gcc/testsuite/g++.dg/ubsan/vptr-13.C	(revision 263967)
@@ -0,0 +1,19 @@
+// PR c++/87095
+// { dg-do run }
+// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" }
+
+struct A
+{
+  virtual ~A () {}
+};
+
+struct B : virtual A {};
+
+struct C : B {};
+
+int
+main ()
+{
+  C c;
+  return 0;
+}

[-- Attachment #7: r264009 --]
[-- Type: text/plain, Size: 2236 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-08-31  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/87138
	* expmed.c (expand_mult_const): Use immed_wide_int_const instead of
	gen_int_mode.  Formatting fixes.

	* gcc.target/i386/avx512bw-pr87138.c: New test.

--- gcc/expmed.c	(revision 264008)
+++ gcc/expmed.c	(revision 264009)
@@ -3347,19 +3347,21 @@ expand_mult_const (machine_mode mode, rt
 	  /* Write a REG_EQUAL note on the last insn so that we can cse
 	     multiplication sequences.  Note that if ACCUM is a SUBREG,
 	     we've set the inner register and must properly indicate that.  */
-          tem = op0, nmode = mode;
-          accum_inner = accum;
-          if (GET_CODE (accum) == SUBREG)
+	  tem = op0, nmode = mode;
+	  accum_inner = accum;
+	  if (GET_CODE (accum) == SUBREG)
 	    {
 	      accum_inner = SUBREG_REG (accum);
 	      nmode = GET_MODE (accum_inner);
 	      tem = gen_lowpart (nmode, op0);
 	    }
 
-          insn = get_last_insn ();
-          set_dst_reg_note (insn, REG_EQUAL,
-			    gen_rtx_MULT (nmode, tem,
-					  gen_int_mode (val_so_far, nmode)),
+	  insn = get_last_insn ();
+	  wide_int wval_so_far
+	    = wi::uhwi (val_so_far,
+			GET_MODE_PRECISION (as_a <scalar_mode> (nmode)));
+	  rtx c = immed_wide_int_const (wval_so_far, nmode);
+	  set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
 			    accum_inner);
 	}
     }
--- gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c	(revision 264009)
@@ -0,0 +1,29 @@
+/* PR middle-end/87138 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O -fno-tree-fre -mavx512bw -mtune=k8" } */
+/* { dg-require-effective-target avx512bw } */
+
+#include "avx512bw-check.h"
+
+typedef int U __attribute__ ((vector_size (64)));
+typedef __int128 V __attribute__ ((vector_size (64)));
+V g, i;
+
+static inline void
+foo (unsigned h, V j, U k, V n)
+{
+  k /= h;
+  __builtin_memmove (&h, &n, 1);
+  n[j[1]] *= 0x7FFFFFFFFFFFFFFF;
+  j[k[5]] = 0;
+  g = n;
+  i = h + j + n;
+}
+
+void
+avx512bw_test ()
+{
+  foo (~0, (V) { }, (U) { 5 }, (V) { 3 });
+  if (g[0] != (__int128) 3 * 0x7FFFFFFFFFFFFFFF)
+    abort ();
+}

[-- Attachment #8: r264088 --]
[-- Type: text/plain, Size: 2627 bytes --]

2018-09-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-09-04  Jakub Jelinek  <jakub@redhat.com>

	PR target/87198
	* common/config/i386/i386-common.c (OPTION_MASK_ISA_XSAVEOPT_SET,
	OPTION_MASK_ISA_XSAVES_SET, OPTION_MASK_ISA_XSAVEC_SET): Use
	OPTION_MASK_ISA_XSAVE_SET instead of OPTION_MASK_ISA_XSAVE.
	(OPTION_MASK_ISA_XSAVE_UNSET): Add OPTION_MASK_ISA_XSAVES_UNSET
	and OPTION_MASK_ISA_XSAVEC_UNSET.

	* gcc.target/i386/pr87198.c: New test.

--- gcc/common/config/i386/i386-common.c	(revision 264087)
+++ gcc/common/config/i386/i386-common.c	(revision 264088)
@@ -59,7 +59,7 @@ along with GCC; see the file COPYING3.
 #define OPTION_MASK_ISA_FXSR_SET OPTION_MASK_ISA_FXSR
 #define OPTION_MASK_ISA_XSAVE_SET OPTION_MASK_ISA_XSAVE
 #define OPTION_MASK_ISA_XSAVEOPT_SET \
-  (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE)
+  (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE_SET)
 #define OPTION_MASK_ISA_AVX512F_SET \
   (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX2_SET)
 #define OPTION_MASK_ISA_AVX512CD_SET \
@@ -95,9 +95,9 @@ along with GCC; see the file COPYING3.
 #define OPTION_MASK_ISA_PREFETCHWT1_SET OPTION_MASK_ISA_PREFETCHWT1
 #define OPTION_MASK_ISA_CLFLUSHOPT_SET OPTION_MASK_ISA_CLFLUSHOPT
 #define OPTION_MASK_ISA_XSAVES_SET \
-  (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE)
+  (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE_SET)
 #define OPTION_MASK_ISA_XSAVEC_SET \
-  (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE)
+  (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE_SET)
 #define OPTION_MASK_ISA_CLWB_SET OPTION_MASK_ISA_CLWB
 
 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same
@@ -185,7 +185,8 @@ along with GCC; see the file COPYING3.
 #define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA
 #define OPTION_MASK_ISA_FXSR_UNSET OPTION_MASK_ISA_FXSR
 #define OPTION_MASK_ISA_XSAVE_UNSET \
-  (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET)
+  (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET \
+   | OPTION_MASK_ISA_XSAVES_UNSET | OPTION_MASK_ISA_XSAVEC_UNSET)
 #define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT
 #define OPTION_MASK_ISA_AVX2_UNSET \
   (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET)
--- gcc/testsuite/gcc.target/i386/pr87198.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr87198.c	(revision 264088)
@@ -0,0 +1,13 @@
+/* PR target/87198 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mxsavec -mno-xsave" } */
+
+#include <x86intrin.h>
+
+void
+test_xsavec (void *__A, long long __B)
+{
+  _xsavec (__A, __B);
+}
+
+/* { dg-error "target specific option mismatch" "" { target *-*-* } 0 } */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Backports to 8.3
@ 2018-11-05 14:13 Jakub Jelinek
  0 siblings, 0 replies; 3+ messages in thread
From: Jakub Jelinek @ 2018-11-05 14:13 UTC (permalink / raw)
  To: gcc-patches

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

Hi!

I've backported from trunk, bootstrapped/regtested on x86_64-linux and
i686-linux and committed to gcc-8-branch the following 6 patches.

	Jakub

[-- Attachment #2: r265335 --]
[-- Type: text/plain, Size: 4036 bytes --]

2018-11-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-10-19  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/85488
	PR middle-end/87649
	* omp-low.c (check_omp_nesting_restrictions): Diagnose ordered without
	depend closely nested inside of loop with ordered clause with
	a parameter.

	* c-c++-common/gomp/doacross-2.c: New test.
	* c-c++-common/gomp/sink-3.c: Expect another error during error
	recovery.

--- gcc/omp-low.c	(revision 265334)
+++ gcc/omp-low.c	(revision 265335)
@@ -2762,14 +2762,25 @@ check_omp_nesting_restrictions (gimple *
 	  case GIMPLE_OMP_FOR:
 	    if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP)
 	      goto ordered_in_taskloop;
-	    if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
-				 OMP_CLAUSE_ORDERED) == NULL)
+	    tree o;
+	    o = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
+				 OMP_CLAUSE_ORDERED);
+	    if (o == NULL)
 	      {
 		error_at (gimple_location (stmt),
 			  "%<ordered%> region must be closely nested inside "
 			  "a loop region with an %<ordered%> clause");
 		return false;
 	      }
+	    if (OMP_CLAUSE_ORDERED_EXPR (o) != NULL_TREE
+		&& omp_find_clause (c, OMP_CLAUSE_DEPEND) == NULL_TREE)
+	      {
+		error_at (gimple_location (stmt),
+			  "%<ordered%> region without %<depend%> clause may "
+			  "not be closely nested inside a loop region with "
+			  "an %<ordered%> clause with a parameter");
+		return false;
+	      }
 	    return true;
 	  case GIMPLE_OMP_TARGET:
 	    if (gimple_omp_target_kind (ctx->stmt)
--- gcc/testsuite/c-c++-common/gomp/sink-3.c	(revision 265334)
+++ gcc/testsuite/c-c++-common/gomp/sink-3.c	(revision 265335)
@@ -14,7 +14,7 @@ foo ()
   for (i=0; i < 100; ++i)
     {
 #pragma omp ordered depend(sink:poo-1,paa+1) /* { dg-error "poo.*declared.*paa.*declared" } */
-    bar(&i);
+    bar(&i);				     /* { dg-error "may not be closely nested" "" { target *-*-* } .-1 } */
 #pragma omp ordered depend(source)
     }
 }
--- gcc/testsuite/c-c++-common/gomp/doacross-2.c	(nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/doacross-2.c	(revision 265335)
@@ -0,0 +1,49 @@
+/* PR middle-end/87649 */
+
+void
+foo (void)
+{
+  int i;
+  #pragma omp for ordered(1)
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered			/* { dg-error "'ordered' region without 'depend' clause may not be closely nested inside a loop region with an 'ordered' clause with a parameter" } */
+      ;
+    }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered threads		/* { dg-error "'ordered' region without 'depend' clause may not be closely nested inside a loop region with an 'ordered' clause with a parameter" } */
+      ;
+    }
+}
+
+void
+bar (void)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(source)	/* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
+      #pragma omp ordered depend(sink: i - 1)	/* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
+    }
+  #pragma omp for
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(source)	/* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
+      #pragma omp ordered depend(sink: i - 1)	/* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
+    }
+  #pragma omp for
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered			/* { dg-error "'ordered' region must be closely nested inside a loop region with an 'ordered' clause" } */
+      ;
+    }
+  #pragma omp for
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered threads		/* { dg-error "'ordered' region must be closely nested inside a loop region with an 'ordered' clause" } */
+      ;
+    }
+}

[-- Attachment #3: r265341 --]
[-- Type: text/plain, Size: 1159 bytes --]

2018-11-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-10-20  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/87647
	* varasm.c (decode_addr_const): Handle COMPOUND_LITERAL_EXPR.

	* gcc.c-torture/compile/pr87647.c: New test.

--- gcc/varasm.c	(revision 265340)
+++ gcc/varasm.c	(revision 265341)
@@ -2953,6 +2953,11 @@ decode_addr_const (tree exp, struct addr
 		       gen_rtx_SYMBOL_REF (Pmode, "origin of addresses"));
       break;
 
+    case COMPOUND_LITERAL_EXPR:
+      gcc_assert (COMPOUND_LITERAL_EXPR_DECL (target));
+      x = DECL_RTL (COMPOUND_LITERAL_EXPR_DECL (target));
+      break;
+
     default:
       gcc_unreachable ();
     }
--- gcc/testsuite/gcc.c-torture/compile/pr87647.c	(nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr87647.c	(revision 265341)
@@ -0,0 +1,15 @@
+/* PR middle-end/87647 */
+
+struct A {};
+struct A *const b = &(struct A) {};
+struct B { char *s; struct A *t; };
+void bar (struct B *);
+
+void
+foo (void)
+{
+  struct B a[] = { "", b, "", b, "", b, "", b, "", b, "", b, "", b, "", b,
+		   "", b, "", b, "", b, "", b, "", b, "", b, "", b, "", b,
+		   "", b };
+  bar (a);
+}

[-- Attachment #4: r265470 --]
[-- Type: text/plain, Size: 2543 bytes --]

2018-11-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-10-24  Jakub Jelinek  <jakub@redhat.com>

	PR c++/86288
	* parser.c (cp_parser_std_attribute): Canonicalize attr_ns, and when
	:: is not present and attr_ns non-NULL, canonicalize also attr_id.
	(cp_parser_attribute_spec): Fix comment typo.

	* g++.dg/cpp0x/gen-attrs-66.C: New test.

--- gcc/cp/parser.c	(revision 265469)
+++ gcc/cp/parser.c	(revision 265470)
@@ -25327,14 +25327,19 @@ cp_parser_std_attribute (cp_parser *pars
 	  return error_mark_node;
 	}
 
+      attr_ns = canonicalize_attr_name (attr_ns);
       attr_id = canonicalize_attr_name (attr_id);
       attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
 				   NULL_TREE);
       token = cp_lexer_peek_token (parser->lexer);
     }
   else if (attr_ns)
-    attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
-				 NULL_TREE);
+    {
+      attr_ns = canonicalize_attr_name (attr_ns);
+      attr_id = canonicalize_attr_name (attr_id);
+      attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
+				   NULL_TREE);
+    }
   else
     {
       attr_id = canonicalize_attr_name (attr_id);
@@ -25526,7 +25531,7 @@ cp_parser_std_attribute_spec (cp_parser
 	  || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
 	cp_parser_skip_to_end_of_statement (parser);
       else
-	/* Warn about parsing c++11 attribute in non-c++1 mode, only
+	/* Warn about parsing c++11 attribute in non-c++11 mode, only
 	   when we are sure that we have actually parsed them.  */
 	maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
     }
--- gcc/testsuite/g++.dg/cpp0x/gen-attrs-66.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-66.C	(revision 265470)
@@ -0,0 +1,12 @@
+// PR c++/86288
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wattributes" }
+
+int a [[gnu::aligned(alignof(int))]];
+int b [[gnu::__aligned__(alignof(int))]];
+int c [[__gnu__::aligned(alignof(int))]];
+int d [[__gnu__::__aligned__(alignof(int))]];
+int e [[using gnu : aligned(alignof(int))]];		// { dg-warning "attribute using prefix only available" "" { target c++14_down } }
+int f [[using gnu : __aligned__(alignof(int))]];	// { dg-warning "attribute using prefix only available" "" { target c++14_down } }
+int g [[using __gnu__ : aligned(alignof(int))]];	// { dg-warning "attribute using prefix only available" "" { target c++14_down } }
+int h [[using __gnu__ : __aligned__(alignof(int))]];	// { dg-warning "attribute using prefix only available" "" { target c++14_down } }

[-- Attachment #5: r265479 --]
[-- Type: text/plain, Size: 8693 bytes --]

2018-11-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-10-25  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/87725
	* openmp.c (gfc_match_omp_clauses): Parse simd, monotonic and
	nonmonotonic modifiers regardless of if they have been parsed
	already or if the opposite one has.  Fix up check whether
	comma after modifier should be parsed.
	(resolve_omp_clauses): Diagnose schedule modifier restrictions.

	* c-c++-common/gomp/schedule-modifiers-1.c (bar): Separate modifier
	from kind with a colon rather than comma.
	* gfortran.dg/gomp/schedule-modifiers-1.f90: New test.
	* gfortran.dg/gomp/schedule-modifiers-2.f90: New test.

--- gcc/fortran/openmp.c	(revision 265478)
+++ gcc/fortran/openmp.c	(revision 265479)
@@ -1710,22 +1710,17 @@ gfc_match_omp_clauses (gfc_omp_clauses *
 	      locus old_loc2 = gfc_current_locus;
 	      do
 		{
-		  if (!c->sched_simd
-		      && gfc_match ("simd") == MATCH_YES)
+		  if (gfc_match ("simd") == MATCH_YES)
 		    {
 		      c->sched_simd = true;
 		      nmodifiers++;
 		    }
-		  else if (!c->sched_monotonic
-			   && !c->sched_nonmonotonic
-			   && gfc_match ("monotonic") == MATCH_YES)
+		  else if (gfc_match ("monotonic") == MATCH_YES)
 		    {
 		      c->sched_monotonic = true;
 		      nmodifiers++;
 		    }
-		  else if (!c->sched_monotonic
-			   && !c->sched_nonmonotonic
-			   && gfc_match ("nonmonotonic") == MATCH_YES)
+		  else if (gfc_match ("nonmonotonic") == MATCH_YES)
 		    {
 		      c->sched_nonmonotonic = true;
 		      nmodifiers++;
@@ -1736,7 +1731,7 @@ gfc_match_omp_clauses (gfc_omp_clauses *
 			gfc_current_locus = old_loc2;
 		      break;
 		    }
-		  if (nmodifiers == 0
+		  if (nmodifiers == 1
 		      && gfc_match (" , ") == MATCH_YES)
 		    continue;
 		  else if (gfc_match (" : ") == MATCH_YES)
@@ -4075,6 +4070,30 @@ resolve_omp_clauses (gfc_code *code, gfc
 	gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
 		     "at %L must be positive", &expr->where);
     }
+  if (omp_clauses->sched_kind != OMP_SCHED_NONE
+      && omp_clauses->sched_nonmonotonic)
+    {
+      if (omp_clauses->sched_kind != OMP_SCHED_DYNAMIC
+	  && omp_clauses->sched_kind != OMP_SCHED_GUIDED)
+	{
+	  const char *p;
+	  switch (omp_clauses->sched_kind)
+	    {
+	    case OMP_SCHED_STATIC: p = "STATIC"; break;
+	    case OMP_SCHED_RUNTIME: p = "RUNTIME"; break;
+	    case OMP_SCHED_AUTO: p = "AUTO"; break;
+	    default: gcc_unreachable ();
+	    }
+	  gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
+		     "at %L", p, &code->loc);
+	}
+      else if (omp_clauses->sched_monotonic)
+	gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
+		   "specified at %L", &code->loc);
+      else if (omp_clauses->ordered)
+	gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
+		   "clause at %L", &code->loc);
+    }
 
   /* Check that no symbol appears on multiple clauses, except that
      a symbol can appear on both firstprivate and lastprivate.  */
--- gcc/testsuite/c-c++-common/gomp/schedule-modifiers-1.c	(revision 265478)
+++ gcc/testsuite/c-c++-common/gomp/schedule-modifiers-1.c	(revision 265479)
@@ -80,21 +80,21 @@ bar (void)
   #pragma omp for schedule (nonmonotonic : auto)	/* { dg-error ".nonmonotonic. modifier specified for .auto. schedule kind" } */
   for (i = 0; i < 64; i++)
     ;
-  #pragma omp for schedule (nonmonotonic, dynamic) ordered	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+  #pragma omp for schedule (nonmonotonic : dynamic) ordered	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
   for (i = 0; i < 64; i++)
     #pragma omp ordered
       ;
-  #pragma omp for ordered schedule(nonmonotonic, dynamic, 5)	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+  #pragma omp for ordered schedule(nonmonotonic : dynamic, 5)	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
   for (i = 0; i < 64; i++)
     #pragma omp ordered
       ;
-  #pragma omp for schedule (nonmonotonic, guided) ordered(1)	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+  #pragma omp for schedule (nonmonotonic : guided) ordered(1)	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
   for (i = 0; i < 64; i++)
     {
       #pragma omp ordered depend(sink: i - 1)
       #pragma omp ordered depend(source)
     }
-  #pragma omp for ordered(1) schedule(nonmonotonic, guided, 2)	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+  #pragma omp for ordered(1) schedule(nonmonotonic : guided, 2)	/* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
   for (i = 0; i < 64; i++)
     {
       #pragma omp ordered depend(source)
--- gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-1.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-1.f90	(revision 265479)
@@ -0,0 +1,63 @@
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+subroutine foo
+  integer :: i
+  !$omp do simd schedule (simd, simd: static, 5)
+  do i = 0, 64
+  end do
+  !$omp do simd schedule (monotonic, simd: static)
+  do i = 0, 64
+  end do
+  !$omp do simd schedule (simd , monotonic : static, 6)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic, monotonic : static, 7)
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic, nonmonotonic : dynamic)
+  do i = 0, 64
+  end do
+  !$omp do simd schedule (nonmonotonic , simd : dynamic, 3)
+  do i = 0, 64
+  end do
+  !$omp do simd schedule (nonmonotonic,simd:guided,4)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic: static, 2)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : static)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : dynamic)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : dynamic, 3)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : guided)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : guided, 7)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : runtime)
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic : auto)
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : dynamic)
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : dynamic, 3)
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : guided)
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : guided, 7)
+  do i = 0, 64
+  end do
+end subroutine foo
--- gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90	(revision 265479)
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+subroutine foo
+  integer :: i
+  !$omp do schedule (nonmonotonic: static, 2)	! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : static)	! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : runtime)	! { dg-error "NONMONOTONIC modifier specified for RUNTIME schedule kind" }
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : auto)	! { dg-error "NONMONOTONIC modifier specified for AUTO schedule kind" }
+  do i = 0, 64
+  end do
+  !$omp do schedule (nonmonotonic : dynamic) ordered	! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
+  do i = 0, 64
+    !$omp ordered
+    !$omp end ordered
+  end do
+  !$omp do ordered schedule(nonmonotonic : dynamic, 5)	! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
+  do i = 0, 64
+    !$omp ordered
+    !$omp end ordered
+  end do
+  !$omp do schedule (nonmonotonic : guided) ordered(1)	! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
+  do i = 0, 64
+    !$omp ordered depend(sink: i - 1)
+    !$omp ordered depend(source)
+  end do
+  !$omp do ordered(1) schedule(nonmonotonic : guided, 2)	! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
+  do i = 0, 64
+    !$omp ordered depend(source)
+    !$ordered depend(sink: i - 1)
+  end do
+  !$omp do schedule (nonmonotonic , monotonic : dynamic)	! { dg-error "Both MONOTONIC and NONMONOTONIC schedule modifiers specified" }
+  do i = 0, 64
+  end do
+  !$omp do schedule (monotonic,nonmonotonic:dynamic)	! { dg-error "Both MONOTONIC and NONMONOTONIC schedule modifiers specified" }
+  do i = 0, 64
+  end do
+end subroutine foo

[-- Attachment #6: r265793 --]
[-- Type: text/plain, Size: 1152 bytes --]

2018-11-05  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/87837
	* match.pd (X + Y < X): Don't optimize if TYPE_OVERFLOW_SANITIZED.

	* c-c++-common/ubsan/pr87837.c: New test.

--- gcc/match.pd	(revision 265792)
+++ gcc/match.pd	(revision 265793)
@@ -1572,6 +1572,7 @@ (define_operator_list COND_TERNARY
   (op:c (plus:c@2 @0 @1) @1)
   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
        && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+       && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
        && (CONSTANT_CLASS_P (@0) || single_use (@2)))
    (op @0 { build_zero_cst (TREE_TYPE (@0)); }))))
 /* For equality, this is also true with wrapping overflow.  */
--- gcc/testsuite/c-c++-common/ubsan/pr87837.c	(nonexistent)
+++ gcc/testsuite/c-c++-common/ubsan/pr87837.c	(revision 265793)
@@ -0,0 +1,18 @@
+/* PR sanitizer/87837 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */
+
+int
+foo (int n)
+{
+  return n + __INT_MAX__ < n;
+}
+
+int
+main ()
+{
+  volatile int a = foo (1);
+  return 0;
+}
+
+/* { dg-output "signed integer overflow: 1 \\+ 2147483647 cannot be represented in type 'int'" } */

[-- Attachment #7: r265794 --]
[-- Type: text/plain, Size: 9872 bytes --]

2018-11-05  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/87859
	* gimple-ssa-store-merging.c (struct merged_store_group): Add
	first_nonmergeable_order member.
	(merged_store_group::merged_store_group): Initialize them.
	(imm_store_chain_info::coalesce_immediate_stores): Don't merge
	stores with order >= first_nonmergeable_order.
	Set merged_store->first_nonmergeable_order if we've skipped any
	stores.  Attempt to merge overlapping INTEGER_CST stores that
	we would otherwise skip.

	* gcc.dg/store_merging_24.c: New test.
	* gcc.dg/store_merging_25.c: New test.

--- gcc/gimple-ssa-store-merging.c	(revision 265793)
+++ gcc/gimple-ssa-store-merging.c	(revision 265794)
@@ -1416,6 +1416,7 @@ struct merged_store_group
   unsigned int load_align[2];
   unsigned int first_order;
   unsigned int last_order;
+  unsigned int first_nonmergeable_order;
 
   auto_vec<store_immediate_info *> stores;
   /* We record the first and last original statements in the sequence because
@@ -1806,6 +1807,7 @@ merged_store_group::merged_store_group (
      width has been finalized.  */
   val = NULL;
   mask = NULL;
+  first_nonmergeable_order = ~0U;
   unsigned HOST_WIDE_INT align_bitpos = 0;
   get_object_alignment_1 (gimple_assign_lhs (info->stmt),
 			  &align, &align_bitpos);
@@ -2640,11 +2642,14 @@ imm_store_chain_info::coalesce_immediate
 	    }
 	}
 
+      if (info->order >= merged_store->first_nonmergeable_order)
+	;
+
       /* |---store 1---|
 	       |---store 2---|
 	 Overlapping stores.  */
-      if (IN_RANGE (info->bitpos, merged_store->start,
-		    merged_store->start + merged_store->width - 1))
+      else if (IN_RANGE (info->bitpos, merged_store->start,
+			 merged_store->start + merged_store->width - 1))
 	{
 	  /* Only allow overlapping stores of constants.  */
 	  if (info->rhs_code == INTEGER_CST
@@ -2676,36 +2681,97 @@ imm_store_chain_info::coalesce_immediate
 		     store_by_bitpos order it comes after the last store that
 		     we can't merge with them.  We can merge the first 3 stores
 		     and keep the last store as is though.  */
-		  unsigned int len = m_store_info.length (), k = i;
-		  for (unsigned int j = i + 1; j < len; ++j)
+		  unsigned int len = m_store_info.length ();
+		  unsigned int try_order = last_order;
+		  unsigned int first_nonmergeable_order;
+		  unsigned int k;
+		  bool last_iter = false;
+		  int attempts = 0;
+		  do
 		    {
-		      store_immediate_info *info2 = m_store_info[j];
-		      if (info2->bitpos >= end)
-			break;
-		      if (info2->order < last_order)
+		      unsigned int max_order = 0;
+		      unsigned first_nonmergeable_int_order = ~0U;
+		      unsigned HOST_WIDE_INT this_end = end;
+		      k = i;
+		      first_nonmergeable_order = ~0U;
+		      for (unsigned int j = i + 1; j < len; ++j)
 			{
-			  if (info2->rhs_code != INTEGER_CST)
+			  store_immediate_info *info2 = m_store_info[j];
+			  if (info2->bitpos >= this_end)
+			    break;
+			  if (info2->order < try_order)
 			    {
-			      /* Normally check_no_overlap makes sure this
-				 doesn't happen, but if end grows below, then
-				 we need to process more stores than
-				 check_no_overlap verified.  Example:
-				    MEM[(int *)p_5] = 0;
-				    MEM[(short *)p_5 + 3B] = 1;
-				    MEM[(char *)p_5 + 4B] = _9;
-				    MEM[(char *)p_5 + 2B] = 2;  */
-			      k = 0;
-			      break;
+			      if (info2->rhs_code != INTEGER_CST)
+				{
+				  /* Normally check_no_overlap makes sure this
+				     doesn't happen, but if end grows below,
+				     then we need to process more stores than
+				     check_no_overlap verified.  Example:
+				      MEM[(int *)p_5] = 0;
+				      MEM[(short *)p_5 + 3B] = 1;
+				      MEM[(char *)p_5 + 4B] = _9;
+				      MEM[(char *)p_5 + 2B] = 2;  */
+				  k = 0;
+				  break;
+				}
+			      k = j;
+			      this_end = MAX (this_end,
+					      info2->bitpos + info2->bitsize);
 			    }
-			  k = j;
-			  end = MAX (end, info2->bitpos + info2->bitsize);
+			  else if (info2->rhs_code == INTEGER_CST
+				   && !last_iter)
+			    {
+			      max_order = MAX (max_order, info2->order + 1);
+			      first_nonmergeable_int_order
+				= MIN (first_nonmergeable_int_order,
+				       info2->order);
+			    }
+			  else
+			    first_nonmergeable_order
+			      = MIN (first_nonmergeable_order, info2->order);
 			}
+		      if (k == 0)
+			{
+			  if (last_order == try_order)
+			    break;
+			  /* If this failed, but only because we grew
+			     try_order, retry with the last working one,
+			     so that we merge at least something.  */
+			  try_order = last_order;
+			  last_iter = true;
+			  continue;
+			}
+		      last_order = try_order;
+		      /* Retry with a larger try_order to see if we could
+			 merge some further INTEGER_CST stores.  */
+		      if (max_order
+			  && (first_nonmergeable_int_order
+			      < first_nonmergeable_order))
+			{
+			  try_order = MIN (max_order,
+					   first_nonmergeable_order);
+			  try_order
+			    = MIN (try_order,
+				   merged_store->first_nonmergeable_order);
+			  if (try_order > last_order && ++attempts < 16)
+			    continue;
+			}
+		      first_nonmergeable_order
+			= MIN (first_nonmergeable_order,
+			       first_nonmergeable_int_order);
+		      end = this_end;
+		      break;
 		    }
+		  while (1);
 
 		  if (k != 0)
 		    {
 		      merged_store->merge_overlapping (info);
 
+		      merged_store->first_nonmergeable_order
+			= MIN (merged_store->first_nonmergeable_order,
+			       first_nonmergeable_order);
+
 		      for (unsigned int j = i + 1; j <= k; j++)
 			{
 			  store_immediate_info *info2 = m_store_info[j];
@@ -2713,7 +2779,8 @@ imm_store_chain_info::coalesce_immediate
 			  if (info2->order < last_order)
 			    {
 			      gcc_assert (info2->rhs_code == INTEGER_CST);
-			      merged_store->merge_overlapping (info2);
+			      if (info != info2)
+				merged_store->merge_overlapping (info2);
 			    }
 			  /* Other stores are kept and not merged in any
 			     way.  */
--- gcc/testsuite/gcc.dg/store_merging_24.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/store_merging_24.c	(revision 265794)
@@ -0,0 +1,75 @@
+/* PR tree-optimization/87859 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-store-merging-details" } */
+/* { dg-final { scan-tree-dump "New sequence of \[23] stmts to replace old one of 19 stmts" "store-merging" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "New sequence of 1 stmts to replace old one of 6 stmts" "store-merging" { target i?86-*-* x86_64-*-* } } } */
+
+struct S {
+  union F {
+    struct T {
+#define A(n) unsigned n:1;
+#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) \
+	     A(n##5) A(n##6) A(n##7) A(n##8) A(n##9)
+      B(f) B(f1) B(f2) B(f3) B(f4) B(f5)
+      A(f60) A(f61) A(f62) A(f63) A(f64) A(f65) A(f66)
+    } q;
+    unsigned int i[3];
+  } f;
+};
+
+struct S s = {
+  .f.q.f0 = 1, .f.q.f1 = 1, .f.q.f2 = 1, .f.q.f5 = 1, .f.q.f6 = 1,
+  .f.q.f7 = 1, .f.q.f8 = 1, .f.q.f9 = 1, .f.q.f13 = 1, .f.q.f14 = 1,
+  .f.q.f15 = 1, .f.q.f16 = 1, .f.q.f17 = 1, .f.q.f19 = 1, .f.q.f21 = 1,
+  .f.q.f66 = 1
+};
+
+__attribute__((noipa)) void
+bar (unsigned *x)
+{
+  if (x[0] != s.f.i[0] || x[1] != s.f.i[1] || x[2] != s.f.i[2])
+    __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+foo (unsigned char *state)
+{
+  struct S i;
+  i.f.i[0] = 0;
+  i.f.i[1] = 0;
+  i.f.i[2] = 0;
+  i.f.q.f7 = 1;
+  i.f.q.f2 = 1;
+  i.f.q.f21 = 1;
+  i.f.q.f19 = 1;
+  i.f.q.f14 = 1;
+  i.f.q.f5 = 1;
+  i.f.q.f0 = 1;
+  i.f.q.f15 = 1;
+  i.f.q.f16 = 1;
+  i.f.q.f6 = 1;
+  i.f.q.f9 = 1;
+  i.f.q.f17 = 1;
+  i.f.q.f1 = 1;
+  i.f.q.f8 = 1;
+  i.f.q.f13 = 1;
+  i.f.q.f66 = 1;
+  if (*state)
+    {
+      i.f.q.f37 = 1;
+      i.f.q.f38 = 1;
+      i.f.q.f39 = 1;
+      i.f.q.f40 = 1;
+      i.f.q.f41 = 1;
+      i.f.q.f36 = 1;
+    }
+  bar (i.f.i);
+}
+
+int
+main ()
+{
+  unsigned char z = 0;
+  foo (&z);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/store_merging_25.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/store_merging_25.c	(revision 265794)
@@ -0,0 +1,75 @@
+/* PR tree-optimization/87859 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-store-merging-details" } */
+/* { dg-final { scan-tree-dump "New sequence of \[23] stmts to replace old one of 14 stmts" "store-merging" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "New sequence of 1 stmts to replace old one of 6 stmts" "store-merging" { target i?86-*-* x86_64-*-* } } } */
+
+struct S {
+  union F {
+    struct T {
+#define A(n) unsigned n:1;
+#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) \
+	     A(n##5) A(n##6) A(n##7) A(n##8) A(n##9)
+      B(f) B(f1) B(f2) B(f3) B(f4) B(f5)
+      A(f60) A(f61) A(f62) A(f63) A(f64) A(f65) A(f66)
+    } q;
+    unsigned int i[3];
+  } f;
+};
+
+struct S s = {
+  .f.q.f0 = 1, .f.q.f1 = 1, .f.q.f2 = 1, .f.q.f5 = 1, .f.q.f6 = 1,
+  .f.q.f7 = 1, .f.q.f8 = 1, .f.q.f9 = 1, .f.q.f13 = 1, .f.q.f14 = 1,
+  .f.q.f15 = 1, .f.q.f16 = 1, .f.q.f17 = 1, .f.q.f19 = 1, .f.q.f21 = 1,
+  .f.q.f66 = 1
+};
+
+__attribute__((noipa)) void
+bar (unsigned *x)
+{
+  if (x[0] != s.f.i[0] || x[1] != s.f.i[1] || x[2] != s.f.i[2])
+    __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+foo (unsigned char *state, unsigned char c)
+{
+  struct S i;
+  i.f.i[0] = 0;
+  i.f.i[1] = 0;
+  i.f.i[2] = 0;
+  i.f.q.f7 = 1;
+  i.f.q.f2 = 1;
+  i.f.q.f21 = 1;
+  i.f.q.f19 = 1;
+  i.f.q.f14 = 1;
+  i.f.q.f5 = 1;
+  i.f.q.f0 = 1;
+  i.f.q.f15 = 1;
+  i.f.q.f16 = 1;
+  i.f.q.f6 = 1;
+  i.f.q.f9 = 1;
+  i.f.q.f17 = c;
+  i.f.q.f1 = 1;
+  i.f.q.f8 = 1;
+  i.f.q.f13 = 1;
+  i.f.q.f66 = 1;
+  if (*state)
+    {
+      i.f.q.f37 = 1;
+      i.f.q.f38 = 1;
+      i.f.q.f39 = 1;
+      i.f.q.f40 = 1;
+      i.f.q.f41 = 1;
+      i.f.q.f36 = 1;
+    }
+  bar (i.f.i);
+}
+
+int
+main ()
+{
+  unsigned char z = 0;
+  foo (&z, 1);
+  return 0;
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Backports to 8.3
@ 2018-07-26 16:41 Jakub Jelinek
  0 siblings, 0 replies; 3+ messages in thread
From: Jakub Jelinek @ 2018-07-26 16:41 UTC (permalink / raw)
  To: gcc-patches

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

Hi!

I've backported 4 commits of mine to gcc-8-branch, after
bootstrapping/regtesting them on x86_64-linux and i686-linux.

	Jakub

[-- Attachment #2: r262535 --]
[-- Type: text/plain, Size: 2616 bytes --]

2018-07-26  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-07-10  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/86421
	* module.c (omp_declare_simd_clauses): Add LINEAR with _REF, _VAL and
	_UVAL suffixes.
	(mio_omp_declare_simd): Save and restore ref, val and uval modifiers
	on linear clauses.  Initialize n->where to gfc_current_locus.

	* gfortran.dg/vect/pr86421.f90: New test.

--- gcc/fortran/module.c	(revision 262534)
+++ gcc/fortran/module.c	(revision 262535)
@@ -4098,6 +4098,9 @@ static const mstring omp_declare_simd_cl
     minit ("UNIFORM", 3),
     minit ("LINEAR", 4),
     minit ("ALIGNED", 5),
+    minit ("LINEAR_REF", 33),
+    minit ("LINEAR_VAL", 34),
+    minit ("LINEAR_UVAL", 35),
     minit (NULL, -1)
 };
 
@@ -4140,7 +4143,10 @@ mio_omp_declare_simd (gfc_namespace *ns,
 	    }
 	  for (n = ods->clauses->lists[OMP_LIST_LINEAR]; n; n = n->next)
 	    {
-	      mio_name (4, omp_declare_simd_clauses);
+	      if (n->u.linear_op == OMP_LINEAR_DEFAULT)
+		mio_name (4, omp_declare_simd_clauses);
+	      else
+		mio_name (32 + n->u.linear_op, omp_declare_simd_clauses);
 	      mio_symbol_ref (&n->sym);
 	      mio_expr (&n->expr);
 	    }
@@ -4181,11 +4187,20 @@ mio_omp_declare_simd (gfc_namespace *ns,
 	    case 4:
 	    case 5:
 	      *ptrs[t - 3] = n = gfc_get_omp_namelist ();
+	    finish_namelist:
+	      n->where = gfc_current_locus;
 	      ptrs[t - 3] = &n->next;
 	      mio_symbol_ref (&n->sym);
 	      if (t != 3)
 		mio_expr (&n->expr);
 	      break;
+	    case 33:
+	    case 34:
+	    case 35:
+	      *ptrs[1] = n = gfc_get_omp_namelist ();
+	      n->u.linear_op = (enum gfc_omp_linear_op) (t - 32);
+	      t = 4;
+	      goto finish_namelist;
 	    }
 	}
     }
--- gcc/testsuite/gfortran.dg/vect/pr86421.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/vect/pr86421.f90	(revision 262535)
@@ -0,0 +1,35 @@
+! PR fortran/86421
+! { dg-require-effective-target vect_simd_clones }
+! { dg-additional-options "-fopenmp-simd" }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+module mod86421
+  implicit none
+contains
+  subroutine foo(x, y, z)
+    real :: x
+    integer :: y, z
+    !$omp declare simd linear(ref(x)) linear(val(y)) linear(uval(z))
+    x = x + y
+    z = z + 1
+  end subroutine
+end module mod86421
+
+program pr86421
+  use mod86421
+  implicit none
+  integer :: i, j
+  real :: a(64)
+  j = 0
+  do i = 1, 64
+    a(i) = i
+  end do
+  !$omp simd
+  do i = 1, 64
+    call foo (a(i), i, j)
+  end do
+  do i = 1, 64
+    if (a(i) .ne. (2 * i)) stop 1
+  end do
+  if (j .ne. 64) stop 2
+end program pr86421

[-- Attachment #3: r262776 --]
[-- Type: text/plain, Size: 3355 bytes --]

2018-07-26  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/86539
	* gimplify.c (gimplify_omp_for): Ensure taskloop firstprivatized init
	and cond temporaries don't have reference type if iterator has
	pointer type.  For init use &for_pre_body instead of pre_p if
	for_pre_body is non-empty.

	* testsuite/libgomp.c++/pr86539.C: New test.

--- gcc/gimplify.c	(revision 262775)
+++ gcc/gimplify.c	(revision 262776)
@@ -9811,9 +9811,26 @@ gimplify_omp_for (tree *expr_p, gimple_s
 	  t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
 	  if (!is_gimple_constant (TREE_OPERAND (t, 1)))
 	    {
+	      tree type = TREE_TYPE (TREE_OPERAND (t, 0));
 	      TREE_OPERAND (t, 1)
 		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
-					   pre_p, NULL, false);
+					   gimple_seq_empty_p (for_pre_body)
+					   ? pre_p : &for_pre_body, NULL,
+					   false);
+	      /* Reference to pointer conversion is considered useless,
+		 but is significant for firstprivate clause.  Force it
+		 here.  */
+	      if (TREE_CODE (type) == POINTER_TYPE
+		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
+		      == REFERENCE_TYPE))
+		{
+		  tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
+		  tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
+				   TREE_OPERAND (t, 1));
+		  gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
+				       ? pre_p : &for_pre_body);
+		  TREE_OPERAND (t, 1) = v;
+		}
 	      tree c = build_omp_clause (input_location,
 					 OMP_CLAUSE_FIRSTPRIVATE);
 	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
@@ -9825,11 +9842,26 @@ gimplify_omp_for (tree *expr_p, gimple_s
 	  t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
 	  if (!is_gimple_constant (TREE_OPERAND (t, 1)))
 	    {
+	      tree type = TREE_TYPE (TREE_OPERAND (t, 0));
 	      TREE_OPERAND (t, 1)
 		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
 					   gimple_seq_empty_p (for_pre_body)
 					   ? pre_p : &for_pre_body, NULL,
 					   false);
+	      /* Reference to pointer conversion is considered useless,
+		 but is significant for firstprivate clause.  Force it
+		 here.  */
+	      if (TREE_CODE (type) == POINTER_TYPE
+		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
+		      == REFERENCE_TYPE))
+		{
+		  tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
+		  tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
+				   TREE_OPERAND (t, 1));
+		  gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
+				       ? pre_p : &for_pre_body);
+		  TREE_OPERAND (t, 1) = v;
+		}
 	      tree c = build_omp_clause (input_location,
 					 OMP_CLAUSE_FIRSTPRIVATE);
 	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
--- libgomp/testsuite/libgomp.c++/pr86539.C	(nonexistent)
+++ libgomp/testsuite/libgomp.c++/pr86539.C	(revision 262776)
@@ -0,0 +1,28 @@
+// PR middle-end/86539
+
+int a[384];
+
+__attribute__((noipa)) void
+foo (int &b, int &c)
+{
+  #pragma omp taskloop shared (a) collapse(3)
+  for (int i = 0; i < 1; i++)
+    for (int *p = &b; p < &c; p++)
+      for (int j = 0; j < 1; j++)
+	if (p < &a[128] || p >= &a[256])
+	  __builtin_abort ();
+	else
+	  p[0]++;
+}
+
+int
+main ()
+{
+  #pragma omp parallel
+  #pragma omp single
+    foo (a[128], a[256]);
+  for (int i = 0; i < 384; i++)
+    if (a[i] != (i >= 128 && i < 256))
+      __builtin_abort ();
+  return 0;
+}

[-- Attachment #4: r262815 --]
[-- Type: text/plain, Size: 2407 bytes --]

2018-07-26  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/86542
	* omp-low.c (create_task_copyfn): Copy over also fields corresponding
	to _looptemp_ clauses, other than the first two.

	* testsuite/libgomp.c++/pr86542.C: New test.

--- gcc/omp-low.c	(revision 262814)
+++ gcc/omp-low.c	(revision 262815)
@@ -7026,6 +7026,7 @@ create_task_copyfn (gomp_task *task_stmt
   splay_tree_node n;
   struct omp_taskcopy_context tcctx;
   location_t loc = gimple_location (task_stmt);
+  size_t looptempno = 0;
 
   child_fn = gimple_omp_task_copy_fn (task_stmt);
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
@@ -7139,6 +7140,15 @@ create_task_copyfn (gomp_task *task_stmt
 	t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
 	append_to_statement_list (t, &list);
 	break;
+      case OMP_CLAUSE__LOOPTEMP_:
+	/* Fields for first two _looptemp_ clauses are initialized by
+	   GOMP_taskloop*, the rest are handled like firstprivate.  */
+        if (looptempno < 2)
+	  {
+	    looptempno++;
+	    break;
+	  }
+	/* FALLTHRU */
       case OMP_CLAUSE_FIRSTPRIVATE:
 	decl = OMP_CLAUSE_DECL (c);
 	if (is_variable_sized (decl))
@@ -7164,7 +7174,10 @@ create_task_copyfn (gomp_task *task_stmt
 	  src = decl;
 	dst = build_simple_mem_ref_loc (loc, arg);
 	dst = omp_build_component_ref (dst, f);
-	t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
+	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__LOOPTEMP_)
+	  t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
+	else
+	  t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
 	append_to_statement_list (t, &list);
 	break;
       case OMP_CLAUSE_PRIVATE:
--- libgomp/testsuite/libgomp.c++/pr86542.C	(nonexistent)
+++ libgomp/testsuite/libgomp.c++/pr86542.C	(revision 262815)
@@ -0,0 +1,37 @@
+// PR middle-end/86542
+
+struct S { int s; S (); ~S (); S (const S &); };
+S s;
+
+S::S ()
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+  s = x.s;
+}
+
+__attribute__((noipa)) void
+foo (int i, int j, int k, S s)
+{
+  if (i != 0 || j != 0 || k != 0 || s.s != 12)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  volatile int inc = 16, jnc = 16, knc = 16;
+  s.s = 12;
+  #pragma omp taskloop collapse (3) firstprivate (s)
+  for (int i = 0; i < 16; i += inc)
+    for (int j = 0; j < 16; j += jnc)
+      for (int k = 0; k < 16; k += knc)
+	foo (i, j, k, s);
+  return 0;
+}

[-- Attachment #5: r262948 --]
[-- Type: text/plain, Size: 1843 bytes --]

2018-07-26  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-07-24  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/86627
	* expmed.c (expand_divmod): Punt if d == HOST_WIDE_INT_MIN
	and size > HOST_BITS_PER_WIDE_INT.  For size > HOST_BITS_PER_WIDE_INT
	and abs_d == d, do the power of two handling if profitable.

	* gcc.target/i386/pr86627.c: New test.

--- gcc/expmed.c	(revision 262947)
+++ gcc/expmed.c	(revision 262948)
@@ -4480,6 +4480,11 @@ expand_divmod (int rem_flag, enum tree_c
 		HOST_WIDE_INT d = INTVAL (op1);
 		unsigned HOST_WIDE_INT abs_d;
 
+		/* Not prepared to handle division/remainder by
+		   0xffffffffffffffff8000000000000000 etc.  */
+		if (d == HOST_WIDE_INT_MIN && size > HOST_BITS_PER_WIDE_INT)
+		  break;
+
 		/* Since d might be INT_MIN, we have to cast to
 		   unsigned HOST_WIDE_INT before negating to avoid
 		   undefined signed overflow.  */
@@ -4522,9 +4527,7 @@ expand_divmod (int rem_flag, enum tree_c
 			     || (optab_handler (sdivmod_optab, int_mode)
 				 != CODE_FOR_nothing)))
 		  ;
-		else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)
-			 && (size <= HOST_BITS_PER_WIDE_INT
-			     || abs_d != (unsigned HOST_WIDE_INT) d))
+		else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
 		  {
 		    if (rem_flag)
 		      {
--- gcc/testsuite/gcc.target/i386/pr86627.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr86627.c	(revision 262948)
@@ -0,0 +1,28 @@
+/* PR middle-end/86627 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "call\[^\n\r]*__divti3" } } */
+
+__int128_t
+f1 (__int128_t a)
+{
+  return a / 2;
+}
+
+__int128_t
+f2 (__int128_t a)
+{
+  return a / -2;
+}
+
+__int128_t
+f3 (__int128_t a)
+{
+  return a / 0x4000000000000000LL;
+}
+
+__int128_t
+f4 (__int128_t a)
+{
+  return a / -0x4000000000000000LL;
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-11-05 14:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-05  7:25 Backports to 8.3 Jakub Jelinek
  -- strict thread matches above, loose matches on Subject: below --
2018-11-05 14:13 Jakub Jelinek
2018-07-26 16:41 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).