Hello,

this is a small short-cut in the common case where the step is 1. This avoids having ldist generate a BIT_AND_EXPR that requires VRP to remove, then forwprop to clean up, etc, very close to the end of the optimization pipeline. Please do check that the test s==1 is the right one.

An alternative would be to add a match.pd transformation

(simplify
 (bit_and (exact_div@3 @0 INTEGER_CST@1) INTEGER_CST@2)
 (if (...)
  @3))

but that duplicates VRP functionality, so I don't like it much, I'd rather compute the range of new SSA_NAMEs when we create them.

Bootstrap+regtest on x86_64-pc-linux-gnu.

2019-06-03  Marc Glisse  <marc.gli...@inria.fr>

        * tree-ssa-loop-niter.c (number_of_iterations_ne): Skip
        computations when step is 1.

--
Marc Glisse
Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c	(revision 271834)
+++ gcc/tree-ssa-loop-niter.c	(working copy)
@@ -1118,22 +1118,29 @@ number_of_iterations_ne (struct loop *lo
 	 assumptions for divisibility of c.  */
       assumption = fold_build2 (FLOOR_MOD_EXPR, niter_type, c, d);
       assumption = fold_build2 (EQ_EXPR, boolean_type_node,
 				assumption, build_int_cst (niter_type, 0));
       if (!integer_nonzerop (assumption))
 	niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
 					  niter->assumptions, assumption);
     }
 
   c = fold_build2 (EXACT_DIV_EXPR, niter_type, c, d);
-  tmp = fold_build2 (MULT_EXPR, niter_type, c, inverse (s, bound));
-  niter->niter = fold_build2 (BIT_AND_EXPR, niter_type, tmp, bound);
+  if (integer_onep (s))
+    {
+      niter->niter = c;
+    }
+  else
+    {
+      tmp = fold_build2 (MULT_EXPR, niter_type, c, inverse (s, bound));
+      niter->niter = fold_build2 (BIT_AND_EXPR, niter_type, tmp, bound);
+    }
   return true;
 }
 
 /* Checks whether we can determine the final value of the control variable
    of the loop with ending condition IV0 < IV1 (computed in TYPE).
    DELTA is the difference IV1->base - IV0->base, STEP is the absolute value
    of the step.  The assumptions necessary to ensure that the computation
    of the final value does not overflow are recorded in NITER.  If we
    find the final value, we adjust DELTA and return TRUE.  Otherwise
    we return false.  BNDS bounds the value of IV1->base - IV0->base,

Reply via email to