public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* 4.7 backports
@ 2013-02-19 17:33 Jakub Jelinek
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2013-02-19 17:33 UTC (permalink / raw)
  To: gcc-patches

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

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

[-- Attachment #2: r193845 --]
[-- Type: text/plain, Size: 1061 bytes --]

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.

--- 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;
+}

[-- Attachment #3: r195796 --]
[-- Type: text/plain, Size: 2721 bytes --]

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 ();
+}

[-- Attachment #4: r195858 --]
[-- Type: text/plain, Size: 1346 bytes --]

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" } }

[-- Attachment #5: r195859 --]
[-- Type: text/plain, Size: 2073 bytes --]

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 ()) ();
+}

[-- Attachment #6: r195866 --]
[-- Type: text/plain, Size: 4153 bytes --]

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 "" }

[-- Attachment #7: r195888 --]
[-- Type: text/plain, Size: 1277 bytes --]

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;
+}

[-- Attachment #8: r195918 --]
[-- Type: text/plain, Size: 1986 bytes --]

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)						\

[-- Attachment #9: r196133 --]
[-- Type: text/plain, Size: 593 bytes --]

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 ();

[-- Attachment #10: r196134 --]
[-- Type: text/plain, Size: 2199 bytes --]

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;
+}

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

* 4.7 backports
@ 2013-04-03 10:36 Jakub Jelinek
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2013-04-03 10:36 UTC (permalink / raw)
  To: gcc-patches

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

Hi!

I've backported, bootstrapped/regtested and committed the following two
patches to 4.7 branch.

	Jakub

[-- Attachment #2: gcc47-pr56510.patch --]
[-- Type: text/plain, Size: 3940 bytes --]

2013-04-03  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-03-05  Jakub Jelinek  <jakub@redhat.com>

	PR debug/56510
	* cfgexpand.c (expand_debug_parm_decl): Call copy_rtx on incoming.
	(avoid_complex_debug_insns): New function.
	(expand_debug_locations): Call it.

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

--- gcc/cfgexpand.c	(revision 196478)
+++ gcc/cfgexpand.c	(revision 196479)
@@ -2622,6 +2622,8 @@ expand_debug_parm_decl (tree decl)
 	      reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
 	      incoming = replace_equiv_address_nv (incoming, reg);
 	    }
+	  else
+	    incoming = copy_rtx (incoming);
 	}
 #endif
 
@@ -2637,7 +2639,7 @@ expand_debug_parm_decl (tree decl)
 	  || (GET_CODE (XEXP (incoming, 0)) == PLUS
 	      && XEXP (XEXP (incoming, 0), 0) == virtual_incoming_args_rtx
 	      && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
-    return incoming;
+    return copy_rtx (incoming);
 
   return NULL_RTX;
 }
@@ -3704,6 +3706,56 @@ expand_debug_source_expr (tree exp)
   return op0;
 }
 
+/* Ensure INSN_VAR_LOCATION_LOC (insn) doesn't have unbound complexity.
+   Allow 4 levels of rtl nesting for most rtl codes, and if we see anything
+   deeper than that, create DEBUG_EXPRs and emit DEBUG_INSNs before INSN.  */
+
+static void
+avoid_complex_debug_insns (rtx insn, rtx *exp_p, int depth)
+{
+  rtx exp = *exp_p;
+
+  if (exp == NULL_RTX)
+    return;
+
+  if ((OBJECT_P (exp) && !MEM_P (exp)) || GET_CODE (exp) == CLOBBER)
+    return;
+
+  if (depth == 4)
+    {
+      /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
+      rtx dval = make_debug_expr_from_rtl (exp);
+
+      /* Emit a debug bind insn before INSN.  */
+      rtx bind = gen_rtx_VAR_LOCATION (GET_MODE (exp),
+				       DEBUG_EXPR_TREE_DECL (dval), exp,
+				       VAR_INIT_STATUS_INITIALIZED);
+
+      emit_debug_insn_before (bind, insn);
+      *exp_p = dval;
+      return;
+    }
+
+  const char *format_ptr = GET_RTX_FORMAT (GET_CODE (exp));
+  int i, j;
+  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
+    switch (*format_ptr++)
+      {
+      case 'e':
+	avoid_complex_debug_insns (insn, &XEXP (exp, i), depth + 1);
+	break;
+
+      case 'E':
+      case 'V':
+	for (j = 0; j < XVECLEN (exp, i); j++)
+	  avoid_complex_debug_insns (insn, &XVECEXP (exp, i, j), depth + 1);
+	break;
+
+      default:
+	break;
+      }
+}
+
 /* Expand the _LOCs in debug insns.  We run this after expanding all
    regular insns, so that any variables referenced in the function
    will have their DECL_RTLs set.  */
@@ -3724,7 +3776,7 @@ expand_debug_locations (void)
     if (DEBUG_INSN_P (insn))
       {
 	tree value = (tree)INSN_VAR_LOCATION_LOC (insn);
-	rtx val;
+	rtx val, prev_insn, insn2;
 	enum machine_mode mode;
 
 	if (value == NULL_TREE)
@@ -3753,6 +3805,9 @@ expand_debug_locations (void)
 	  }
 
 	INSN_VAR_LOCATION_LOC (insn) = val;
+	prev_insn = PREV_INSN (insn);
+	for (insn2 = insn; insn2 != prev_insn; insn2 = PREV_INSN (insn2))
+	  avoid_complex_debug_insns (insn2, &INSN_VAR_LOCATION_LOC (insn2), 0);
       }
 
   flag_strict_aliasing = save_strict_alias;
--- gcc/testsuite/gcc.dg/pr56510.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr56510.c	(revision 196479)
@@ -0,0 +1,37 @@
+/* PR debug/56510 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+struct S { unsigned long s1; void **s2[0]; };
+void **a, **b, **c, **d, **e, **f;
+
+static void **
+baz (long x, long y)
+{
+  void **s = f;
+  *f = (void **) (y << 8 | (x & 0xff));
+  f += y + 1;
+  return s;
+}
+
+void bar (void);
+void
+foo (void)
+{
+  void **g = b[4];
+  a = b[2];
+  b = b[1];
+  g[2] = e;
+  void **h
+    = ((void **************************)
+       a)[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][66];
+  void **i = ((struct S *) h)->s2[4];
+  d = baz (4, 3);
+  d[1] = b;
+  d[2] = a;
+  d[3] = bar;
+  b = d;
+  g[1] = i[2];
+  a = g;
+  ((void (*) (void)) (i[1])) ();
+}

[-- Attachment #3: gcc47-pr56539.patch --]
[-- Type: text/plain, Size: 1567 bytes --]

2013-04-03  Jakub Jelinek  <jakub@redhat.com>

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

	PR tree-optimization/56539
	* tree-tailcall.c (adjust_return_value_with_ops): Use GSI_SAME_STMT
	instead of GSI_CONTINUE_LINKING as last argument to
	force_gimple_operand_gsi.  Adjust function comment.

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

--- gcc/tree-tailcall.c	(revision 196510)
+++ gcc/tree-tailcall.c	(revision 196511)
@@ -601,8 +601,8 @@ add_successor_phi_arg (edge e, tree var,
 }
 
 /* Creates a GIMPLE statement which computes the operation specified by
-   CODE, OP0 and OP1 to a new variable with name LABEL and inserts the
-   statement in the position specified by GSI and UPDATE.  Returns the
+   CODE, ACC and OP1 to a new variable with name LABEL and inserts the
+   statement in the position specified by GSI.  Returns the
    tree node of the statement's result.  */
 
 static tree
@@ -627,7 +627,7 @@ adjust_return_value_with_ops (enum tree_
 					    fold_convert (TREE_TYPE (op1), acc),
 					    op1));
       rhs = force_gimple_operand_gsi (&gsi, rhs,
-				      false, NULL, true, GSI_CONTINUE_LINKING);
+				      false, NULL, true, GSI_SAME_STMT);
       stmt = gimple_build_assign (NULL_TREE, rhs);
     }
 
--- gcc/testsuite/gcc.c-torture/compile/pr56539.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr56539.c	(revision 196511)
@@ -0,0 +1,7 @@
+/* PR tree-optimization/56539 */
+
+short
+foo (const char *x, unsigned y)
+{
+  return y > 1 ? (x[y - 1] - '0') + 10 * foo (x, y - 1) : (*x - '0');
+}

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

end of thread, other threads:[~2013-04-03  8:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-19 17:33 4.7 backports Jakub Jelinek
2013-04-03 10:36 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).