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]

[PATCH]: Mark builtin erf as an "odd" function


This patch adds builtin erf to the list of functions that are considered
"odd".  I.e. symmetric around the origin, f(-x) == -f(x). I couldn't find
a testcase for the builtins previously declared "odd", so I added a new
test to check all of them.  I also test the "even" functions, i.e.
symmetric around the y-axis or f(x) == f(-x), even though builtins-20.c
does that already.  So far the only "even" function in GCC is cos.

I plan to add cosh (hyperbolic) to the "even" list in a followup patch.
Can anyone think of any other "even" or "odd" functions among the math
builtins we have, or is that it?

Also in a follow up patch, I'm going to update fold_strip_sign_ops to
strip the arguments of "odd" functions and use fold_strip_sign_ops for cos
and hypot instead of manually optimizing them.  But that'll be an update.

Note: the optimization doesn't require -ffast-math, but checking that
FOO(x) != FOO(x) seems to need it.  I don't like looking for patterns in
tree dumps if I don't have to, so I went with this style anyway.

Tested on sparc-sun-solaris2.10, no regressions and the new testcase
passes.

Okay for mainline?

		Thanks,
		--Kaveh


2006-11-09  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* fold-const.c (negate_mathfn_p): Add BUILT_IN_ERF.

testsuite:
	* gcc.dg/torture/builtin-symmetric-1.c: New test.

diff -rup orig/egcc-SVN20061108/gcc/fold-const.c egcc-SVN20061108/gcc/fold-const.c
--- orig/egcc-SVN20061108/gcc/fold-const.c	2006-11-08 20:01:45.000000000 -0500
+++ egcc-SVN20061108/gcc/fold-const.c	2006-11-09 09:48:13.674127424 -0500
@@ -894,6 +894,7 @@ negate_mathfn_p (enum built_in_function
     CASE_FLT_FN (BUILT_IN_SINH):
     CASE_FLT_FN (BUILT_IN_TAN):
     CASE_FLT_FN (BUILT_IN_TANH):
+    CASE_FLT_FN (BUILT_IN_ERF):
       return true;

     default:
diff -rup orig/egcc-SVN20061108/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c egcc-SVN20061108/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c
--- orig/egcc-SVN20061108/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c	2006-11-09 10:06:00.798919909 -0500
+++ egcc-SVN20061108/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c	2006-11-09 10:04:59.201114570 -0500
@@ -0,0 +1,54 @@
+/* Copyright (C) 2006  Free Software Foundation.
+
+   Verify that built-in math function folding of symmetric even and
+   odd functions is correctly performed by the compiler.
+
+   Origin: Kaveh R. Ghazi,  November 09, 2006.  */
+
+/* { dg-do link } */
+/* { dg-options "-ffast-math" } */
+
+/* All references to link_error should go away at compile-time.  */
+extern void link_error(int);
+
+/* Test that FUNC(-ARG) == FUNC(ARG).  */
+#define TESTIT_EVEN(FUNC) do { \
+  if (__builtin_##FUNC##f(-xf) != __builtin_##FUNC##f(xf)) \
+    link_error(__LINE__); \
+  if (__builtin_##FUNC(-x) != __builtin_##FUNC(x)) \
+    link_error(__LINE__); \
+  if (__builtin_##FUNC##l(-xl) != __builtin_##FUNC##l(xl)) \
+    link_error(__LINE__); \
+  } while (0)
+
+/* Test that -FUNC(ARG) == FUNC(-ARG).  */
+#define TESTIT_ODD(FUNC) do { \
+  if (-__builtin_##FUNC##f(-xf) != __builtin_##FUNC##f(xf)) \
+    link_error(__LINE__); \
+  if (-__builtin_##FUNC(-x) != __builtin_##FUNC(x)) \
+    link_error(__LINE__); \
+  if (-__builtin_##FUNC##l(-xl) != __builtin_##FUNC##l(xl)) \
+    link_error(__LINE__); \
+  } while (0)
+
+void foo (float xf, double x, long double xl)
+{
+  TESTIT_EVEN(cos);
+
+  TESTIT_ODD(asin);
+  TESTIT_ODD(asinh);
+  TESTIT_ODD(atan);
+  TESTIT_ODD(atanh);
+  TESTIT_ODD(cbrt);
+  TESTIT_ODD(sin);
+  TESTIT_ODD(sinh);
+  TESTIT_ODD(tan);
+  TESTIT_ODD(tanh);
+  TESTIT_ODD(erf);
+}
+
+int main()
+{
+  foo (1,1,1);
+  return 0;
+}


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