diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47eef982a59..036a4030308 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2020-05-04 Jakub Jelinek + PR tree-optimization/94718 + * match.pd (bitop (convert @0) (convert? @1)): For GIMPLE, if we can, + replace two nop conversions on bit_{and,ior,xor} argument + and result with just one conversion on the result or another argument. + PR tree-optimization/94718 * fold-const.c (fold_binary_loc): Move (X & C) eqne (Y & C) -> (X ^ Y) & C eqne 0 optimization to ... diff --git a/gcc/match.pd b/gcc/match.pd index 123e670f9ee..929be14e8b7 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1311,7 +1311,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) We combine the above two cases by using a conditional convert. */ (for bitop (bit_and bit_ior bit_xor) (simplify - (bitop (convert @0) (convert? @1)) + (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))) @@ -1330,8 +1330,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT /* Or if the precision of TO is not the same as the precision of its mode. */ - || !type_has_mode_precision_p (type))) - (convert (bitop @0 (convert @1)))))) + || !type_has_mode_precision_p (type) + /* In GIMPLE, getting rid of 2 conversions for one new results + in smaller IL. */ + || (GIMPLE + && TREE_CODE (@1) != INTEGER_CST + && tree_nop_conversion_p (type, TREE_TYPE (@0)) + && single_use (@2) + && single_use (@3)))) + (convert (bitop @0 (convert @1))))) + /* In GIMPLE, getting rid of 2 conversions for one new results + in smaller IL. */ + (simplify + (convert (bitop:cs@2 (nop_convert:s @0) @1)) + (if (GIMPLE + && TREE_CODE (@1) != INTEGER_CST + && tree_nop_conversion_p (type, TREE_TYPE (@2)) + && types_match (type, @0)) + (bitop @0 (convert @1))))) (for bitop (bit_and bit_ior) rbitop (bit_ior bit_and) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 100870acedb..09979b5749c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-05-04 Jakub Jelinek + PR tree-optimization/94718 + * gcc.dg/tree-ssa/pr94718-3.c: New test. + PR tree-optimization/94718 * gcc.dg/tree-ssa/pr94718-1.c: New test. * gcc.dg/tree-ssa/pr94718-2.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c new file mode 100644 index 00000000000..d1fb4a64504 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c @@ -0,0 +1,45 @@ +/* PR tree-optimization/94718 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times " \\\(int\\\) " 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \\\(unsigned int\\\) " 2 "optimized" } } */ + +int +f1 (int x, int y) +{ + return (int) ((unsigned) x | (unsigned) y); +} + +int +f2 (int x, int y) +{ + unsigned a = x; + unsigned b = y; + return a | b; +} + +int +f3 (int x, unsigned y) +{ + return (int) ((unsigned) x | y); +} + +int +f4 (int x, unsigned y) +{ + unsigned a = x; + return a | y; +} + +unsigned +f5 (int x, unsigned y) +{ + return (unsigned) (x | (int) y); +} + +unsigned +f6 (int x, unsigned y) +{ + int a = y; + return x | a; +}