From patchwork Thu Apr 27 11:08:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 88198 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp186405vqo; Thu, 27 Apr 2023 04:09:05 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5mYXRO5gv5yEsbsXoZRHDqthFFaj/6zlTobwowjdGB034oP31idaHXiREKH4CypgitEYxJ X-Received: by 2002:aa7:d6cf:0:b0:506:b933:d937 with SMTP id x15-20020aa7d6cf000000b00506b933d937mr1159215edr.37.1682593745218; Thu, 27 Apr 2023 04:09:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682593745; cv=none; d=google.com; s=arc-20160816; b=IZ034BsBeB5Xmr9zq2iCYxnmh2NXNXMSHL0V8XWqD4h9snC9eZXtJt11hS8usihqGP sYH3MbaNmffMRdcg0VTXMdvduAKbqssMIiZX4oECzPIDrjbmxVsT7m6SnSTkS91HgVoV PtcsZAx3DD0X+tMlwOC2/oH+kON42Pb5zoeDSr85JbgR/eeCS7uzPBfVQNjkkGAH4Rzq ZeEXyk5uLyv4Jt0Ifw1sZbOMpg3Z0MYTp2jFddutI2Du7cdBWHrlU58Hb5lOwSwU4/Pz s7/kBcWUYMs+A6kouR0pnEqek5XJeie9+V9+kGLwNCxvcS/DAUQRYsb/+gNYadSXX6DY HEdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:in-reply-to:mime-version:references:message-id :subject:cc:to:date:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=b8esOLw2UTsUu7sDj9lYPjj+weUTKvJijidXOoTifTs=; b=k1FZ4GS4vlfCaH/lUlA4y93XZeUifO524MyH1D6WXHPLGuXYa3GVLrUkmHWvGojp3O ao2311z/YlrH26NSq/FbmldhJSQ1LpBTWWWYfDI+b5Ykjx3XXrco+rk4EQOmaQuYN7z7 wby/PaY3eaOS20ys3YXCq8tEYpwpKMDV54+U3IWt6jf6A0N1yfyAc7kFrWQhQgARK5Yt G1T+iK3QnqJAhhCrH3Z3OEYuEEzCwEGLP/67AqwXSuJeHWvUORbwj/uH+DIKcOlHs/NV DWg6PduroJIrOthdHR/Q3Sn0Z0sZxX0OmXGZyj/WeggvUyM3BKGTf70rT6KotxhO7Doj d5ow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=bR2kpdBQ; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id n21-20020aa7db55000000b005068d6ae607si13256895edt.574.2023.04.27.04.09.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Apr 2023 04:09:05 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=bR2kpdBQ; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0C8053858D37 for ; Thu, 27 Apr 2023 11:09:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0C8053858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682593744; bh=b8esOLw2UTsUu7sDj9lYPjj+weUTKvJijidXOoTifTs=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=bR2kpdBQ/m3u4mSZQ00UZBa3GAkQphHfqzWinqAYoQ90O69dlMULTPE64XZ+Rd3KH YGUsSTJyY/MGvXrUb8PS/aljW1Woi5BJlFfYy7/oN1UhWo08fHJVRvmPA24+yIWRgx iimMoq7GaEadVcpXC3dD70SVQBSIPQPlJqN3CNZ8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id D41793858D33 for ; Thu, 27 Apr 2023 11:08:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D41793858D33 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-140-O9godrHFOt-L-K3RKP0Mng-1; Thu, 27 Apr 2023 07:08:14 -0400 X-MC-Unique: O9godrHFOt-L-K3RKP0Mng-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CCFA238601B4; Thu, 27 Apr 2023 11:08:13 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.194.156]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 726B940C2064; Thu, 27 Apr 2023 11:08:13 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 33RB8AZc2757382 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 27 Apr 2023 13:08:10 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 33RB897r2757381; Thu, 27 Apr 2023 13:08:09 +0200 Date: Thu, 27 Apr 2023 13:08:09 +0200 To: Richard Biener Cc: Aldy Hernandez , "Joseph S. Myers" , gcc-patches@gcc.gnu.org, Siddhesh Poyarekar , Andrew MacLeod Subject: [PATCH] v2: Add targetm.libm_function_max_error Message-ID: References: MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1764327419030958935?= X-GMAIL-MSGID: =?utf-8?q?1764327419030958935?= 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: 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. Jakub --- 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