diff mbox

Backports to 7.x

Message ID 20170717194944.GM2123@tucnak
State New
Headers show

Commit Message

Jakub Jelinek July 17, 2017, 7:49 p.m. UTC
Hi!

I've bootstrapped/regtested and committed following 5 backports from
mainline to 7.x.

	Jakub
2017-07-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2017-06-30  Jakub Jelinek  <jakub@redhat.com>

	PR target/81225
	* config/i386/sse.md (vec_extract_lo_<mode><mask_name>): For
	V8FI, V16FI and VI8F_256 iterators, use <store_mask_predicate> instead
	of nonimmediate_operand and <store_mask_constraint> instead of m for
	the input operand.  For V8FI iterator, always split if input is a MEM.
	For V16FI and V8SF_256 iterators, don't test if both operands are MEM
	if <mask_applied>.  For VI4F_256 iterator, use <store_mask_predicate>
	instead of register_operand and <store_mask_constraint> instead of v for
	the input operand.  Make sure both operands aren't MEMs for if not
	<mask_applied>.

	* gcc.target/i386/pr81225.c: New test.
2017-07-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2017-07-04  Jakub Jelinek  <jakub@redhat.com>

	PR c++/81258
	* parser.c (cp_parser_decomposition_declaration): Diagnose invalid
	forms of structured binding initializers.

	* g++.dg/cpp1z/decomp21.C (foo): Adjust expected diagnostics.
	* g++.dg/cpp1z/decomp30.C: New test.

--- gcc/cp/parser.c	(revision 249946)
+++ gcc/cp/parser.c	(revision 249947)
@@ -13210,6 +13210,16 @@ cp_parser_decomposition_declaration (cp_
       *init_loc = cp_lexer_peek_token (parser->lexer)->location;
       tree initializer = cp_parser_initializer (parser, &is_direct_init,
 						&non_constant_p);
+      if (initializer == NULL_TREE
+	  || (TREE_CODE (initializer) == TREE_LIST
+	      && TREE_CHAIN (initializer))
+	  || (TREE_CODE (initializer) == CONSTRUCTOR
+	      && CONSTRUCTOR_NELTS (initializer) != 1))
+	{
+	  error_at (loc, "invalid initializer for structured binding "
+		    "declaration");
+	  initializer = error_mark_node;
+	}
 
       if (decl != error_mark_node)
 	{
--- gcc/testsuite/g++.dg/cpp1z/decomp21.C	(revision 249946)
+++ gcc/testsuite/g++.dg/cpp1z/decomp21.C	(revision 249947)
@@ -12,5 +12,6 @@ foo ()
   auto [ n, o, p ] { a };
   auto [ q, r, t ] ( s );
   auto [ u, v, w ] ( s, );      // { dg-error "expected primary-expression before '.' token" }
-  auto [ x, y, z ] ( a );       // { dg-error "expression list treated as compound expression in initializer" "" { target *-*-* } .-1 }
+				// { dg-error "invalid initializer for structured binding declaration" "" { target *-*-* } .-1 }
+  auto [ x, y, z ] ( a );
 }
--- gcc/testsuite/g++.dg/cpp1z/decomp30.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp1z/decomp30.C	(revision 249947)
@@ -0,0 +1,12 @@
+// PR c++/81258
+// { dg-options -std=c++1z }
+
+int a[2];
+auto [b, c] (a);
+auto [d, e] { a };
+auto [f, g] = a;
+auto [h, i] ( a, a );	// { dg-error "invalid initializer for structured binding declaration" }
+auto [j, k] { a, a };	// { dg-error "invalid initializer for structured binding declaration" }
+auto [l, m] = { a };	// { dg-error "deducing from brace-enclosed initializer list requires" }
+auto [n, o] {};		// { dg-error "invalid initializer for structured binding declaration" }
+auto [p, q] ();		// { dg-error "invalid initializer for structured binding declaration" }
2017-07-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2017-07-14  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/81066
	* sanitizer_common/sanitizer_linux.h: Cherry-pick upstream r307969.
	* sanitizer_common/sanitizer_linux.cc: Likewise.
	* sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc: Likewise.
	* tsan/tsan_platform_linux.cc: Likewise.

--- libsanitizer/sanitizer_common/sanitizer_linux.cc	(revision 250199)
+++ libsanitizer/sanitizer_common/sanitizer_linux.cc	(revision 250200)
@@ -605,8 +605,7 @@ uptr internal_prctl(int option, uptr arg
 }
 #endif
 
-uptr internal_sigaltstack(const struct sigaltstack *ss,
-                         struct sigaltstack *oss) {
+uptr internal_sigaltstack(const void *ss, void *oss) {
   return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
 }
 
--- libsanitizer/sanitizer_common/sanitizer_linux.h	(revision 250199)
+++ libsanitizer/sanitizer_common/sanitizer_linux.h	(revision 250200)
@@ -19,7 +19,6 @@
 #include "sanitizer_platform_limits_posix.h"
 
 struct link_map;  // Opaque type returned by dlopen().
-struct sigaltstack;
 
 namespace __sanitizer {
 // Dirent structure for getdents(). Note that this structure is different from
@@ -28,8 +27,7 @@ struct linux_dirent;
 
 // Syscall wrappers.
 uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
-uptr internal_sigaltstack(const struct sigaltstack* ss,
-                          struct sigaltstack* oss);
+uptr internal_sigaltstack(const void* ss, void* oss);
 uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
     __sanitizer_sigset_t *oldset);
 
--- libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc	(revision 250199)
+++ libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc	(revision 250200)
@@ -273,7 +273,7 @@ static int TracerThread(void* argument)
 
   // Alternate stack for signal handling.
   InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize);
-  struct sigaltstack handler_stack;
+  stack_t handler_stack;
   internal_memset(&handler_stack, 0, sizeof(handler_stack));
   handler_stack.ss_sp = handler_stack_memory.data();
   handler_stack.ss_size = kHandlerStackSize;
--- libsanitizer/tsan/tsan_platform_linux.cc	(revision 250199)
+++ libsanitizer/tsan/tsan_platform_linux.cc	(revision 250200)
@@ -287,7 +287,7 @@ void InitializePlatform() {
 int ExtractResolvFDs(void *state, int *fds, int nfd) {
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
   int cnt = 0;
-  __res_state *statp = (__res_state*)state;
+  struct __res_state *statp = (struct __res_state*)state;
   for (int i = 0; i < MAXNS && cnt < nfd; i++) {
     if (statp->_u._ext.nsaddrs[i] && statp->_u._ext.nssocks[i] != -1)
       fds[cnt++] = statp->_u._ext.nssocks[i];
2017-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/81365
	* tree-ssa-phiprop.c (propagate_with_phi): When considering hoisting
	aggregate moves onto bb predecessor edges, make sure there are no
	loads that could alias the lhs in between the start of bb and the
	loads from *phi.

	* g++.dg/torture/pr81365.C: New test.

--- gcc/tree-ssa-phiprop.c	(revision 250260)
+++ gcc/tree-ssa-phiprop.c	(revision 250261)
@@ -327,7 +327,7 @@ propagate_with_phi (basic_block bb, gphi
       if (!dominated_by_p (CDI_POST_DOMINATORS,
 			   bb, gimple_bb (use_stmt)))
 	continue;
-         
+
       /* Check whether this is a load of *ptr.  */
       if (!(is_gimple_assign (use_stmt)
 	    && gimple_assign_rhs_code (use_stmt) == MEM_REF
@@ -356,6 +356,9 @@ propagate_with_phi (basic_block bb, gphi
          insert aggregate copies on the edges instead.  */
       if (!is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
 	{
+	  if (!gimple_vdef (use_stmt))
+	    goto next;
+
 	  /* As we replicate the lhs on each incoming edge all
 	     used SSA names have to be available there.  */
 	  if (! for_each_index (gimple_assign_lhs_ptr (use_stmt),
@@ -363,6 +366,28 @@ propagate_with_phi (basic_block bb, gphi
 				get_immediate_dominator (CDI_DOMINATORS,
 							 gimple_bb (phi))))
 	    goto next;
+
+	  gimple *vuse_stmt;
+	  imm_use_iterator vui;
+	  use_operand_p vuse_p;
+	  /* In order to move the aggregate copies earlier, make sure
+	     there are no statements that could read from memory
+	     aliasing the lhs in between the start of bb and use_stmt.
+	     As we require use_stmt to have a VDEF above, loads after
+	     use_stmt will use a different virtual SSA_NAME.  */
+	  FOR_EACH_IMM_USE_FAST (vuse_p, vui, vuse)
+	    {
+	      vuse_stmt = USE_STMT (vuse_p);
+	      if (vuse_stmt == use_stmt)
+		continue;
+	      if (!dominated_by_p (CDI_DOMINATORS,
+				   gimple_bb (vuse_stmt), bb))
+		continue;
+	      if (ref_maybe_used_by_stmt_p (vuse_stmt,
+					    gimple_assign_lhs (use_stmt)))
+		goto next;
+	    }
+
 	  phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
 
 	  /* Remove old stmt.  The phi is taken care of by DCE.  */
--- gcc/testsuite/g++.dg/torture/pr81365.C	(nonexistent)
+++ gcc/testsuite/g++.dg/torture/pr81365.C	(revision 250261)
@@ -0,0 +1,39 @@
+// PR tree-optimization/81365
+// { dg-do run }
+
+struct A { unsigned a; };
+
+struct B {
+  B (const A *x)
+  {
+    __builtin_memcpy (b, x, 3 * sizeof (A));
+    __builtin_memcpy (c, x + 3, sizeof (A));
+    __builtin_memset (c + 1, 0, sizeof (A));
+  }
+  bool
+  foo (unsigned x)
+  {
+    A *it = c;
+    if (it->a == x || (++it)->a == x)
+      {
+	A t(b[0]);
+	b[0] = *it;
+	*it = t;
+	return true;
+      }
+    return false;
+  }
+  A b[3];
+  A c[2];
+};
+
+int
+main ()
+{
+  A x[] = { 4, 8, 12, 18 };
+  B y(x);
+  if (!y.foo (18))
+    __builtin_abort ();
+  if (!y.foo (4))
+    __builtin_abort ();
+}
2017-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/81428
	* match.pd (X / X -> one): Don't optimize _Fract divisions, as 1
	can't be built for those types.

	* gcc.dg/fixed-point/pr81428.c: New test.

--- gcc/match.pd	(revision 250264)
+++ gcc/match.pd	(revision 250265)
@@ -243,8 +243,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  /* X / X is one.  */
  (simplify
   (div @0 @0)
-  /* But not for 0 / 0 so that we can get the proper warnings and errors.  */
-  (if (!integer_zerop (@0))
+  /* But not for 0 / 0 so that we can get the proper warnings and errors.
+     And not for _Fract types where we can't build 1.  */
+  (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type)))
    { build_one_cst (type); }))
  /* X / abs (X) is X < 0 ? -1 : 1.  */ 
  (simplify
--- gcc/testsuite/gcc.dg/fixed-point/pr81428.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/fixed-point/pr81428.c	(revision 250265)
@@ -0,0 +1,9 @@
+/* PR tree-optimization/81428 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+foo (long _Fract *a, long _Fract *b)
+{
+  *b = *a / *a;
+}
diff mbox

Patch

--- gcc/config/i386/sse.md	(revision 249843)
+++ gcc/config/i386/sse.md	(revision 249844)
@@ -7359,13 +7359,13 @@  (define_insn "vec_extract_lo_<mode>_mask
 (define_insn "vec_extract_lo_<mode><mask_name>"
   [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=<store_mask_constraint>,v")
 	(vec_select:<ssehalfvecmode>
-	  (match_operand:V8FI 1 "nonimmediate_operand" "v,m")
+	  (match_operand:V8FI 1 "<store_mask_predicate>" "v,<store_mask_constraint>")
 	  (parallel [(const_int 0) (const_int 1)
             (const_int 2) (const_int 3)])))]
   "TARGET_AVX512F
    && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
-  if (<mask_applied> || !TARGET_AVX512VL)
+  if (<mask_applied> || (!TARGET_AVX512VL && !MEM_P (operands[1])))
     return "vextract<shuffletype>64x4\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
   else
     return "#";
@@ -7515,14 +7515,15 @@  (define_expand "avx_vextractf128<mode>"
 (define_insn "vec_extract_lo_<mode><mask_name>"
   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=v,m")
 	(vec_select:<ssehalfvecmode>
-	  (match_operand:V16FI 1 "nonimmediate_operand" "vm,v")
+	  (match_operand:V16FI 1 "<store_mask_predicate>"
+				 "<store_mask_constraint>,v")
 	  (parallel [(const_int 0) (const_int 1)
                      (const_int 2) (const_int 3)
                      (const_int 4) (const_int 5)
                      (const_int 6) (const_int 7)])))]
   "TARGET_AVX512F
    && <mask_mode512bit_condition>
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+   && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
   if (<mask_applied>)
     return "vextract<shuffletype>32x8\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
@@ -7546,11 +7547,12 @@  (define_split
 (define_insn "vec_extract_lo_<mode><mask_name>"
   [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=v,m")
 	(vec_select:<ssehalfvecmode>
-	  (match_operand:VI8F_256 1 "nonimmediate_operand" "vm,v")
+	  (match_operand:VI8F_256 1 "<store_mask_predicate>"
+				    "<store_mask_constraint>,v")
 	  (parallel [(const_int 0) (const_int 1)])))]
   "TARGET_AVX
    && <mask_avx512vl_condition> && <mask_avx512dq_condition>
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+   && (<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}";
@@ -7610,12 +7612,16 @@  (define_split
   "operands[1] = gen_lowpart (<ssehalfvecmode>mode, operands[1]);")
 
 (define_insn "vec_extract_lo_<mode><mask_name>"
-  [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=<store_mask_constraint>")
+  [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>"
+					  "=<store_mask_constraint>,v")
 	(vec_select:<ssehalfvecmode>
-	  (match_operand:VI4F_256 1 "register_operand" "v")
+	  (match_operand:VI4F_256 1 "<store_mask_predicate>"
+				    "v,<store_mask_constraint>")
 	  (parallel [(const_int 0) (const_int 1)
 		     (const_int 2) (const_int 3)])))]
-  "TARGET_AVX && <mask_avx512vl_condition> && <mask_avx512dq_condition>"
+  "TARGET_AVX
+   && <mask_avx512vl_condition> && <mask_avx512dq_condition>
+   && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
   if (<mask_applied>)
     return "vextract<shuffletype>32x4\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
--- gcc/testsuite/gcc.target/i386/pr81225.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr81225.c	(revision 249844)
@@ -0,0 +1,14 @@ 
+/* PR target/81225 */
+/* { dg-do compile } */
+/* { dg-options "-mavx512ifma -O3 -ffloat-store" } */
+
+long a[24];
+float b[4], c[24];
+int d;
+
+void
+foo ()
+{
+  for (d = 0; d < 24; d++)
+    c[d] = (float) d ? : b[a[d]];
+}