On Tue, 24 Sep 2019, Jakub Jelinek wrote: > Hi! > > As mentioned in the PR, the following patch decreases number of +/- > operation when one is inside sign extension, done with undefined overflow, > and the outer is using wrapping arithmetics. > > The :s as well as the outer + are there in order to make sure it is actually > beneficial, that we decrease the number of +/-, either from two to one or > from two to zero, depending on whether they cancel each other. > The price for the reduction is that we loose information about the undefined > behavior for certain @0 values. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. > 2019-09-24 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/91866 > * match.pd (((T)(A)) + CST -> (T)(A + CST)): Formatting fix. > (((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2): New optimization. > > * gcc.dg/tree-ssa/pr91866.c: New test. > > --- gcc/match.pd.jj 2019-09-21 23:53:52.108385196 +0200 > +++ gcc/match.pd 2019-09-24 10:18:58.804114496 +0200 > @@ -2265,8 +2265,9 @@ (define_operator_list COND_TERNARY > max_ovf = wi::OVF_OVERFLOW; > tree inner_type = TREE_TYPE (@0); > > - wide_int w1 = wide_int::from (wi::to_wide (@1), TYPE_PRECISION > (inner_type), > - TYPE_SIGN (inner_type)); > + wide_int w1 > + = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type), > + TYPE_SIGN (inner_type)); > > wide_int wmin0, wmax0; > if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE) > @@ -2280,6 +2281,20 @@ (define_operator_list COND_TERNARY > ))) > #endif > > +/* ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2 */ > +#if GIMPLE > + (for op (plus minus) > + (simplify > + (plus (convert:s (op:s @0 INTEGER_CST@1)) INTEGER_CST@2) > + (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE > + && TREE_CODE (type) == INTEGER_TYPE > + && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0)) > + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) > + && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)) > + && TYPE_OVERFLOW_WRAPS (type)) > + (plus (convert @0) (op @2 (convert @1)))))) > +#endif > + > /* ~A + A -> -1 */ > (simplify > (plus:c (bit_not @0) @0) > --- gcc/testsuite/gcc.dg/tree-ssa/pr91866.c.jj 2019-09-24 > 10:35:34.035784152 +0200 > +++ gcc/testsuite/gcc.dg/tree-ssa/pr91866.c 2019-09-24 10:36:59.858463024 > +0200 > @@ -0,0 +1,12 @@ > +/* PR middle-end/91866 */ > +/* { dg-do compile { target { ilp32 || lp64 } } } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } * / > +/* { dg-final { scan-tree-dump-times " \\+ 11;" 3 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times " \[+-] \[0-9-]\[0-9]*;" 3 "optimized" > } } */ > +/* { dg-final { scan-tree-dump-times "\\(long long unsigned int\\) x_" 5 > "optimized" } } */ > + > +unsigned long long f1 (int x) { return (x + 1) - 1ULL; } > +unsigned long long f2 (int x) { return (x - 5) + 5ULL; } > +unsigned long long f3 (int x) { return (x - 15) + 26ULL; } > +unsigned long long f4 (int x) { return (x + 6) + 5ULL; } > +unsigned long long f5 (int x) { return (x - (-1 - __INT_MAX__)) + 10ULL - > __INT_MAX__; } > > Jakub > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 247165 (AG München)