summaryrefslogtreecommitdiff
path: root/0060-Backport-Optimize-x-0-y-y-to-x-31-y-in-match.pd.patch
blob: 80d602ae22e52fd24f9e1e71b4cd3b15a97a7bb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
From 4352b952ba24c413697fcfc191d06165a8a31ced Mon Sep 17 00:00:00 2001
From: Andrew Pinski <apinski@marvell.com>
Date: Sat, 22 May 2021 19:49:50 +0000
Subject: [PATCH 12/35] [Backport] Optimize x < 0 ? ~y : y to (x >> 31) ^ y in
 match.pd

Reference: https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=1fd76b24306ed4df4cf9e797d900699ed59ce7f7

This copies the optimization that is done in phiopt for
"x < 0 ? ~y : y to (x >> 31) ^ y" into match.pd. The code
for phiopt is kept around until phiopt uses match.pd (which
I am working towards).

Note the original testcase is now optimized early on and I added a
new testcase to optimize during phiopt.

OK?  Bootstrapped and tested on x86_64-linux-gnu with no regressions.

Thanks,
Andrew Pinski

Differences from v1:
V2: Add check for integeral type to make sure vector types are not done.

gcc:
	* match.pd (x < 0 ? ~y : y): New patterns.

gcc/testsuite:
	* gcc.dg/tree-ssa/pr96928.c: Update test for slightly different IR.
	* gcc.dg/tree-ssa/pr96928-1.c: New testcase.
---
 gcc/match.pd                              | 32 +++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c | 48 +++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr96928.c   |  7 +++-
 3 files changed, 85 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 032830b0d..5899eea95 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4390,6 +4390,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cmp (bit_and@2 @0 integer_pow2p@1) @1)
   (icmp @2 { build_zero_cst (TREE_TYPE (@0)); })))
 
+(for cmp (ge lt)
+/* x < 0 ? ~y : y into (x >> (prec-1)) ^ y. */
+/* x >= 0 ? ~y : y into ~((x >> (prec-1)) ^ y). */
+ (simplify
+  (cond (cmp @0 integer_zerop) (bit_not @1) @1)
+   (if (INTEGRAL_TYPE_P (type)
+	&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        && !TYPE_UNSIGNED (TREE_TYPE (@0))
+        && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
+    (with
+     {
+       tree shifter = build_int_cst (integer_type_node, TYPE_PRECISION (type) - 1);
+     }
+    (if (cmp == LT_EXPR)
+     (bit_xor (convert (rshift @0 {shifter;})) @1)
+     (bit_not (bit_xor (convert (rshift @0 {shifter;})) @1))))))
+/* x < 0 ? y : ~y into ~((x >> (prec-1)) ^ y). */
+/* x >= 0 ? y : ~y into (x >> (prec-1)) ^ y. */
+ (simplify
+  (cond (cmp @0 integer_zerop) @1 (bit_not @1))
+   (if (INTEGRAL_TYPE_P (type)
+	&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        && !TYPE_UNSIGNED (TREE_TYPE (@0))
+        && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
+    (with
+     {
+       tree shifter = build_int_cst (integer_type_node, TYPE_PRECISION (type) - 1);
+     }
+    (if (cmp == GE_EXPR)
+     (bit_xor (convert (rshift @0 {shifter;})) @1)
+     (bit_not (bit_xor (convert (rshift @0 {shifter;})) @1)))))))
+
 /* If we have (A & C) != 0 ? D : 0 where C and D are powers of 2,
    convert this into a shift followed by ANDing with D.  */
 (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c
new file mode 100644
index 000000000..a2770e5e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c
@@ -0,0 +1,48 @@
+/* PR tree-optimization/96928 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-phiopt2" } */
+/* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */
+
+int
+foo (int a)
+{
+  if (a < 0)
+    return ~a;
+  return a;
+}
+
+int
+bar (int a, int b)
+{
+  if (a < 0)
+    return ~b;
+  return b;
+}
+
+unsigned
+baz (int a, unsigned int b)
+{
+  if (a < 0)
+    return ~b;
+  return b;
+}
+
+unsigned
+qux (int a, unsigned int c)
+{
+  if (a >= 0)
+    return ~c;
+  return c;
+}
+
+int
+corge (int a, int b)
+{
+  if (a >= 0)
+    return b;
+  return ~b;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c
index 209135726..e8fd82fc2 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c
@@ -1,8 +1,11 @@
 /* PR tree-optimization/96928 */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-phiopt2" } */
+/* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */
 /* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */
-/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */
+/* The following check is done at optimized because a ^ (~b) is rewritten as ~(a^b)
+   and in the case of match.pd optimizing these ?:, the ~ is moved out already
+   by the time we get to phiopt2. */
+/* { dg-final { scan-tree-dump-times "\\\^ c_\[0-9]*\\\(D\\\);" 1 "optimized" } } */
 /* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */
 /* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */
 /* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */
-- 
2.27.0.windows.1