This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Canonicalize constant multiplies in division
- From: Wilco Dijkstra <Wilco dot Dijkstra at arm dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, nd <nd at arm dot com>
- Date: Wed, 15 Nov 2017 14:39:58 +0000
- Subject: Re: [PATCH] Canonicalize constant multiplies in division
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Wilco dot Dijkstra at arm dot com;
- Nodisclaimer: True
- References: <DB6PR0801MB20531AD31F805B799B74E470834C0@DB6PR0801MB2053.eurprd08.prod.outlook.com>,<CAFiYyc0JUU0qXB78W39to0YtuXnjm3XxGwQOtMYjPMp0t36xsA@mail.gmail.com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
Richard Biener wrote:
> On Tue, Oct 17, 2017 at 6:32 PM, Wilco Dijkstra <Wilco.Dijkstra@arm.com> wrote:
>> (if (flag_reciprocal_math)
>> - /* Convert (A/B)/C to A/(B*C) */
>> + /* Convert (A/B)/C to A/(B*C). */
>> (simplify
>> (rdiv (rdiv:s @0 @1) @2)
>> - (rdiv @0 (mult @1 @2)))
>> + (rdiv @0 (mult @1 @2)))
>> +
>> + /* Canonicalize x / (C1 * y) to (x * C2) / y. */
>> + (if (optimize)
>
> why if (optimize) here? The pattern you removed has no
> such check. As discussed this may undo CSE of C1 * y
> so please check for a single-use on the mult with :s
I think that came from an earlier version of this patch. I've removed it
and added a single use check.
>> + (simplify
>> + (rdiv @0 (mult @1 REAL_CST@2))
>> + (if (!real_zerop (@1))
>
> why this check? The pattern below didn't have it.
Presumably to avoid the change when dividing by zero. I've removed it, here is
the updated version. This passes bootstrap and regress:
ChangeLog
2017-11-15 Wilco Dijkstra <wdijkstr@arm.com>
Jackson Woodruff <jackson.woodruff@arm.com>
gcc/
PR 71026/tree-optimization
* match.pd: Canonicalize constant multiplies in division.
gcc/testsuite/
PR 71026/tree-optimization
* gcc.dg/cse_recip.c: New test.
--
diff --git a/gcc/match.pd b/gcc/match.pd
index b5042b783c0830a2da08c44bed39842a17911844..ea7d90ed977cfff991d74bee54e91ecb209b6030 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -344,10 +344,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(negate @0)))
(if (flag_reciprocal_math)
- /* Convert (A/B)/C to A/(B*C) */
+ /* Convert (A/B)/C to A/(B*C). */
(simplify
(rdiv (rdiv:s @0 @1) @2)
- (rdiv @0 (mult @1 @2)))
+ (rdiv @0 (mult @1 @2)))
+
+ /* Canonicalize x / (C1 * y) to (x * C2) / y. */
+ (simplify
+ (rdiv @0 (mult:s @1 REAL_CST@2))
+ (with
+ { tree tem = const_binop (RDIV_EXPR, type, build_one_cst (type), @2); }
+ (if (tem)
+ (rdiv (mult @0 { tem; } ) @1))))
/* Convert A/(B/C) to (A/B)*C */
(simplify
@@ -646,15 +654,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (tem)
(rdiv { tem; } @1)))))
-/* Convert C1/(X*C2) into (C1/C2)/X */
-(simplify
- (rdiv REAL_CST@0 (mult @1 REAL_CST@2))
- (if (flag_reciprocal_math)
- (with
- { tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
- (if (tem)
- (rdiv { tem; } @1)))))
-
/* Simplify ~X & X as zero. */
(simplify
(bit_and:c (convert? @0) (convert? (bit_not @0)))
diff --git a/gcc/testsuite/gcc.dg/cse_recip.c b/gcc/testsuite/gcc.dg/cse_recip.c
new file mode 100644
index 0000000000000000000000000000000000000000..88cba9930c0eb1fdee22a797eff110cd9a14fcda
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cse_recip.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */
+
+void
+cse_recip (float x, float y, float *a)
+{
+ a[0] = y / (5 * x);
+ a[1] = y / (3 * x);
+ a[2] = y / x;
+}
+
+/* { dg-final { scan-tree-dump-times "rdiv_expr" 1 "optimized" } } */