From 149a3e4d4e3aacdbfee165f0efea4d6327327265 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 23 Oct 2019 11:34:48 +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: r277314 --- gcc/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 4 + .../gcc.c-torture/execute/20191023-1.c | 73 +++++++++++++++++++ gcc/tree-vrp.c | 15 ++-- 4 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20191023-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 958c9ae3802..3ff5227cbec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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-23 Martin Liska PR middle-end/81669 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 482ff0ccabc..c578af30ce8 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-23 Martin Liska PR ipa/91969 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 00000000000..3811ebca151 --- /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 8d4f16e9e1f..ad9be74daf0 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1652,7 +1652,7 @@ extract_range_from_plus_minus_expr (value_range_base *vr, value_range_kind vr0_kind = vr0.kind (), vr1_kind = vr1.kind (); tree vr0_min = vr0.min (), vr0_max = vr0.max (); tree vr1_min = vr1.min (), vr1_max = vr1.max (); - tree min = NULL, max = NULL; + tree min = NULL_TREE, max = NULL_TREE; /* This will normalize things such that calculating [0,0] - VR_VARYING is not dropped to varying, but is @@ -1715,18 +1715,19 @@ extract_range_from_plus_minus_expr (value_range_base *vr, combine_bound (code, wmin, min_ovf, expr_type, min_op0, min_op1); combine_bound (code, wmax, max_ovf, expr_type, max_op0, max_op1); - /* If we have overflow for the constant part and the resulting - range will be symbolic, drop to VR_VARYING. */ - if (((bool)min_ovf && sym_min_op0 != sym_min_op1) - || ((bool)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) + && ((bool)min_ovf || (bool)max_ovf + || (min_op0 != max_op0 && min_op1 != max_op1))) { vr->set_varying (expr_type); return; } /* Adjust the range for possible overflow. */ - min = NULL_TREE; - max = NULL_TREE; set_value_range_with_overflow (kind, min, max, expr_type, wmin, wmax, min_ovf, max_ovf); if (kind == VR_VARYING) -- 2.30.2