diff options
author | Bin Cheng <bin.cheng@arm.com> | 2016-01-12 17:49:51 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2016-01-12 17:49:51 +0000 |
commit | c446cf07e903f12bd0926078b5afd3d9183b744d (patch) | |
tree | 1d315a0fb804131369f77bee4d8c37167cf44194 /gcc/tree-vrp.c | |
parent | ee30410c37af792ec093aee52adc742ea2e7d03d (diff) | |
download | gcc-c446cf07e903f12bd0926078b5afd3d9183b744d.zip gcc-c446cf07e903f12bd0926078b5afd3d9183b744d.tar.gz gcc-c446cf07e903f12bd0926078b5afd3d9183b744d.tar.bz2 |
re PR tree-optimization/68911 (wrong code with -O1 -ftree-vrp)
PR tree-optimization/68911
* tree-vrp.c (adjust_range_with_scev): Check overflow in range
information computed for expression "init + nit * step".
gcc/testsuite/ChangeLog
PR tree-optimization/68911
* gcc.c-torture/execute/pr68911.c: New test.
From-SVN: r232286
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 920a9b1..8f35eb7 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4259,6 +4259,27 @@ adjust_range_with_scev (value_range *vr, struct loop *loop, /* Likewise if the addition did. */ if (maxvr.type == VR_RANGE) { + value_range initvr = VR_INITIALIZER; + + if (TREE_CODE (init) == SSA_NAME) + initvr = *(get_value_range (init)); + else if (is_gimple_min_invariant (init)) + set_value_range_to_value (&initvr, init, NULL); + else + return; + + /* Check if init + nit * step overflows. Though we checked + scev {init, step}_loop doesn't wrap, it is not enough + because the loop may exit immediately. Overflow could + happen in the plus expression in this case. */ + if ((dir == EV_DIR_DECREASES + && (is_negative_overflow_infinity (maxvr.min) + || compare_values (maxvr.min, initvr.min) != -1)) + || (dir == EV_DIR_GROWS + && (is_positive_overflow_infinity (maxvr.max) + || compare_values (maxvr.max, initvr.max) != 1))) + return; + tmin = maxvr.min; tmax = maxvr.max; } |