aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr79666.c30
-rw-r--r--gcc/tree-vrp.c26
4 files changed, 64 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1911946..aa7a1cf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2017-02-22 Martin Liska <mliska@suse.cz>
PR lto/79587
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 19ddc6e..af56482 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-02-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/79666
+ * gcc.dg/torture/pr79666.c: New testcase.
+
2017-02-22 Martin Liska <mliska@suse.cz>
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 0000000..3d83229
--- /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 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
{