Two obvious loop-iv fixes

Jan Hubicka hubicka@ucw.cz
Sat Oct 13 17:44:00 GMT 2012


Hi,
while proofreading loop-iv for possible cause of the miscompilation that turned
out to be webizer bug I noticed two minor problems.
1) determine_max_iter has path dealing with AND that is bogus, because
   constant argument is always canonized to be second. Enabling the path
   however somethimes leads to worse results, so I improved it a bit
   by combining both estimates.
2) bounds are recorded as signed values intead of unsigned.  This means
   that values with upper bit set gets promoted to almost infinity for
   double int.

Bootstrapped&regtested x86_64-linux, comitted as obvious.

Honza

	* loop-iv.c (determine_max_iter): Fix handling of AND.
	(iv_number_of_iterations): Record upper bounds as unsigned
	values.
Index: loop-iv.c
===================================================================
--- loop-iv.c	(revision 192409)
+++ loop-iv.c	(working copy)
@@ -2224,13 +2224,18 @@ determine_max_iter (struct loop *loop, s
   rtx niter = desc->niter_expr;
   rtx mmin, mmax, cmp;
   unsigned HOST_WIDEST_INT nmax, inc;
+  unsigned HOST_WIDEST_INT andmax = 0;
+
+  /* We used to look for constant operand 0 of AND,
+     but canonicalization should always make this impossible.  */
+  gcc_checking_assert (GET_CODE (niter) != AND
+	               || !CONST_INT_P (XEXP (niter, 0)));
 
   if (GET_CODE (niter) == AND
-      && CONST_INT_P (XEXP (niter, 0)))
+      && CONST_INT_P (XEXP (niter, 1)))
     {
-      nmax = INTVAL (XEXP (niter, 0));
-      if (!(nmax & (nmax + 1)))
-	return nmax;
+      andmax = UINTVAL (XEXP (niter, 1));
+      niter = XEXP (niter, 0);
     }
 
   get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax);
@@ -2258,7 +2263,13 @@ determine_max_iter (struct loop *loop, s
       if (dump_file)
 	fprintf (dump_file, ";; improved upper bound by one.\n");
     }
-  return nmax / inc;
+  nmax /= inc;
+  if (andmax)
+    nmax = MIN (nmax, andmax);
+  if (dump_file)
+    fprintf (dump_file, ";; Determined upper bound "HOST_WIDEST_INT_PRINT_DEC".\n",
+	     nmax);
+  return nmax;
 }
 
 /* Computes number of iterations of the CONDITION in INSN in LOOP and stores
@@ -2563,7 +2574,7 @@ iv_number_of_iterations (struct loop *lo
 			 ? iv0.base
 			 : mode_mmin);
 	  max = (up - down) / inc + 1;
-	  record_niter_bound (loop, double_int::from_shwi (max),
+	  record_niter_bound (loop, double_int::from_uhwi (max),
 			      false, true);
 
 	  if (iv0.step == const0_rtx)
@@ -2776,14 +2787,14 @@ iv_number_of_iterations (struct loop *lo
 
       desc->const_iter = true;
       desc->niter = val & GET_MODE_MASK (desc->mode);
-      record_niter_bound (loop, double_int::from_shwi (desc->niter),
+      record_niter_bound (loop, double_int::from_uhwi (desc->niter),
 			  false, true);
     }
   else
     {
       max = determine_max_iter (loop, desc, old_niter);
       gcc_assert (max);
-      record_niter_bound (loop, double_int::from_shwi (max),
+      record_niter_bound (loop, double_int::from_uhwi (max),
 			  false, true);
 
       /* simplify_using_initial_values does a copy propagation on the registers



More information about the Gcc-patches mailing list