On Tue, 5 Jan 2021, Jakub Jelinek wrote: > Hi! > > The following patch improves the A / (1 << B) -> A >> B simplification, > as seen in the testcase, if there is unnecessary widening for the division, > we just optimize it into a shift on the widened type, but if the lshift > is widened too, there is no reason to do that, we can just shift it in the > original type and convert after. The tree_nonzero_bits & wi::mask check > already ensures it is fine even for signed values. > > I've split the vr-values optimization into a separate patch as it causes > a small regression on two testcases, but this patch fixes what has been > reported in the PR alone. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. > 2021-01-05 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/96930 > * match.pd ((A / (1 << B)) -> (A >> B)): If A is extended > from narrower value which has the same type as 1 << B, perform > the right shift on the narrower value followed by extension. > > * g++.dg/tree-ssa/pr96930.C: New test. > > --- gcc/match.pd.jj 2021-01-04 10:37:06.000000000 +0100 > +++ gcc/match.pd 2021-01-05 10:27:56.653791400 +0100 > @@ -321,7 +321,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (unsigned long long) (1 << 31) is -2147483648ULL, not 2147483648ULL, > so it is valid only if A >> 31 is zero. */ > (simplify > - (trunc_div @0 (convert? (lshift integer_onep@1 @2))) > + (trunc_div (convert?@0 @3) (convert2? (lshift integer_onep@1 @2))) > (if ((TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (@0)) > && (!VECTOR_TYPE_P (type) > || target_supports_op_p (type, RSHIFT_EXPR, optab_vector) > @@ -336,7 +336,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > & wi::mask (element_precision (TREE_TYPE (@1)) - 1, > true, > element_precision (type))) == 0))))) > - (rshift @0 @2))) > + (if (!VECTOR_TYPE_P (type) > + && useless_type_conversion_p (TREE_TYPE (@3), TREE_TYPE (@1)) > + && element_precision (TREE_TYPE (@3)) < element_precision (type)) > + (convert (rshift @3 @2)) > + (rshift @0 @2)))) > > /* Preserve explicit divisions by 0: the C++ front-end wants to detect > undefined behavior in constexpr evaluation, and assuming that the division > --- gcc/testsuite/g++.dg/tree-ssa/pr96930.C.jj 2021-01-04 > 14:18:15.513100038 +0100 > +++ gcc/testsuite/g++.dg/tree-ssa/pr96930.C 2021-01-04 14:25:35.512148709 > +0100 > @@ -0,0 +1,10 @@ > +// PR tree-optimization/96930 > +// { dg-do compile } > +// { dg-options "-O2 -fdump-tree-optimized" } > +// { dg-final { scan-tree-dump " = a_\[0-9]\\\(D\\\) >> b_\[0-9]\\\(D\\\);" > "optimized" } } > + > +unsigned > +foo (unsigned a, unsigned b) > +{ > + return a / (unsigned long long) (1U << b); > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)