From patchwork Mon Feb 10 10:22:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 863747 Delivered-To: patch@linaro.org Received: by 2002:a5d:4e42:0:b0:385:e875:8a9e with SMTP id r2csp1517590wrt; Mon, 10 Feb 2025 02:24:24 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCWbGib5L3hWQmyYOcO/yjPP4BkvDSyPohbzZ/cBysuny+8xShUPifkzds5MEqTzZYSSSoLsZA==@linaro.org X-Google-Smtp-Source: AGHT+IH4dVcXN7enQCt40NiBKgY5ugwJ4bFMUB9xpI6eNqtigGDaust94eiQIccm9rT0OfqKePMh X-Received: by 2002:a05:620a:4251:b0:7b6:d4ea:fe8a with SMTP id af79cd13be357-7c047bf3af3mr1717379585a.12.1739183064433; Mon, 10 Feb 2025 02:24:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1739183064; cv=none; d=google.com; s=arc-20240605; b=b//fu2kyask6zlJ369XdjFkp+qu6AKnOhaddrHWFD+Z8nJfUtY5spCR/GYCqROGTjW fP1MJexjAYQT1ltVIjT0H+dlSCagwg9uskxxaIU8dgxKnv0v2umCzJwhu9NfizUby6so YWx3zlYpjQ0d+YL1cIKPDIK+1Sethbxxc+5s32C1WAigCB/k1iyMi9O43j81GRjoA+8M zS7azRqEyTGEwsaCxLpOU9iv67SeaME4apCAgsPsBMjATjwYKiQ35QHcBJX3O0u8krIa G5cQz2ymUZgjgIjTY12HcdlRe6IQZlp0qEQdwwi39wwsfTrmq6CkVd0o8mDBU2+QkznZ lD0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=dGTMV/JVOhgwSD7zfFhjmY9o50J6ILSLJjCbihcs1Oc=; fh=mAkTJkmys9sHI/rBpbMW0gFFmA1+Q6Xmaym6a9hMRlo=; b=eBUhg3+sGmlbWYdihwg2ykgho4F+3Fc5KX77gazRL5nasg+MjjNTxpvh/FLLOQIBVa 6clcvODEAwoDn2/iFD7QMfXyWhyUE4OqCe59q7RvtYOEnZUfCXUoJg6Z+rtp5UYyOT9x 142e66IGHR/IMyMF/2LbaavJFxXTR/RdDNOah1WZ4Kl6euXvOiJu8hvU3E5ArRsTXCvW GwPlBbdL/02EUJGpEHsiNA+Jgo12VNB/Wv0WDaWCyEuuuP/dtwPPqBGFfn32Bsw5DSeE fPr2OSPv4jcaE90gedcJrn8upxykvXyXba7Q+UDMAweQc6Uj3oizsm9N2E5kINF7jk1B uifw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CLU+pHR5; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id af79cd13be357-7c05fbeeaefsi153146085a.45.2025.02.10.02.24.24 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Mon, 10 Feb 2025 02:24:24 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CLU+pHR5; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1thQwg-0002Ol-O0; Mon, 10 Feb 2025 05:23:18 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1thQwe-0002NU-1T for qemu-devel@nongnu.org; Mon, 10 Feb 2025 05:23:16 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1thQwb-0000MN-TT for qemu-devel@nongnu.org; Mon, 10 Feb 2025 05:23:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739182993; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dGTMV/JVOhgwSD7zfFhjmY9o50J6ILSLJjCbihcs1Oc=; b=CLU+pHR5G8/IA2aIndM1i2IjbdSlB8xAaMmU8z83Qhq3aYxXNzLhzikVi5WsaWaFiODp/G udDjrPoB38gB9FOJLXfZn/jSzH7UvYWo3utyOcYDkteK1KkbOz3PMQYhNMCrAZSVWjm8KI rBGnNlD3mHTAnF++buLggggNMxeOwJA= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-333-IKXnFx1ONMSw8OeeRsWHng-1; Mon, 10 Feb 2025 05:23:11 -0500 X-MC-Unique: IKXnFx1ONMSw8OeeRsWHng-1 X-Mimecast-MFC-AGG-ID: IKXnFx1ONMSw8OeeRsWHng Received: by mail-ej1-f70.google.com with SMTP id a640c23a62f3a-ab79858cd31so234989666b.2 for ; Mon, 10 Feb 2025 02:23:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739182989; x=1739787789; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dGTMV/JVOhgwSD7zfFhjmY9o50J6ILSLJjCbihcs1Oc=; b=tMeC/GUsM24zLFYt4uwGlAGYdMCI/a9YE2f3WPRlfW7+9SKEnyOuauYhvxJqDjMCA3 92Z7Xq+ssSIcjViYmy7WWwWwouCa56XdqGR77M1yfpcH93Nq8xE3XZ5W859REo8wqjMN S7WfO9wbo+/jukrUw4YDMfzfspeHU15b0Yl2leDaiWi/Ka85ReEkdJLGOsaIGLXCbjr0 FojVwL8+9xNUC5FsqYldMwPuGOsK9+JAYxXScKjGXDVkeOltA4RKv9MsxxD66sosxevt RpE0X6L63UcrG0WaO/i7ks16MSDZvKj5ZH8QqYu1xlyDWXZjUdVoKzqiw1ZsgLElX2yv 4Q2A== X-Gm-Message-State: AOJu0Yz+vP3d3644zrZOFScmA2thf1F8X8FnNgr2CXXfEjXPuPYYYelC +lpYhDDHe+HTVI2YYajzeSKxkCrismZfsyzy9vR/RbSX50mv/u04KvzcBDGDe7t1PYMTNk/U/yR ltepD0kqx38c9AS3DCjPy/nmD2ZrsQ1IL1I3+D0CWSzsHXR7DaloeiBH7OuJX7RRRazvi8ucwIT QucsQWyA6LGZ9vDJSErCJ+4ymbmijpsD9Ivqt00Ko= X-Gm-Gg: ASbGnctsLLgf6+NdYd4YEFP9j1V8xroL8GiDN3zyks7JPyFYKsxQgXJrm5woAbPh2ZW 0SSPi1jcb/glsZnb45dqFLrlB0jfwjZpwbWpNp+DTirqn7sgOlWyNbF2jjvSFJFoyB4V6n1vHuu B6k+6X2JroP5Fl+QFqvoW+dDe063f1IjPvhOFgkoIFhCjprRoCRho0/cfRrVJqlYhAnXH3eoxlV Sa5FvPDHYXcQ0NKd/B7fbdsAknaT/qVjDj51xx1SfaAzbkNfnHmxKOKXdn0y0/F4Da/isJQOPTA xjtpwg== X-Received: by 2002:a17:907:1b27:b0:aa6:8cbc:8d15 with SMTP id a640c23a62f3a-ab789ac0169mr1438222166b.14.1739182989010; Mon, 10 Feb 2025 02:23:09 -0800 (PST) X-Received: by 2002:a17:907:1b27:b0:aa6:8cbc:8d15 with SMTP id a640c23a62f3a-ab789ac0169mr1438219166b.14.1739182988387; Mon, 10 Feb 2025 02:23:08 -0800 (PST) Received: from [192.168.10.3] ([151.62.97.55]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab79bf7ca1esm538707366b.30.2025.02.10.02.23.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 02:23:06 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Peter Maydell , Richard Henderson Subject: [PULL 6/9] tests/tcg/x86_64/fma: Test some x86 fused-multiply-add cases Date: Mon, 10 Feb 2025 11:22:51 +0100 Message-ID: <20250210102255.2555097-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250210102255.2555097-1-pbonzini@redhat.com> References: <20250210102255.2555097-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.405, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=-1, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org From: Peter Maydell Add a test case which tests some corner case behaviour of fused-multiply-add on x86: * 0 * Inf + SNaN should raise Invalid * 0 * Inf + QNaN shouldh not raise Invalid * tininess should be detected after rounding There is also one currently-disabled test case: * flush-to-zero should be done after rounding This is disabled because QEMU's emulation currently does this incorrectly (and so would fail the test). The test case is kept in but disabled, as the justification for why the test running harness has support for testing both with and without FTZ set. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Link: https://lore.kernel.org/r/20250116112536.4117889-3-peter.maydell@linaro.org Signed-off-by: Paolo Bonzini --- tests/tcg/x86_64/fma.c | 109 +++++++++++++++++++++++++++++++ tests/tcg/x86_64/Makefile.target | 1 + 2 files changed, 110 insertions(+) create mode 100644 tests/tcg/x86_64/fma.c diff --git a/tests/tcg/x86_64/fma.c b/tests/tcg/x86_64/fma.c new file mode 100644 index 00000000000..09c622ebc00 --- /dev/null +++ b/tests/tcg/x86_64/fma.c @@ -0,0 +1,109 @@ +/* + * Test some fused multiply add corner cases. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include +#include +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* + * Perform one "n * m + a" operation using the vfmadd insn and return + * the result; on return *mxcsr_p is set to the bottom 6 bits of MXCSR + * (the Flag bits). If ftz is true then we set MXCSR.FTZ while doing + * the operation. + * We print the operation and its results to stdout. + */ +static uint64_t do_fmadd(uint64_t n, uint64_t m, uint64_t a, + bool ftz, uint32_t *mxcsr_p) +{ + uint64_t r; + uint32_t mxcsr = 0; + uint32_t ftz_bit = ftz ? (1 << 15) : 0; + uint32_t saved_mxcsr = 0; + + asm volatile("stmxcsr %[saved_mxcsr]\n" + "stmxcsr %[mxcsr]\n" + "andl $0xffff7fc0, %[mxcsr]\n" + "orl %[ftz_bit], %[mxcsr]\n" + "ldmxcsr %[mxcsr]\n" + "movq %[a], %%xmm0\n" + "movq %[m], %%xmm1\n" + "movq %[n], %%xmm2\n" + /* xmm0 = xmm0 + xmm2 * xmm1 */ + "vfmadd231sd %%xmm1, %%xmm2, %%xmm0\n" + "movq %%xmm0, %[r]\n" + "stmxcsr %[mxcsr]\n" + "ldmxcsr %[saved_mxcsr]\n" + : [r] "=r" (r), [mxcsr] "=m" (mxcsr), + [saved_mxcsr] "=m" (saved_mxcsr) + : [n] "r" (n), [m] "r" (m), [a] "r" (a), + [ftz_bit] "r" (ftz_bit) + : "xmm0", "xmm1", "xmm2"); + *mxcsr_p = mxcsr & 0x3f; + printf("vfmadd132sd 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 + " = 0x%" PRIx64 " MXCSR flags 0x%" PRIx32 "\n", + n, m, a, r, *mxcsr_p); + return r; +} + +typedef struct testdata { + /* Input n, m, a */ + uint64_t n; + uint64_t m; + uint64_t a; + bool ftz; + /* Expected result */ + uint64_t expected_r; + /* Expected low 6 bits of MXCSR (the Flag bits) */ + uint32_t expected_mxcsr; +} testdata; + +static testdata tests[] = { + { 0, 0x7ff0000000000000, 0x7ff000000000aaaa, false, /* 0 * Inf + SNaN */ + 0x7ff800000000aaaa, 1 }, /* Should be QNaN and does raise Invalid */ + { 0, 0x7ff0000000000000, 0x7ff800000000aaaa, false, /* 0 * Inf + QNaN */ + 0x7ff800000000aaaa, 0 }, /* Should be QNaN and does *not* raise Invalid */ + /* + * These inputs give a result which is tiny before rounding but which + * becomes non-tiny after rounding. x86 is a "detect tininess after + * rounding" architecture, so it should give a non-denormal result and + * not set the Underflow flag (only the Precision flag for an inexact + * result). + */ + { 0x3fdfffffffffffff, 0x001fffffffffffff, 0x801fffffffffffff, false, + 0x8010000000000000, 0x20 }, + /* + * Flushing of denormal outputs to zero should also happen after + * rounding, so setting FTZ should not affect the result or the flags. + * QEMU currently does not emulate this correctly because we do the + * flush-to-zero check before rounding, so we incorrectly produce a + * zero result and set Underflow as well as Precision. + */ +#ifdef ENABLE_FAILING_TESTS + { 0x3fdfffffffffffff, 0x001fffffffffffff, 0x801fffffffffffff, true, + 0x8010000000000000, 0x20 }, /* Enabling FTZ shouldn't change flags */ +#endif +}; + +int main(void) +{ + bool passed = true; + for (int i = 0; i < ARRAY_SIZE(tests); i++) { + uint32_t mxcsr; + uint64_t r = do_fmadd(tests[i].n, tests[i].m, tests[i].a, + tests[i].ftz, &mxcsr); + if (r != tests[i].expected_r) { + printf("expected result 0x%" PRIx64 "\n", tests[i].expected_r); + passed = false; + } + if (mxcsr != tests[i].expected_mxcsr) { + printf("expected MXCSR flags 0x%x\n", tests[i].expected_mxcsr); + passed = false; + } + } + return passed ? 0 : 1; +} diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target index d6dff559c7d..be20fc64e88 100644 --- a/tests/tcg/x86_64/Makefile.target +++ b/tests/tcg/x86_64/Makefile.target @@ -18,6 +18,7 @@ X86_64_TESTS += adox X86_64_TESTS += test-1648 X86_64_TESTS += test-2175 X86_64_TESTS += cross-modifying-code +X86_64_TESTS += fma TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64 else TESTS=$(MULTIARCH_TESTS)