@@ -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
new file mode 100644
@@ -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)
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