From f29deac9bd4ae965809d7735631f707e38b40f82 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <sebastian.pop@amd.com>
Date: Wed, 21 Oct 2009 23:05:39 +0000
Subject: [PATCH] re PR tree-optimization/41497 (apparent integer wrong code
 bug)

	PR tree-optimization/41497
	* tree-scalar-evolution.c (analyze_evolution_in_loop): Return
	chrec_dont_know if the evolution function returned by follow_ssa_edge
	is constant in the analyzed loop and is not compatible with the
	initial value before the loop.
	* tree-chrec.h (no_evolution_in_loop_p): Call STRIP_NOPS.

	* gcc.dg/tree-ssa/pr41497.c: New.

From-SVN: r153441
---
 gcc/ChangeLog                           |  9 +++++++++
 gcc/testsuite/ChangeLog                 |  5 +++++
 gcc/testsuite/gcc.dg/tree-ssa/pr41497.c | 27 +++++++++++++++++++++++++
 gcc/tree-chrec.h                        |  1 +
 gcc/tree-scalar-evolution.c             | 15 ++++++++++++--
 5 files changed, 55 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr41497.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf2bc8f38573..d5e3ce94a1f3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2009-10-21  Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/41497
+	* tree-scalar-evolution.c (analyze_evolution_in_loop): Return
+	chrec_dont_know if the evolution function returned by follow_ssa_edge
+	is constant in the analyzed loop and is not compatible with the
+	initial value before the loop.
+	* tree-chrec.h (no_evolution_in_loop_p): Call STRIP_NOPS.
+
 2009-10-21  Joseph Myers  <joseph@codesourcery.com>
 
 	* config/sh/sh.c (nonpic_symbol_mentioned_p): Allow UNSPEC_TPOFF.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 75eb83d76ee5..d8b50b7b18d0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-21  Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/41497
+	* gcc.dg/tree-ssa/pr41497.c: New.
+
 2009-10-21  Steve Ellcey  <sje@cup.hp.com>
 
 	* g++.dg/tree-ssa/copyprop.C: Use include to define free().
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr41497.c b/gcc/testsuite/gcc.dg/tree-ssa/pr41497.c
new file mode 100644
index 000000000000..e66ee846491c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr41497.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+extern void abort (void);
+
+unsigned int a;
+int b, c;
+
+void
+foo (void)
+{
+  b = 0;
+  do {
+    for (a = -13; a == 0; a = (unsigned short)a)
+      c = 1;
+    b++;
+  } while (b == 0);
+}
+
+int
+main ()
+{
+  foo ();
+  if (a != -13)
+    abort ();
+  return 0;
+}
diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h
index f21aa74d795f..545db38a7308 100644
--- a/gcc/tree-chrec.h
+++ b/gcc/tree-chrec.h
@@ -115,6 +115,7 @@ no_evolution_in_loop_p (tree chrec, unsigned loop_num, bool *res)
       || chrec_contains_symbols_defined_in_loop (chrec, loop_num))
     return false;
 
+  STRIP_NOPS (chrec);
   scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num);
   *res = !tree_is_chrec (scev);
   return true;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 02a4eed646ea..70af0fda610e 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1492,18 +1492,29 @@ analyze_evolution_in_loop (gimple loop_phi_node,
       bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
       if (!flow_bb_inside_loop_p (loop, bb))
 	continue;
-      
+
       if (TREE_CODE (arg) == SSA_NAME)
 	{
+	  bool val = false;
+
 	  ssa_chain = SSA_NAME_DEF_STMT (arg);
 
 	  /* Pass in the initial condition to the follow edge function.  */
 	  ev_fn = init_cond;
 	  res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn, 0);
+
+	  /* If ev_fn has no evolution in the inner loop, and the
+	     init_cond is not equal to ev_fn, then we have an
+	     ambiguity between two possible values, as we cannot know
+	     the number of iterations at this point.  */
+	  if (TREE_CODE (ev_fn) != POLYNOMIAL_CHREC
+	      && no_evolution_in_loop_p (ev_fn, loop->num, &val) && val
+	      && !operand_equal_p (init_cond, ev_fn, 0))
+	    ev_fn = chrec_dont_know;
 	}
       else
 	res = t_false;
-	      
+
       /* When it is impossible to go back on the same
 	 loop_phi_node by following the ssa edges, the
 	 evolution is represented by a peeled chrec, i.e. the
-- 
GitLab