From a9c774d2ae7c0ae983aa33fd53d34ef054dbee5a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 22 Feb 2017 12:11:27 +0000 Subject: [PATCH] re PR tree-optimization/79666 (wrong code (SIGFPE) at -O2 on x86_64-linux-gnu (in both 32-bit and 64-bit modes)) 2017-02-22 Richard Biener PR tree-optimization/79666 * tree-vrp.c (extract_range_from_binary_expr_1): Make sure to not symbolically negate if that may introduce undefined overflow. * gcc.dg/torture/pr79666.c: New testcase. From-SVN: r245648 --- gcc/ChangeLog | 7 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr79666.c | 30 ++++++++++++++++++++++++++ gcc/tree-vrp.c | 26 ++++++++++++++++++---- 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr79666.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1911946edcd..aa7a1cfc7e3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-02-22 Richard Biener + + PR tree-optimization/79666 + * tree-vrp.c (extract_range_from_binary_expr_1): Make sure + to not symbolically negate if that may introduce undefined + overflow. + 2017-02-22 Martin Liska PR lto/79587 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 19ddc6efac8..af56482b5af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-02-22 Richard Biener + + PR tree-optimization/79666 + * gcc.dg/torture/pr79666.c: New testcase. + 2017-02-22 Martin Liska PR lto/79587 diff --git a/gcc/testsuite/gcc.dg/torture/pr79666.c b/gcc/testsuite/gcc.dg/torture/pr79666.c new file mode 100644 index 00000000000..3d83229521c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr79666.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +struct +{ + unsigned a:6; +} b; + +int c, e, g = 7; +signed char d, f = 6, h = -10; + +void fn1 () +{ + for (; c < 9; c++) + { + if (f) + g = ~(~0 / (g ^ e)); + b.a = ~0; + d = ~((h ^ b.a) & 132 & (~(f && g) | (d && 1))); + e = ~0; + if (d < 127 || f < 1) + continue; + g = 0; + } +} + +int main () +{ + fn1 (); + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 95bf1cf8696..6420041fd13 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2631,8 +2631,17 @@ extract_range_from_binary_expr_1 (value_range *vr, min = build_symbolic_expr (expr_type, sym_min_op0, neg_min_op0, min); else if (sym_min_op1) - min = build_symbolic_expr (expr_type, sym_min_op1, - neg_min_op1 ^ minus_p, min); + { + /* We may not negate if that might introduce + undefined overflow. */ + if (! minus_p + || neg_min_op1 + || TYPE_OVERFLOW_WRAPS (expr_type)) + min = build_symbolic_expr (expr_type, sym_min_op1, + neg_min_op1 ^ minus_p, min); + else + min = NULL_TREE; + } /* Likewise for the upper bound. */ if (sym_max_op0 == sym_max_op1) @@ -2641,8 +2650,17 @@ extract_range_from_binary_expr_1 (value_range *vr, max = build_symbolic_expr (expr_type, sym_max_op0, neg_max_op0, max); else if (sym_max_op1) - max = build_symbolic_expr (expr_type, sym_max_op1, - neg_max_op1 ^ minus_p, max); + { + /* We may not negate if that might introduce + undefined overflow. */ + if (! minus_p + || neg_max_op1 + || TYPE_OVERFLOW_WRAPS (expr_type)) + max = build_symbolic_expr (expr_type, sym_max_op1, + neg_max_op1 ^ minus_p, max); + else + max = NULL_TREE; + } } else { -- 2.30.2