This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Mark builtin erf as an "odd" function
- From: "Kaveh R. GHAZI" <ghazi at caip dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 10 Nov 2006 09:20:59 -0500 (EST)
- Subject: [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;
+}