From: Andrew Pinski <apin...@marvell.com> The problem here is that int_fits_type_p will return false if we just change the sign of things like -2 (or 254) so we should accept the case where we just change the sign (and not the precision) of the type.
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. PR tree-optimization/103220 gcc/ChangeLog: * match.pd ((type) X bitop CST): Don't check if CST fits into the type if only the sign changes. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr103220-1.c: New test. * gcc.dg/tree-ssa/pr103220-2.c: New test. * gcc.dg/pr25530.c: Update test to check for 4294967294 in the case -2 is not matched. --- gcc/match.pd | 3 ++- gcc/testsuite/gcc.dg/pr25530.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr103220-1.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr103220-2.c | 16 ++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr103220-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr103220-2.c diff --git a/gcc/match.pd b/gcc/match.pd index 24a84e3b504..37c5be9e5f4 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1607,7 +1607,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bitop (convert@2 @0) (convert?@3 @1)) (if (((TREE_CODE (@1) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (@0)) - && int_fits_type_p (@1, TREE_TYPE (@0))) + && (int_fits_type_p (@1, TREE_TYPE (@0)) + || tree_nop_conversion_p (TREE_TYPE (@0), type))) || types_match (@0, @1)) /* ??? This transform conflicts with fold-const.c doing Convert (T)(x & c) into (T)x & (T)c, if c is an integer diff --git a/gcc/testsuite/gcc.dg/pr25530.c b/gcc/testsuite/gcc.dg/pr25530.c index b846ab30140..771b36b9c29 100644 --- a/gcc/testsuite/gcc.dg/pr25530.c +++ b/gcc/testsuite/gcc.dg/pr25530.c @@ -8,4 +8,4 @@ f (unsigned t) return (t / 2) * 2; } -/* { dg-final { scan-tree-dump "\& -2" "optimized" } } */ +/* { dg-final { scan-tree-dump "\& -2|4294967294" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr103220-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr103220-1.c new file mode 100644 index 00000000000..f2ef3f1d93c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr103220-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +unsigned char f(unsigned char a) +{ + signed char d = (signed char) a; + signed char e = d & ~1; + unsigned char t = e; + t &= ~2; + return t; +} +/* The above should reduce down to just & 252 rather than keping + the two &s there. */ +/* { dg-final { scan-tree-dump-times "& 252" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "& -2" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "& 253" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr103220-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr103220-2.c new file mode 100644 index 00000000000..25d7412a095 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr103220-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +signed char f(unsigned char a) +{ + unsigned char b = a & 127; + signed char c = (signed char) b; + signed char d = (signed char) a; + signed char e = d & -128; + signed char h = c | e; + return h; +} +/* The above should reduce down to just return with a cast. + removing the two &s there and |'s. */ +/* { dg-final { scan-tree-dump-times "& 127" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "& -128" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\\\| " 0 "optimized"} } */ -- 2.17.1