diff options
-rw-r--r-- | gcc/match.pd | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/fold-parity-8.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/fold-popcount-11.c | 25 |
3 files changed, 67 insertions, 10 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 1fe0559..6e32f47 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7865,10 +7865,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (popcount (convert?@0 (bswap:s@1 @2))) (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1))) - (with { unsigned int prec0 = TYPE_PRECISION (TREE_TYPE (@0)); - unsigned int prec1 = TYPE_PRECISION (TREE_TYPE (@1)); } - (if (prec0 == prec1 || (prec0 > prec1 && TYPE_UNSIGNED (TREE_TYPE (@1)))) - (popcount @2))))))) + (with { tree type0 = TREE_TYPE (@0); + tree type1 = TREE_TYPE (@1); + unsigned int prec0 = TYPE_PRECISION (type0); + unsigned int prec1 = TYPE_PRECISION (type1); } + (if (prec0 == prec1 || (prec0 > prec1 && TYPE_UNSIGNED (type1))) + (popcount (convert:type0 (convert:type1 @2))))))))) /* popcount(rotate(X Y)) is popcount(X). */ (for popcount (POPCOUNT) @@ -7878,10 +7880,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)) && (GIMPLE || !TREE_SIDE_EFFECTS (@3))) - (with { unsigned int prec0 = TYPE_PRECISION (TREE_TYPE (@0)); - unsigned int prec1 = TYPE_PRECISION (TREE_TYPE (@1)); } - (if (prec0 == prec1 || (prec0 > prec1 && TYPE_UNSIGNED (TREE_TYPE (@1)))) - (popcount @2))))))) + (with { tree type0 = TREE_TYPE (@0); + tree type1 = TREE_TYPE (@1); + unsigned int prec0 = TYPE_PRECISION (type0); + unsigned int prec1 = TYPE_PRECISION (type1); } + (if (prec0 == prec1 || (prec0 > prec1 && TYPE_UNSIGNED (type1))) + (popcount (convert:type0 @2)))))))) /* Canonicalize POPCOUNT(x)&1 as PARITY(X). */ (simplify @@ -7923,7 +7927,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && INTEGRAL_TYPE_P (TREE_TYPE (@1)) && TYPE_PRECISION (TREE_TYPE (@0)) >= TYPE_PRECISION (TREE_TYPE (@1))) - (parity @2))))) + (with { tree type0 = TREE_TYPE (@0); + tree type1 = TREE_TYPE (@1); } + (parity (convert:type0 (convert:type1 @2)))))))) /* parity(rotate(X Y)) is parity(X). */ (for parity (PARITY) @@ -7935,7 +7941,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (GIMPLE || !TREE_SIDE_EFFECTS (@3)) && TYPE_PRECISION (TREE_TYPE (@0)) >= TYPE_PRECISION (TREE_TYPE (@1))) - (parity @2))))) + (with { tree type0 = TREE_TYPE (@0); } + (parity (convert:type0 @2))))))) /* parity(X)^parity(Y) is parity(X^Y). */ (simplify diff --git a/gcc/testsuite/gcc.dg/fold-parity-8.c b/gcc/testsuite/gcc.dg/fold-parity-8.c new file mode 100644 index 0000000..48e1f7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-parity-8.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int foo(unsigned short x) +{ + unsigned short t1 = __builtin_bswap16(x); + unsigned int t2 = t1; + return __builtin_parity (t2); +} + +int fool(unsigned short x) +{ + unsigned short t1 = __builtin_bswap16(x); + unsigned long t2 = t1; + return __builtin_parityl (t2); +} + +int fooll(unsigned short x) +{ + unsigned short t1 = __builtin_bswap16(x); + unsigned long long t2 = t1; + return __builtin_parityll (t2); +} + +/* { dg-final { scan-tree-dump-not "bswap" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/fold-popcount-11.c b/gcc/testsuite/gcc.dg/fold-popcount-11.c new file mode 100644 index 0000000..e59be00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-popcount-11.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int foo(unsigned short x) +{ + unsigned short t1 = __builtin_bswap16(x); + unsigned int t2 = t1; + return __builtin_popcount (t2); +} + +int fool(unsigned short x) +{ + unsigned short t1 = __builtin_bswap16(x); + unsigned long t2 = t1; + return __builtin_popcountl (t2); +} + +int fooll(unsigned short x) +{ + unsigned short t1 = __builtin_bswap16(x); + unsigned long long t2 = t1; + return __builtin_popcountll (t2); +} + +/* { dg-final { scan-tree-dump-not "bswap" "optimized" } } */ |