This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Improve merge_ranges (PR tree-optimization/69615)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 4 Jun 2018 08:48:21 +0200 (CEST)
- Subject: Re: [PATCH] Improve merge_ranges (PR tree-optimization/69615)
- References: <20180603173652.GT14160@tucnak>
On Sun, 3 Jun 2018, Jakub Jelinek wrote:
> Hi!
>
> We canonicalize x < type_max_val (type (x)) as x != type_max_val (type (x))
> and similarly for x > type_min_val (type (x)). Unfortunately the former
> form is what is often more beneficial for merge_ranges, if we have as in the
> testcase e.g. x >= 0 && x != __INT_MAX__, in?_p is different and we don't
> optimize it, but it can be optimized into [0, __INT_MAX__-1] range.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
OK.
Richard.
> 2018-06-03 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, -].
>
> * gcc.dg/pr69615.c: New test.
>
> --- gcc/fold-const.c.jj 2018-05-31 20:53:33.000000000 +0200
> +++ gcc/fold-const.c 2018-06-02 19:20:10.210975502 +0200
> @@ -5084,6 +5084,29 @@ merge_ranges (int *pin_p, tree *plow, tr
> 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. */
> --- gcc/testsuite/gcc.dg/pr69615.c.jj 2018-06-02 19:40:26.282663273 +0200
> +++ gcc/testsuite/gcc.dg/pr69615.c 2018-06-02 19:40:01.427633205 +0200
> @@ -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 ();
> +}
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)