From: Jakub Jelinek Date: Wed, 17 Dec 2014 09:29:12 +0000 (+0100) Subject: re PR tree-optimization/64322 (More optimize opportunity for constant folding) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4c57980f9d30e6947025424536eeed42bf6e1239;p=gcc.git re PR tree-optimization/64322 (More optimize opportunity for constant folding) PR tree-optimization/64322 * tree-vrp.c (extract_range_from_binary_expr_1): Attempt to derive range for RSHIFT_EXPR even if vr0 range is not VR_RANGE or is symbolic. * gcc.dg/tree-ssa/vrp95.c: New test. From-SVN: r218812 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index badd40e7c54..631d7268013 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-12-17 Jakub Jelinek + + PR tree-optimization/64322 + * tree-vrp.c (extract_range_from_binary_expr_1): Attempt to derive + range for RSHIFT_EXPR even if vr0 range is not VR_RANGE or is symbolic. + 2014-12-17 Tobias Burnus PR fortran/54687 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f6fd314747..fbafb565dac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2014-12-17 Jakub Jelinek + PR tree-optimization/64322 + * gcc.dg/tree-ssa/vrp95.c: New test. + PR sanitizer/64289 * c-c++-common/ubsan/pr64289.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp95.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp95.c new file mode 100644 index 00000000000..be208bafd60 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp95.c @@ -0,0 +1,50 @@ +/* PR tree-optimization/64322 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +extern void link_error (); +extern void required_check (); + +long long int +foo (long long int x) +{ + x >>= sizeof (long long int) * __CHAR_BIT__ - 1; + if (x != 0 && x != -1) + link_error (); + return x; +} + +unsigned long long int +bar (unsigned long long int x) +{ + x >>= sizeof (long long int) * __CHAR_BIT__ - 1; + if (x != 0 && x != 1) + link_error (); + return x; +} + +long long int +baz (long long int x) +{ + x = (x >> sizeof (long long int) * __CHAR_BIT__ - 1) << 1; + x = x / 0x100000000LL; + if (x != 0) + link_error (); + return x; +} + +unsigned long long int +range (unsigned long long int x, int y) +{ + y &= 3; + x >>= sizeof (long long int) * __CHAR_BIT__ - 1 - y; + if (x > 15) + link_error (); + if (x == 15) + required_check (); + return x; +} + +/* { dg-final { scan-tree-dump-not "link_error" "vrp1" } } */ +/* { dg-final { scan-tree-dump "required_check" "vrp1" } } */ +/* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index bd238d57700..c49c9424885 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2434,6 +2434,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr, && code != MAX_EXPR && code != PLUS_EXPR && code != MINUS_EXPR + && code != RSHIFT_EXPR && (vr0.type == VR_VARYING || vr1.type == VR_VARYING || vr0.type != vr1.type @@ -2948,6 +2949,15 @@ extract_range_from_binary_expr_1 (value_range_t *vr, { if (code == RSHIFT_EXPR) { + /* Even if vr0 is VARYING or otherwise not usable, we can derive + useful ranges just from the shift count. E.g. + x >> 63 for signed 64-bit x is always [-1, 0]. */ + if (vr0.type != VR_RANGE || symbolic_range_p (&vr0)) + { + vr0.type = type = VR_RANGE; + vr0.min = vrp_val_min (expr_type); + vr0.max = vrp_val_max (expr_type); + } extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1); return; }