This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Improve merge_ranges (PR tree-optimization/69615)


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]