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 <ja...@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 <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)