aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-06-04 09:37:56 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2018-06-04 09:37:56 +0200
commit261ef15d46a4220c0b7453ac55265c61cda171b1 (patch)
tree32e5e1d6f447d3cd145d1d5bc36670f50dbfcc38 /gcc
parent20b11fd41a51d669eec3601571e21e0081f5c5e0 (diff)
downloadgcc-261ef15d46a4220c0b7453ac55265c61cda171b1.zip
gcc-261ef15d46a4220c0b7453ac55265c61cda171b1.tar.gz
gcc-261ef15d46a4220c0b7453ac55265c61cda171b1.tar.bz2
re PR tree-optimization/69615 (0 to limit signed range checks don't always use unsigned compare)
PR tree-optimization/69615 * fold-const.c (merge_ranges): If range1 is - [x, x] and x is the maximum or minimum of the type, try to merge it also as if range1 is + [-, x - 1] or + [x + 1, -]. * gcc.dg/pr69615.c: New test. From-SVN: r261139
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/fold-const.c23
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/pr69615.c37
4 files changed, 68 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3882e60..95c8d7d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2018-06-04 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/69615
+ * fold-const.c (merge_ranges): If range1 is - [x, x] and x is the
+ maximum or minimum of the type, try to merge it also as if
+ range1 is + [-, x - 1] or + [x + 1, -].
+
PR c++/86025
* tree.c (inchash::add_expr): Handle IDENTIFIER_NODE.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 6f80f1b..1e8d79e 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5084,6 +5084,29 @@ merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
tem = high0, high0 = high1, high1 = tem;
}
+ /* If the second range is != high1 where high1 is the type maximum of
+ the type, try first merging with < high1 range. */
+ if (low1
+ && high1
+ && TREE_CODE (low1) == INTEGER_CST
+ && (TREE_CODE (TREE_TYPE (low1)) == INTEGER_TYPE
+ || (TREE_CODE (TREE_TYPE (low1)) == ENUMERAL_TYPE
+ && known_eq (TYPE_PRECISION (TREE_TYPE (low1)),
+ GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low1))))))
+ && operand_equal_p (low1, high1, 0))
+ {
+ if (tree_int_cst_equal (low1, TYPE_MAX_VALUE (TREE_TYPE (low1)))
+ && merge_ranges (pin_p, plow, phigh, in0_p, low0, high0,
+ !in1_p, NULL_TREE, range_predecessor (low1)))
+ return true;
+ /* Similarly for the second range != low1 where low1 is the type minimum
+ of the type, try first merging with > low1 range. */
+ if (tree_int_cst_equal (low1, TYPE_MIN_VALUE (TREE_TYPE (low1)))
+ && merge_ranges (pin_p, plow, phigh, in0_p, low0, high0,
+ !in1_p, range_successor (low1), NULL_TREE))
+ return true;
+ }
+
/* Now flag two cases, whether the ranges are disjoint or whether the
second range is totally subsumed in the first. Note that the tests
below are simplified by the ones above. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7352e41..f889ebb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2018-06-04 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/69615
+ * gcc.dg/pr69615.c: New test.
+
PR c++/86025
* c-c++-common/gomp/pr86025.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr69615.c b/gcc/testsuite/gcc.dg/pr69615.c
new file mode 100644
index 0000000..43ecf6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr69615.c
@@ -0,0 +1,37 @@
+/* PR tree-optimization/69615 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " >= 0" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < 0" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " <= 23" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " > 23" "optimized" } } */
+
+extern void foo (void);
+
+void
+f1 (int x)
+{
+ if (x >= 0 && x <= __INT_MAX__ - 1)
+ foo ();
+}
+
+void
+f2 (int x, int y)
+{
+ if (x >= 0 && y && x <= __INT_MAX__ - 1)
+ foo ();
+}
+
+void
+f3 (int x)
+{
+ if (x > -__INT_MAX__ - 1 && x <= 23)
+ foo ();
+}
+
+void
+f4 (int x, int y)
+{
+ if (x > -__INT_MAX__ - 1 && y && x <= 23)
+ foo ();
+}