Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	(revision 184625)
+++ gcc/tree-scalar-evolution.c	(working copy)
@@ -474,11 +474,22 @@
 	    return chrec_dont_know;
 	  else
 	    {
+	      tree type = TREE_TYPE (evolution_fn), utype = type;
 	      tree res;
 
+	      /* Since the number of iterations is always unsigned, we perform
+		 the computation in an unsigned type (if feasible) to allow for
+		 improved simplification of subexpressions.  */
+	      if ((INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
+		  || POINTER_TYPE_P (type))
+		utype = build_nonstandard_integer_type
+			  (TYPE_PRECISION (type), 1);
+
 	      /* evolution_fn is the evolution function in LOOP.  Get
 		 its value in the nb_iter-th iteration.  */
-	      res = chrec_apply (inner_loop->num, evolution_fn, nb_iter);
+	      res = chrec_convert (utype, evolution_fn, NULL);
+	      res = chrec_apply (inner_loop->num, res, nb_iter);
+	      res = chrec_convert (type, res, NULL);
 
 	      if (chrec_contains_symbols_defined_in_loop (res, loop->num))
 		res = instantiate_parameters (loop, res);



Patch: Use STRIP_NOPS on subexpressions in fold_plusminus_mult_expr

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 184625)
+++ gcc/fold-const.c	(working copy)
@@ -7081,6 +7081,8 @@
     {
       arg00 = TREE_OPERAND (arg0, 0);
       arg01 = TREE_OPERAND (arg0, 1);
+      STRIP_NOPS (arg00);
+      STRIP_NOPS (arg01);
     }
   else if (TREE_CODE (arg0) == INTEGER_CST)
     {
@@ -7099,6 +7101,8 @@
     {
       arg10 = TREE_OPERAND (arg1, 0);
       arg11 = TREE_OPERAND (arg1, 1);
+      STRIP_NOPS (arg10);
+      STRIP_NOPS (arg11);
     }
   else if (TREE_CODE (arg1) == INTEGER_CST)
     {



Patch: Use STRIP_NOPS when following scalar evolutions

Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	(revision 184625)
+++ gcc/tree-scalar-evolution.c	(working copy)
@@ -1154,8 +1165,8 @@
       rhs0 = TREE_OPERAND (expr, 0);
       rhs1 = TREE_OPERAND (expr, 1);
       type = TREE_TYPE (rhs0);
-      STRIP_USELESS_TYPE_CONVERSION (rhs0);
-      STRIP_USELESS_TYPE_CONVERSION (rhs1);
+      STRIP_NOPS (rhs0);
+      STRIP_NOPS (rhs1);
       res = follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
 				    halting_phi, evolution_of_loop, limit);
       break;
@@ -1168,8 +1179,8 @@
 	  rhs0 = TREE_OPERAND (expr, 0);
 	  rhs1 = TREE_OPERAND (expr, 1);
 	  type = TREE_TYPE (rhs0);
-	  STRIP_USELESS_TYPE_CONVERSION (rhs0);
-	  STRIP_USELESS_TYPE_CONVERSION (rhs1);
+	  STRIP_NOPS (rhs0);
+	  STRIP_NOPS (rhs1);
 	  res = follow_ssa_edge_binary (loop, at_stmt, type,
 					rhs0, POINTER_PLUS_EXPR, rhs1,
 					halting_phi, evolution_of_loop, limit);
