diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-06-04 09:37:56 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-06-04 09:37:56 +0200 |
commit | 261ef15d46a4220c0b7453ac55265c61cda171b1 (patch) | |
tree | 32e5e1d6f447d3cd145d1d5bc36670f50dbfcc38 /gcc | |
parent | 20b11fd41a51d669eec3601571e21e0081f5c5e0 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/fold-const.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr69615.c | 37 |
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 (); +} |