From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by sourceware.org (Postfix) with ESMTPS id F23913858D37 for ; Wed, 5 Oct 2022 11:14:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F23913858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-x1031.google.com with SMTP id fw14so8227615pjb.3 for ; Wed, 05 Oct 2022 04:14:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date; bh=GLG4mvc+eclQ2Aikr0Aj0D+OvhE06jWh3bZa17Aq6ME=; b=J2P7aMjemeU0QssVgawPEda4R3k/2+IRwPcoHoxWbh0nKyyRjlbNPsuZK1tN4o1sCr ljw2rE2kjF7V5TEZRd6nV1nL15GESz/fdOTPl0eUuM865JVrAbRYlXtTz9IAa7yV56+d pjvNv5R11jCshV5JW2o54SE54WN/cGmwNYcnJRblx3uqM7HzrVbVKOtMDjXITFXgpFX2 usBY3FAVKGItAFP/EebaWYVF9O1bQOlF7Q3Q/10RhcJItQtMX+AK3DnvEKAimSVFo2u8 OZolgph4EefrHObbueK6S7NtIc2UDpJK0HUuWvBt1I0zo93vRJRRttE1XF3Mzrz7GpFw jWaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date; bh=GLG4mvc+eclQ2Aikr0Aj0D+OvhE06jWh3bZa17Aq6ME=; b=m7hpFlljNT7FaSlbbYSBVPiPJwZzqqkP5sbZZ5vnEe2NFU1YzC59u63OL+taujQQEX Dxh/yxhBm/kiLvlROdmfIbkQ8TiMLTrl10KaY0P8dcJey6e9FrswllSuSWSxZO4udzlS 2MEHzX3FpmtN8FE7Pp3d+LiCbsYWbsQ3l7UahIIp9JPGqETFsWfPvf69c2ASo5/i8CoN 9eM2w+GPZCYbGObHilCdA4Lrba5QO7nozU9u2sh/NfxZ2+lJqvBj/EyMSrKYBV/wyHfK EFr1Q+VgkUzDx+gKrxpc6inRi0n4kbndVcWETP4Y1l7ATIjSt2T50GhbPNrI3yEjDsGG jrUw== X-Gm-Message-State: ACrzQf3kDh1/sFxAFbX4Ws8zZ3rOJa3AFLuSQ/u5joPVkiTOcycc5MeN +rjzyeoeQYF/pQQXsHPee6lt57IQ6doPBK3rR90= X-Google-Smtp-Source: AMsMyM7OhJDQmc8oIqACinJ7z4J28duvIJz0JH0mxU3l13Q41t303LhGrOlrw4lVwFKoz2Ut+hBPhw== X-Received: by 2002:a17:902:8346:b0:178:a33f:89cf with SMTP id z6-20020a170902834600b00178a33f89cfmr31417202pln.9.1664968473801; Wed, 05 Oct 2022 04:14:33 -0700 (PDT) Received: from fanta-arch.tsinghua.edu.cn (ec2-18-162-45-232.ap-east-1.compute.amazonaws.com. [18.162.45.232]) by smtp.gmail.com with ESMTPSA id h13-20020aa796cd000000b0053eec4bb1b1sm6438363pfq.64.2022.10.05.04.14.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Oct 2022 04:14:33 -0700 (PDT) From: Letu Ren To: libc-alpha@sourceware.org Cc: fweimer@redhat.com, joseph@codesourcery.com, Letu Ren Subject: [PATCH] stdlib/strfrom: Add copysign to fix NAN issue on riscv (BZ #29501) Date: Wed, 5 Oct 2022 19:13:53 +0800 Message-Id: <20221005111353.3921-1-fantasquex@gmail.com> X-Mailer: git-send-email 2.37.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,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: According to the specification of ISO/IEC TS 18661-1:2014, The strfromd, strfromf, and strfroml functions are equivalent to snprintf(s, n, format, fp) (7.21.6.5), except the format string contains only the character %, an optional precision that does not contain an asterisk *, and one of the conversion specifiers a, A, e, E, f, F, g, or G, which applies to the type (double, float, or long double) indicated by the function suffix (rather than by a length modifier). Use of these functions with any other 20 format string results in undefined behavior. strfromf will convert the arguement with type float to double first. According to the latest version of IEEE754 which is published in 2019, Conversion of a quiet NaN from a narrower format to a wider format in the same radix, and then back to the same narrower format, should not change the quiet NaN payload in any way except to make it canonical. When either an input or result is a NaN, this standard does not interpret the sign of a NaN. However, operations on bit strings—copy, negate, abs, copySign—specify the sign bit of a NaN result, sometimes based upon the sign bit of a NaN operand. The logical predicates totalOrder and isSignMinus are also affected by the sign bit of a NaN operand. For all other operations, this standard does not specify the sign bit of a NaN result, even when there is only one input NaN, or when the NaN is produced from an invalid operation. converting NAN or -NAN with type float to double doesn't need to keep the signbit. As a result, this test case isn't mandatory. The problem is that according to RISC-V ISA manual in chapter 11.3 of riscv-isa-20191213, Except when otherwise stated, if the result of a floating-point operation is NaN, it is the canonical NaN. The canonical NaN has a positive sign and all significand bits clear except the MSB, a.k.a. the quiet bit. For single-precision floating-point, this corresponds to the pattern 0x7fc00000. which means that conversion -NAN from float to double won't keep the signbit. Since glibc ought to be consistent here between types and architectures, this patch adds copysign to fix this problem if the string is NAN. This patch leverge Macro instead of creating a function under sysdeps directory because there is only one place which needs a keep-sign conversion. This patch has been tested on x86_64 and riscv64. Resolves: BZ #29501 Signed-off-by: Letu Ren --- stdlib/strfrom-skeleton.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/stdlib/strfrom-skeleton.c b/stdlib/strfrom-skeleton.c index 1fba04bf6a..f22b8bb30b 100644 --- a/stdlib/strfrom-skeleton.c +++ b/stdlib/strfrom-skeleton.c @@ -33,6 +33,10 @@ #define ISDIGIT(Ch) isdigit (Ch) #include "stdio-common/printf-parse.h" +#ifdef __riscv +#include +#endif + int STRFROM (char *dest, size_t size, const char *format, FLOAT f) { @@ -61,7 +65,19 @@ STRFROM (char *dest, size_t size, const char *format, FLOAT f) because __printf_fp and __printf_fphex only accept double and long double as the floating-point argument. */ if (__builtin_types_compatible_p (FLOAT, float)) - fpnum.flt = f; + { +#ifdef __riscv + if (isnan(f)) + { + float x = copysignf(1.f, f); + fpnum.flt = copysign((double) f, (double) x); + } + else + fpnum.flt = (double) f; +#else + fpnum.flt = (double) f; +#endif + } else fpnum.value = f; -- 2.37.3