Move hypot folds to match.pd
diff mbox

Message ID 87wpuavujt.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford Oct. 26, 2015, 9:38 a.m. UTC
Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.
OK to install?

Thanks,
Richard


gcc/
	* builtins.c (fold_builtin_hypot): Delete.
	(fold_builtin_2): Handle constant hypot arguments here.
	* match.pd: Fold hypot(x, 0) and hypot(0, x) to x.  Canonicalize
	hypot(x, x) to fabs(x)*sqrt(2).

Comments

Richard Biener Oct. 26, 2015, 9:59 a.m. UTC | #1
On Mon, Oct 26, 2015 at 10:38 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.
> OK to install?

Ok.

Thanks,
Richard.

> Thanks,
> Richard
>
>
> gcc/
>         * builtins.c (fold_builtin_hypot): Delete.
>         (fold_builtin_2): Handle constant hypot arguments here.
>         * match.pd: Fold hypot(x, 0) and hypot(0, x) to x.  Canonicalize
>         hypot(x, x) to fabs(x)*sqrt(2).
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index f947f1e..64106a1 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -7475,39 +7475,6 @@ fold_builtin_bswap (tree fndecl, tree arg)
>    return NULL_TREE;
>  }
>
> -/* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
> -   NULL_TREE if no simplification can be made.  */
> -
> -static tree
> -fold_builtin_hypot (location_t loc, tree arg0, tree arg1, tree type)
> -{
> -  tree res;
> -
> -  if (!validate_arg (arg0, REAL_TYPE)
> -      || !validate_arg (arg1, REAL_TYPE))
> -    return NULL_TREE;
> -
> -  /* Calculate the result when the argument is a constant.  */
> -  if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
> -    return res;
> -
> -  /* If either argument is zero, hypot is fabs of the other.  */
> -  if (real_zerop (arg0))
> -    return fold_build1_loc (loc, ABS_EXPR, type, arg1);
> -  else if (real_zerop (arg1))
> -    return fold_build1_loc (loc, ABS_EXPR, type, arg0);
> -
> -  /* hypot(x,x) -> fabs(x)*sqrt(2).  */
> -  if (flag_unsafe_math_optimizations
> -      && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
> -    return fold_build2_loc (loc, MULT_EXPR, type,
> -                           fold_build1_loc (loc, ABS_EXPR, type, arg0),
> -                           build_real_truncate (type, dconst_sqrt2 ()));
> -
> -  return NULL_TREE;
> -}
> -
> -
>  /* Fold a builtin function call to pow, powf, or powl.  Return
>     NULL_TREE if no simplification can be made.  */
>  static tree
> @@ -9456,7 +9423,10 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
>      break;
>
>      CASE_FLT_FN (BUILT_IN_HYPOT):
> -      return fold_builtin_hypot (loc, arg0, arg1, type);
> +      if (validate_arg (arg0, REAL_TYPE)
> +         && validate_arg (arg1, REAL_TYPE))
> +       return do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot);
> +      break;
>
>      CASE_FLT_FN (BUILT_IN_CPOW):
>        if (validate_arg (arg0, COMPLEX_TYPE)
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 00c6e7c..8cd55f6 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2520,6 +2520,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>    (RINT integer_valued_real_p@0)
>    @0))
>
> +/* hypot(x,0) and hypot(0,x) -> abs(x).  */
> +(simplify
> + (hypot:c @0 real_zerop@1)
> + (abs @0))
> +
>  /* Canonicalization of sequences of math builtins.  These rules represent
>     IL simplifications but are not necessarily optimizations.
>
> @@ -2618,6 +2623,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>    (CABS (complex @0 @0))
>    (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); }))
>
> + /* hypot(x,x) -> fabs(x)*sqrt(2).  */
> + (simplify
> +  (HYPOT @0 @0)
> +  (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); }))
> +
>   /* cexp(x+yi) -> exp(x)*cexpi(y).  */
>   (for cexps (CEXP)
>        exps (EXP)
>

Patch
diff mbox

diff --git a/gcc/builtins.c b/gcc/builtins.c
index f947f1e..64106a1 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7475,39 +7475,6 @@  fold_builtin_bswap (tree fndecl, tree arg)
   return NULL_TREE;
 }
 
-/* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
-   NULL_TREE if no simplification can be made.  */
-
-static tree
-fold_builtin_hypot (location_t loc, tree arg0, tree arg1, tree type)
-{
-  tree res;
-
-  if (!validate_arg (arg0, REAL_TYPE)
-      || !validate_arg (arg1, REAL_TYPE))
-    return NULL_TREE;
-
-  /* Calculate the result when the argument is a constant.  */
-  if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
-    return res;
-
-  /* If either argument is zero, hypot is fabs of the other.  */
-  if (real_zerop (arg0))
-    return fold_build1_loc (loc, ABS_EXPR, type, arg1);
-  else if (real_zerop (arg1))
-    return fold_build1_loc (loc, ABS_EXPR, type, arg0);
-
-  /* hypot(x,x) -> fabs(x)*sqrt(2).  */
-  if (flag_unsafe_math_optimizations
-      && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
-    return fold_build2_loc (loc, MULT_EXPR, type,
-			    fold_build1_loc (loc, ABS_EXPR, type, arg0),
-			    build_real_truncate (type, dconst_sqrt2 ()));
-
-  return NULL_TREE;
-}
-
-
 /* Fold a builtin function call to pow, powf, or powl.  Return
    NULL_TREE if no simplification can be made.  */
 static tree
@@ -9456,7 +9423,10 @@  fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
     break;
 
     CASE_FLT_FN (BUILT_IN_HYPOT):
-      return fold_builtin_hypot (loc, arg0, arg1, type);
+      if (validate_arg (arg0, REAL_TYPE)
+	  && validate_arg (arg1, REAL_TYPE))
+	return do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot);
+      break;
 
     CASE_FLT_FN (BUILT_IN_CPOW):
       if (validate_arg (arg0, COMPLEX_TYPE)
diff --git a/gcc/match.pd b/gcc/match.pd
index 00c6e7c..8cd55f6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2520,6 +2520,11 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (RINT integer_valued_real_p@0)
   @0))
 
+/* hypot(x,0) and hypot(0,x) -> abs(x).  */
+(simplify
+ (hypot:c @0 real_zerop@1)
+ (abs @0))
+
 /* Canonicalization of sequences of math builtins.  These rules represent
    IL simplifications but are not necessarily optimizations.
 
@@ -2618,6 +2623,11 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (CABS (complex @0 @0))
   (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); }))
 
+ /* hypot(x,x) -> fabs(x)*sqrt(2).  */
+ (simplify
+  (HYPOT @0 @0)
+  (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); }))
+
  /* cexp(x+yi) -> exp(x)*cexpi(y).  */
  (for cexps (CEXP)
       exps (EXP)