From 261ef15d46a4220c0b7453ac55265c61cda171b1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 4 Jun 2018 09:37:56 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/fold-const.c | 23 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/pr69615.c | 37 ++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr69615.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3882e6098cf..95c8d7de9b3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-06-04 Jakub Jelinek + 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 6f80f1b1d69..1e8d79e4022 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 7352e41c3fc..f889ebb5cde 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-06-04 Jakub Jelinek + 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 00000000000..43ecf6bd05d --- /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 (); +} -- 2.30.2