diff options
author | Richard Biener <rguenther@suse.de> | 2017-02-22 12:11:27 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-02-22 12:11:27 +0000 |
commit | a9c774d2ae7c0ae983aa33fd53d34ef054dbee5a (patch) | |
tree | 8a5ad3859902304523759d96288cf70c11359104 /gcc/tree-vrp.c | |
parent | 8f4f841a3e443d7de88fcb76075eb3003f280bd7 (diff) | |
download | gcc-a9c774d2ae7c0ae983aa33fd53d34ef054dbee5a.zip gcc-a9c774d2ae7c0ae983aa33fd53d34ef054dbee5a.tar.gz gcc-a9c774d2ae7c0ae983aa33fd53d34ef054dbee5a.tar.bz2 |
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 <rguenther@suse.de>
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
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 95bf1cf..6420041 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 { |