This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR66375


The following patch fixes PR66375, SCEV computing a wrong evolution
for the loop PHI node defining 'c', ignoring the conversion to/from char.

The issue here is, I believe, that we first follow the SSA edge but
only then add to the evolution, so the SSA edge following transfers
the initial condition (a constant) while it really should transfer
the evolution { init, +, step }.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2015-06-03  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/66375
	* tree-scalar-evolution.c (follow_ssa_edge_binary): First
	add to the evolution before following SSA edges.

	* gcc.dg/torture/pr66375.c: New testcase.

Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	(revision 224028)
+++ gcc/tree-scalar-evolution.c	(working copy)
@@ -958,27 +958,25 @@ follow_ssa_edge_binary (struct loop *loo
 	      limit++;
 
 	      evol = *evolution_of_loop;
-	      res = follow_ssa_edge
-		(loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit);
-
-	      if (res == t_true)
-		*evolution_of_loop = add_to_evolution
+	      evol = add_to_evolution
 		  (loop->num,
 		   chrec_convert (type, evol, at_stmt),
 		   code, rhs1, at_stmt);
-
+	      res = follow_ssa_edge
+		(loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit);
+	      if (res == t_true)
+		*evolution_of_loop = evol;
 	      else if (res == t_false)
 		{
+		  *evolution_of_loop = add_to_evolution
+		      (loop->num,
+		       chrec_convert (type, *evolution_of_loop, at_stmt),
+		       code, rhs0, at_stmt);
 		  res = follow_ssa_edge
 		    (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
 		     evolution_of_loop, limit);
-
 		  if (res == t_true)
-		    *evolution_of_loop = add_to_evolution
-		      (loop->num,
-		       chrec_convert (type, *evolution_of_loop, at_stmt),
-		       code, rhs0, at_stmt);
-
+		    ;
 		  else if (res == t_dont_know)
 		    *evolution_of_loop = chrec_dont_know;
 		}
@@ -991,15 +989,15 @@ follow_ssa_edge_binary (struct loop *loo
 	    {
 	      /* Match an assignment under the form:
 		 "a = b + ...".  */
+	      *evolution_of_loop = add_to_evolution
+		  (loop->num, chrec_convert (type, *evolution_of_loop,
+					     at_stmt),
+		   code, rhs1, at_stmt);
 	      res = follow_ssa_edge
 		(loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
 		 evolution_of_loop, limit);
 	      if (res == t_true)
-		*evolution_of_loop = add_to_evolution
-		  (loop->num, chrec_convert (type, *evolution_of_loop,
-					     at_stmt),
-		   code, rhs1, at_stmt);
-
+		;	
 	      else if (res == t_dont_know)
 		*evolution_of_loop = chrec_dont_know;
 	    }
@@ -1009,15 +1007,15 @@ follow_ssa_edge_binary (struct loop *loo
 	{
 	  /* Match an assignment under the form:
 	     "a = ... + c".  */
+	  *evolution_of_loop = add_to_evolution
+	      (loop->num, chrec_convert (type, *evolution_of_loop,
+					 at_stmt),
+	       code, rhs0, at_stmt);
 	  res = follow_ssa_edge
 	    (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
 	     evolution_of_loop, limit);
 	  if (res == t_true)
-	    *evolution_of_loop = add_to_evolution
-	      (loop->num, chrec_convert (type, *evolution_of_loop,
-					 at_stmt),
-	       code, rhs0, at_stmt);
-
+	    ;
 	  else if (res == t_dont_know)
 	    *evolution_of_loop = chrec_dont_know;
 	}
@@ -1042,13 +1040,13 @@ follow_ssa_edge_binary (struct loop *loo
 	  if (TREE_CODE (rhs1) == SSA_NAME)
 	    limit++;
 
+	  *evolution_of_loop = add_to_evolution
+	      (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt),
+	       MINUS_EXPR, rhs1, at_stmt);
 	  res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
 				 evolution_of_loop, limit);
 	  if (res == t_true)
-	    *evolution_of_loop = add_to_evolution
-	      (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt),
-	       MINUS_EXPR, rhs1, at_stmt);
-
+	    ;
 	  else if (res == t_dont_know)
 	    *evolution_of_loop = chrec_dont_know;
 	}
Index: gcc/testsuite/gcc.dg/torture/pr66375.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr66375.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr66375.c	(working copy)
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+int a;
+extern void abort (void);
+int main ()
+{
+  int c = 0;
+  for (; a < 13; ++a)
+    c = (signed char)c - 11;
+  if (c != 113)
+    abort ();
+  return 0;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]