public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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

      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).