On Wed, 19 Nov 2025, [email protected] wrote: > From: Dhruv Chawla <[email protected]> > > These patterns should not be in match.pd as they require range > information checks that ideally belong in VRP. They were also causing > breakages as the checks weren't tight enough. > > Bootstrapped and regtested on aarch64-linux-gnu.
OK. > Signed-off-by: Dhruv Chawla <[email protected]> > > PR tree-optimization/122733 > > gcc/ChangeLog: > > * match.pd: Remove patterns. Also call constant_boolean_node instead of > build_one_cst and build_zero_cst. > > gcc/testsuite/ChangeLog: > > * gcc.dg/match-shift-cmp-1.c: Update test to only check > equality. > * gcc.dg/match-shift-cmp-2.c: Likewise. > * gcc.dg/match-shift-cmp-3.c: Likewise. > * gcc.dg/match-shift-cmp-4.c: Removed. > --- > gcc/match.pd | 26 ++---------- > gcc/testsuite/gcc.dg/match-shift-cmp-1.c | 11 +---- > gcc/testsuite/gcc.dg/match-shift-cmp-2.c | 23 ++--------- > gcc/testsuite/gcc.dg/match-shift-cmp-3.c | 27 ++++++------- > gcc/testsuite/gcc.dg/match-shift-cmp-4.c | 51 ------------------------ > 5 files changed, 22 insertions(+), 116 deletions(-) > delete mode 100644 gcc/testsuite/gcc.dg/match-shift-cmp-4.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 63d56b08192..9b42c4e3c59 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -1339,37 +1339,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (if (INTEGRAL_TYPE_P (type)) > (rshift (op @0 @2) @1)))) > > -/* (y << x) == x -> 0 when y != 0. */ > +/* (y << x) == x -> false when y != 0. */ > (simplify > (eq:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) > (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) > && tree_expr_nonzero_p (@0)) > - { build_zero_cst (type); })) > - > -/* (y << x) {<,<=} x -> 0 when y > 0. */ > -(for cmp (lt le) > - (simplify > - (cmp:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) > - (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) > - && tree_expr_nonzero_p (@0) > - && tree_expr_nonnegative_p (@0)) > - { build_zero_cst (type); }))) > + { constant_boolean_node (false, type); })) > > -/* (y << x) != x -> 1 when y != 0. */ > +/* (y << x) != x -> true when y != 0. */ > (simplify > (ne:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) > (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) > && tree_expr_nonzero_p (@0)) > - { build_one_cst (type); })) > - > -/* (y << x) {>,>=} x -> 1 when y > 0. */ > -(for cmp (gt ge) > - (simplify > - (cmp:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) > - (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) > - && tree_expr_nonzero_p (@0) > - && tree_expr_nonnegative_p (@0)) > - { build_one_cst (type); }))) > + { constant_boolean_node (true, type); })) > > /* Fold (1 << (C - x)) where C = precision(type) - 1 > into ((1 << C) >> x). */ > diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-1.c > b/gcc/testsuite/gcc.dg/match-shift-cmp-1.c > index b22d57d370f..7a69cd19437 100644 > --- a/gcc/testsuite/gcc.dg/match-shift-cmp-1.c > +++ b/gcc/testsuite/gcc.dg/match-shift-cmp-1.c > @@ -34,17 +34,8 @@ typedef enum > > TEST_OP_CST (eq, ==, 1) > TEST_OP_CST (ne, !=, 2) > -TEST_OP_CST (lt, <, 3) > -TEST_OP_CST (gt, >, 4) > -TEST_OP_CST (le, <=, 5) > -TEST_OP_CST (ge, >=, 6) > > TEST_OP (eq, ==) > TEST_OP (ne, !=) > -TEST_OP (lt, <) > -TEST_OP (gt, >) > -TEST_OP (le, <=) > -TEST_OP (ge, >=) > > -/* FIXME: The lt, le, gt and ge cases for int and enum don't get optimized. > */ > -/* { dg-final { scan-tree-dump-times "<<" 8 optimized } } */ > +/* { dg-final { scan-tree-dump-not "<<" optimized } } */ > diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-2.c > b/gcc/testsuite/gcc.dg/match-shift-cmp-2.c > index 96a2fd954f6..3d514ba1ee1 100644 > --- a/gcc/testsuite/gcc.dg/match-shift-cmp-2.c > +++ b/gcc/testsuite/gcc.dg/match-shift-cmp-2.c > @@ -36,27 +36,12 @@ typedef enum > > TEST_OP_CST (eq, ==, 0) > TEST_OP_CST (ne, !=, 0) > -TEST_OP_CST (lt, <, 0) > -TEST_OP_CST (gt, >, 0) > -TEST_OP_CST (le, <=, 0) > -TEST_OP_CST (ge, >=, 0) > > TEST_OP (eq, ==) > TEST_OP (ne, !=) > -TEST_OP (lt, <) > -TEST_OP (gt, >) > -TEST_OP (le, <=) > -TEST_OP (ge, >=) > > /* These end up getting folded by other patterns. */ > -/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) == 0" 8 optimized } } */ > -/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) != 0" 8 optimized } } */ > -/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) > 0" 4 optimized } } */ > -/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) < 0" 4 optimized } } */ > -/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) >= 0" 4 optimized } } */ > -/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) <= 0" 4 optimized } } */ > -/* { dg-final { scan-tree-dump-times "~x_\\d\\(D\\)" 4 optimized } } */ > -/* { dg-final { scan-tree-dump-times "return x_\\d\\(D\\);" 4 optimized } } > */ > -/* { dg-final { scan-tree-dump-times "return 0;" 4 optimized } } */ > -/* { dg-final { scan-tree-dump-times "return 1;" 4 optimized } } */ > -/* Total: 48. */ > +/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) == 0" 6 optimized } } */ > +/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) != 0" 6 optimized } } */ > +/* { dg-final { scan-tree-dump-times "~x_\\d\\(D\\)" 2 optimized } } */ > +/* { dg-final { scan-tree-dump-times "return x_\\d\\(D\\);" 2 optimized } } > */ > diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-3.c > b/gcc/testsuite/gcc.dg/match-shift-cmp-3.c > index 34380cfeb96..e46ac30b905 100644 > --- a/gcc/testsuite/gcc.dg/match-shift-cmp-3.c > +++ b/gcc/testsuite/gcc.dg/match-shift-cmp-3.c > @@ -1,25 +1,27 @@ > /* { dg-do compile } */ > /* { dg-options "-O2 -fdump-tree-optimized" } */ > > -/* The fold (y << x) <op> x -> 0|1 shouldn't trigger when y is negative or > - zero unsigned (except for == and !=). */ > +/* The fold (y << x) <op> x -> 0|1 should trigger when y is negative > + unsigned. */ > > #define TEST_ONE_CST(n, op, type, cst) > \ > - bool lshift_cst_##type##_##n (type x) { return ((cst << x) op x); } > + bool lshift_cst_##type##_##n (type x) { return ((unsigned) (cst) << x) op > x; } > > #define TEST_OP_CST(n, op, cst) > \ > + TEST_ONE_CST (n, op, unsigned, cst) > \ > TEST_ONE_CST (n, op, int, cst) > \ > TEST_ONE_CST (n, op, test_enum, cst) > > #define TEST_ONE(n, op, type) > \ > bool lshift_##type##_##n (type x, type y) > \ > { > \ > - if (y > 0) > \ > + if ((int) y <= 0) > \ > __builtin_unreachable (); > \ > - return ((y << x) op x); > \ > + return ((unsigned) (y) << x) op x; > \ > } > > #define TEST_OP(n, op) > \ > + TEST_ONE (n, op, unsigned) > \ > TEST_ONE (n, op, int) > \ > TEST_ONE (n, op, test_enum) > > @@ -31,14 +33,11 @@ typedef enum > TWO = 2 > } test_enum; > > -TEST_OP_CST (lt, <, -1) > -TEST_OP_CST (gt, >, -2) > -TEST_OP_CST (le, <=, -3) > -TEST_OP_CST (ge, >=, -4) > +TEST_OP_CST (eq, ==, -1) > +TEST_OP_CST (ne, !=, -2) > > -TEST_OP (lt, <) > -TEST_OP (gt, >) > -TEST_OP (le, <=) > -TEST_OP (ge, >=) > +TEST_OP (eq, ==) > +TEST_OP (ne, !=) > > -/* { dg-final { scan-tree-dump-times "<<" 16 optimized } } */ > +/* { dg-final { scan-tree-dump-times "return 0;" 6 optimized } } */ > +/* { dg-final { scan-tree-dump-times "return 1;" 6 optimized } } */ > diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-4.c > b/gcc/testsuite/gcc.dg/match-shift-cmp-4.c > deleted file mode 100644 > index 629e2a376d1..00000000000 > --- a/gcc/testsuite/gcc.dg/match-shift-cmp-4.c > +++ /dev/null > @@ -1,51 +0,0 @@ > -/* { dg-do compile } */ > -/* { dg-options "-O2 -fdump-tree-optimized" } */ > - > -/* The fold (y << x) <op> x -> 0|1 should trigger when y is negative > - unsigned. */ > - > -#define TEST_ONE_CST(n, op, type, cst) > \ > - bool lshift_cst_##type##_##n (type x) { return ((unsigned) (cst) << x) op > x; } > - > -#define TEST_OP_CST(n, op, cst) > \ > - TEST_ONE_CST (n, op, unsigned, cst) > \ > - TEST_ONE_CST (n, op, int, cst) > \ > - TEST_ONE_CST (n, op, test_enum, cst) > - > -#define TEST_ONE(n, op, type) > \ > - bool lshift_##type##_##n (type x, type y) > \ > - { > \ > - if ((int) y <= 0) > \ > - __builtin_unreachable (); > \ > - return ((unsigned) (y) << x) op x; > \ > - } > - > -#define TEST_OP(n, op) > \ > - TEST_ONE (n, op, unsigned) > \ > - TEST_ONE (n, op, int) > \ > - TEST_ONE (n, op, test_enum) > - > -typedef enum > -{ > - MONE = -1, > - ZERO = 0, > - ONE = 1, > - TWO = 2 > -} test_enum; > - > -TEST_OP_CST (eq, ==, -1) > -TEST_OP_CST (ne, !=, -2) > -TEST_OP_CST (lt, <, -3) > -TEST_OP_CST (gt, >, -4) > -TEST_OP_CST (le, <=, -5) > -TEST_OP_CST (ge, >=, -6) > - > -TEST_OP (eq, ==) > -TEST_OP (ne, !=) > -TEST_OP (lt, <) > -TEST_OP (gt, >) > -TEST_OP (le, <=) > -TEST_OP (ge, >=) > - > -/* { dg-final { scan-tree-dump-times "return 0;" 18 optimized } } */ > -/* { dg-final { scan-tree-dump-times "return 1;" 18 optimized } } */ > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
