This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Committed] Fold cabs(-z) and cabs(~z) as cabs(z)


The following simple "missed optimization" bug-fix (though I admit
it's stretching the definition) was spotted whilst investigating and
developing my recent fix for PR 23452.  Mathematically, z*~z is
cabs(z)**2, which lead to the observation that cabs(~z) and cabs(-z)
weren't being optimized by GCC as well as they should.

The following patch was tested on x86_64-unknown-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.

Committed to mainline as revision 114276.



2006-05-31  Roger Sayle  <roger@eyesopen.com>

	* builtins.c (fold_builtin_cabs): Delete prototype.  Require an
	additional FNDECL argument.  Optimize cabs(-z) and cabs(~z) as
	cabs(z).
	(fold_builtin_decl) <BUILT_IN_CABS>: Update fold_builtin_cabs call.

	* gcc.dg/builtins-54.c: New test case.


Index: builtins.c
===================================================================
*** builtins.c	(revision 114166)
--- builtins.c	(working copy)
*************** static tree fold_trunc_transparent_mathf
*** 146,152 ****
  static bool readonly_data_expr (tree);
  static rtx expand_builtin_fabs (tree, rtx, rtx);
  static rtx expand_builtin_signbit (tree, rtx);
- static tree fold_builtin_cabs (tree, tree);
  static tree fold_builtin_sqrt (tree, tree);
  static tree fold_builtin_cbrt (tree, tree);
  static tree fold_builtin_pow (tree, tree, tree);
--- 146,151 ----
*************** fold_fixed_mathfn (tree fndecl, tree arg
*** 6772,6782 ****
  }

  /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
!    is the argument list and TYPE is the return type.  Return
!    NULL_TREE if no if no simplification can be made.  */

  static tree
! fold_builtin_cabs (tree arglist, tree type)
  {
    tree arg;

--- 6771,6782 ----
  }

  /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
!    is the argument list, TYPE is the return type and FNDECL is the
!    original function DECL.  Return NULL_TREE if no if no simplification
!    can be made.  */

  static tree
! fold_builtin_cabs (tree arglist, tree type, tree fndecl)
  {
    tree arg;

*************** fold_builtin_cabs (tree arglist, tree ty
*** 6817,6822 ****
--- 6817,6830 ----
        && real_zerop (TREE_OPERAND (arg, 1)))
      return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));

+   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
+   if (TREE_CODE (arg) == NEGATE_EXPR
+       || TREE_CODE (arg) == CONJ_EXPR)
+     {
+       tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
+       return build_function_call_expr (fndecl, arglist);
+     }
+
    /* Don't do this when optimizing for size.  */
    if (flag_unsafe_math_optimizations
        && optimize && !optimize_size)
*************** fold_builtin_1 (tree fndecl, tree arglis
*** 8648,8654 ****
        break;

      CASE_FLT_FN (BUILT_IN_CABS):
!       return fold_builtin_cabs (arglist, type);

      CASE_FLT_FN (BUILT_IN_SQRT):
        return fold_builtin_sqrt (arglist, type);
--- 8656,8662 ----
        break;

      CASE_FLT_FN (BUILT_IN_CABS):
!       return fold_builtin_cabs (arglist, type, fndecl);

      CASE_FLT_FN (BUILT_IN_SQRT):
        return fold_builtin_sqrt (arglist, type);


/* { dg-do link } */
/* { dg-options "-O2 -ffast-math" } */

double cabs(__complex__ double);
float cabsf(__complex__ float);
long double cabsl(__complex__ long double);

void link_error (void);

void test(__complex__ double x)
{
  if (cabs(x) != cabs(-x))
    link_error();

  if (cabs(x) != cabs(~x))
    link_error();
}

void testf(__complex__ float x)
{
  if (cabsf(x) != cabsf(-x))
    link_error();

  if (cabsf(x) != cabsf(~x))
    link_error();
}

void testl(__complex__ long double x)
{
  if (cabsl(x) != cabsl(-x))
    link_error();

  if (cabsl(x) != cabsl(~x))
    link_error();
}

int main()
{
  test(0.0);
  testf(0.0);
  testl(0.0);
  return 0;
}


Roger
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]