From 20adc5b14897a3705f708982c4887db66d49835d Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 11 Dec 2013 10:19:41 +0100
Subject: [PATCH] re PR tree-optimization/59417 (ICE in determine_value_range,
 at tree-ssa-loop-niter.c:176)

	PR tree-optimization/59417
	* tree-ssa-copy.c (fini_copy_prop): If copy_of[i].value is defined
	in a different bb rhan var, only duplicate points-to info and
	not alignment info and don't duplicate range info.
	* tree-ssa-loop-niter.c (determine_value_range): Instead of
	assertion failure handle inconsistencies in range info by only
	using var's range info and not PHI result range infos.

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

From-SVN: r205884
---
 gcc/ChangeLog                                 |  8 ++++
 gcc/testsuite/ChangeLog                       |  3 ++
 gcc/testsuite/gcc.c-torture/compile/pr59417.c | 39 +++++++++++++++++++
 gcc/tree-ssa-copy.c                           | 20 ++++++++--
 gcc/tree-ssa-loop-niter.c                     | 10 ++++-
 5 files changed, 76 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr59417.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 22caa76f771d..10fae5ac1660 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
 2013-12-11  Jakub Jelinek  <jakub@redhat.com>
 
+	PR tree-optimization/59417
+	* tree-ssa-copy.c (fini_copy_prop): If copy_of[i].value is defined
+	in a different bb rhan var, only duplicate points-to info and
+	not alignment info and don't duplicate range info.
+	* tree-ssa-loop-niter.c (determine_value_range): Instead of
+	assertion failure handle inconsistencies in range info by only
+	using var's range info and not PHI result range infos.
+
 	PR tree-optimization/59386
 	* tree-inline.c (remap_gimple_stmt): If not id->do_not_unshare,
 	unshare_expr (id->retval) before passing it to gimple_build_assign.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ebd99960b42e..b7e72deb7b8a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2013-12-11  Jakub Jelinek  <jakub@redhat.com>
 
+	PR tree-optimization/59417
+	* gcc.c-torture/compile/pr59417.c: New test.
+
 	PR tree-optimization/59386
 	* gcc.c-torture/compile/pr59386.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59417.c b/gcc/testsuite/gcc.c-torture/compile/pr59417.c
new file mode 100644
index 000000000000..227c5d841059
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr59417.c
@@ -0,0 +1,39 @@
+/* PR tree-optimization/59417 */
+
+int a, b, d;
+short c;
+
+void
+f (void)
+{
+  if (b)
+    {
+      int *e;
+
+      if (d)
+	{
+	  for (; b; a++)
+	  lbl1:
+	    d = 0;
+
+	  for (; d <= 1; d++)
+	    {
+	      int **q = &e;
+	      for (**q = 0; **q <= 0; **q++)
+		d = 0;
+	    }
+	}
+    }
+
+  else
+    {
+      int t;
+      for (c = 0; c < 77; c++)
+	for (c = 0; c < 46; c++);
+      for (; t <= 0; t++)
+      lbl2:
+	;
+      goto lbl1;
+    }
+  goto lbl2;
+}
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 3da262b2a771..11daa5f59cb2 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -567,14 +567,28 @@ fini_copy_prop (void)
       if (copy_of[i].value != var
 	  && TREE_CODE (copy_of[i].value) == SSA_NAME)
 	{
+	  basic_block copy_of_bb
+	    = gimple_bb (SSA_NAME_DEF_STMT (copy_of[i].value));
+	  basic_block var_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
 	  if (POINTER_TYPE_P (TREE_TYPE (var))
 	      && SSA_NAME_PTR_INFO (var)
 	      && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	    duplicate_ssa_name_ptr_info (copy_of[i].value,
-					 SSA_NAME_PTR_INFO (var));
+	    {
+	      duplicate_ssa_name_ptr_info (copy_of[i].value,
+					   SSA_NAME_PTR_INFO (var));
+	      /* Points-to information is cfg insensitive,
+		 but alignment info might be cfg sensitive, if it
+		 e.g. is derived from VRP derived non-zero bits.
+		 So, do not copy alignment info if the two SSA_NAMEs
+		 aren't defined in the same basic block.  */
+	      if (var_bb != copy_of_bb)
+		mark_ptr_info_alignment_unknown
+				(SSA_NAME_PTR_INFO (copy_of[i].value));
+	    }
 	  else if (!POINTER_TYPE_P (TREE_TYPE (var))
 		   && SSA_NAME_RANGE_INFO (var)
-		   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+		   && !SSA_NAME_RANGE_INFO (copy_of[i].value)
+		   && var_bb == copy_of_bb)
 	    duplicate_ssa_name_range_info (copy_of[i].value,
 					   SSA_NAME_RANGE_TYPE (var),
 					   SSA_NAME_RANGE_INFO (var));
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 08c8541b490c..a5a76a497c33 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -173,7 +173,15 @@ determine_value_range (struct loop *loop, tree type, tree var, mpz_t off,
 		{
 		  minv = minv.max (minc, TYPE_UNSIGNED (type));
 		  maxv = maxv.min (maxc, TYPE_UNSIGNED (type));
-		  gcc_assert (minv.cmp (maxv, TYPE_UNSIGNED (type)) <= 0);
+		  /* If the PHI result range are inconsistent with
+		     the VAR range, give up on looking at the PHI
+		     results.  This can happen if VR_UNDEFINED is
+		     involved.  */
+		  if (minv.cmp (maxv, TYPE_UNSIGNED (type)) > 0)
+		    {
+		      rtype = get_range_info (var, &minv, &maxv);
+		      break;
+		    }
 		}
 	    }
 	}
-- 
GitLab