re PR tree-optimization/69615 (0 to limit signed range checks don't always use unsign...
authorJakub Jelinek <jakub@redhat.com>
Mon, 4 Jun 2018 07:37:56 +0000 (09:37 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 4 Jun 2018 07:37:56 +0000 (09:37 +0200)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr69615.c [new file with mode: 0644]

index 3882e6098cfc7f9a1950974152a1ecae699c003a..95c8d7de9b3379b2f83979647d705dcbadcfb51c 100644 (file)
@@ -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.
 
index 6f80f1b1d695fd6920ddab46ce8ce8db47bb9ed3..1e8d79e40221ae93cc06b5896dc9312926917acf 100644 (file)
@@ -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.  */
index 7352e41c3fcd5f5a9e5acbdbed802c44bec2f4b0..f889ebb5cdea8465c1e83db15b06336a4a5697dc 100644 (file)
@@ -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 (file)
index 0000000..43ecf6b
--- /dev/null
@@ -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 ();
+}