[gcc/devel/ranger] match.pd: Canonicalize (X + (X >> (prec - 1))) ^ (X >> (prec - 1)) to abs (X) [PR94783]

Aldy Hernandez aldyh@gcc.gnu.org
Wed Jun 17 21:12:19 GMT 2020


https://gcc.gnu.org/g:a0d732eea2e152fc51f7c5249abaa9ef56fc5121

commit a0d732eea2e152fc51f7c5249abaa9ef56fc5121
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri May 8 09:35:41 2020 +0200

    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  <jakub@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.

Diff:
---
 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(+)

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  <jakub@redhat.com>
 
+	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  <jakub@redhat.com>
 
+	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;
+}


More information about the Gcc-cvs mailing list