From: Jakub Jelinek Date: Fri, 8 May 2020 07:35:41 +0000 (+0200) Subject: match.pd: Canonicalize (X + (X >> (prec - 1))) ^ (X >> (prec - 1)) to abs (X) [PR94783] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0d732eea2e152fc51f7c5249abaa9ef56fc5121;p=gcc.git match.pd: Canonicalize (X + (X >> (prec - 1))) ^ (X >> (prec - 1)) to abs (X) [PR94783] 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. 2020-05-08 Jakub Jelinek 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. --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5bad3ff924b..75b0ed1542f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2020-05-08 Jakub Jelinek + PR tree-optimization/94783 + * match.pd ((X + (X >> (prec - 1))) ^ (X >> (prec - 1)) to abs (X)): + New simplification. + PR tree-optimization/94956 * match.pd (FFS): Optimize __builtin_ffs* of non-zero argument into __builtin_ctz* + 1 if direct IFN_CTZ is supported. diff --git a/gcc/match.pd b/gcc/match.pd index 892df1ec3d3..e8c53e347f4 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -120,6 +120,15 @@ 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) + (abs @0))) +#endif /* Simplifications of operations with one constant operand and simplifications to constants or single values. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e8c54c7cd67..174198fdbe4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-05-08 Jakub Jelinek + PR tree-optimization/94783 + * gcc.dg/tree-ssa/pr94783.c: New test. + PR tree-optimization/94956 * gcc.target/i386/pr94956.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94783.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94783.c new file mode 100644 index 00000000000..c52f657520e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94783.c @@ -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; +}