diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fold-const.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/i386/pr108934.C | 28 | ||||
-rw-r--r-- | 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 9aaea71..99882ef 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 0000000..bd8f0ff --- /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 5b4fd87..d9af8f3 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 } } } } */ |