On Thu, May 07, 2020 at 10:12:12AM +0200, Richard Biener wrote: > 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))?
Ok. > Do you really need the TYPE_OVERFLOW_UNDEFINED check? Probably not, if overflow isn't undefined, then ABS_EXPR will not be undefined on the type minimum either. So like this (including dropping :s from plus), or should there be single_use for it? You've said that if the replacement is a simple stmt :s is ignored... 2020-05-07 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-07 16:30:15.666817448 +0200 @@ -120,6 +120,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (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:c @0 (rshift@2 @0 INTEGER_CST@1)) @2) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && wi::to_widest (@1) == element_precision (TREE_TYPE (@0)) - 1 + && TREE_CODE (@2) == SSA_NAME) + (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