public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Sandiford <richard.sandiford@arm.com>
To: Jakub Jelinek via Gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Richard Biener <rguenther@suse.de>,
	 Jakub Jelinek <jakub@redhat.com>,
	 Aldy Hernandez <aldyh@redhat.com>,
	 "Joseph S. Myers" <joseph@codesourcery.com>,
	 Siddhesh Poyarekar <siddhesh@gotplt.org>,
	 Andrew MacLeod <amacleod@redhat.com>
Subject: Re: [PATCH] v2: Add targetm.libm_function_max_error
Date: Fri, 28 Apr 2023 12:29:58 +0100	[thread overview]
Message-ID: <mpt354k1byh.fsf@arm.com> (raw)
In-Reply-To: <ZEpXmaFjRBeJA2yp@tucnak> (Jakub Jelinek via Gcc-patches's message of "Thu, 27 Apr 2023 13:08:09 +0200")

Jakub Jelinek via Gcc-patches <gcc-patches@gcc.gnu.org> 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  <jakub@redhat.com>
>
> 	* 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

  reply	other threads:[~2023-04-28 11:30 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-26 14:21 [PATCH] " Jakub Jelinek
2023-04-26 16:10 ` Michael Matz
2023-04-27  8:59   ` Jakub Jelinek
2023-04-27 11:05     ` Jakub Jelinek
2023-04-27 14:48       ` Michael Matz
2023-04-27  7:18 ` Richard Biener
2023-04-27  9:20   ` Jakub Jelinek
2023-04-27 10:34     ` Richard Biener
2023-04-27 11:08       ` [PATCH] v2: " Jakub Jelinek
2023-04-28 11:29         ` Richard Sandiford [this message]
2023-04-28 11:39           ` Jakub Jelinek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mpt354k1byh.fsf@arm.com \
    --to=richard.sandiford@arm.com \
    --cc=aldyh@redhat.com \
    --cc=amacleod@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=rguenther@suse.de \
    --cc=siddhesh@gotplt.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).