* adjusted the test with 'float16' as pointed out

* moved common real_to_target call before the branch

* added assertions for multiple of 32 or exactly 16 bits

* added a comment to the branch

The long double mangling issue should get its own PR & patch.

Tested on x86_64. However, I got a CI failure on ARM for the previous patch: 
https://forge.sourceware.org/gcc/gcc-TEST/pulls/72#issuecomment-2046. I assume 
this resolved with the changes to the test. (How can I get a rerun of the CI 
after force-pushing to the PR?)

OK for trunk and backports?

-------------- 8< --------------

Signed-off-by: Matthias Kretz <m.kr...@gsi.de>

gcc/testsuite/ChangeLog:

        * g++.dg/pr121801_float16_cst_mangling.C: New test.

gcc/cp/ChangeLog:

        * mangle.cc (write_real_cst): Handle 16-bit real and assert
        that reals have 16 bits or a multiple of 32 bits.
---
 gcc/cp/mangle.cc                                   | 14 +++++++++++++-
 .../g++.dg/pr121801_float16_cst_mangling.C         | 13 +++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/pr121801_float16_cst_mangling.C

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 80be40d2dce..9de1a9ec919 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -2176,11 +2176,23 @@ write_real_cst (const tree value)
   int i, limit, dir;
 
   tree type = TREE_TYPE (value);
-  int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32;
+  int bits = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type));
+  int words = bits / 32;
 
   real_to_target (target_real, &TREE_REAL_CST (value),
                  TYPE_MODE (type));
 
+  if (words == 0)
+    {
+      /* _Float16 is the only supported type smaller than 32 bits. */
+      gcc_assert (bits == 16);
+      sprintf (buffer, "%04lx", (unsigned long) target_real[0]);
+      write_chars (buffer, 4);
+      return;
+    }
+
+  gcc_assert (bits % 32 == 0);
+
   /* The value in target_real is in the target word order,
      so we must write it out backward if that happens to be
      little-endian.  write_number cannot be used, it will
diff --git a/gcc/testsuite/g++.dg/pr121801_float16_cst_mangling.C b/gcc/
testsuite/g++.dg/pr121801_float16_cst_mangling.C
new file mode 100644
index 00000000000..cd35186d888
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr121801_float16_cst_mangling.C
@@ -0,0 +1,13 @@
+// PR c++/121801
+// { dg-do compile { target { c++20 && float16 } } }
+// { dg-add-options float16 }
+
+template<_Float16 T> void f() {}
+
+void uses() {
+  f<_Float16(1)>();
+  f<_Float16(2)>();
+}
+
+// { dg-final { scan-assembler "_Z1fILDF16_3c00EEvv" } }
+// { dg-final { scan-assembler "_Z1fILDF16_4000EEvv" } }

-- 
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Center for Heavy Ion Research               https://gsi.de
 std::simd
──────────────────────────────────────────────────────────────────────────




Reply via email to