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)