aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-04 11:01:08 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-04 11:01:08 +0200
commit496f4f884716ae061f771a62e44868a32dbd502f (patch)
tree97ee7206b36e9c4ad10545727c3d0f13eec435c9 /gcc
parent73a8043481d24ac86ce8d19459276181dfd9c858 (diff)
downloadgcc-496f4f884716ae061f771a62e44868a32dbd502f.zip
gcc-496f4f884716ae061f771a62e44868a32dbd502f.tar.gz
gcc-496f4f884716ae061f771a62e44868a32dbd502f.tar.bz2
match.pd: Decrease number of nop conversions around bitwise ops [PR94718]
On the following testcase, there are in *.optimized dump 14 nop conversions (from signed to unsigned and back), while this patch decreases that number to just 4; for bitwise ops it really doesn't matter if they are performed in signed or unsigned, so the patch (in GIMPLE only, there are some comments about it being undesirable during GENERIC earlier), if it sees both bitop operands nop converted from the same types performs the bitop in their non-converted type and converts the result (i.e. 2 conversions into 1), similarly, if a bitop has one operand nop converted from something, the other not and the result is converted back to the type of the nop converted operand before conversion, it is possible to replace those 2 conversions with just a single conversion of the other operand. 2020-05-04 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94718 * match.pd (bitop (convert @0) (convert? @1)): For GIMPLE, if we can, replace two nop conversions on bit_{and,ior,xor} argument and result with just one conversion on the result or another argument. * gcc.dg/tree-ssa/pr94718-3.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/match.pd22
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c45
4 files changed, 72 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 47eef98..036a403 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,11 @@
2020-05-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94718
+ * match.pd (bitop (convert @0) (convert? @1)): For GIMPLE, if we can,
+ replace two nop conversions on bit_{and,ior,xor} argument
+ and result with just one conversion on the result or another argument.
+
+ PR tree-optimization/94718
* fold-const.c (fold_binary_loc): Move (X & C) eqne (Y & C)
-> (X ^ Y) & C eqne 0 optimization to ...
* match.pd ((X & C) op (Y & C) into (X ^ Y) & C op 0): ... here.
diff --git a/gcc/match.pd b/gcc/match.pd
index 123e670..929be14 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1311,7 +1311,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
We combine the above two cases by using a conditional convert. */
(for bitop (bit_and bit_ior bit_xor)
(simplify
- (bitop (convert @0) (convert? @1))
+ (bitop (convert@2 @0) (convert?@3 @1))
(if (((TREE_CODE (@1) == INTEGER_CST
&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& int_fits_type_p (@1, TREE_TYPE (@0)))
@@ -1330,8 +1330,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|| GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
/* Or if the precision of TO is not the same as the precision
of its mode. */
- || !type_has_mode_precision_p (type)))
- (convert (bitop @0 (convert @1))))))
+ || !type_has_mode_precision_p (type)
+ /* In GIMPLE, getting rid of 2 conversions for one new results
+ in smaller IL. */
+ || (GIMPLE
+ && TREE_CODE (@1) != INTEGER_CST
+ && tree_nop_conversion_p (type, TREE_TYPE (@0))
+ && single_use (@2)
+ && single_use (@3))))
+ (convert (bitop @0 (convert @1)))))
+ /* In GIMPLE, getting rid of 2 conversions for one new results
+ in smaller IL. */
+ (simplify
+ (convert (bitop:cs@2 (nop_convert:s @0) @1))
+ (if (GIMPLE
+ && TREE_CODE (@1) != INTEGER_CST
+ && tree_nop_conversion_p (type, TREE_TYPE (@2))
+ && types_match (type, @0))
+ (bitop @0 (convert @1)))))
(for bitop (bit_and bit_ior)
rbitop (bit_ior bit_and)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 100870a..09979b5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,9 @@
2020-05-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94718
+ * gcc.dg/tree-ssa/pr94718-3.c: New test.
+
+ PR tree-optimization/94718
* gcc.dg/tree-ssa/pr94718-1.c: New test.
* gcc.dg/tree-ssa/pr94718-2.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c
new file mode 100644
index 0000000..d1fb4a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c
@@ -0,0 +1,45 @@
+/* PR tree-optimization/94718 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " \\\(int\\\) " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\\(unsigned int\\\) " 2 "optimized" } } */
+
+int
+f1 (int x, int y)
+{
+ return (int) ((unsigned) x | (unsigned) y);
+}
+
+int
+f2 (int x, int y)
+{
+ unsigned a = x;
+ unsigned b = y;
+ return a | b;
+}
+
+int
+f3 (int x, unsigned y)
+{
+ return (int) ((unsigned) x | y);
+}
+
+int
+f4 (int x, unsigned y)
+{
+ unsigned a = x;
+ return a | y;
+}
+
+unsigned
+f5 (int x, unsigned y)
+{
+ return (unsigned) (x | (int) y);
+}
+
+unsigned
+f6 (int x, unsigned y)
+{
+ int a = y;
+ return x | a;
+}