From: Richard Biener <richard.guenther@gmail.com>
To: Joseph Myers <joseph@codesourcery.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: tree.cc: Fix optimization of DFP default initialization
Date: Wed, 24 Aug 2022 07:08:19 +0200 [thread overview]
Message-ID: <4A1EE58E-F843-45DE-82BC-206A912C7B3B@gmail.com> (raw)
In-Reply-To: <alpine.DEB.2.22.394.2208232352390.392053@digraph.polyomino.org.uk>
> Am 24.08.2022 um 01:54 schrieb Joseph Myers <joseph@codesourcery.com>:
>
> When an object of decimal floating-point type is default-initialized,
> GCC is inconsistent about whether it is given the all-zero-bits
> representation (zero with the least quantum exponent) or whether it
> acts like a conversion of integer 0 to the DFP type (zero with quantum
> exponent 0). In particular, the representation stored in memory can
> have all zero bits, but optimization of access to the same object
> based on its known constant value can then produce zero with quantum
> exponent 0 instead.
>
> C2x leaves the quantum exponent for default initialization
> implementation-defined, but that doesn't allow such inconsistency in
> the interpretation of a single object. All zero bits seems most
> appropriate; change build_real to special-case dconst0 the same way
> other constants are special-cased and ensure that the correct zero for
> the type is generated.
>
> Bootstrapped with no regressions for x86_64-pc-linux-gnu. OK to commit?
Ok
Thanks,
Richard
> gcc/
> * tree.cc (build_real): Give DFP dconst0 the minimum quantum
> exponent for the type.
>
> gcc/testsuite/
> * gcc.dg/torture/dfp-default-init-1.c,
> gcc.dg/torture/dfp-default-init-2.c,
> gcc.dg/torture/dfp-default-init-3.c: New tests.
>
> diff --git a/gcc/testsuite/gcc.dg/torture/dfp-default-init-1.c b/gcc/testsuite/gcc.dg/torture/dfp-default-init-1.c
> new file mode 100644
> index 00000000000..f893ddb52b9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/dfp-default-init-1.c
> @@ -0,0 +1,113 @@
> +/* Test that default-initialized DFP values consistently have the least quantum
> + exponent. */
> +/* { dg-do run } */
> +/* { dg-require-effective-target dfp } */
> +
> +extern void exit (int);
> +extern void abort (void);
> +void *memset (void *, int, __SIZE_TYPE__);
> +int memcmp (const void *, const void *, __SIZE_TYPE__);
> +
> +#ifndef TYPE
> +#define TYPE _Decimal32
> +#endif
> +
> +#ifndef ZEROFP
> +#define ZEROFP 0e-101DF
> +#endif
> +
> +TYPE zero_int = 0;
> +TYPE zero_fp = ZEROFP;
> +TYPE default_init;
> +TYPE zero_bytes;
> +TYPE x;
> +
> +struct s { TYPE a, b; };
> +struct s s_default_init;
> +struct s s_empty_init = {};
> +struct s s_first_int = { 0 };
> +struct s s_both_int = { 0, 0 };
> +struct s sx;
> +
> +const TYPE a_default_init[10];
> +const TYPE a_empty_init[10] = {};
> +const TYPE a_first_int[10] = { 0 };
> +const TYPE a_two_int[10] = { 0, 0 };
> +
> +#define CHECK_ZERO_BYTES(expr) \
> + do \
> + { \
> + if (memcmp (expr, &zero_bytes, sizeof zero_bytes) != 0) \
> + abort (); \
> + TYPE tmp = *expr; \
> + if (memcmp (&tmp, &zero_bytes, sizeof zero_bytes) != 0) \
> + abort (); \
> + } \
> + while (0)
> +
> +#define CHECK_INT_BYTES(expr) \
> + do \
> + { \
> + if (memcmp (expr, &zero_int, sizeof zero_int) != 0) \
> + abort (); \
> + TYPE tmp = *expr; \
> + if (memcmp (&tmp, &zero_int, sizeof zero_int) != 0) \
> + abort (); \
> + } \
> + while (0)
> +
> +int
> +main (void)
> +{
> + memset (&zero_bytes, 0, sizeof zero_bytes);
> + if (memcmp (&zero_bytes, &zero_int, sizeof zero_int) == 0)
> + abort ();
> + CHECK_ZERO_BYTES (&zero_fp);
> + CHECK_ZERO_BYTES (&default_init);
> + CHECK_ZERO_BYTES (&s_default_init.a);
> + CHECK_ZERO_BYTES (&s_default_init.b);
> + CHECK_ZERO_BYTES (&s_empty_init.a);
> + CHECK_ZERO_BYTES (&s_empty_init.b);
> + CHECK_INT_BYTES (&s_first_int.a);
> + CHECK_ZERO_BYTES (&s_first_int.b);
> + CHECK_INT_BYTES (&s_both_int.a);
> + CHECK_INT_BYTES (&s_both_int.b);
> + CHECK_ZERO_BYTES (&a_default_init[0]);
> + CHECK_ZERO_BYTES (&a_default_init[1]);
> + CHECK_ZERO_BYTES (&a_default_init[2]);
> + CHECK_ZERO_BYTES (&a_default_init[9]);
> + CHECK_ZERO_BYTES (&a_empty_init[0]);
> + CHECK_ZERO_BYTES (&a_empty_init[1]);
> + CHECK_ZERO_BYTES (&a_empty_init[2]);
> + CHECK_ZERO_BYTES (&a_empty_init[9]);
> + CHECK_INT_BYTES (&a_first_int[0]);
> + CHECK_ZERO_BYTES (&a_first_int[1]);
> + CHECK_ZERO_BYTES (&a_first_int[2]);
> + CHECK_ZERO_BYTES (&a_first_int[9]);
> + CHECK_INT_BYTES (&a_two_int[0]);
> + CHECK_INT_BYTES (&a_two_int[1]);
> + CHECK_ZERO_BYTES (&a_two_int[2]);
> + CHECK_ZERO_BYTES (&a_two_int[9]);
> + struct s s2 = {};
> + CHECK_ZERO_BYTES (&s2.a);
> + CHECK_ZERO_BYTES (&s2.b);
> + struct s s3 = { 0 };
> + CHECK_INT_BYTES (&s3.a);
> + CHECK_ZERO_BYTES (&s3.b);
> + struct s s4 = { 0, 0 };
> + CHECK_INT_BYTES (&s4.a);
> + CHECK_INT_BYTES (&s4.b);
> + struct s s5 = { 0 };
> + sx = s5;
> + CHECK_INT_BYTES (&sx.a);
> + CHECK_ZERO_BYTES (&sx.b);
> + x = default_init;
> + CHECK_ZERO_BYTES (&x);
> + x = zero_int;
> + CHECK_INT_BYTES (&x);
> + x = s_default_init.a;
> + CHECK_ZERO_BYTES (&x);
> + x = s_default_init.b;
> + CHECK_ZERO_BYTES (&x);
> + exit (0);
> +}
> diff --git a/gcc/testsuite/gcc.dg/torture/dfp-default-init-2.c b/gcc/testsuite/gcc.dg/torture/dfp-default-init-2.c
> new file mode 100644
> index 00000000000..30f850be2ee
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/dfp-default-init-2.c
> @@ -0,0 +1,8 @@
> +/* Test that default-initialized DFP values consistently have the least quantum
> + exponent. */
> +/* { dg-do run } */
> +/* { dg-require-effective-target dfp } */
> +
> +#define TYPE _Decimal64
> +#define ZEROFP 0e-398DD
> +#include "dfp-default-init-1.c"
> diff --git a/gcc/testsuite/gcc.dg/torture/dfp-default-init-3.c b/gcc/testsuite/gcc.dg/torture/dfp-default-init-3.c
> new file mode 100644
> index 00000000000..cdf73508c76
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/dfp-default-init-3.c
> @@ -0,0 +1,8 @@
> +/* Test that default-initialized DFP values consistently have the least quantum
> + exponent. */
> +/* { dg-do run } */
> +/* { dg-require-effective-target dfp } */
> +
> +#define TYPE _Decimal128
> +#define ZEROFP 0e-6176DL
> +#include "dfp-default-init-1.c"
> diff --git a/gcc/tree.cc b/gcc/tree.cc
> index fed1434d141..007c9325b17 100644
> --- a/gcc/tree.cc
> +++ b/gcc/tree.cc
> @@ -2385,12 +2385,12 @@ build_real (tree type, REAL_VALUE_TYPE d)
> tree v;
> int overflow = 0;
>
> - /* dconst{1,2,m1,half} are used in various places in
> + /* dconst{0,1,2,m1,half} are used in various places in
> the middle-end and optimizers, allow them here
> even for decimal floating point types as an exception
> by converting them to decimal. */
> if (DECIMAL_FLOAT_MODE_P (TYPE_MODE (type))
> - && d.cl == rvc_normal
> + && (d.cl == rvc_normal || d.cl == rvc_zero)
> && !d.decimal)
> {
> if (memcmp (&d, &dconst1, sizeof (d)) == 0)
> @@ -2401,6 +2401,15 @@ build_real (tree type, REAL_VALUE_TYPE d)
> decimal_real_from_string (&d, "-1");
> else if (memcmp (&d, &dconsthalf, sizeof (d)) == 0)
> decimal_real_from_string (&d, "0.5");
> + else if (memcmp (&d, &dconst0, sizeof (d)) == 0)
> + {
> + /* Make sure to give zero the minimum quantum exponent for
> + the type (which corresponds to all bits zero). */
> + const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
> + char buf[16];
> + sprintf (buf, "0e%d", fmt->emin - fmt->p);
> + decimal_real_from_string (&d, buf);
> + }
> else
> gcc_unreachable ();
> }
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
prev parent reply other threads:[~2022-08-24 5:08 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-23 23:54 Joseph Myers
2022-08-24 5:08 ` Richard Biener [this message]
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=4A1EE58E-F843-45DE-82BC-206A912C7B3B@gmail.com \
--to=richard.guenther@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=joseph@codesourcery.com \
/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 read-only IMAP folder(s) and NNTP newsgroup(s).