aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-04-18 21:17:32 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-04-18 21:17:32 +0200
commit0155ed56af293eac25c3eda84b0977c82659d2d9 (patch)
treebd98f09658d83ba8af9235cf1a7c8425added391
parentf380f6082268c9e88fe635b198d9e6e735f07c5f (diff)
downloadgcc-0155ed56af293eac25c3eda84b0977c82659d2d9.zip
gcc-0155ed56af293eac25c3eda84b0977c82659d2d9.tar.gz
gcc-0155ed56af293eac25c3eda84b0977c82659d2d9.tar.bz2
re PR tree-optimization/80443 (ICE on valid code at -O2 on x86_64-linux-gnu: in set_value_range, at tree-vrp.c:367)
PR tree-optimization/80443 * tree-vrp.c (intersect_ranges): For signed 1-bit precision type, instead of adding 1, subtract -1 and similarly instead of subtracting 1 add -1. * gcc.c-torture/compile/pr80443.c: New test. From-SVN: r246981
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr80443.c20
-rw-r--r--gcc/tree-vrp.c56
4 files changed, 72 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0278e49..ea44ddb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-04-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/80443
+ * tree-vrp.c (intersect_ranges): For signed 1-bit precision type,
+ instead of adding 1, subtract -1 and similarly instead of subtracting
+ 1 add -1.
+
2017-04-18 Richard Sandiford <richard.sandiford@arm.com>
PR rtl-optimization/80357
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 05c5e23..11410bb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/80443
+ * gcc.c-torture/compile/pr80443.c: New test.
+
2017-04-18 Richard Sandiford <richard.sandiford@arm.com>
PR rtl-optimization/80357
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr80443.c b/gcc/testsuite/gcc.c-torture/compile/pr80443.c
new file mode 100644
index 0000000..8c30cce
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr80443.c
@@ -0,0 +1,20 @@
+/* PR tree-optimization/80443 */
+
+struct S { int a : 1; } b, c;
+signed char d, e, f;
+
+void
+foo ()
+{
+ while (f)
+ {
+ signed char g = b.a;
+ if (g)
+ b.a = ~(1 + (d || c.a));
+ if (b.a < g && b.a)
+ g = 0;
+ if (b.a > c.a)
+ b.a = g;
+ c.a = e;
+ }
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 28d9c17..6d802de 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8756,20 +8756,32 @@ intersect_ranges (enum value_range_type *vr0type,
/* Choose the right gap if the left one is empty. */
if (mineq)
{
- if (TREE_CODE (vr1max) == INTEGER_CST)
- *vr0min = int_const_binop (PLUS_EXPR, vr1max,
- build_int_cst (TREE_TYPE (vr1max), 1));
- else
+ if (TREE_CODE (vr1max) != INTEGER_CST)
*vr0min = vr1max;
+ else if (TYPE_PRECISION (TREE_TYPE (vr1max)) == 1
+ && !TYPE_UNSIGNED (TREE_TYPE (vr1max)))
+ *vr0min
+ = int_const_binop (MINUS_EXPR, vr1max,
+ build_int_cst (TREE_TYPE (vr1max), -1));
+ else
+ *vr0min
+ = int_const_binop (PLUS_EXPR, vr1max,
+ build_int_cst (TREE_TYPE (vr1max), 1));
}
/* Choose the left gap if the right one is empty. */
else if (maxeq)
{
- if (TREE_CODE (vr1min) == INTEGER_CST)
- *vr0max = int_const_binop (MINUS_EXPR, vr1min,
- build_int_cst (TREE_TYPE (vr1min), 1));
- else
+ if (TREE_CODE (vr1min) != INTEGER_CST)
*vr0max = vr1min;
+ else if (TYPE_PRECISION (TREE_TYPE (vr1min)) == 1
+ && !TYPE_UNSIGNED (TREE_TYPE (vr1min)))
+ *vr0max
+ = int_const_binop (PLUS_EXPR, vr1min,
+ build_int_cst (TREE_TYPE (vr1min), -1));
+ else
+ *vr0max
+ = int_const_binop (MINUS_EXPR, vr1min,
+ build_int_cst (TREE_TYPE (vr1min), 1));
}
/* Choose the anti-range if the range is effectively varying. */
else if (vrp_val_is_min (*vr0min)
@@ -8811,22 +8823,34 @@ intersect_ranges (enum value_range_type *vr0type,
if (mineq)
{
*vr0type = VR_RANGE;
- if (TREE_CODE (*vr0max) == INTEGER_CST)
- *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
- build_int_cst (TREE_TYPE (*vr0max), 1));
- else
+ if (TREE_CODE (*vr0max) != INTEGER_CST)
*vr0min = *vr0max;
+ else if (TYPE_PRECISION (TREE_TYPE (*vr0max)) == 1
+ && !TYPE_UNSIGNED (TREE_TYPE (*vr0max)))
+ *vr0min
+ = int_const_binop (MINUS_EXPR, *vr0max,
+ build_int_cst (TREE_TYPE (*vr0max), -1));
+ else
+ *vr0min
+ = int_const_binop (PLUS_EXPR, *vr0max,
+ build_int_cst (TREE_TYPE (*vr0max), 1));
*vr0max = vr1max;
}
/* Choose the left gap if the right is empty. */
else if (maxeq)
{
*vr0type = VR_RANGE;
- if (TREE_CODE (*vr0min) == INTEGER_CST)
- *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
- build_int_cst (TREE_TYPE (*vr0min), 1));
- else
+ if (TREE_CODE (*vr0min) != INTEGER_CST)
*vr0max = *vr0min;
+ else if (TYPE_PRECISION (TREE_TYPE (*vr0min)) == 1
+ && !TYPE_UNSIGNED (TREE_TYPE (*vr0min)))
+ *vr0max
+ = int_const_binop (PLUS_EXPR, *vr0min,
+ build_int_cst (TREE_TYPE (*vr0min), -1));
+ else
+ *vr0max
+ = int_const_binop (MINUS_EXPR, *vr0min,
+ build_int_cst (TREE_TYPE (*vr0min), 1));
*vr0min = vr1min;
}
/* Choose the anti-range if the range is effectively varying. */