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  <ja...@redhat.com>
> 
>       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 <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to