On Tue, 3 Dec 2019, Jakub Jelinek wrote:

> Hi!
> 
> The following patch extends the improvements Marc did to the
> (A +- CST1) +- CST2 -> A +- CST3
> match.pd simplification some time ago to the other two patterns,
> in particular handle the case when the inner subtraction is done in a
> different, but nop_convert compatible, type from the outer +/-.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2019-12-03  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/92734
>       * match.pd ((CST1 - A) +- CST2 -> CST3 - A,
>       CST1 - (CST2 - A) -> CST3 + A): Handle nop casts around
>       inner subtraction.
> 
>       * gcc.dg/tree-ssa/pr92734.c: New test.
> 
> --- gcc/match.pd.jj   2019-12-02 09:50:27.000000000 +0100
> +++ gcc/match.pd      2019-12-02 16:23:43.825040429 +0100
> @@ -2237,17 +2237,39 @@ (define_operator_list COND_TERNARY
>    /* (CST1 - A) +- CST2 -> CST3 - A  */
>    (for outer_op (plus minus)
>     (simplify
> -    (outer_op (minus CONSTANT_CLASS_P@1 @0) CONSTANT_CLASS_P@2)
> -    (with { tree cst = const_binop (outer_op, type, @1, @2); }
> -     (if (cst && !TREE_OVERFLOW (cst))
> -      (minus { cst; } @0)))))
> +    (outer_op (nop_convert (minus CONSTANT_CLASS_P@1 @0)) CONSTANT_CLASS_P@2)
> +    /* If one of the types wraps, use that one.  */
> +    (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
> +     /* If all 3 captures are CONSTANT_CLASS_P, punt, as we might recurse
> +     forever if something doesn't simplify into a constant.  */
> +     (if (!CONSTANT_CLASS_P (@0))
> +      (minus (outer_op (view_convert @1) @2) (view_convert @0)))
> +     (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +       || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
> +      (view_convert (minus (outer_op @1 (view_convert @2)) @0))
> +      (if (types_match (type, @0))
> +       (with { tree cst = const_binop (outer_op, type, @1, @2); }
> +     (if (cst && !TREE_OVERFLOW (cst))
> +      (minus { cst; } @0))))))))
>  
> -  /* CST1 - (CST2 - A) -> CST3 + A  */
> +  /* CST1 - (CST2 - A) -> CST3 + A
> +     Use view_convert because it is safe for vectors and equivalent for
> +     scalars.  */
>    (simplify
> -   (minus CONSTANT_CLASS_P@1 (minus CONSTANT_CLASS_P@2 @0))
> -   (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); }
> -    (if (cst && !TREE_OVERFLOW (cst))
> -     (plus { cst; } @0))))
> +   (minus CONSTANT_CLASS_P@1 (nop_convert (minus CONSTANT_CLASS_P@2 @0)))
> +   /* If one of the types wraps, use that one.  */
> +   (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
> +    /* If all 3 captures are CONSTANT_CLASS_P, punt, as we might recurse
> +      forever if something doesn't simplify into a constant.  */
> +    (if (!CONSTANT_CLASS_P (@0))
> +     (plus (view_convert @0) (minus @1 (view_convert @2))))
> +    (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +      || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
> +     (view_convert (plus @0 (minus (view_convert @1) @2)))
> +     (if (types_match (type, @0))
> +      (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); }
> +       (if (cst && !TREE_OVERFLOW (cst))
> +     (plus { cst; } @0)))))))
>  
>  /* ((T)(A)) + CST -> (T)(A + CST)  */
>  #if GIMPLE
> --- gcc/testsuite/gcc.dg/tree-ssa/pr92734.c.jj        2019-12-02 
> 16:26:55.771057273 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr92734.c   2019-12-02 16:29:59.922195268 
> +0100
> @@ -0,0 +1,31 @@
> +/* PR tree-optimization/92734 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-forwprop1" } */
> +/* { dg-final { scan-tree-dump-times "return t_\[0-9]*\\\(D\\\);" 4 
> "forwprop1" } } */
> +
> +int
> +f1 (int t)
> +{
> +  return 1 - (int) (1U - t);
> +}
> +
> +int
> +f2 (int t)
> +{
> +  int a = 7U - t;
> +  return 7 - a;
> +}
> +
> +int
> +f3 (int t)
> +{
> +  int a = 32U - t;
> +  return 32 - a;
> +}
> +
> +int
> +f4 (int t)
> +{
> +  int a = 32 - t;
> +  return (int) (32 - (unsigned) 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