From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id 4F4533858C62 for ; Thu, 23 May 2024 14:37:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4F4533858C62 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4F4533858C62 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::630 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716475032; cv=none; b=YzoYHEqx/ijJzYaZ/JNBfnHdnECljCISatjP1eonrrGvmT3LNhAakveYB3QN9tDpy/7gCK5vrQvDeI8u5mzKSKXMeTMVGW+DTd8YEdjl/l73V/Ml98lp1KTAR9V1xhJHSFjiZpOWNByaXZlzEu96tFBLUdLSKmLP0z5kUfy8BNE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716475032; c=relaxed/simple; bh=fWZXNiY6bwwh4V6zHxiAKNfA0dlFJMpEjx+7NWRwSd4=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=V0xJVFzJAV+UwtBLDjiN36RS6Ll0tIW43ZOv6U3UggK8hnCIqIVi2f8N/T7vc2JwaoMrr45SpWu+hL09vRfK+W1woaSNOHHuNmGT6SH7AzStEH8QnPhdcJ+1hYVKBXNzu+z4FKEMoZEaPUp7x+TYGpXR6F+g70FBZNNNxciTGMg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-1f3310a21d8so12414265ad.1 for ; Thu, 23 May 2024 07:37:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1716475029; x=1717079829; darn=sourceware.org; h=content-transfer-encoding:in-reply-to:organization:from :content-language:references:to:subject:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=iI1nix8MLnH22AxNHYGmj9UmRto1O1nmOA5My0mjniQ=; b=pEG3h+xWbpqhR1w0zqa5pge/RpIxBHIptl/CBbjU1jFAlKZMoy9YgZwmPEThKmAJWS eD4UAZBtprMtE2Q4/OnBF+bhh3/hIseEjvF/E8pIRC8GV9bkWEAA1jNL97+2LTxBT35s 4+UPaV9tMsIjixESzWJ0ee5ydjroFbVT8qOxgDCbTq6hMUo7pKZMykF9NQg7277HARV8 G2gmDaRcbr4Xm+8/2X42s2KRsJRC4iIuAd9xK4C8/aMDurHdMatBOPI7geqRf5H/tzfr 5xcjvMsWD2XI8mgZFXUc2aXxYnae+YqyLMz9dDgR8i3me+xE0mLfhvvv1j7zcGsnYvSG dr8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716475029; x=1717079829; h=content-transfer-encoding:in-reply-to:organization:from :content-language:references:to:subject:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=iI1nix8MLnH22AxNHYGmj9UmRto1O1nmOA5My0mjniQ=; b=EBYaVqO4RVXIAaVoIDlqmUiGb550LubO/T8swWL0+njiPshCJgxHiG0u2VZO9FZN+3 dqbX4W3mTpoxB8zC+Jfxpc6/uU1LXsXf/c6hc4SYPDE1E35jWnoZvlN2fi3G+76FD5sV uIN5SP1wEJU5Wk35F/F3qwLevnhZzpXj1KJ1x/qoQicZ4xSigbStqNP2hsDUzWlOKSr6 Wy5+Z/x3cIKqQsP+llA12bni+bKwhApaoKr3+7C50NMOnQGwOKJreUTz580Xw6+5Ianj Sw+w0yUlKzx0745ZGebRwUrYwL5Z8gDNd0obOw46QytC2k8VzQ7HJydIDX4q+dl2ncIu RCKg== X-Forwarded-Encrypted: i=1; AJvYcCUyuAImjRrwBlsJ6HVeja6Fw3wDKpK/sESitihQhy67KLdCzSnUD1ZYUht2tY10FutiQL42u0mUpBIWnoIrpC621F2MB0BVkCmg X-Gm-Message-State: AOJu0Yz5l1xWqsT0VhirzsA64f2AZliGhzfs3+ynllc/QgEMvSMXGdHo R7Nq5viWqR/ZPBtPDzICyKRPq8FHIQ6NkcvTSXpfBEsspAYZAcUEbSMwO6cf0dY= X-Google-Smtp-Source: AGHT+IEgCx8Re5D46GtNm/gHB+R7KusZ3r4AvNKQTkgvoMPFwGy2P3+0OM8ie8i+HoaxQxnTkscu7A== X-Received: by 2002:a17:903:11c6:b0:1f2:efa5:f070 with SMTP id d9443c01a7336-1f31c975a2cmr58280115ad.8.1716475029109; Thu, 23 May 2024 07:37:09 -0700 (PDT) Received: from ?IPV6:2804:1b3:a7c3:7718:5dd8:d5e8:7ff2:a12a? ([2804:1b3:a7c3:7718:5dd8:d5e8:7ff2:a12a]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f33569120esm18581195ad.284.2024.05.23.07.37.07 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 23 May 2024 07:37:08 -0700 (PDT) Message-ID: <3f2ab027-57f4-465a-97b2-e404e845172a@linaro.org> Date: Thu, 23 May 2024 11:37:06 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 3/6] MIPS/math: Implement optimized issignaling(f) To: YunQiang Su , libc-alpha@sourceware.org References: <20240513081429.1749898-1-syq@gcc.gnu.org> <20240513081429.1749898-4-syq@gcc.gnu.org> Content-Language: en-US From: Adhemerval Zanella Netto Organization: Linaro In-Reply-To: <20240513081429.1749898-4-syq@gcc.gnu.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 13/05/24 05:14, YunQiang Su wrote: > MIPSr6 introduces class.fmt instructions, which can help us to > determine whether a number is sNAN. > > We define __mips_issignaling(f) as always inline in mips/math_private.h, > and call them in s_issignaling(f).c. Issignaling operation is also used > by some other functions, such as fmax. Inlining it can introduce better > codesize and performance, due to libcall may issue some stack operations. We used to provide such internal inlines optimizations, which requires a lot of boilerplate code to inline alternative implementation of C standard symbols (such as isnan/isinf). This tend of get really complicate to maintain, and it leads to worse outcomes once compilers start to optimize it way (by providing proper builtins) since we need to either reimplement internally the symbol or use a different name (that compiler can not map to the builtin). Also recently, we started to use builtins more to implement such math symbol (check the math-use-builtins-*), so the idea would to add support for the builtin use on both dbl-64 and flt-32 issignaling, and enable it to use if compiler supports it (afaik it was enabled as arch-independent way on gcc 13). Another possible optimization is also to add a similar enablement on math/math.h, where if compiler supports also route issignaling to its builtin (similar to isnan/isinf/etc.). Then you can focus on optimizing the compiler code generation of issignaling to the emit the class.s. With all these in place there will be no need to internally re-implement the symbol and it would be future-proof regarding compiler optimizations. > > * sysdeps/mips/fpu_control.h: Define FCLASS constants. > * sysdeps/mips/ieee754/s_issignaling.c > * sysdeps/mips/ieee754/s_issignalingf.c > * sysdeps/mips/math_private.h: Define __mips_issignaling(f). > > Signed-off-by: YunQiang Su > --- > sysdeps/mips/fpu_control.h | 17 +++++++ > sysdeps/mips/ieee754/s_issignaling.c | 28 ++++++++++++ > sysdeps/mips/ieee754/s_issignalingf.c | 27 +++++++++++ > sysdeps/mips/math_private.h | 65 +++++++++++++++++++++++++++ > 4 files changed, 137 insertions(+) > create mode 100644 sysdeps/mips/ieee754/s_issignaling.c > create mode 100644 sysdeps/mips/ieee754/s_issignalingf.c > > diff --git a/sysdeps/mips/fpu_control.h b/sysdeps/mips/fpu_control.h > index 3ceb34fc25..086293117e 100644 > --- a/sysdeps/mips/fpu_control.h > +++ b/sysdeps/mips/fpu_control.h > @@ -127,6 +127,23 @@ extern void __mips_fpu_setcw (fpu_control_t) __THROW; > /* Default control word set at startup. */ > extern fpu_control_t __fpu_control; > > +# define _FCLASS_SNAN (1 << 0) > +# define _FCLASS_QNAN (1 << 1) > +# define _FCLASS_MINF (1 << 2) > +# define _FCLASS_MNORM (1 << 3) > +# define _FCLASS_MSUBNORM (1 << 4) > +# define _FCLASS_MZERO (1 << 5) > +# define _FCLASS_PINF (1 << 6) > +# define _FCLASS_PNORM (1 << 7) > +# define _FCLASS_PSUBNORM (1 << 8) > +# define _FCLASS_PZERO (1 << 9) > + > +# define _FCLASS_ZERO (_FCLASS_MZERO | _FCLASS_PZERO) > +# define _FCLASS_SUBNORM (_FCLASS_MSUBNORM | _FCLASS_PSUBNORM) > +# define _FCLASS_NORM (_FCLASS_MNORM | _FCLASS_PNORM) > +# define _FCLASS_INF (_FCLASS_MINF | _FCLASS_PINF) > +# define _FCLASS_NAN (_FCLASS_SNAN | _FCLASS_QNAN) > + > #endif /* __mips_soft_float */ > > #endif /* fpu_control.h */ > diff --git a/sysdeps/mips/ieee754/s_issignaling.c b/sysdeps/mips/ieee754/s_issignaling.c > new file mode 100644 > index 0000000000..3bf65f07a5 > --- /dev/null > +++ b/sysdeps/mips/ieee754/s_issignaling.c > @@ -0,0 +1,28 @@ > +/* issignaling(). MIPS version. > + Copyright (C) 2024 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library. If not, see > + . */ > + > +#include > +#include > +#include > + > +int > +__issignaling (double x) > +{ > + return __mips_issignaling (x); > +} > +libm_hidden_def (__issignaling) > diff --git a/sysdeps/mips/ieee754/s_issignalingf.c b/sysdeps/mips/ieee754/s_issignalingf.c > new file mode 100644 > index 0000000000..14863595bc > --- /dev/null > +++ b/sysdeps/mips/ieee754/s_issignalingf.c > @@ -0,0 +1,27 @@ > +/* issignalingf(). MIPS version. > + Copyright (C) 2024 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library. If not, see > + . */ > + > +#include > +#include > + > +int > +__issignalingf (float x) > +{ > + return __mips_issignalingf (x); > +} > +libm_hidden_def (__issignalingf) > diff --git a/sysdeps/mips/math_private.h b/sysdeps/mips/math_private.h > index 4da8b0c2d9..6c388ddb64 100644 > --- a/sysdeps/mips/math_private.h > +++ b/sysdeps/mips/math_private.h > @@ -53,4 +53,69 @@ > # endif > #endif /* __mips_hard_float && !__mips_single_float */ > > +/* Copy from sysdeps/ieee754/flt-32/s_issignalingf.c. > + Function call can introduce lots for stack operations. Inline can even > + reduce codesize. */ > +static __always_inline int > +__mips_issignalingf (float x) > +{ > +#if __mips_isa_rev >= 6 && defined(__mips_hard_float) > + float c; > + int ret; > + asm volatile("class.s %0, %1" : "=f"(c) : "f"(x)); > + asm volatile("mfc1 %0, %1" : "=r"(ret) : "f"(c)); > + return ret & _FCLASS_SNAN; > +#else > + uint32_t xi; > + GET_FLOAT_WORD (xi, x); > +# if HIGH_ORDER_BIT_IS_SET_FOR_SNAN > + /* We only have to care about the high-order bit of x's significand, because > + having it set (sNaN) already makes the significand different from that > + used to designate infinity. */ > + return (xi & 0x7fc00000) == 0x7fc00000; > +# else > + /* To keep the following comparison simple, toggle the quiet/signaling bit, > + so that it is set for sNaNs. This is inverse to IEEE 754-2008 (as well as > + common practice for IEEE 754-1985). */ > + xi ^= 0x00400000; > + /* We have to compare for greater (instead of greater or equal), because x's > + significand being all-zero designates infinity not NaN. */ > + return (xi & 0x7fffffff) > 0x7fc00000; > +# endif > +#endif > +} > + > +/* Copy from sysdeps/ieee754/dbl-64/s_issignaling.c. > + Function call can introduce lots for stack operations. Inline can even > + reduce codesize. */ > +static __always_inline int > +__mips_issignaling (double x) > +{ > +#if __mips_isa_rev >= 6 && defined(__mips_hard_float) \ > + && !defined(__mips_single_float) > + double c; > + int ret; > + asm volatile("class.d %0, %1" : "=f"(c) : "f"(x)); > + asm volatile("mfc1 %0, %1" : "=r"(ret) : "f"(c)); > + return ret & _FCLASS_SNAN; > +#else > + uint32_t xi; > + GET_HIGH_WORD (xi, x); > +# if HIGH_ORDER_BIT_IS_SET_FOR_SNAN > + /* We only have to care about the high-order bit of x's significand, because > + having it set (sNaN) already makes the significand different from that > + used to designate infinity. */ > + return (xi & UINT32_C (0x7ff80000)) == UINT32_C (0x7ff80000); > +# else > + /* To keep the following comparison simple, toggle the quiet/signaling bit, > + so that it is set for sNaNs. This is inverse to IEEE 754-2008 (as well as > + common practice for IEEE 754-1985). */ > + xi ^= UINT32_C (0x00080000); > + /* We have to compare for greater (instead of greater or equal), because x's > + significand being all-zero designates infinity not NaN. */ > + return (xi & UINT32_C (0x7fffffff)) > UINT32_C (0x7ff80000); > +# endif > +#endif > +} > + > #endif /* MIPS_MATH_PRIVATE_H */