diff mbox series

Canonicalize negates in division

Message ID DB6PR0801MB2053364EC1B187DD2CF2FBA9834C0@DB6PR0801MB2053.eurprd08.prod.outlook.com
State New
Headers show
Series Canonicalize negates in division | expand

Commit Message

Wilco Dijkstra Oct. 17, 2017, 4:30 p.m. UTC
This patch implements some of the optimizations discussed in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71026.

Canonicalize x / (- y) into (-x) / y.

This moves negates out of the RHS of a division in order to
allow further simplifications and potentially more reciprocal CSEs.

OK for commit?

ChangeLog
2017-10-17  Wilco Dijkstra  <wdijkstr@arm.com>  
	    Jackson Woodruff  <jackson.woodruff@arm.com>

    gcc/
	PR 71026/tree-optimization
	* match.pd: Canonicalize negate in division.

    gcc/testsuite/
	PR 71026/tree-optimization
	* gcc.dg/div_neg: New test.
--

Comments

Richard Biener Oct. 18, 2017, 11:28 a.m. UTC | #1
On Tue, Oct 17, 2017 at 6:30 PM, Wilco Dijkstra <Wilco.Dijkstra@arm.com> wrote:
> This patch implements some of the optimizations discussed in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71026.
>
> Canonicalize x / (- y) into (-x) / y.
>
> This moves negates out of the RHS of a division in order to
> allow further simplifications and potentially more reciprocal CSEs.
>
> OK for commit?

Ok.

Richard.

> ChangeLog
> 2017-10-17  Wilco Dijkstra  <wdijkstr@arm.com>
>             Jackson Woodruff  <jackson.woodruff@arm.com>
>
>     gcc/
>         PR 71026/tree-optimization
>         * match.pd: Canonicalize negate in division.
>
>     gcc/testsuite/
>         PR 71026/tree-optimization
>         * gcc.dg/div_neg: New test.
> --
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index cb48f079b4a310272e49cc319a1b3b0ff2023ba4..ade851f78fb9ac6ce03b752f63e03f3b5a19cda9 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -352,6 +352,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>    (rdiv @0 (rdiv:s @1 @2))
>     (mult (rdiv @0 @1) @2)))
>
> +/* Simplify x / (- y) to -x / y.  */
> +(simplify
> + (rdiv @0 (negate @1))
> + (rdiv (negate @0) @1))
> +
>  (if (flag_unsafe_math_optimizations)
>    /* Simplify (C / x op 0.0) to x op 0.0 for C > 0.  */
>    (for op (lt le gt ge)
> diff --git a/gcc/testsuite/gcc.dg/div_neg.c b/gcc/testsuite/gcc.dg/div_neg.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..da499cda2fba6c943ec99c55cae2ea389f9e1cca
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/div_neg.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +float
> +div_neg (float x, float y)
> +{
> +  return (-x / y) * (x / -y);
> +}
> +
> +/* { dg-final { scan-tree-dump-times " / " 1 "optimized" } } */
diff mbox series

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index cb48f079b4a310272e49cc319a1b3b0ff2023ba4..ade851f78fb9ac6ce03b752f63e03f3b5a19cda9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -352,6 +352,11 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (rdiv @0 (rdiv:s @1 @2))
    (mult (rdiv @0 @1) @2)))
 
+/* Simplify x / (- y) to -x / y.  */
+(simplify
+ (rdiv @0 (negate @1))
+ (rdiv (negate @0) @1))
+
 (if (flag_unsafe_math_optimizations)
   /* Simplify (C / x op 0.0) to x op 0.0 for C > 0.  */
   (for op (lt le gt ge)
diff --git a/gcc/testsuite/gcc.dg/div_neg.c b/gcc/testsuite/gcc.dg/div_neg.c
new file mode 100644
index 0000000000000000000000000000000000000000..da499cda2fba6c943ec99c55cae2ea389f9e1cca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/div_neg.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+float
+div_neg (float x, float y)
+{
+  return (-x / y) * (x / -y);
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "optimized" } } */