diff mbox series

match.pd: Add std::pow folding optimizations.

Message ID BEA21137-FDCB-478A-82C0-C88C42FF74B0@nvidia.com
State New
Headers show
Series match.pd: Add std::pow folding optimizations. | expand

Commit Message

Jennifer Schmitz Oct. 18, 2024, 12:08 p.m. UTC
This patch adds the following two simplifications in match.pd:
- pow (1.0/x, y) to pow (x, -y), avoiding the division
- pow (0.0, x) to 0.0, avoiding the call to pow.
The patterns are guarded by flag_unsafe_math_optimizations,
!flag_trapping_math, !flag_errno_math, !HONOR_SIGNED_ZEROS,
and !HONOR_INFINITIES.

Tests were added to confirm the application of the transform for float,
double, and long double.

The patch was bootstrapped and regtested on aarch64-linux-gnu and
x86_64-linux-gnu, no regression.
OK for mainline?

Signed-off-by: Jennifer Schmitz <jschmitz@nvidia.com>

gcc/
	* match.pd: Fold pow (1.0/x, y) -> pow (x, -y) and
	pow (0.0, x) -> 0.0.

gcc/testsuite/
	* gcc.dg/tree-ssa/pow_fold_1.c: New test.
---
 gcc/match.pd                               | 14 +++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pow_fold_1.c | 34 ++++++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pow_fold_1.c
diff mbox series

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 12d81fcac0d..ba100b117e7 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -8203,6 +8203,20 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (rdiv @0 (exps:s @1))
     (mult @0 (exps (negate @1)))))
 
+ /* Simplify pow(1.0/x, y) into pow(x, -y).  */
+ (if (! HONOR_INFINITIES (type)
+      && ! HONOR_SIGNED_ZEROS (type)
+      && ! flag_trapping_math
+      && ! flag_errno_math)
+  (simplify
+   (POW (rdiv:s real_onep@0 @1) @2)
+    (POW @1 (negate @2)))
+
+  /* Simplify pow(0.0, x) into 0.0.  */
+  (simplify
+   (POW real_zerop@0 @1)
+    @0))
+
  (if (! HONOR_SIGN_DEPENDENT_ROUNDING (type)
       && ! HONOR_NANS (type) && ! HONOR_INFINITIES (type)
       && ! flag_trapping_math
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pow_fold_1.c b/gcc/testsuite/gcc.dg/tree-ssa/pow_fold_1.c
new file mode 100644
index 00000000000..113df572661
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pow_fold_1.c
@@ -0,0 +1,34 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+/* { dg-require-effective-target c99_runtime } */
+
+extern void link_error (void);
+
+#define POW1OVER(TYPE, C_TY, TY)			\
+  void							\
+  pow1over_##TY (TYPE x, TYPE y)			\
+  {							\
+    TYPE t1 = 1.0##C_TY / x;				\
+    TYPE t2 = __builtin_pow##TY (t1, y);		\
+    TYPE t3 = -y;					\
+    TYPE t4 = __builtin_pow##TY (x, t3);		\
+    if (t2 != t4)					\
+      link_error ();					\
+  }							\
+
+#define POW0(TYPE, C_TY, TY)				\
+  void							\
+  pow0_##TY (TYPE x)					\
+  {							\
+    TYPE t1 = __builtin_pow##TY (0.0##C_TY, x);		\
+    if (t1 != 0.0##C_TY)				\
+      link_error ();					\
+  }							\
+
+#define TEST_ALL(TYPE, C_TY, TY)			\
+  POW1OVER (TYPE, C_TY, TY)				\
+  POW0 (TYPE, C_TY, TY)
+
+TEST_ALL (double, , )
+TEST_ALL (float, f, f)
+TEST_ALL (long double, L, l)