Commit 1e3d54b4 by Jan Hubicka Committed by Jan Hubicka

tree-scalar-evolution.c (iv_can_overflow_p): New function.

	* tree-scalar-evolution.c (iv_can_overflow_p): New function.
	(simple_iv): Use it.

	* gcc.dg/tree-ssa/scev-14.c: new testcase.

From-SVN: r238012
parent 341c5337
2016-07-05 Jan Hubicka <jh@suse.cz> 2016-07-05 Jan Hubicka <jh@suse.cz>
* tree-scalar-evolution.c (iv_can_overflow_p): New function.
(simple_iv): Use it.
2016-07-05 Jan Hubicka <jh@suse.cz>
* tree-ssa-loop-niter.c (nowrap_type_p): Use ANY_INTEGRAL_TYPE_P. * tree-ssa-loop-niter.c (nowrap_type_p): Use ANY_INTEGRAL_TYPE_P.
2016-07-05 Jiong Wang <jiong.wang@arm.com> 2016-07-05 Jiong Wang <jiong.wang@arm.com>
......
2016-07-05 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/scev-14.c: new testcase.
2016-07-05 David Malcolm <dmalcolm@redhat.com> 2016-07-05 David Malcolm <dmalcolm@redhat.com>
PR c++/62314 PR c++/62314
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
int a[100];
void t(unsigned int n)
{
unsigned int i;
for (i=0; i<n; i++)
a[i]++;
}
/* { dg-final { scan-tree-dump "Overflowness wrto loop niter: No-overflow" "ivopts" } } */
/* { dg-final { scan-tree-dump-not "Overflowness wrto loop niter: Overflow" "ivopts" } } */
...@@ -3309,6 +3309,91 @@ scev_reset (void) ...@@ -3309,6 +3309,91 @@ scev_reset (void)
} }
} }
/* Return true if the IV calculation in TYPE can overflow based on the knowledge
of the upper bound on the number of iterations of LOOP, the BASE and STEP
of IV.
We do not use information whether TYPE can overflow so it is safe to
use this test even for derived IVs not computed every iteration or
hypotetical IVs to be inserted into code. */
static bool
iv_can_overflow_p (struct loop *loop, tree type, tree base, tree step)
{
widest_int nit;
wide_int base_min, base_max, step_min, step_max, type_min, type_max;
signop sgn = TYPE_SIGN (type);
if (integer_zerop (step))
return false;
if (TREE_CODE (base) == INTEGER_CST)
base_min = base_max = base;
else if (TREE_CODE (base) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (base))
&& get_range_info (base, &base_min, &base_max) == VR_RANGE)
;
else
return true;
if (TREE_CODE (step) == INTEGER_CST)
step_min = step_max = step;
else if (TREE_CODE (step) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (step))
&& get_range_info (step, &step_min, &step_max) == VR_RANGE)
;
else
return true;
if (!get_max_loop_iterations (loop, &nit))
return true;
type_min = wi::min_value (type);
type_max = wi::max_value (type);
/* Just sanity check that we don't see values out of the range of the type.
In this case the arithmetics bellow would overflow. */
gcc_checking_assert (wi::ge_p (base_min, type_min, sgn)
&& wi::le_p (base_max, type_max, sgn));
/* Account the possible increment in the last ieration. */
bool overflow = false;
nit = wi::add (nit, 1, SIGNED, &overflow);
if (overflow)
return true;
/* NIT is typeless and can exceed the precision of the type. In this case
overflow is always possible, because we know STEP is non-zero. */
if (wi::min_precision (nit, UNSIGNED) > TYPE_PRECISION (type))
return true;
wide_int nit2 = wide_int::from (nit, TYPE_PRECISION (type), UNSIGNED);
/* If step can be positive, check that nit*step <= type_max-base.
This can be done by unsigned arithmetic and we only need to watch overflow
in the multiplication. The right hand side can always be represented in
the type. */
if (sgn == UNSIGNED || !wi::neg_p (step_max))
{
bool overflow = false;
if (wi::gtu_p (wi::mul (step_max, nit2, UNSIGNED, &overflow),
type_max - base_max)
|| overflow)
return true;
}
/* If step can be negative, check that nit*(-step) <= base_min-type_min. */
if (sgn == SIGNED && wi::neg_p (step_min))
{
bool overflow = false, overflow2 = false;
if (wi::gtu_p (wi::mul (wi::neg (step_min, &overflow2),
nit2, UNSIGNED, &overflow),
base_min - type_min)
|| overflow || overflow2)
return true;
}
return false;
}
/* Checks whether use of OP in USE_LOOP behaves as a simple affine iv with /* Checks whether use of OP in USE_LOOP behaves as a simple affine iv with
respect to WRTO_LOOP and returns its base and step in IV if possible respect to WRTO_LOOP and returns its base and step in IV if possible
(see analyze_scalar_evolution_in_loop for more details on USE_LOOP (see analyze_scalar_evolution_in_loop for more details on USE_LOOP
...@@ -3377,6 +3462,10 @@ simple_iv (struct loop *wrto_loop, struct loop *use_loop, tree op, ...@@ -3377,6 +3462,10 @@ simple_iv (struct loop *wrto_loop, struct loop *use_loop, tree op,
iv->no_overflow = !folded_casts && nowrap_type_p (type); iv->no_overflow = !folded_casts && nowrap_type_p (type);
if (!iv->no_overflow
&& !iv_can_overflow_p (wrto_loop, type, iv->base, iv->step))
iv->no_overflow = true;
/* Try to simplify iv base: /* Try to simplify iv base:
(signed T) ((unsigned T)base + step) ;; TREE_TYPE (base) == signed T (signed T) ((unsigned T)base + step) ;; TREE_TYPE (base) == signed T
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment