From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
qemu-stable@nongnu.org,
Richard Henderson <richard.henderson@linaro.org>
Subject: [PULL 5/7] target/i386: Do not raise Invalid for 0 * Inf + QNaN
Date: Fri, 7 Feb 2025 11:27:59 +0100 [thread overview]
Message-ID: <20250207102802.2445596-6-pbonzini@redhat.com> (raw)
In-Reply-To: <20250207102802.2445596-1-pbonzini@redhat.com>
From: Peter Maydell <peter.maydell@linaro.org>
In commit 8adcff4ae7 ("fpu: handle raising Invalid for infzero in
pick_nan_muladd") we changed the handling of 0 * Inf + QNaN to always
raise the Invalid exception regardless of target architecture. (This
was a change affecting hppa, i386, sh4 and tricore.) However, this
was incorrect for i386, which documents in the SDM section 14.5.2
that for the 0 * Inf + NaN case that it will only raise the Invalid
exception when the input is an SNaN. (This is permitted by the IEEE
754-2008 specification, which documents that whether we raise Invalid
for 0 * Inf + QNaN is implementation defined.)
Adjust the softfloat pick_nan_muladd code to allow the target to
suppress the raising of Invalid for the inf * zero + NaN case (as an
extra flag orthogonal to its choice for when to use the default NaN),
and enable that for x86.
We do not revert here the behaviour change for hppa, sh4 or tricore:
* The sh4 manual is clear that it should signal Invalid
* The tricore manual is a bit vague but doesn't say it shouldn't
* The hppa manual doesn't talk about fused multiply-add corner
cases at all
Cc: qemu-stable@nongnu.org
Fixes: 8adcff4ae7 (""fpu: handle raising Invalid for infzero in pick_nan_muladd")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Link: https://lore.kernel.org/r/20250116112536.4117889-2-peter.maydell@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/fpu/softfloat-types.h | 16 +++++++++++++---
target/i386/tcg/fpu_helper.c | 5 ++++-
fpu/softfloat-parts.c.inc | 5 +++--
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 616c290145f..2e43d1dd9e6 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -280,11 +280,21 @@ typedef enum __attribute__((__packed__)) {
/* No propagation rule specified */
float_infzeronan_none = 0,
/* Result is never the default NaN (so always the input NaN) */
- float_infzeronan_dnan_never,
+ float_infzeronan_dnan_never = 1,
/* Result is always the default NaN */
- float_infzeronan_dnan_always,
+ float_infzeronan_dnan_always = 2,
/* Result is the default NaN if the input NaN is quiet */
- float_infzeronan_dnan_if_qnan,
+ float_infzeronan_dnan_if_qnan = 3,
+ /*
+ * Don't raise Invalid for 0 * Inf + NaN. Default is to raise.
+ * IEEE 754-2008 section 7.2 makes it implementation defined whether
+ * 0 * Inf + QNaN raises Invalid or not. Note that 0 * Inf + SNaN will
+ * raise the Invalid flag for the SNaN anyway.
+ *
+ * This is a flag which can be ORed in with any of the above
+ * DNaN behaviour options.
+ */
+ float_infzeronan_suppress_invalid = (1 << 7),
} FloatInfZeroNaNRule;
/*
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 3d764bc138d..de6d0b252ec 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -178,8 +178,11 @@ void cpu_init_fp_statuses(CPUX86State *env)
* "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
* specified -- for 0 * inf + NaN the input NaN is selected, and if
* there are multiple input NaNs they are selected in the order a, b, c.
+ * We also do not raise Invalid for the 0 * inf + (Q)NaN case.
*/
- set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
+ set_float_infzeronan_rule(float_infzeronan_dnan_never |
+ float_infzeronan_suppress_invalid,
+ &env->sse_status);
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
/* Default NaN: sign bit set, most significant frac bit set */
set_float_default_nan_pattern(0b11000000, &env->fp_status);
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index fee05d0a863..73621f4a970 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -126,7 +126,8 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
}
- if (infzero) {
+ if (infzero &&
+ !(s->float_infzeronan_rule & float_infzeronan_suppress_invalid)) {
/* This is (0 * inf) + NaN or (inf * 0) + NaN */
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
}
@@ -144,7 +145,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
* Inf * 0 + NaN -- some implementations return the
* default NaN here, and some return the input NaN.
*/
- switch (s->float_infzeronan_rule) {
+ switch (s->float_infzeronan_rule & ~float_infzeronan_suppress_invalid) {
case float_infzeronan_dnan_never:
break;
case float_infzeronan_dnan_always:
--
2.48.1
next prev parent reply other threads:[~2025-02-07 10:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-07 10:27 [PULL 0/7] Rust, TCG, x86 patches for 2025-02-07 Paolo Bonzini
2025-02-07 10:27 ` [PULL 1/7] rust: remove unnecessary Cargo.toml metadata Paolo Bonzini
2025-02-07 10:27 ` [PULL 2/7] rust: include rust_version in Cargo.toml Paolo Bonzini
2025-02-07 10:27 ` [PULL 3/7] rust: add docs Paolo Bonzini
2025-02-07 10:27 ` [PULL 4/7] rust: add clippy configuration file Paolo Bonzini
2025-02-07 10:27 ` Paolo Bonzini [this message]
2025-02-07 11:53 ` [PULL 5/7] target/i386: Do not raise Invalid for 0 * Inf + QNaN Michael Tokarev
2025-02-07 13:43 ` Peter Maydell
2025-02-07 10:28 ` [PULL 6/7] tests/tcg/x86_64/fma: Test some x86 fused-multiply-add cases Paolo Bonzini
2025-02-07 10:28 ` [PULL 7/7] tcg/optimize: optimize TSTNE using smask and zmask Paolo Bonzini
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=20250207102802.2445596-6-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@nongnu.org \
--cc=richard.henderson@linaro.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 NNTP newsgroup(s).