From a0d732eea2e152fc51f7c5249abaa9ef56fc5121 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 8 May 2020 09:35:41 +0200 Subject: [PATCH] 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. --- gcc/ChangeLog | 4 ++++ gcc/match.pd | 9 +++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/tree-ssa/pr94783.c | 12 ++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr94783.c 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; +} -- 2.30.2