From: Marc Glisse Date: Sat, 9 May 2015 15:40:05 +0000 (+0200) Subject: re PR tree-optimization/64454 (optimize (x%5)%5) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=441898b206386821ce990266a88e5fba252ad8cd;p=gcc.git re PR tree-optimization/64454 (optimize (x%5)%5) 2015-05-09 Marc Glisse PR tree-optimization/64454 gcc/ * tree-vrp.c (extract_range_from_binary_expr_1) : Rewrite. gcc/testsuite/ * gcc.dg/tree-ssa/vrp97.c: New file. * gcc.dg/vect/slp-perm-7.c: Update. From-SVN: r222970 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f5bd82d9b3..3a56037814d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-05-09 Marc Glisse + + PR tree-optimization/64454 + * tree-vrp.c (extract_range_from_binary_expr_1) : + Rewrite. + 2015-05-08 Jason Merrill * bitmap.c, c/c-aux-info.c, cfg.c, cfghooks.c, cgraph.c, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d3beeb9ce9f..53fd15206fc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-05-09 Marc Glisse + + PR tree-optimization/64454 + * gcc.dg/tree-ssa/vrp97.c: New file. + * gcc.dg/vect/slp-perm-7.c: Update. + 2015-05-09 Andre Vehreschild PR fortran/65894 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp97.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp97.c new file mode 100644 index 00000000000..3805ca9f31f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp97.c @@ -0,0 +1,19 @@ +/* PR tree-optimization/64454 */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +int f(int a, int b) +{ + if (a < -3 || a > 13) __builtin_unreachable(); + if (b < -6 || b > 9) __builtin_unreachable(); + int c = a % b; + return c >= -3 && c <= 8; +} + +int g(int a, int b) +{ + int c = a % b; + return c != -__INT_MAX__ - 1; +} + +/* { dg-final { scan-tree-dump-times "return 1;" 2 "vrp1" } } */ +/* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c index 6291096f001..9eff25e2f27 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c @@ -70,7 +70,7 @@ int main (int argc, const char* argv[]) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_perm } } } */ /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 6744a91f6e9..c0b381df648 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3196,26 +3196,60 @@ extract_range_from_binary_expr_1 (value_range_t *vr, } else if (code == TRUNC_MOD_EXPR) { - if (vr1.type != VR_RANGE - || range_includes_zero_p (vr1.min, vr1.max) != 0 - || vrp_val_is_min (vr1.min)) + if (range_is_null (&vr1)) { - set_value_range_to_varying (vr); + set_value_range_to_undefined (vr); return; } + /* ABS (A % B) < ABS (B) and either + 0 <= A % B <= A or A <= A % B <= 0. */ type = VR_RANGE; - /* Compute MAX <|vr1.min|, |vr1.max|> - 1. */ - max = fold_unary_to_constant (ABS_EXPR, expr_type, vr1.min); - if (tree_int_cst_lt (max, vr1.max)) - max = vr1.max; - max = int_const_binop (MINUS_EXPR, max, build_int_cst (TREE_TYPE (max), 1)); - /* If the dividend is non-negative the modulus will be - non-negative as well. */ - if (TYPE_UNSIGNED (expr_type) - || value_range_nonnegative_p (&vr0)) - min = build_int_cst (TREE_TYPE (max), 0); + signop sgn = TYPE_SIGN (expr_type); + unsigned int prec = TYPE_PRECISION (expr_type); + wide_int wmin, wmax, tmp; + wide_int zero = wi::zero (prec); + wide_int one = wi::one (prec); + if (vr1.type == VR_RANGE && !symbolic_range_p (&vr1)) + { + wmax = wi::sub (vr1.max, one); + if (sgn == SIGNED) + { + tmp = wi::sub (wi::minus_one (prec), vr1.min); + wmax = wi::smax (wmax, tmp); + } + } else - min = fold_unary_to_constant (NEGATE_EXPR, expr_type, max); + { + wmax = wi::max_value (prec, sgn); + /* X % INT_MIN may be INT_MAX. */ + if (sgn == UNSIGNED) + wmax = wmax - one; + } + + if (sgn == UNSIGNED) + wmin = zero; + else + { + wmin = -wmax; + if (vr0.type == VR_RANGE && TREE_CODE (vr0.min) == INTEGER_CST) + { + tmp = vr0.min; + if (wi::gts_p (tmp, zero)) + tmp = zero; + wmin = wi::smax (wmin, tmp); + } + } + + if (vr0.type == VR_RANGE && TREE_CODE (vr0.max) == INTEGER_CST) + { + tmp = vr0.max; + if (sgn == SIGNED && wi::neg_p (tmp)) + tmp = zero; + wmax = wi::min (wmax, tmp, sgn); + } + + min = wide_int_to_tree (expr_type, wmin); + max = wide_int_to_tree (expr_type, wmax); } else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR) {