Patchwork 4.7 backports

login
register
mail settings
Submitter Jakub Jelinek
Date Feb. 19, 2013, 5:33 p.m.
Message ID <20130219173343.GM1215@tucnak.zalov.cz>
Download mbox | patch
Permalink /patch/221742/
State New
Headers show

Comments

Jakub Jelinek - Feb. 19, 2013, 5:33 p.m.
Hi!

I've backported a bunch of patches from trunk to 4.7, after
bootstrapping/regtesting them on x86_64-linux and i686-linux.

	Jakub
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-11-27  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/55110
	* tree-vect-loop.c (vectorizable_reduction): Don't assert
	that STMT_VINFO_RELATED_STMT of orig_stmt is stmt.

	* gcc.dg/pr55110.c: New test.
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-06  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/56217
	* omp-low.c (use_pointer_for_field): Return false if
	lower_send_shared_vars doesn't generate any copy-out code.

	* g++.dg/gomp/pr56217.C: New test.

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

--- gcc/omp-low.c	(revision 195795)
+++ gcc/omp-low.c	(revision 195796)
@@ -757,12 +757,20 @@ use_pointer_for_field (tree decl, omp_co
       if (TREE_ADDRESSABLE (decl))
 	return true;
 
+      /* lower_send_shared_vars only uses copy-in, but not copy-out
+	 for these.  */
+      if (TREE_READONLY (decl)
+	  || ((TREE_CODE (decl) == RESULT_DECL
+	       || TREE_CODE (decl) == PARM_DECL)
+	      && DECL_BY_REFERENCE (decl)))
+	return false;
+
       /* Disallow copy-in/out in nested parallel if
 	 decl is shared in outer parallel, otherwise
 	 each thread could store the shared variable
 	 in its own copy-in location, making the
 	 variable no longer really shared.  */
-      if (!TREE_READONLY (decl) && shared_ctx->is_nested)
+      if (shared_ctx->is_nested)
 	{
 	  omp_context *up;
 
@@ -785,11 +793,10 @@ use_pointer_for_field (tree decl, omp_co
 	    }
 	}
 
-      /* For tasks avoid using copy-in/out, unless they are readonly
-	 (in which case just copy-in is used).  As tasks can be
+      /* For tasks avoid using copy-in/out.  As tasks can be
 	 deferred or executed in different thread, when GOMP_task
 	 returns, the task hasn't necessarily terminated.  */
-      if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
+      if (is_task_ctx (shared_ctx))
 	{
 	  tree outer;
 	maybe_mark_addressable_and_ret:
--- gcc/testsuite/g++.dg/gomp/pr56217.C	(revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr56217.C	(revision 195796)
@@ -0,0 +1,14 @@
+// PR middle-end/56217
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+struct S { int *p; S (); S (S &); };
+
+S
+foo ()
+{
+  S s;
+  #pragma omp task shared (s)
+    s.p = 0;
+  return s;
+}
--- libgomp/testsuite/libgomp.c++/pr56217.C	(revision 0)
+++ libgomp/testsuite/libgomp.c++/pr56217.C	(revision 195796)
@@ -0,0 +1,36 @@
+// PR middle-end/56217
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+extern "C" void abort ();
+
+template <typename T>
+struct ptr {
+  T *p;
+  ptr () : p () {}
+  ptr (ptr &) = delete;
+  ptr (ptr &&o) : p(o) {}
+  operator T * () { return p; }
+};
+
+int a[6] = { 100, 101, 102, 103, 104, 105 };
+
+static ptr<int>
+f ()
+{
+  ptr<int> pt;
+  #pragma omp task shared (pt)
+    pt.p = a + 2;
+  #pragma omp taskwait
+  return pt;
+}
+
+int
+main ()
+{
+  ptr<int> pt;
+  #pragma omp parallel
+  #pragma omp single
+  if (f () != a + 2 || *f () != 102)
+    abort ();
+}
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-07  Jakub Jelinek  <jakub@redhat.com>

	PR c++/56237
	* decl.c (push_local_name): Look at DECL_DISCRIMINATOR (t)
	only if DECL_DISCRIMINATOR_SET_P (t) rather than just
	DECL_LANG_SPECIFIC (t).

	* g++.dg/abi/mangle61.C: New test.

--- gcc/cp/decl.c	(revision 195857)
+++ gcc/cp/decl.c	(revision 195858)
@@ -920,7 +920,7 @@ push_local_name (tree decl)
 	  if (!DECL_LANG_SPECIFIC (decl))
 	    retrofit_lang_decl (decl);
 	  DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
-	  if (DECL_LANG_SPECIFIC (t))
+	  if (DECL_DISCRIMINATOR_SET_P (t))
 	    DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
 	  else
 	    DECL_DISCRIMINATOR (decl) = 1;
--- gcc/testsuite/g++.dg/abi/mangle61.C	(revision 0)
+++ gcc/testsuite/g++.dg/abi/mangle61.C	(revision 195858)
@@ -0,0 +1,28 @@
+// PR c++/56237
+// { dg-do compile }
+
+void *p[4];
+
+void
+foo ()
+{
+  static union { } u;
+  p[0] = &u;
+  {
+    static union { } u; 
+    p[1] = &u;
+    {
+      static union { } u;
+      p[2] = &u;
+    }
+  }
+  {
+    static union { } u;
+    p[3] = &u;
+  }
+}
+
+// { dg-final { scan-assembler "_ZZ3foovE1u\[^_\]" } }
+// { dg-final { scan-assembler "_ZZ3foovE1u_0" } }
+// { dg-final { scan-assembler "_ZZ3foovE1u_1" } }
+// { dg-final { scan-assembler "_ZZ3foovE1u_2" } }
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-07  Jakub Jelinek  <jakub@redhat.com>
 
	PR c++/56239
	* parser.c (cp_parser_token_starts_cast_expression): Renamed to...
	(cp_parser_tokens_start_cast_expression): ... this.  Change parameter
	to cp_parser *, call cp_lexer_peek_token first.  For CPP_OPEN_PAREN,
	return true only if 2nd token isn't CPP_CLOSE_PAREN.
	(cp_parser_cast_expression): Adjust caller.

	* g++.dg/parse/pr56239.C: New test.

--- gcc/cp/parser.c	(revision 195858)
+++ gcc/cp/parser.c	(revision 195859)
@@ -7091,8 +7091,9 @@ cp_parser_delete_expression (cp_parser*
    otherwise.  */
 
 static bool
-cp_parser_token_starts_cast_expression (cp_token *token)
+cp_parser_tokens_start_cast_expression (cp_parser *parser)
 {
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
   switch (token->type)
     {
     case CPP_COMMA:
@@ -7133,6 +7134,12 @@ cp_parser_token_starts_cast_expression (
     case CPP_EOF:
       return false;
 
+    case CPP_OPEN_PAREN:
+      /* In ((type ()) () the last () isn't a valid cast-expression,
+	 so the whole must be parsed as postfix-expression.  */
+      return cp_lexer_peek_nth_token (parser->lexer, 2)->type
+	     != CPP_CLOSE_PAREN;
+
       /* '[' may start a primary-expression in obj-c++.  */
     case CPP_OPEN_SQUARE:
       return c_dialect_objc ();
@@ -7225,8 +7232,7 @@ cp_parser_cast_expression (cp_parser *pa
 	 parenthesized ctor such as `(T ())' that looks like a cast to
 	 function returning T.  */
       if (!cp_parser_error_occurred (parser)
-	  && cp_parser_token_starts_cast_expression (cp_lexer_peek_token
-						     (parser->lexer)))
+	  && cp_parser_tokens_start_cast_expression (parser))
 	{
 	  cp_parser_parse_definitely (parser);
 	  expr = cp_parser_cast_expression (parser,
--- gcc/testsuite/g++.dg/parse/pr56239.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr56239.C	(revision 195859)
@@ -0,0 +1,13 @@
+// PR c++/56239
+// { dg-do compile }
+
+struct S
+{
+  int operator () () { return 0; }
+};
+
+int
+main ()
+{
+  return (S ()) ();
+}
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-07  Jakub Jelinek  <jakub@redhat.com>

	PR c++/56241
	* init.c (build_vec_init): Don't append NULL values into new_vec.
	(build_zero_init_1): Don't push anything into v if recursive call
	returned NULL_TREE.
	(build_value_init_noctor): Don't push anything into v if
	build_value_init call returned NULL_TREE.

	* g++.dg/parse/crash61.C: New test.

--- gcc/cp/init.c	(revision 195865)
+++ gcc/cp/init.c	(revision 195866)
@@ -254,21 +254,23 @@ build_zero_init_1 (tree type, tree nelts
 	 have an upper bound of -1.  */
       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
 	{
-	  constructor_elt *ce;
-
-	  v = VEC_alloc (constructor_elt, gc, 1);
-	  ce = VEC_quick_push (constructor_elt, v, NULL);
+	  constructor_elt ce;
 
 	  /* If this is a one element array, we just use a regular init.  */
 	  if (tree_int_cst_equal (size_zero_node, max_index))
-	    ce->index = size_zero_node;
+	    ce.index = size_zero_node;
 	  else
-	    ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
-				max_index);
+	    ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
+			       max_index);
 
-	  ce->value = build_zero_init_1 (TREE_TYPE (type),
-					 /*nelts=*/NULL_TREE,
-					 static_storage_p, NULL_TREE);
+	  ce.value = build_zero_init_1 (TREE_TYPE (type),
+					/*nelts=*/NULL_TREE,
+					static_storage_p, NULL_TREE);
+	  if (ce.value)
+	    {
+	      v = VEC_alloc (constructor_elt, gc, 1);
+	      *VEC_quick_push (constructor_elt, v, NULL) = ce;
+	    }
 	}
 
       /* Build a constructor to contain the initializations.  */
@@ -449,28 +451,31 @@ build_value_init_noctor (tree type, tsub
 	 have an upper bound of -1.  */
       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
 	{
-	  constructor_elt *ce;
-
-	  v = VEC_alloc (constructor_elt, gc, 1);
-	  ce = VEC_quick_push (constructor_elt, v, NULL);
+	  constructor_elt ce;
 
 	  /* If this is a one element array, we just use a regular init.  */
 	  if (tree_int_cst_equal (size_zero_node, max_index))
-	    ce->index = size_zero_node;
+	    ce.index = size_zero_node;
 	  else
-	    ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
-				max_index);
+	    ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
+			       max_index);
 
-	  ce->value = build_value_init (TREE_TYPE (type), complain);
+	  ce.value = build_value_init (TREE_TYPE (type), complain);
 
-	  if (ce->value == error_mark_node)
-	    return error_mark_node;
+	  if (ce.value)
+	    {
+	      if (ce.value == error_mark_node)
+		return error_mark_node;
+
+	      v = VEC_alloc (constructor_elt, gc, 1);
+	      *VEC_quick_push (constructor_elt, v, NULL) = ce;
 
-	  /* We shouldn't have gotten here for anything that would need
-	     non-trivial initialization, and gimplify_init_ctor_preeval
-	     would need to be fixed to allow it.  */
-	  gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR
-		      && TREE_CODE (ce->value) != AGGR_INIT_EXPR);
+	      /* We shouldn't have gotten here for anything that would need
+		 non-trivial initialization, and gimplify_init_ctor_preeval
+		 would need to be fixed to allow it.  */
+	      gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
+			  && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
+	    }
 	}
 
       /* Build a constructor to contain the initializations.  */
@@ -3335,9 +3340,12 @@ build_vec_init (tree base, tree maxindex
 	      else
 		{
 		  if (do_static_init)
-		    CONSTRUCTOR_APPEND_ELT (new_vec, field,
-					    build_zero_init (TREE_TYPE (e),
-							     NULL_TREE, true));
+		    {
+		      tree value = build_zero_init (TREE_TYPE (e), NULL_TREE,
+						    true);
+		      if (value)
+			CONSTRUCTOR_APPEND_ELT (new_vec, field, value);
+		    }
 		  saw_non_const = true;
 		}
 	    }
--- gcc/testsuite/g++.dg/parse/crash61.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/crash61.C	(revision 195866)
@@ -0,0 +1,6 @@
+// PR c++/56241
+// { dg-do compile }
+
+struct pair { constexpr pair (const) : }; // { dg-error "" }
+template <0> make_pair () {}		  // { dg-error "" }
+pair prefix[] = { 0, make_pair }	  // { dg-error "" }
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

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

	PR tree-optimization/56250
	* fold-const.c (extract_muldiv_1) <case NEGATE_EXPR>: Don't optimize
	if type is unsigned and code isn't MULT_EXPR.

	* gcc.c-torture/execute/pr56250.c: New test.

--- gcc/fold-const.c	(revision 195887)
+++ gcc/fold-const.c	(revision 195888)
@@ -5695,6 +5695,11 @@ extract_muldiv_1 (tree t, tree c, enum t
         break;
       /* FALLTHROUGH */
     case NEGATE_EXPR:
+      /* For division and modulus, type can't be unsigned, as e.g.
+	 (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2.
+	 For signed types, even with wrapping overflow, this is fine.  */
+      if (code != MULT_EXPR && TYPE_UNSIGNED (type))
+	break;
       if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p))
 	  != 0)
 	return fold_build1 (tcode, ctype, fold_convert (ctype, t1));
--- gcc/testsuite/gcc.c-torture/execute/pr56250.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr56250.c	(revision 195888)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/56250 */
+
+extern void abort (void);
+
+int
+main ()
+{
+  unsigned int x = 2;
+  unsigned int y = (0U - x / 2) / 2;
+  if (-1U / x != y)
+    abort ();
+  return 0;
+}
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-09  Jakub Jelinek  <jakub@redhat.com>

	PR other/56245
	* regex.c (PTR_INT_TYPE): Define.
	(EXTEND_BUFFER): Change incr type from int to PTR_INT_TYPE.

--- libiberty/regex.c	(revision 195917)
+++ libiberty/regex.c	(revision 195918)
@@ -46,9 +46,11 @@
 
 # if defined STDC_HEADERS && !defined emacs
 #  include <stddef.h>
+#  define PTR_INT_TYPE ptrdiff_t
 # else
 /* We need this for `regex.h', and perhaps for the Emacs include files.  */
 #  include <sys/types.h>
+#  define PTR_INT_TYPE long
 # endif
 
 # define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
@@ -2045,7 +2047,7 @@ static reg_errcode_t byte_compile_range
     /* How many characters the new buffer can have?  */			\
     wchar_count = bufp->allocated / sizeof(UCHAR_T);			\
     if (wchar_count == 0) wchar_count = 1;				\
-    /* Truncate the buffer to CHAR_T align.  */			\
+    /* Truncate the buffer to CHAR_T align.  */				\
     bufp->allocated = wchar_count * sizeof(UCHAR_T);			\
     RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T);		\
     bufp->buffer = (char*)COMPILED_BUFFER_VAR;				\
@@ -2054,7 +2056,7 @@ static reg_errcode_t byte_compile_range
     /* If the buffer moved, move all the pointers into it.  */		\
     if (old_buffer != COMPILED_BUFFER_VAR)				\
       {									\
-	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
+	PTR_INT_TYPE incr = COMPILED_BUFFER_VAR - old_buffer;		\
 	MOVE_BUFFER_POINTER (b);					\
 	MOVE_BUFFER_POINTER (begalt);					\
 	if (fixup_alt_jump)						\
@@ -2082,7 +2084,7 @@ static reg_errcode_t byte_compile_range
     /* If the buffer moved, move all the pointers into it.  */		\
     if (old_buffer != COMPILED_BUFFER_VAR)				\
       {									\
-	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
+	PTR_INT_TYPE incr = COMPILED_BUFFER_VAR - old_buffer;		\
 	MOVE_BUFFER_POINTER (b);					\
 	MOVE_BUFFER_POINTER (begalt);					\
 	if (fixup_alt_jump)						\
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/56381
	* tree-ssa-pre.c (create_expression_by_pieces): Fix up last argument
	to fold_build3.

--- gcc/tree-ssa-pre.c	(revision 196132)
+++ gcc/tree-ssa-pre.c	(revision 196133)
@@ -2923,7 +2923,7 @@ create_expression_by_pieces (basic_block
 		break;
 	      case 3:
 		folded = fold_build3 (nary->opcode, nary->type,
-				      genop[0], genop[1], genop[3]);
+				      genop[0], genop[1], genop[2]);
 		break;
 	      default:
 		gcc_unreachable ();
2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-02-19  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/56350
	* tree-vect-loop.c (vectorizable_reduction): If orig_stmt, return false
	if haven't found reduction or nested cycle operand, rather than
	asserting we must find it.

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

--- gcc/tree-vect-loop.c	(revision 196133)
+++ gcc/tree-vect-loop.c	(revision 196134)
@@ -4707,7 +4707,7 @@ vectorizable_reduction (gimple stmt, gim
      The last use is the reduction variable.  In case of nested cycle this
      assumption is not true: we use reduc_index to record the index of the
      reduction variable.  */
-  for (i = 0; i < op_type-1; i++)
+  for (i = 0; i < op_type - 1; i++)
     {
       /* The condition of COND_EXPR is checked in vectorizable_condition().  */
       if (i == 0 && code == COND_EXPR)
@@ -4739,11 +4739,18 @@ vectorizable_reduction (gimple stmt, gim
   if (!vectype_in)
     vectype_in = tem;
   gcc_assert (is_simple_use);
-  gcc_assert (dt == vect_reduction_def
-              || dt == vect_nested_cycle
-              || ((dt == vect_internal_def || dt == vect_external_def
-                   || dt == vect_constant_def || dt == vect_induction_def)
-                   && nested_cycle && found_nested_cycle_def));
+  if (!(dt == vect_reduction_def
+	|| dt == vect_nested_cycle
+	|| ((dt == vect_internal_def || dt == vect_external_def
+	     || dt == vect_constant_def || dt == vect_induction_def)
+	    && nested_cycle && found_nested_cycle_def)))
+    {
+      /* For pattern recognized stmts, orig_stmt might be a reduction,
+	 but some helper statements for the pattern might not, or
+	 might be COND_EXPRs with reduction uses in the condition.  */
+      gcc_assert (orig_stmt);
+      return false;
+    }
   if (!found_nested_cycle_def)
     reduc_def_stmt = def_stmt;
 
--- gcc/testsuite/gcc.dg/pr56350.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr56350.c	(revision 196134)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/56350 */
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-vectorize" } */
+
+int a, b, c;
+
+void
+f (void)
+{
+  for (; c; c++)
+    for (b = 0; b < 2; b++)
+      a /= 8;
+}

Patch

--- gcc/tree-vect-loop.c	(revision 193844)
+++ gcc/tree-vect-loop.c	(revision 193845)
@@ -4624,7 +4624,6 @@  vectorizable_reduction (gimple stmt, gim
   if (orig_stmt)
     {
       orig_stmt_info = vinfo_for_stmt (orig_stmt);
-      gcc_assert (STMT_VINFO_RELATED_STMT (orig_stmt_info) == stmt);
       gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info));
       gcc_assert (!STMT_VINFO_IN_PATTERN_P (stmt_info));
     }
--- gcc/testsuite/gcc.dg/pr55110.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr55110.c	(revision 193845)
@@ -0,0 +1,13 @@ 
+/* PR tree-optimization/55110 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-vectorize" } */
+
+int
+foo (int x)
+{
+  int a, b;
+  for (b = 0; b < 8; b++)
+    for (a = 0; a < 2; a++)
+      x /= 3;
+  return x;
+}