On Mon, 27 Apr 2020, Jakub Jelinek wrote:
> Hi!
>
> On the following testcase, there are in *.optimized dump 14 nop conversions
> (from signed to unsigned and back), while this patch decreases that number
> to just 4; for bitwise ops it really doesn't matter if they are performed in
> signed or unsigned, so the patch (in GIMPLE only, there are some comments
> about it being undesirable during GENERIC earlier), if it sees both
> bitop operands nop converted from the same types performs the bitop in their
> non-converted type and converts the result (i.e. 2 conversions into 1),
> similarly, if a bitop has one operand nop converted from something, the
> other not and the result is converted back to the type of the nop converted
> operand before conversion, it is possible to replace those 2 conversions
> with just a single conversion of the other operand.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2020-04-27 Jakub Jelinek <[email protected]>
>
> 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.
>
> * gcc.dg/tree-ssa/pr94718-3.c: New test.
>
> --- gcc/match.pd.jj 2020-04-24 19:12:56.969197128 +0200
> +++ gcc/match.pd 2020-04-27 16:54:48.340656033 +0200
> @@ -1311,7 +1311,7 @@ (define_operator_list COND_TERNARY
> 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_operator_list COND_TERNARY
> || 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))))
I think you don't need explicit single_use checks here but could use :s
in the pattern since the result expression will be "complex" and thus
the :s isn't elided.
OK for stage1.
Thanks,
Richard.
> + (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)
> --- gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c.jj 2020-04-27
> 16:59:33.650366084 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c 2020-04-27 16:58:46.634073029
> +0200
> @@ -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;
> +}
>
> Jakub
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)