aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-08 09:35:41 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-08 09:35:41 +0200
commita0d732eea2e152fc51f7c5249abaa9ef56fc5121 (patch)
tree7d2fb107ac7cbf4d72a6934db371dc075494caf5 /gcc
parentdf569f7da567af4996821dc0a1871eec79957d04 (diff)
downloadgcc-a0d732eea2e152fc51f7c5249abaa9ef56fc5121.zip
gcc-a0d732eea2e152fc51f7c5249abaa9ef56fc5121.tar.gz
gcc-a0d732eea2e152fc51f7c5249abaa9ef56fc5121.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/match.pd9
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94783.c12
4 files changed, 28 insertions, 0 deletions
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 <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 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 <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 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;
+}