public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-6408] fold-const: Ignore padding bits in native_interpret_expr REAL_CST reverse verification [PR108934] Date: Thu, 2 Mar 2023 08:28:20 +0000 (GMT) [thread overview] Message-ID: <20230302082820.C42E33858D33@sourceware.org> (raw) https://gcc.gnu.org/g:cc88366a80e35b3e53141f49d3071010ff3c2ef8 commit r13-6408-gcc88366a80e35b3e53141f49d3071010ff3c2ef8 Author: Jakub Jelinek <jakub@redhat.com> Date: Thu Mar 2 09:27:40 2023 +0100 fold-const: Ignore padding bits in native_interpret_expr REAL_CST reverse verification [PR108934] In the following testcase we try to std::bit_cast a (pair of) integral value(s) which has some non-zero bits in the place of x86 long double (for 64-bit 16 byte type with 10 bytes actually loaded/stored by hw, for 32-bit 12 byte) and starting with my PR104522 change we reject that as native_interpret_expr fails on it. The PR104522 change extends what has been done before for MODE_COMPOSITE_P (but those don't have any padding bits) to all floating point types, because e.g. the exact x86 long double has various bit combinations we don't support, like pseudo-(denormals,infinities,NaNs) or unnormals. The HW handles some of those as exceptional cases and others similarly to the non-pseudo ones. But for the padding bits it actually doesn't load/store those bits at all, it loads/stores 10 bytes. So, I think we should exempt the padding bits from the reverse comparison (the native_encode_expr bits for the padding will be all zeros), which the following patch does. For bit_cast it is similar to e.g. ignoring padding bits if the destination is a structure which has padding bits in there. The change changed auto-init-4.c to how it has been behaving before the PR105259 change, where some more VCEs can be now done. 2023-03-02 Jakub Jelinek <jakub@redhat.com> PR c++/108934 * fold-const.cc (native_interpret_expr) <case REAL_CST>: Before memcmp comparison copy the bytes from ptr to a temporary buffer and clearing padding bits in there. * gcc.target/i386/auto-init-4.c: Revert PR105259 change. * g++.target/i386/pr108934.C: New test. Diff: --- gcc/fold-const.cc | 6 ++++-- gcc/testsuite/g++.target/i386/pr108934.C | 28 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/auto-init-4.c | 5 ++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 9aaea71a2fc..99882ef820a 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -8873,11 +8873,13 @@ native_interpret_expr (tree type, const unsigned char *ptr, int len) valid values that GCC can't really represent accurately. See PR95450. Even for other modes, e.g. x86 XFmode can have some bit combinationations which GCC doesn't preserve. */ - unsigned char buf[24]; + unsigned char buf[24 * 2]; scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type); int total_bytes = GET_MODE_SIZE (mode); + memcpy (buf + 24, ptr, total_bytes); + clear_type_padding_in_mask (type, buf + 24); if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes - || memcmp (ptr, buf, total_bytes) != 0) + || memcmp (buf + 24, buf, total_bytes) != 0) return NULL_TREE; return ret; } diff --git a/gcc/testsuite/g++.target/i386/pr108934.C b/gcc/testsuite/g++.target/i386/pr108934.C new file mode 100644 index 00000000000..bd8f0ffd820 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr108934.C @@ -0,0 +1,28 @@ +// PR c++/108934 +// { dg-do compile { target c++11 } } + +struct S { unsigned long long a[2]; }; +struct T { unsigned long long b[6]; }; +struct U { unsigned long long c[2]; long double d; unsigned long long e[2]; }; + +#if __SIZEOF_LONG_DOUBLE__ == 16 && __LDBL_MANT_DIG__ == 64 && __SIZEOF_LONG_LONG__ == 8 +constexpr long double +foo (S x) +{ + return __builtin_bit_cast (long double, x); +} + +constexpr S a = { 0ULL, 0xffffffffffff0000ULL }; +constexpr long double b = foo (a); +static_assert (b == 0.0L, ""); + +constexpr U +bar (T x) +{ + return __builtin_bit_cast (U, x); +} + +constexpr T c = { 0ULL, 0ULL, 0ULL, 0xffffffffffff0000ULL, 0ULL, 0ULL }; +constexpr U d = bar (c); +static_assert (d.d == 0.0L, ""); +#endif diff --git a/gcc/testsuite/gcc.target/i386/auto-init-4.c b/gcc/testsuite/gcc.target/i386/auto-init-4.c index 5b4fd870c36..d9af8f30bb0 100644 --- a/gcc/testsuite/gcc.target/i386/auto-init-4.c +++ b/gcc/testsuite/gcc.target/i386/auto-init-4.c @@ -15,6 +15,5 @@ long double foo() } -/* The long double init isn't expanded optimally, see PR105259. For ia32 - it uses zero-initialization. */ -/* { dg-final { scan-assembler-times "long\t-16843010" 3 } } */ +/* { dg-final { scan-assembler-times "long\t-16843010" 5 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "long\t-16843010" 3 { target { ia32 } } } } */
reply other threads:[~2023-03-02 8:28 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20230302082820.C42E33858D33@sourceware.org \ --to=jakub@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.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: linkBe 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 read-only IMAP folder(s) and NNTP newsgroup(s).