This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] implement log10 and log2 functions as x87 builtins
- From: Uros Bizjak <uros at kss-loka dot si>
- To: Roger Sayle <roger at eyesopen dot com>, gcc-patches at gcc dot gnu dot org
- Date: Wed, 11 Feb 2004 12:03:17 +0100
- Subject: Re: [PATCH] implement log10 and log2 functions as x87 builtins
- References: <Pine.LNX.4.44.0402100942390.1776-100000@www.eyesopen.com>
Roger Sayle wrote:
Please resubmit this patch once you've added and tested a testcase.
Attached to this message, please find updated patch and testcase for
log10 and log2 builtins.
BTW: I think that testing log10 and log2 functions with compile-time
constants is not necessary. In the
future, perhaps some -ffast-math optimization pass could replace
functions with constant arguments with
their calculated value.
Uros.
? gcc/testsuite/gcc.dg/builtins-33.c
Index: gcc/ChangeLog
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.2740
diff -u -r2.2740 ChangeLog
--- gcc/ChangeLog 11 Feb 2004 08:59:47 -0000 2.2740
+++ gcc/ChangeLog 11 Feb 2004 10:49:57 -0000
@@ -1,3 +1,19 @@
+2003-02-11 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_log10 and OTI_log2.
+ (log10_optab, log2_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize log10_optab and log2_optab.
+ * genopinit.c (optabs): Implement log10_optab and log2_optab
+ using log10?f2 and log2?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG10{,F,L}
+ using log10_optab, and BUILT_IN_LOG2{,F,L} using log2_optab.
+ (expand_builtin): Expand BUILT_IN_LOG10{,F,L} and BUILT_IN_LOG2{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (log10sf2, log10df2, log10xf2, log2sf2,
+ log2df2, log2xf2): New patterns to implement log10, log10f, log10l
+ log2, log2f and log2l built-ins as inline x87 intrinsics.
+
2004-02-11 Hartmut Penner <hpenner@de.ibm.com>
* gcc/config/rs6000/rs6000.c (rs6000_override_options)
Index: gcc/builtins.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.283
diff -u -r1.283 builtins.c
--- gcc/builtins.c 9 Feb 2004 21:18:45 -0000 1.283
+++ gcc/builtins.c 11 Feb 2004 10:49:58 -0000
@@ -1662,6 +1662,14 @@
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
errno_set = true; builtin_optab = log_optab; break;
+ case BUILT_IN_LOG10:
+ case BUILT_IN_LOG10F:
+ case BUILT_IN_LOG10L:
+ errno_set = true; builtin_optab = log10_optab; break;
+ case BUILT_IN_LOG2:
+ case BUILT_IN_LOG2F:
+ case BUILT_IN_LOG2L:
+ errno_set = true; builtin_optab = log2_optab; break;
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
@@ -5130,6 +5138,12 @@
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
+ case BUILT_IN_LOG10:
+ case BUILT_IN_LOG10F:
+ case BUILT_IN_LOG10L:
+ case BUILT_IN_LOG2:
+ case BUILT_IN_LOG2F:
+ case BUILT_IN_LOG2L:
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
Index: gcc/genopinit.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/genopinit.c,v
retrieving revision 1.66
diff -u -r1.66 genopinit.c
--- gcc/genopinit.c 21 Jan 2004 20:40:01 -0000 1.66
+++ gcc/genopinit.c 11 Feb 2004 10:49:58 -0000
@@ -126,6 +126,8 @@
"cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
"exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
"log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
+ "log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",
+ "log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",
"tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
"atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
"strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
Index: gcc/optabs.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.206
diff -u -r1.206 optabs.c
--- gcc/optabs.c 3 Feb 2004 05:39:50 -0000 1.206
+++ gcc/optabs.c 11 Feb 2004 10:49:59 -0000
@@ -5263,6 +5263,8 @@
cos_optab = init_optab (UNKNOWN);
exp_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
+ log10_optab = init_optab (UNKNOWN);
+ log2_optab = init_optab (UNKNOWN);
tan_optab = init_optab (UNKNOWN);
atan_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN);
Index: gcc/optabs.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/optabs.h,v
retrieving revision 1.21
diff -u -r1.21 optabs.h
--- gcc/optabs.h 21 Jan 2004 20:40:03 -0000 1.21
+++ gcc/optabs.h 11 Feb 2004 10:49:59 -0000
@@ -156,6 +156,10 @@
OTI_exp,
/* Natural Logarithm */
OTI_log,
+ /* Base-10 Logarithm */
+ OTI_log10,
+ /* Base-2 Logarithm */
+ OTI_log2,
/* Rounding functions */
OTI_floor,
OTI_ceil,
@@ -260,6 +264,8 @@
#define cos_optab (optab_table[OTI_cos])
#define exp_optab (optab_table[OTI_exp])
#define log_optab (optab_table[OTI_log])
+#define log10_optab (optab_table[OTI_log10])
+#define log2_optab (optab_table[OTI_log2])
#define floor_optab (optab_table[OTI_floor])
#define ceil_optab (optab_table[OTI_ceil])
#define btrunc_optab (optab_table[OTI_trunc])
Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.509
diff -u -r1.509 i386.md
--- gcc/config/i386/i386.md 4 Feb 2004 20:27:03 -0000 1.509
+++ gcc/config/i386/i386.md 11 Feb 2004 10:50:03 -0000
@@ -15154,6 +15154,88 @@
emit_move_insn (operands[2], temp);
})
+(define_expand "log10sf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (3); /* fldlg2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "log10df2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (3); /* fldlg2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "log10xf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (3); /* fldlg2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "log2sf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+
+})
+
+(define_expand "log2df2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "log2xf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+})
+
(define_insn "*fscale_sfxf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:XF 2 "register_operand" "0")
? gcc.dg/builtins-33.c
Index: ChangeLog
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.3488
diff -u -r1.3488 ChangeLog
--- ChangeLog 11 Feb 2004 09:00:06 -0000 1.3488
+++ ChangeLog 11 Feb 2004 10:54:31 -0000
@@ -1,3 +1,7 @@
+2004-02-11 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-33.c: New test.
+
2004-02-11 Hartmut Penner <hpenner@de.ibm.com>
* gcc.dg/ppc64-abi-3.c: New test.
/* Copyright (C) 2004 Free Software Foundation.
Check that log10, log10f, log10l, log2, log2f and log2l
built-in functions compile
Written by Uros Bizjak, 11th February 2004. */
/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math" } */
double test1(double x)
{
return log10(x);
}
double test2(double x)
{
return log2(x);
}
float test1f(float x)
{
return log10f(x);
}
float test2f(float x)
{
return log2f(x);
}
long double test1l(long double x)
{
return log10l(x);
}
long double test2l(long double x)
{
return log2l(x);
}