public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-2174] tree.cc: Fix optimization of DFP default initialization
@ 2022-08-24 14:11 Joseph Myers
  0 siblings, 0 replies; only message in thread
From: Joseph Myers @ 2022-08-24 14:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:02de9d26b1820e4af35ebdd271c3a788e3c99035

commit r13-2174-g02de9d26b1820e4af35ebdd271c3a788e3c99035
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Wed Aug 24 14:10:25 2022 +0000

    tree.cc: Fix optimization of DFP default initialization
    
    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.
    
    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:
---
 gcc/testsuite/gcc.dg/torture/dfp-default-init-1.c | 113 ++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/dfp-default-init-2.c |   8 ++
 gcc/testsuite/gcc.dg/torture/dfp-default-init-3.c |   8 ++
 gcc/tree.cc                                       |  13 ++-
 4 files changed, 140 insertions(+), 2 deletions(-)

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 ();
     }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-08-24 14:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-24 14:11 [gcc r13-2174] tree.cc: Fix optimization of DFP default initialization Joseph Myers

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