]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
loop-iv.c (determine_max_iter): Fix handling of AND.
authorJan Hubicka <jh@suse.cz>
Sat, 13 Oct 2012 16:50:03 +0000 (18:50 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 13 Oct 2012 16:50:03 +0000 (16:50 +0000)
* loop-iv.c (determine_max_iter): Fix handling of AND.
(iv_number_of_iterations): Record upper bounds as unsigned
values.

From-SVN: r192424

gcc/ChangeLog
gcc/loop-iv.c

index 804d74053d6ffd75a37fde2d01403a7758c42402..000b0d2cfea183c3a807d8783eb12532cea65748 100644 (file)
@@ -1,3 +1,9 @@
+2012-10-13  Jan Hubicka  <jh@suse.cz>
+
+       * loop-iv.c (determine_max_iter): Fix handling of AND.
+       (iv_number_of_iterations): Record upper bounds as unsigned
+       values.
+
 2012-10-13  Steven Bosscher  <steven@gcc.gnu.org>
 
        * ira.c (ira): Set current_loops to &ira_loops before recording
index 658f20360f786cd8ff44133574083c4021b6297a..f1e19d82072079acdc96ea2cd44bf843f9a77e8e 100644 (file)
@@ -2224,13 +2224,18 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
   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, struct niter_desc *desc, rtx old_niter)
       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 *loop, rtx insn, rtx condition,
                         ? 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 *loop, rtx insn, rtx condition,
 
       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