From a0d732eea2e152fc51f7c5249abaa9ef56fc5121 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 8 May 2020 09:35:41 +0200 Subject: 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 (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5bad3ff..75b0ed1 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 892df1e..e8c53e3 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 e8c54c7..174198f 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 0000000..c52f657 --- /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; +} -- cgit v1.1