aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2018-10-03 17:36:29 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2018-10-03 17:36:29 +0000
commit9b918e82027599898e5f2ff75342a51da06672a9 (patch)
tree8bcd98852b04d4e16319dc8c385b377d9821b018
parent78125561e39be43dc140d5648abf402c4f7cf1c0 (diff)
downloadgcc-9b918e82027599898e5f2ff75342a51da06672a9.zip
gcc-9b918e82027599898e5f2ff75342a51da06672a9.tar.gz
gcc-9b918e82027599898e5f2ff75342a51da06672a9.tar.bz2
re PR tree-optimization/87415 (wrong code at -O1 and above on x86_64-linux-gnu)
PR tree-optimization/87415 * tree-vrp.c (set_value_range_with_overflow): Special case one bit precision fields. From-SVN: r264817
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/pr87415.c20
-rw-r--r--gcc/tree-vrp.c9
3 files changed, 35 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aa10aa0..30d7e77 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-10-03 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/87415
+ * tree-vrp.c (set_value_range_with_overflow): Special case one bit
+ precision fields.
+
2018-10-02 Jeff Law <law@redhat.com>
* gimple-fold.c (get_range_strlen): Only set *nonstr when
diff --git a/gcc/testsuite/gcc.dg/pr87415.c b/gcc/testsuite/gcc.dg/pr87415.c
new file mode 100644
index 0000000..473384a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr87415.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+struct A
+{
+ int b:1;
+};
+
+int d;
+
+int main ()
+{
+ struct A e = { 0 };
+ if (!d)
+ e.b = -1;
+ if (!e.b)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 005fc2f..cbc2ea2 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1116,6 +1116,15 @@ set_value_range_with_overflow (value_range &vr,
const unsigned int prec = TYPE_PRECISION (type);
vr.type = VR_RANGE;
vr.equiv = NULL;
+
+ /* For one bit precision if max < min, then the swapped
+ range covers all values. */
+ if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
+ {
+ set_value_range_to_varying (&vr);
+ return;
+ }
+
if (TYPE_OVERFLOW_WRAPS (type))
{
/* If overflow wraps, truncate the values and adjust the