From: Andrew Pinski Date: Sat, 20 Nov 2021 01:37:54 +0000 (+0000) Subject: Fix tree-optimization/103220: Another missing folding of (type) X op CST where type... X-Git-Tag: basepoints/gcc-13~2883 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=74faa9834a9ad208e34f67b08c854c20b0fcfe92;p=thirdparty%2Fgcc.git Fix tree-optimization/103220: Another missing folding of (type) X op CST where type is a nop convert 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. --- diff --git a/gcc/match.pd b/gcc/match.pd index e5985defe6f7..f059b477f583 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 b846ab301400..771b36b9c290 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 000000000000..f2ef3f1d93cc --- /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 000000000000..25d7412a0958 --- /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"} } */