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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr68911.c | 27 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 21 |
4 files changed, 59 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6fcf9b2..ca02f82 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-01-12 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/68911 + * tree-vrp.c (adjust_range_with_scev): Check overflow in range + information computed for expression "init + nit * step". + 2016-01-12 Sandra Loosemore <sandra@codesourcery.com> * doc/invoke.texi (Invoking GCC): Copy-edit. Incorporate information diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec887e9..435ffde 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-12 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/68911 + * gcc.c-torture/execute/pr68911.c: New test. + 2016-01-12 Marek Polacek <polacek@redhat.com> PR c++/68979 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68911.c b/gcc/testsuite/gcc.c-torture/execute/pr68911.c new file mode 100644 index 0000000..b8cbdb5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr68911.c @@ -0,0 +1,27 @@ +extern void abort (void); + +char a; +int b, c; +short d; + +int main () +{ + unsigned e = 2; + unsigned timeout = 0; + + for (; c < 2; c++) + { + int f = ~e / 7; + if (f) + a = e = ~(b && d); + while (e < 94) + { + e++; + if (++timeout > 100) + goto die; + } + } + return 0; +die: + abort (); +} 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; } |