aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-01-12 17:49:51 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-01-12 17:49:51 +0000
commitc446cf07e903f12bd0926078b5afd3d9183b744d (patch)
tree1d315a0fb804131369f77bee4d8c37167cf44194 /gcc
parentee30410c37af792ec093aee52adc742ea2e7d03d (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr68911.c27
-rw-r--r--gcc/tree-vrp.c21
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;
}