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 AA880393BA41 for ; Sat, 17 Sep 2022 06:14:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AA880393BA41 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 x1-20020a17090ab00100b001fda21bbc90so1781234pjq.3 for ; Fri, 16 Sep 2022 23:14:58 -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=U4wgFUWzB8W0UCRJWNZJK4XRN8GfN5ThLWMtOX/6MKA=; b=aaIE4wgspy6HFXjvqPJIy/V2V2yobRBJpVs9p9Rf1WX+3dJqmZ7ALcCNcsaxZzU3kn Og0m/egWQkL5s7dDO9529mNCK8HPlWoRDy8fooqq7jADloE1pRoUQt89H4P1TQfO278h KaxPpP3BVraCLZoLNLraDJDtrpLob0o58AzqCtD1bib8ROUQk/4r7pKHWsF3+kdF3nAn 9/Ud4XtGXLOPSoVGPY52ujXz3bkopw2lEwyka+4Pt0o/dbuLcCJSJrxWebhwSSMBdpaM 6P5CZ8J43omZw+kudohTG5nx3j5w2rGjVx+gDGUstqU6FkGImXx/C5nu224NogrOJUfL H2AQ== 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=U4wgFUWzB8W0UCRJWNZJK4XRN8GfN5ThLWMtOX/6MKA=; b=iHVBS3VmXVDwZF5Nr3PtKN4Gf7b1x4bruGXXhn/zVlzEeeSJpO7bXJIH/HCE1ppZzS hOqmMCd/xq7+qSmoVrLGm3flViHK7XOMOAae+XVsj9cg0U9ss3Dn3t0tRmZ0ctyB/KHb Yo/UHg1BezGQzzusjQCBZb7tgl/oc+lo+ibCT2+2C06lC/rIljil7k4wZCgh0I0pnwM3 9RXvvkYKNI5tyFaFH2/JqBKj4D9wdL3pSfVSGyuN4mtQOmw3pcE3Inlj0hwTmejZXWgw llLynyqhMzwIOo6dmdArMym16v58YjQWNBC8L8z1fXM7/Mp6gwIaFoKE41+kc4wTS50W BmWA== X-Gm-Message-State: ACrzQf3sKQCtCft6/+FGc4EkicZk1KCiuY3fHksA/ZH5fR+LNHLHghgN t3Xl9SxFnqPjvZBUxkopuTH8Xy6zF4hsxw== X-Google-Smtp-Source: AMsMyM6lM7BvziViUhi8zvSBi4l+p7jkYxJ2C5IfMWu8N3334X59mTRDrCkrHutn5tTQ2oK//8Ov1Q== X-Received: by 2002:a17:902:b415:b0:178:2835:29e7 with SMTP id x21-20020a170902b41500b00178283529e7mr3300185plr.86.1663395297265; Fri, 16 Sep 2022 23:14:57 -0700 (PDT) Received: from fanta-arch.localdomain ([2406:da1e:8db:a800:58a3:2979:14fa:1426]) by smtp.gmail.com with ESMTPSA id 128-20020a620486000000b0053e93aa8fb9sm15485384pfe.71.2022.09.16.23.14.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Sep 2022 23:14:56 -0700 (PDT) From: Letu Ren To: libc-alpha@sourceware.org Cc: fweimer@redhat.com, Letu Ren Subject: [PATCH v2] stdlib/strfrom: Change -NAN test to multiple possible results (bug 29501) Date: Sat, 17 Sep 2022 14:13:29 +0800 Message-Id: <20220917061328.8620-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=-9.8 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. This patch changes the original -NAN test case to NAN and adds a special test which accepts two possible results to test -NAN. This patch has been tested on x86_64 and riscv64. Except some tests fails on riscv64 due to timeout, all tests pass. Signed-off-by: Letu Ren --- stdlib/tst-strfrom-locale.c | 6 +++++- stdlib/tst-strfrom.c | 6 +++++- stdlib/tst-strfrom.h | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/stdlib/tst-strfrom-locale.c b/stdlib/tst-strfrom-locale.c index 85907c0ce1..1b0418c20e 100644 --- a/stdlib/tst-strfrom-locale.c +++ b/stdlib/tst-strfrom-locale.c @@ -37,10 +37,14 @@ static const struct test tests[] = { TEST ("5,900000e-16", "%e", 50, 12, 5.9e-16), TEST ("1,234500e+20", "%e", 50, 12, 12.345e19), TEST ("1,000000e+05", "%e", 50, 12, 1e5), - TEST ("-NAN", "%G", 50, 4, -NAN_), + TEST ("NAN", "%G", 50, 3, NAN_), TEST ("-inf", "%g", 50, 4, -INF), TEST ("inf", "%g", 50, 3, INF) }; +/* Tests with multiple possible results. */ +static const struct sptest sptests[] = { + SPTEST ("-NAN", "NAN", "%G", 50, 4, 3, -NAN_) +}; /* Tests with buffer size small. */ static const struct test stest[] = { TEST ("1234", "%g", 5, 7, 12345.345), diff --git a/stdlib/tst-strfrom.c b/stdlib/tst-strfrom.c index 3a447eac12..3186db86fd 100644 --- a/stdlib/tst-strfrom.c +++ b/stdlib/tst-strfrom.c @@ -37,10 +37,14 @@ static const struct test tests[] = { TEST ("5.900000e-16", "%e", 50, 12, 5.9e-16), TEST ("1.234500e+20", "%e", 50, 12, 12.345e19), TEST ("1.000000e+05", "%e", 50, 12, 1e5), - TEST ("-NAN", "%G", 50, 4, -NAN_), + TEST ("NAN", "%G", 50, 3, NAN_), TEST ("-inf", "%g", 50, 4, -INF), TEST ("inf", "%g", 50, 3, INF) }; +/* Tests with multiple possible results. */ +static const struct sptest sptests[] = { + SPTEST ("-NAN", "NAN", "%G", 50, 4, 3, -NAN_) +}; /* Tests with buffer size small. */ static const struct test stest[] = { TEST ("1234", "%g", 5, 7, 12345.345), diff --git a/stdlib/tst-strfrom.h b/stdlib/tst-strfrom.h index 2820a580c2..e80027fde9 100644 --- a/stdlib/tst-strfrom.h +++ b/stdlib/tst-strfrom.h @@ -59,6 +59,20 @@ struct test { { \ s, fmt, size, rc, { GEN_TEST_STRTOD_FOREACH (ENTRY, val) } \ } +/* Tests with multiple possible results. */ +struct sptest { + const char *s0; + const char *s1; + const char *fmt; + int size; + int rc0; + int rc1; + struct test_input t; +}; +#define SPTEST(s0, s1, fmt, size, rc0, rc1, val) \ + { \ + s0, s1, fmt, size, rc0, rc1, { GEN_TEST_STRTOD_FOREACH (ENTRY, val) } \ + } /* Hexadecimal tests. */ struct htests { @@ -100,6 +114,18 @@ test_ ## FSUF (void) \ status++; \ } \ } \ + for (i = 0; i < sizeof (sptests) / sizeof (sptests[0]); i++) \ + { \ + rc = FTOSTR (buf, sptests[i].size, sptests[i].fmt, sptests[i].t.FSUF); \ + rc1 = (strcmp (buf, sptests[i].s0) != 0) || (rc != sptests[i].rc0); \ + rc1 &= (strcmp (buf, sptests[i].s1) != 0) || (rc != sptests[i].rc1); \ + if (rc1) \ + { \ + printf (#FTOSTR ": got %s (%d), expected %s (%d) or %s (%d)\n", \ + buf, rc, sptests[i].s0, sptests[i].rc0, sptests[i].s1, sptests[i].rc1); \ + status++; \ + } \ + } \ for (i = 0; i < sizeof (htest) / sizeof (htest[0]); i++) \ { \ rc = FTOSTR (buf, 50, htest[i].fmt, htest[i].t.FSUF); \ -- 2.37.3