aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYury Gribov <tetra2005@gmail.com>2018-05-23 07:40:43 +0000
committerMartin Liska <marxin@gcc.gnu.org>2018-05-23 07:40:43 +0000
commitad4f3f5d4eb21c886b168a092cc7e5860e3b3119 (patch)
tree4d4faf458c5f0a9360d69a79fa3a4e41b6beae2b /gcc
parentb72feab889cd7925fab59771269638fcc88bc195 (diff)
downloadgcc-ad4f3f5d4eb21c886b168a092cc7e5860e3b3119.zip
gcc-ad4f3f5d4eb21c886b168a092cc7e5860e3b3119.tar.gz
gcc-ad4f3f5d4eb21c886b168a092cc7e5860e3b3119.tar.bz2
re PR tree-optimization/85822 (Maybe wrong code in VRP since r249150)
PR tree-optimization/85822 From-SVN: r260566
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/pr85822.c27
-rw-r--r--gcc/tree-vrp.c11
4 files changed, 44 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fbb0120..202b658 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-05-23 Yury Gribov <tetra2005@gmail.com>
+
+ PR tree-optimization/85822
+ * tree-vrp.c (is_masked_range_test): Fix handling of negative
+ constants.
+
2018-05-23 Richard Biener <rguenther@suse.de>
* tree-ssa-sccvn.c (vn_reference_lookup_3): Handle arbitrary
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6bd7a15..075f845 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-23 Yury Gribov <tetra2005@gmail.com>
+
+ PR tree-optimization/85822
+ * c-c++-common/pr85822.c: New test.
+
2018-05-23 Richard Biener <rguenther@suse.de>
* gcc.dg/tree-ssa/ssa-fre-65.c: New testcase.
diff --git a/gcc/testsuite/c-c++-common/pr85822.c b/gcc/testsuite/c-c++-common/pr85822.c
new file mode 100644
index 0000000..3b09188
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr85822.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O2" } */
+/* { dg-do run } */
+
+static const long long int TagTypeNumber = 0xffff000000000000ll;
+
+long long int x;
+
+void foo(void)
+{
+ x = TagTypeNumber + 1;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 0)
+ foo ();
+
+ if ((x & TagTypeNumber) == TagTypeNumber)
+ {
+ unsigned y = (unsigned)x;
+ __builtin_printf ("v: %u\n", y);
+ if (y != 1)
+ __builtin_abort ();
+ }
+
+ return 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index aa53db6..6c482dd 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3844,10 +3844,10 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
Such comparison can yield assertions like
X >= XX...X00...0
X <= XX...X11...1
- in case of COND_OP being NE_EXPR or
+ in case of COND_OP being EQ_EXPR or
X < XX...X00...0
X > XX...X11...1
- in case of EQ_EXPR. */
+ in case of NE_EXPR. */
static bool
is_masked_range_test (tree name, tree valt, enum tree_code cond_code,
@@ -3867,6 +3867,10 @@ is_masked_range_test (tree name, tree valt, enum tree_code cond_code,
wi::tree_to_wide_ref mask = wi::to_wide (maskt);
wide_int inv_mask = ~mask;
+ /* Must have been removed by now so don't bother optimizing. */
+ if (mask == 0 || inv_mask == 0)
+ return false;
+
/* Assume VALT is INTEGER_CST. */
wi::tree_to_wide_ref val = wi::to_wide (valt);
@@ -3907,9 +3911,6 @@ is_masked_range_test (tree name, tree valt, enum tree_code cond_code,
*low = wide_int_to_tree (type, val);
*high = wide_int_to_tree (type, val | inv_mask);
- if (wi::neg_p (val, TYPE_SIGN (type)))
- std::swap (*low, *high);
-
return true;
}