From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id DE2A43858CDA for ; Fri, 28 Apr 2023 11:30:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DE2A43858CDA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8AC35C14; Fri, 28 Apr 2023 04:30:44 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 57D2D3F64C; Fri, 28 Apr 2023 04:29:59 -0700 (PDT) From: Richard Sandiford To: Jakub Jelinek via Gcc-patches Mail-Followup-To: Jakub Jelinek via Gcc-patches ,Richard Biener , Jakub Jelinek , Aldy Hernandez , "Joseph S. Myers" , Siddhesh Poyarekar , Andrew MacLeod , richard.sandiford@arm.com Cc: Richard Biener , Jakub Jelinek , Aldy Hernandez , "Joseph S. Myers" , Siddhesh Poyarekar , Andrew MacLeod Subject: Re: [PATCH] v2: Add targetm.libm_function_max_error References: Date: Fri, 28 Apr 2023 12:29:58 +0100 In-Reply-To: (Jakub Jelinek via Gcc-patches's message of "Thu, 27 Apr 2023 13:08:09 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-24.3 required=5.0 tests=BAYES_00,KAM_DMARC_NONE,KAM_DMARC_STATUS,KAM_LAZY_DOMAIN_SECURITY,KAM_SHORT,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Jakub Jelinek via Gcc-patches writes: > Hi! > > On Thu, Apr 27, 2023 at 10:34:59AM +0000, Richard Biener wrote: >> OK. As said the patch itself looks good to me, let's go ahead. We >> have plenty of time to backtrack until GCC 14. > > Thanks. Unfortunately when I started using it, I've discovered that the > CASE_CFN_xxx_ALL macros don't include the CFN_xxx cases, just > CFN_BUILT_IN_xxx* cases. > > So here is an updated version of the patch I'll bootstrap/regtest tonight > which instead uses CASE_CFN_xxx: CASE_CFN_xxx_FN: Shouldn't we change something in that case? The point of these macros is to wrap things up a single easy-to-use name, so something feels wrong if we're having to use a repeated pattern like this. Thanks, Richard > 2023-04-27 Jakub Jelinek > > * target.def (libm_function_max_error): New target hook. > * doc/tm.texi.in (TARGET_LIBM_FUNCTION_MAX_ERROR): Add. > * doc/tm.texi: Regenerated. > * targhooks.h (default_libm_function_max_error, > glibc_linux_libm_function_max_error): Declare. > * targhooks.cc: Include case-cfn-macros.h. > (default_libm_function_max_error, > glibc_linux_libm_function_max_error): New functions. > * config/linux.h (TARGET_LIBM_FUNCTION_MAX_ERROR): Redefine. > * config/linux-protos.h (linux_libm_function_max_error): Declare. > * config/linux.cc: Include target.h and targhooks.h. > (linux_libm_function_max_error): New function. > * config/arc/arc.cc: Include targhooks.h and case-cfn-macros.h. > (arc_libm_function_max_error): New function. > (TARGET_LIBM_FUNCTION_MAX_ERROR): Redefine. > * config/i386/i386.cc (ix86_libc_has_fast_function): Formatting fix. > (ix86_libm_function_max_error): New function. > (TARGET_LIBM_FUNCTION_MAX_ERROR): Redefine. > * config/rs6000/rs6000-protos.h > (rs6000_linux_libm_function_max_error): Declare. > * config/rs6000/rs6000-linux.cc: Include target.h, targhooks.h, tree.h > and case-cfn-macros.h. > (rs6000_linux_libm_function_max_error): New function. > * config/rs6000/linux.h (TARGET_LIBM_FUNCTION_MAX_ERROR): Redefine. > * config/rs6000/linux64.h (TARGET_LIBM_FUNCTION_MAX_ERROR): Redefine. > * config/or1k/or1k.cc: Include targhooks.h and case-cfn-macros.h. > (or1k_libm_function_max_error): New function. > (TARGET_LIBM_FUNCTION_MAX_ERROR): Redefine. > > --- gcc/target.def.jj 2023-04-27 10:17:32.598686398 +0200 > +++ gcc/target.def 2023-04-27 10:26:58.361490211 +0200 > @@ -2670,6 +2670,23 @@ DEFHOOK > bool, (int fcode), > default_libc_has_fast_function) > > +DEFHOOK > +(libm_function_max_error, > + "This hook determines expected maximum errors for math functions measured\n\ > +in ulps (units of the last place). 0 means 0.5ulps precision (correctly\n\ > +rounded). ~0U means unknown errors. The @code{combined_fn} @var{cfn}\n\ > +argument should identify just which math built-in function it is rather than\n\ > +its variant, @var{mode} the variant in terms of floating-point machine mode.\n\ > +The hook should also take into account @code{flag_rounding_math} whether it\n\ > +is maximum error just in default rounding mode, or in all possible rounding\n\ > +modes. @var{boundary_p} is @code{true} for maximum errors on intrinsic math\n\ > +boundaries of functions rather than errors inside of the usual result ranges\n\ > +of the functions. E.g.@ the sin/cos function finite result is in between\n\ > +-1.0 and 1.0 inclusive, with @var{boundary_p} true the function returns how\n\ > +many ulps below or above those boundaries result could be.", > + unsigned, (unsigned cfn, machine_mode mode, bool boundary_p), > + default_libm_function_max_error) > + > /* True if new jumps cannot be created, to replace existing ones or > not, at the current point in the compilation. */ > DEFHOOK > --- gcc/doc/tm.texi.in.jj 2023-04-27 10:17:32.596686427 +0200 > +++ gcc/doc/tm.texi.in 2023-04-27 10:26:58.362490196 +0200 > @@ -4004,6 +4004,8 @@ macro, a reasonable default is used. > > @hook TARGET_LIBC_HAS_FAST_FUNCTION > > +@hook TARGET_LIBM_FUNCTION_MAX_ERROR > + > @defmac NEXT_OBJC_RUNTIME > Set this macro to 1 to use the "NeXT" Objective-C message sending conventions > by default. This calling convention involves passing the object, the selector > --- gcc/doc/tm.texi.jj 2023-04-27 10:17:32.593686470 +0200 > +++ gcc/doc/tm.texi 2023-04-27 10:26:58.364490167 +0200 > @@ -5760,6 +5760,21 @@ This hook determines whether a function > @code{(enum function_class)}@var{fcode} has a fast implementation. > @end deftypefn > > +@deftypefn {Target Hook} unsigned TARGET_LIBM_FUNCTION_MAX_ERROR (unsigned @var{cfn}, machine_mode @var{mode}, bool @var{boundary_p}) > +This hook determines expected maximum errors for math functions measured > +in ulps (units of the last place). 0 means 0.5ulps precision (correctly > +rounded). ~0U means unknown errors. The @code{combined_fn} @var{cfn} > +argument should identify just which math built-in function it is rather than > +its variant, @var{mode} the variant in terms of floating-point machine mode. > +The hook should also take into account @code{flag_rounding_math} whether it > +is maximum error just in default rounding mode, or in all possible rounding > +modes. @var{boundary_p} is @code{true} for maximum errors on intrinsic math > +boundaries of functions rather than errors inside of the usual result ranges > +of the functions. E.g.@ the sin/cos function finite result is in between > +-1.0 and 1.0 inclusive, with @var{boundary_p} true the function returns how > +many ulps below or above those boundaries result could be. > +@end deftypefn > + > @defmac NEXT_OBJC_RUNTIME > Set this macro to 1 to use the "NeXT" Objective-C message sending conventions > by default. This calling convention involves passing the object, the selector > --- gcc/targhooks.h.jj 2023-04-27 10:17:32.598686398 +0200 > +++ gcc/targhooks.h 2023-04-27 10:26:58.364490167 +0200 > @@ -219,6 +219,9 @@ extern bool default_libc_has_fast_functi > extern bool no_c99_libc_has_function (enum function_class, tree); > extern bool gnu_libc_has_function (enum function_class, tree); > extern bool bsd_libc_has_function (enum function_class, tree); > +extern unsigned default_libm_function_max_error (unsigned, machine_mode, bool); > +extern unsigned glibc_linux_libm_function_max_error (unsigned, machine_mode, > + bool); > > extern tree default_builtin_tm_load_store (tree); > > --- gcc/targhooks.cc.jj 2023-04-27 10:17:32.598686398 +0200 > +++ gcc/targhooks.cc 2023-04-27 12:19:32.831330868 +0200 > @@ -94,6 +94,7 @@ along with GCC; see the file COPYING3. > #include "cfgloop.h" > #include "tree-vectorizer.h" > #include "options.h" > +#include "case-cfn-macros.h" > > bool > default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, > @@ -1903,6 +1904,73 @@ bsd_libc_has_function (enum function_cla > return false; > } > > +unsigned > +default_libm_function_max_error (unsigned, machine_mode, bool) > +{ > + return ~0U; > +} > + > +unsigned > +glibc_linux_libm_function_max_error (unsigned cfn, machine_mode mode, > + bool boundary_p) > +{ > + /* Let's use > + https://www.gnu.org/software/libc/manual/2.22/html_node/Errors-in-Math-Functions.html > + https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html > + with usual values recorded here and significant outliers handled in > + target CPU specific overriders. The tables only record default > + rounding to nearest, for -frounding-math let's add some extra ulps. > + For boundary_p values (say finite results outside of [-1.,1.] for > + sin/cos, or [-0.,+Inf] for sqrt etc. let's use custom random testers. */ > + int rnd = flag_rounding_math ? 4 : 0; > + bool sf = (REAL_MODE_FORMAT (mode) == &ieee_single_format > + || REAL_MODE_FORMAT (mode) == &mips_single_format > + || REAL_MODE_FORMAT (mode) == &motorola_single_format); > + bool df = (REAL_MODE_FORMAT (mode) == &ieee_double_format > + || REAL_MODE_FORMAT (mode) == &mips_double_format > + || REAL_MODE_FORMAT (mode) == &motorola_double_format); > + bool xf = (REAL_MODE_FORMAT (mode) == &ieee_extended_intel_96_format > + || REAL_MODE_FORMAT (mode) == &ieee_extended_intel_128_format > + || REAL_MODE_FORMAT (mode) == &ieee_extended_motorola_format); > + bool tf = (REAL_MODE_FORMAT (mode) == &ieee_quad_format > + || REAL_MODE_FORMAT (mode) == &mips_quad_format); > + > + switch (cfn) > + { > + CASE_CFN_SQRT: > + CASE_CFN_SQRT_FN: > + if (boundary_p) > + /* https://gcc.gnu.org/pipermail/gcc-patches/2023-April/616595.html */ > + return 0; > + if (sf || df || xf || tf) > + return 0 + rnd; > + break; > + CASE_CFN_COS: > + CASE_CFN_COS_FN: > + /* cos is generally errors like sin, but far more arches have 2ulps > + for double. */ > + if (!boundary_p && df) > + return 2 + rnd; > + gcc_fallthrough (); > + CASE_CFN_SIN: > + CASE_CFN_SIN_FN: > + if (boundary_p) > + /* According to > + https://sourceware.org/pipermail/gcc-patches/2023-April/616315.html > + seems default rounding sin/cos stay strictly in [-1.,1.] range, > + with rounding to infinity it can be 1ulp larger/smaller. */ > + return flag_rounding_math ? 1 : 0; > + if (sf || df) > + return 1 + rnd; > + if (xf || tf) > + return 2 + rnd; > + break; > + default: > + break; > + } > + > + return default_libm_function_max_error (cfn, mode, boundary_p); > +} > > tree > default_builtin_tm_load_store (tree ARG_UNUSED (type)) > --- gcc/config/linux.h.jj 2023-04-27 10:17:32.551687077 +0200 > +++ gcc/config/linux.h 2023-04-27 10:26:58.365490153 +0200 > @@ -212,4 +212,7 @@ see the files COPYING3 and COPYING.RUNTI > # undef TARGET_LIBC_HAS_FUNCTION > # define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function > > +# undef TARGET_LIBM_FUNCTION_MAX_ERROR > +# define TARGET_LIBM_FUNCTION_MAX_ERROR linux_libm_function_max_error > + > #endif > --- gcc/config/linux-protos.h.jj 2023-04-27 10:17:32.551687077 +0200 > +++ gcc/config/linux-protos.h 2023-04-27 10:26:58.365490153 +0200 > @@ -20,3 +20,5 @@ along with GCC; see the file COPYING3. > extern bool linux_has_ifunc_p (void); > > extern bool linux_libc_has_function (enum function_class fn_class, tree); > + > +extern unsigned linux_libm_function_max_error (unsigned, machine_mode, bool); > --- gcc/config/linux.cc.jj 2023-04-27 10:17:32.551687077 +0200 > +++ gcc/config/linux.cc 2023-04-27 10:26:58.365490153 +0200 > @@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. > #include "tm.h" > #include "tree.h" > #include "linux-protos.h" > +#include "target.h" > +#include "targhooks.h" > > bool > linux_libc_has_function (enum function_class fn_class, > @@ -38,3 +40,12 @@ linux_libc_has_function (enum function_c > > return false; > } > + > +unsigned > +linux_libm_function_max_error (unsigned cfn, machine_mode mode, > + bool boundary_p) > +{ > + if (OPTION_GLIBC) > + return glibc_linux_libm_function_max_error (cfn, mode, boundary_p); > + return default_libm_function_max_error (cfn, mode, boundary_p); > +} > --- gcc/config/arc/arc.cc.jj 2023-04-27 10:17:32.546687149 +0200 > +++ gcc/config/arc/arc.cc 2023-04-27 12:20:28.155525126 +0200 > @@ -68,6 +68,8 @@ along with GCC; see the file COPYING3. > #include "alias.h" > #include "opts.h" > #include "hw-doloop.h" > +#include "targhooks.h" > +#include "case-cfn-macros.h" > > /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */ > static char arc_cpu_name[10] = ""; > @@ -11808,6 +11810,37 @@ arc_insn_cost (rtx_insn *insn, bool spee > return cost; > } > > +static unsigned > +arc_libm_function_max_error (unsigned cfn, machine_mode mode, > + bool boundary_p) > +{ > +#ifdef OPTION_GLIBC > + bool glibc_p = OPTION_GLIBC; > +#else > + bool glibc_p = false; > +#endif > + if (glibc_p) > + { > + int rnd = flag_rounding_math ? 4 : 0; > + switch (cfn) > + { > + CASE_CFN_SIN: > + CASE_CFN_SIN_FN: > + if (!boundary_p && mode == DFmode) > + return 7 + rnd; > + break; > + CASE_CFN_COS: > + CASE_CFN_COS_FN: > + if (!boundary_p && mode == DFmode) > + return 4 + rnd; > + default: > + break; > + } > + return glibc_linux_libm_function_max_error (cfn, mode, boundary_p); > + } > + return default_libm_function_max_error (cfn, mode, boundary_p); > +} > + > #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P > #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p > > @@ -11832,6 +11865,9 @@ arc_insn_cost (rtx_insn *insn, bool spee > #undef TARGET_INSN_COST > #define TARGET_INSN_COST arc_insn_cost > > +#undef TARGET_LIBM_FUNCTION_MAX_ERROR > +#define TARGET_LIBM_FUNCTION_MAX_ERROR arc_libm_function_max_error > + > struct gcc_target targetm = TARGET_INITIALIZER; > > #include "gt-arc.h" > --- gcc/config/i386/i386.cc.jj 2023-04-27 10:17:32.550687091 +0200 > +++ gcc/config/i386/i386.cc 2023-04-27 12:20:53.102161814 +0200 > @@ -25250,7 +25250,8 @@ ix86_libgcc_floating_mode_supported_p > #undef TARGET_MEMTAG_TAG_SIZE > #define TARGET_MEMTAG_TAG_SIZE ix86_memtag_tag_size > > -static bool ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED) > +static bool > +ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED) > { > #ifdef OPTION_GLIBC > if (OPTION_GLIBC) > @@ -25265,6 +25266,58 @@ static bool ix86_libc_has_fast_function > #undef TARGET_LIBC_HAS_FAST_FUNCTION > #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function > > +static unsigned > +ix86_libm_function_max_error (unsigned cfn, machine_mode mode, > + bool boundary_p) > +{ > +#ifdef OPTION_GLIBC > + bool glibc_p = OPTION_GLIBC; > +#else > + bool glibc_p = false; > +#endif > + if (glibc_p) > + { > + /* If __FAST_MATH__ is defined, glibc provides libmvec. */ > + unsigned int libmvec_ret = 0; > + if (!flag_trapping_math > + && flag_unsafe_math_optimizations > + && flag_finite_math_only > + && !flag_signed_zeros > + && !flag_errno_math) > + switch (cfn) > + { > + CASE_CFN_COS: > + CASE_CFN_COS_FN: > + CASE_CFN_SIN: > + CASE_CFN_SIN_FN: > + if (!boundary_p) > + { > + /* With non-default rounding modes, libmvec provides > + complete garbage in results. E.g. > + _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD > + returns 0.00333309174f rather than 1.40129846e-45f. */ > + if (flag_rounding_math) > + return ~0U; > + /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html > + claims libmvec maximum error is 4ulps. > + My own random testing indicates 2ulps for SFmode and > + 0.5ulps for DFmode, but let's go with the 4ulps. */ > + libmvec_ret = 4; > + } > + break; > + default: > + break; > + } > + unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode, > + boundary_p); > + return MAX (ret, libmvec_ret); > + } > + return default_libm_function_max_error (cfn, mode, boundary_p); > +} > + > +#undef TARGET_LIBM_FUNCTION_MAX_ERROR > +#define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error > + > #if CHECKING_P > #undef TARGET_RUN_TARGET_SELFTESTS > #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests > --- gcc/config/rs6000/rs6000-protos.h.jj 2023-04-27 10:17:32.589686528 +0200 > +++ gcc/config/rs6000/rs6000-protos.h 2023-04-27 10:26:58.370490081 +0200 > @@ -334,6 +334,8 @@ extern unsigned char rs6000_class_max_nr > extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER]; > > extern bool rs6000_linux_float_exceptions_rounding_supported_p (void); > +extern unsigned rs6000_linux_libm_function_max_error (unsigned, machine_mode, > + bool); > > /* Pass management. */ > namespace gcc { class context; } > --- gcc/config/rs6000/rs6000-linux.cc.jj 2023-04-27 10:17:32.588686542 +0200 > +++ gcc/config/rs6000/rs6000-linux.cc 2023-04-27 12:21:29.024638633 +0200 > @@ -23,6 +23,10 @@ along with GCC; see the file COPYING3. > #include "system.h" > #include "coretypes.h" > #include "tm.h" > +#include "target.h" > +#include "targhooks.h" > +#include "tree.h" > +#include "case-cfn-macros.h" > > /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P. */ > > @@ -36,3 +40,39 @@ rs6000_linux_float_exceptions_rounding_s > else > return TARGET_HARD_FLOAT; > } > + > +/* Implement TARGET_LIBM_FUNCTION_MAX_ERROR. */ > + > +unsigned > +rs6000_linux_libm_function_max_error (unsigned cfn, machine_mode mode, > + bool boundary_p) > +{ > + if (OPTION_GLIBC) > + { > + int rnd = flag_rounding_math ? 4 : 0; > + switch (cfn) > + { > + CASE_CFN_SQRT: > + CASE_CFN_SQRT_FN: > + if (!boundary_p && MODE_COMPOSITE_P (mode)) > + return 1 + rnd; > + break; > + CASE_CFN_COS: > + CASE_CFN_COS_FN: > + if (!boundary_p && mode == SFmode) > + return 3 + rnd; > + if (!boundary_p && MODE_COMPOSITE_P (mode)) > + return 4 + rnd; > + break; > + CASE_CFN_SIN: > + CASE_CFN_SIN_FN: > + if (!boundary_p && MODE_COMPOSITE_P (mode)) > + return 1 + rnd; > + break; > + default: > + break; > + } > + return glibc_linux_libm_function_max_error (cfn, mode, boundary_p); > + } > + return default_libm_function_max_error (cfn, mode, boundary_p); > +} > --- gcc/config/rs6000/linux.h.jj 2023-04-27 10:17:32.588686542 +0200 > +++ gcc/config/rs6000/linux.h 2023-04-27 10:26:58.370490081 +0200 > @@ -50,6 +50,9 @@ > #undef TARGET_LIBC_HAS_FUNCTION > #define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function > > +#undef TARGET_LIBM_FUNCTION_MAX_ERROR > +#define TARGET_LIBM_FUNCTION_MAX_ERROR rs6000_linux_libm_function_max_error > + > #undef TARGET_OS_CPP_BUILTINS > #define TARGET_OS_CPP_BUILTINS() \ > do \ > --- gcc/config/rs6000/linux64.h.jj 2023-04-27 10:17:32.588686542 +0200 > +++ gcc/config/rs6000/linux64.h 2023-04-27 10:26:58.370490081 +0200 > @@ -288,6 +288,9 @@ extern int dot_symbols; > #undef TARGET_LIBC_HAS_FUNCTION > #define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function > > +#undef TARGET_LIBM_FUNCTION_MAX_ERROR > +#define TARGET_LIBM_FUNCTION_MAX_ERROR rs6000_linux_libm_function_max_error > + > #undef TARGET_OS_CPP_BUILTINS > #define TARGET_OS_CPP_BUILTINS() \ > do \ > --- gcc/config/or1k/or1k.cc.jj 2023-04-27 10:17:32.551687077 +0200 > +++ gcc/config/or1k/or1k.cc 2023-04-27 12:22:02.886145476 +0200 > @@ -44,6 +44,8 @@ > #include "explow.h" > #include "cfgrtl.h" > #include "alias.h" > +#include "targhooks.h" > +#include "case-cfn-macros.h" > > /* These 4 are needed to allow using satisfies_constraint_J. */ > #include "insn-config.h" > @@ -2191,6 +2193,32 @@ or1k_output_mi_thunk (FILE *file, tree t > epilogue_completed = 0; > } > > +static unsigned > +or1k_libm_function_max_error (unsigned cfn, machine_mode mode, > + bool boundary_p) > +{ > +#ifdef OPTION_GLIBC > + bool glibc_p = OPTION_GLIBC; > +#else > + bool glibc_p = false; > +#endif > + if (glibc_p) > + { > + switch (cfn) > + { > + CASE_CFN_SIN: > + CASE_CFN_SIN_FN: > + if (!boundary_p && mode == DFmode && flag_rounding_math) > + return 7; > + break; > + default: > + break; > + } > + return glibc_linux_libm_function_max_error (cfn, mode, boundary_p); > + } > + return default_libm_function_max_error (cfn, mode, boundary_p); > +} > + > #undef TARGET_ASM_OUTPUT_MI_THUNK > #define TARGET_ASM_OUTPUT_MI_THUNK or1k_output_mi_thunk > #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK > @@ -2214,6 +2242,9 @@ or1k_output_mi_thunk (FILE *file, tree t > #undef TARGET_HAVE_SPECULATION_SAFE_VALUE > #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed > > +#undef TARGET_LIBM_FUNCTION_MAX_ERROR > +#define TARGET_LIBM_FUNCTION_MAX_ERROR or1k_libm_function_max_error > + > /* Calling Conventions. */ > #undef TARGET_FUNCTION_VALUE > #define TARGET_FUNCTION_VALUE or1k_function_value > > > Jakub