From 1e2d5f2b2cca43fed86d55c947df90915e541c5c Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 23 Oct 2019 13:17:34 +0000 Subject: [PATCH] re PR tree-optimization/92131 (incorrect assumption that (ao >= 0) is always false) PR tree-optimization/92131 * tree-vrp.c (extract_range_from_plus_minus_expr): If the resulting range would be symbolic, drop to varying for any explicit overflow in the constant part or if neither range is a singleton. From-SVN: r277331 --- gcc/ChangeLog | 10 ++- gcc/testsuite/ChangeLog | 4 + .../gcc.c-torture/execute/20191023-1.c | 73 +++++++++++++++++++ gcc/tree-vrp.c | 11 ++- 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20191023-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2300b57f48db..fe43786a8e12 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,14 @@ +2019-10-23 Eric Botcazou + + PR tree-optimization/92131 + * tree-vrp.c (extract_range_from_plus_minus_expr): If the resulting + range would be symbolic, drop to varying for any explicit overflow + in the constant part or if neither range is a singleton. + 2019-10-18 Georg-Johann Lay - Backport from 2019-10-18 trunk r277143. + Backport from trunk + 2019-10-18 Georg-Johann Lay PR target/86040 * config/avr/avr.c (avr_out_lpm): Do not shortcut-return. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fc2a754361ae..9dfad63b9ab3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-10-23 Eric Botcazou + + * gcc.c-torture/execute/20191023-1.c: New test. + 2019-10-18 Steven G. Kargl PR fortran/69455 diff --git a/gcc/testsuite/gcc.c-torture/execute/20191023-1.c b/gcc/testsuite/gcc.c-torture/execute/20191023-1.c new file mode 100644 index 000000000000..3811ebca151a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20191023-1.c @@ -0,0 +1,73 @@ +/* PR tree-optimization/92131 */ +/* Testcase by Armin Rigo */ + +long b, c, d, e, f, i; +char g, h, j, k; +int *aa; + +static void error (void) __attribute__((noipa)); +static void error (void) { __builtin_abort(); } + +static void see_me_here (void) __attribute__((noipa)); +static void see_me_here (void) {} + +static void aaa (void) __attribute__((noipa)); +static void aaa (void) {} + +static void a (void) __attribute__((noipa)); +static void a (void) { + long am, ao; + if (aa == 0) { + aaa(); + if (j) + goto ay; + } + return; +ay: + aaa(); + if (k) { + aaa(); + goto az; + } + return; +az: + if (i) + if (g) + if (h) + if (e) + goto bd; + return; +bd: + am = 0; + while (am < e) { + switch (c) { + case 8: + goto bh; + case 4: + return; + } + bh: + if (am >= 0) + b = -am; + ao = am + b; + f = ao & 7; + if (f == 0) + see_me_here(); + if (ao >= 0) + am++; + else + error(); + } +} + +int main (void) +{ + j++; + k++; + i++; + g++; + h++; + e = 1; + a(); + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b5424befc785..f2ef37290de3 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2535,10 +2535,13 @@ extract_range_from_binary_expr_1 (value_range *vr, max_ovf = 1; } - /* If we have overflow for the constant part and the resulting - range will be symbolic, drop to VR_VARYING. */ - if ((min_ovf && sym_min_op0 != sym_min_op1) - || (max_ovf && sym_max_op0 != sym_max_op1)) + /* If the resulting range will be symbolic, we need to eliminate any + explicit or implicit overflow introduced in the above computation + because compare_values could make an incorrect use of it. That's + why we require one of the ranges to be a singleton. */ + if ((sym_min_op0 != sym_min_op1 || sym_max_op0 != sym_max_op1) + && (min_ovf || max_ovf + || (min_op0 != max_op0 && min_op1 != max_op1))) { set_value_range_to_varying (vr); return; -- 2.47.2