This fixes PR60766, a case where IVOPTs generating signed expressions from originally unsigned ones breaks because that introduces undefined overflow and VRP manages to exploit that fact. The solution is to use unsigned arithmetic when doing simplification using tree-affine. In general that's always mandated as that facility doesn't care for association limits that signed expressions have. Rather than trying to address this generally the folllowing fixes the single place that this bug runs into.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk sofar. Richard. 2014-04-07 Richard Biener <rguent...@suse.de> PR tree-optimization/60766 * tree-ssa-loop-ivopts.c (cand_value_at): Compute in an unsigned type. (may_eliminate_iv): Convert cand_value_at result to desired type. * gcc.dg/torture/pr60766.c: New testcase. Index: gcc/tree-ssa-loop-ivopts.c =================================================================== *** gcc/tree-ssa-loop-ivopts.c (revision 209181) --- gcc/tree-ssa-loop-ivopts.c (working copy) *************** cand_value_at (struct loop *loop, struct *** 4236,4243 **** tree steptype = type; if (POINTER_TYPE_P (type)) steptype = sizetype; ! tree_to_aff_combination (iv->step, steptype, &step); tree_to_aff_combination (niter, TREE_TYPE (niter), &nit); aff_combination_convert (&nit, steptype); aff_combination_mult (&nit, &step, &delta); --- 4236,4245 ---- tree steptype = type; if (POINTER_TYPE_P (type)) steptype = sizetype; + steptype = unsigned_type_for (type); ! tree_to_aff_combination (iv->step, TREE_TYPE (iv->step), &step); ! aff_combination_convert (&step, steptype); tree_to_aff_combination (niter, TREE_TYPE (niter), &nit); aff_combination_convert (&nit, steptype); aff_combination_mult (&nit, &step, &delta); *************** cand_value_at (struct loop *loop, struct *** 4245,4250 **** --- 4247,4254 ---- aff_combination_add (&delta, &step); tree_to_aff_combination (iv->base, type, val); + if (!POINTER_TYPE_P (type)) + aff_combination_convert (val, steptype); aff_combination_add (val, &delta); } *************** may_eliminate_iv (struct ivopts_data *da *** 4623,4629 **** cand_value_at (loop, cand, use->stmt, desc->niter, &bnd); ! *bound = aff_combination_to_tree (&bnd); *comp = iv_elimination_compare (data, use); /* It is unlikely that computing the number of iterations using division --- 4627,4634 ---- cand_value_at (loop, cand, use->stmt, desc->niter, &bnd); ! *bound = fold_convert (TREE_TYPE (cand->iv->base), ! aff_combination_to_tree (&bnd)); *comp = iv_elimination_compare (data, use); /* It is unlikely that computing the number of iterations using division Index: gcc/testsuite/gcc.dg/torture/pr60766.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr60766.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr60766.c (working copy) *************** *** 0 **** --- 1,15 ---- + /* { dg-do run } */ + + int m = 9; + + int main() + { + int n, x; + + n = m; + for (x = 0; x <= n; x++) + if (n == x + (x + 1) + (x + 2)) + return 0; + + __builtin_abort(); + }