From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 8CCF13858C54; Wed, 1 Mar 2023 15:56:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8CCF13858C54 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1677686172; bh=TdsT+aZKVEwH0ko8ZTpQhdXM1/RqxjvVsca8VldXu0g=; h=From:To:Subject:Date:In-Reply-To:References:From; b=egF/wy+EcOa1AtW+RDn4VJu76jLsiy9zztBVHl74qahAVfVpoznSfE6fBZY5ajjc1 LNe4x7b2oPHRAFl5t8p44QOSKMZn6LWvJtt0UzovHXMS7jxGcX9eOYi4jEHwKfpR9n 1x37R/dbODLtC6xxuxBjkXKoop2E09J8UV3HcfLE= From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/108934] bit_cast'ing to long double errors out with "the argument cannot be interpreted" since gcc-12 Date: Wed, 01 Mar 2023 15:56:11 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 13.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D108934 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #5 from Jakub Jelinek --- If you are complaining about: 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__ =3D=3D 16 && __LDBL_MANT_DIG__ =3D=3D 64 && __SIZEOF_LONG_LONG__ =3D=3D 8 constexpr long double foo (S x) { return __builtin_bit_cast (long double, x); } constexpr S a =3D { 0ULL, 0xffffffffffff0000ULL }; constexpr long double b =3D foo (a); static_assert (b =3D=3D 0.0L, ""); constexpr U bar (T x) { return __builtin_bit_cast (U, x); } constexpr T c =3D { 0ULL, 0ULL, 0ULL, 0xffffffffffff0000ULL, 0ULL, 0ULL }; constexpr U d =3D bar (c); static_assert (d.d =3D=3D 0.0L, ""); #endif which is an unintended side-effects of the PR104522 changes, then that can = be fixed e.g. with 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 ch= ar *ptr, int len) valid values that GCC can't really represent accurately. See PR95450. Even for other modes, e.g. x86 XFmode can have s= ome bit combinationations which GCC doesn't preserve. */ - unsigned char buf[24]; + unsigned char buf[24 * 2]; scalar_float_mode mode =3D SCALAR_FLOAT_TYPE_MODE (type); int total_bytes =3D 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) !=3D total_bytes - || memcmp (ptr, buf, total_bytes) !=3D 0) + || memcmp (buf + 24, buf, total_bytes) !=3D 0) return NULL_TREE; return ret; } The intent of the PR104522 change was to verify that the interpreted floati= ng point value represents the in memory value correctly, but padding bits shouldn't be considered in that, they can contain anything. That said, for= IBM double double format or e.g. x86=20 extended format there are still many values which can't be interpretted correctly, for the latter e.g. pseudo denormals, pseudo infinities, pseudo NaNs and unnormal values.=