Patchwork Two obvious loop-iv fixes

login
register
mail settings
Submitter Jan Hubicka
Date Oct. 13, 2012, 4:54 p.m.
Message ID <20121013165410.GA5237@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/191301/
State New
Headers show

Comments

Jan Hubicka - Oct. 13, 2012, 4:54 p.m.
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.
Steven Bosscher - Oct. 13, 2012, 4:59 p.m.
On Sat, Oct 13, 2012 at 6:54 PM, Jan Hubicka wrote:
> 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.

Could you check and see if this change fixes PR54919?

Ciao!
Steven

Patch

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