On Fri, Aug 11, 2023 at 11:17 AM Andrew Pinski via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > So with my next VRP patch, VRP causes: > ``` > # c$_M_value_18 = PHI <-1(3), 0(2), 1(4)> > _11 = (unsigned int) c$_M_value_18; > _16 = _11 <= 1; > ``` > To be changed to: > ``` > # c$_M_value_18 = PHI <-1(3), 0(2), 1(4)> > _11 = (unsigned int) c$_M_value_18; > _16 = _11 != 4294967295; > ``` > > So let's add support for the above. > A few changes was needed, first to change > the range check of the rhs of the comparison to possibly > integer_all_onesp also. > > The next is to add support for the cast and EQ/NE case. > > Note on the testcases pr110984-1.c is basically pr94589-2.c but > with what the C++ code is doing with the signed char type; > pr110984-2.c is pr110984-1.c with the cast added to give an > explicit testcase to test against. > > OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
LGTM. > Thanks, > Andrew Pinski > > PR tree-optimization/110984 > > gcc/ChangeLog: > > * tree-ssa-phiopt.cc (spaceship_replacement): Add support for > NE/EQ for the cast case. > > gcc/testsuite/ChangeLog: > > * gcc.dg/pr110984-1.c: New test. > * gcc.dg/pr110984-2.c: New test. > --- > gcc/testsuite/gcc.dg/pr110984-1.c | 37 +++++++++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/pr110984-2.c | 21 ++++++++++++++++++ > gcc/tree-ssa-phiopt.cc | 19 +++++++++++++--- > 3 files changed, 74 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/pr110984-1.c > create mode 100644 gcc/testsuite/gcc.dg/pr110984-2.c > > diff --git a/gcc/testsuite/gcc.dg/pr110984-1.c > b/gcc/testsuite/gcc.dg/pr110984-1.c > new file mode 100644 > index 00000000000..85b19eb8279 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr110984-1.c > @@ -0,0 +1,37 @@ > +/* PR tree-optimization/110984 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) > (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) > 5\\.0" 14 "optimized" } } */ > + > +/* This is similar to pr94589-2.c except use signed char as the type for the > [-1,2] case */ > + > +#define A __attribute__((noipa)) > +A int f1 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c == 0; } > +A int f2 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c != 0; } > +A int f3 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c > 0; } > +A int f4 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c < 0; } > +A int f5 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c >= 0; } > +A int f6 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c <= 0; } > +A int f7 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c == -1; } > +A int f8 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c != -1; } > +A int f9 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; return c > -1; } > +A int f10 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c <= -1; } > +A int f11 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == 1; } > +A int f12 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != 1; } > +A int f13 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c < 1; } > +A int f14 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c >= 1; } > +A int f15 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c == 0; } > +A int f16 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c != 0; } > +A int f17 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c > 0; } > +A int f18 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c < 0; } > +A int f19 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c >= 0; } > +A int f20 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c <= 0; } > +A int f21 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c == -1; } > +A int f22 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c != -1; } > +A int f23 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c > -1; } > +A int f24 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c <= -1; } > +A int f25 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c == 1; } > +A int f26 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c != 1; } > +A int f27 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c < 1; } > +A int f28 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; return c >= 1; } > diff --git a/gcc/testsuite/gcc.dg/pr110984-2.c > b/gcc/testsuite/gcc.dg/pr110984-2.c > new file mode 100644 > index 00000000000..cddce045745 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr110984-2.c > @@ -0,0 +1,21 @@ > +/* PR tree-optimization/110984 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) > (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 6 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) > 5\\.0" 6 "optimized" } } */ > + > +/* This is similar to pr94589-2.c except use signed char and use unsigned > types to check against the variable, which means removing the non !=/== > comparisons. */ > + > +#define A __attribute__((noipa)) > +A int f1 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; unsigned t = c; return t == > 0; } > +A int f2 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; unsigned t = c; return t != > 0; } > +A int f7 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; unsigned t = c; return t == > -1; } > +A int f8 (double i, double j) { signed char c; if (i == j) c = 0; else if (i > < j) c = -1; else if (i > j) c = 1; else c = 2; unsigned t = c; return t != > -1; } > +A int f11 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; unsigned t = c; return t > == 1; } > +A int f12 (double i, double j) { signed char c; if (i == j) c = 0; else if > (i < j) c = -1; else if (i > j) c = 1; else c = 2; unsigned t = c; return t > != 1; } > +A int f15 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; unsigned t = c; return t == 0; } > +A int f16 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; unsigned t = c; return t != 0; } > +A int f21 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; unsigned t = c; return t == -1; } > +A int f22 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; unsigned t = c; return t != -1; } > +A int f25 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; unsigned t = c; return t == 1; } > +A int f26 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) > c = -1; else if (i > 5.0) c = 1; else c = 2; unsigned t = c; return t != 1; } > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc > index 485662dfcc7..5f24d62c49a 100644 > --- a/gcc/tree-ssa-phiopt.cc > +++ b/gcc/tree-ssa-phiopt.cc > @@ -2346,7 +2346,8 @@ spaceship_replacement (basic_block cond_bb, basic_block > middle_bb, > } > if (lhs != (orig_use_lhs ? orig_use_lhs : phires) > || !tree_fits_shwi_p (rhs) > - || !IN_RANGE (tree_to_shwi (rhs), -1, 1)) > + || !(IN_RANGE (tree_to_shwi (rhs), 0, 1) > + || integer_all_onesp (rhs))) > return false; > > if (is_cast) > @@ -2356,9 +2357,20 @@ spaceship_replacement (basic_block cond_bb, > basic_block middle_bb, > /* As for -ffast-math we assume the 2 return to be > impossible, canonicalize (unsigned) res <= 1U or > (unsigned) res < 2U into res >= 0 and (unsigned) res > 1U > - or (unsigned) res >= 2U as res < 0. */ > + or (unsigned) res >= 2U as res < 0. > + Sometimes we get (unsigned)res != N. Support those cases too. */ > switch (cmp) > { > + case NE_EXPR: > + case EQ_EXPR: > + { > + tree newrhs = fold_convert (TREE_TYPE (phires), rhs); > + tree tmp = fold_convert (TREE_TYPE (rhs), newrhs); > + if (!tree_int_cst_equal (rhs, tmp)) > + return false; > + rhs = newrhs; > + break; > + } > case LE_EXPR: > if (!integer_onep (rhs)) > return false; > @@ -2382,7 +2394,8 @@ spaceship_replacement (basic_block cond_bb, basic_block > middle_bb, > default: > return false; > } > - rhs = build_zero_cst (TREE_TYPE (phires)); > + if (cmp != EQ_EXPR && cmp != NE_EXPR) > + rhs = build_zero_cst (TREE_TYPE (phires)); > } > else if (orig_use_lhs) > { > -- > 2.31.1 >