On Thu, 7 May 2020, Jakub Jelinek wrote: > Hi! > > The following patch canonicalizes M = X >> (prec - 1); (X + M) ^ M > for signed integral types into ABS_EXPR (X). For X == min it is already > UB because M is -1 and min + -1 is UB, so we can use ABS_EXPR rather than > say ABSU_EXPR + cast. > > The backend might then emit the abs code back using the shift and addition > and xor if it is the best sequence for the target, but could do something > different that is better. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2020-05-06 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/94783 > * match.pd ((X + (X >> (prec - 1))) ^ (X >> (prec - 1)) to abs (X)): > New simplification. > > * gcc.dg/tree-ssa/pr94783.c: New test. > > --- gcc/match.pd.jj 2020-05-06 15:48:23.658858289 +0200 > +++ gcc/match.pd 2020-05-06 17:47:02.035347946 +0200 > @@ -120,6 +120,18 @@ (define_operator_list COND_TERNARY > (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); } > (convert (absu:utype @0))))) > > +#if GIMPLE > +/* Optimize (X + (X >> (prec - 1))) ^ (X >> (prec - 1)) into abs (X). */ > +(simplify > + (bit_xor:c (plus:cs @0 (rshift@2 @0 INTEGER_CST@1)) @2) > + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) > + && !TYPE_UNSIGNED (TREE_TYPE (@0)) > + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) > + && wi::to_widest (@1) == element_precision (TREE_TYPE (@0)) - 1 > + && TREE_CODE (@2) == SSA_NAME > + && num_imm_uses (@2) == 2)
I fear this num_imm_uses test is quite fragile since match.pd patterns are invoked on transient sequences (w/o SSA operands) as well (that of course holds for all single_use () tests as well but that at least allows zero uses for this very reason - still fragile since the single use might be _in_ the IL and thus a second). I think unconditionally using (abs @0) is simplifying things enough (getting rid of one xor and one plus) to not worry about keeping the (x >> (prec - 1))? Do you really need the TYPE_OVERFLOW_UNDEFINED check? > + (abs @0))) > +#endif > > /* Simplifications of operations with one constant operand and > simplifications to constants or single values. */ > --- gcc/testsuite/gcc.dg/tree-ssa/pr94783.c.jj 2020-05-06 > 17:52:35.515323297 +0200 > +++ gcc/testsuite/gcc.dg/tree-ssa/pr94783.c 2020-05-06 17:52:10.915693948 > +0200 > @@ -0,0 +1,12 @@ > +/* PR tree-optimization/94783 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump "ABS_EXPR" "optimized" } } */ > +/* { dg-final { scan-tree-dump-not " >> 31" "optimized" } } */ > + > +int > +foo (int v) > +{ > + int mask = v >> (__SIZEOF_INT__ * __CHAR_BIT__ - 1); > + return (v + mask) ^ mask; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)