Hi,

With some historical reasons, rs6000 defines KFmode, TFmode
and IFmode to have different mode precision, but it causes
some issues and needs some workarounds such as r14-6478 for
PR112788.  So we are going to make all rs6000 128 bit scalar
FP modes have 128 bit precision.  Be prepared for that, this
patch is to make function convert_mode_scalar allow same
precision FP modes conversion if their underlying formats are
ibm_extended_format and ieee_quad_format respectively, just
like the existing special treatment on arm_bfloat_half_format
<-> ieee_half_format.  It also factors out all the relevant
checks into a lambda function.

Bootstrapped and regtested on x86_64-redhat-linux and
powerpc64{,le}-linux-gnu.

Is it ok for trunk?

BR,
Kewen
-----
        PR target/112993

gcc/ChangeLog:

        * expr.cc (convert_mode_scalar): Allow same precision conversion
        between scalar floating point modes if whose underlying format is
        ibm_extended_format or ieee_quad_format, and refactor assertion
        with new lambda function acceptable_same_precision_modes.
---
 gcc/expr.cc | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/gcc/expr.cc b/gcc/expr.cc
index ffbac513692..eac4dcc982e 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -338,6 +338,29 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
   enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
                              : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));

+  auto acceptable_same_precision_modes
+    = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
+    {
+      if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
+       return true;
+
+      /* arm_bfloat_half_format <-> ieee_half_format */
+      if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
+          && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
+         || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
+             && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
+       return true;
+
+      /* ibm_extended_format <-> ieee_quad_format */
+      if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
+          && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
+         || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
+             && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
+       return true;
+
+      return false;
+    };
+
   if (to_real)
     {
       rtx value;
@@ -346,12 +369,7 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)

       gcc_assert ((GET_MODE_PRECISION (from_mode)
                   != GET_MODE_PRECISION (to_mode))
-                 || (DECIMAL_FLOAT_MODE_P (from_mode)
-                     != DECIMAL_FLOAT_MODE_P (to_mode))
-                 || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
-                     && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
-                 || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
-                     && REAL_MODE_FORMAT (from_mode) == &ieee_half_format));
+                 || acceptable_same_precision_modes (from_mode, to_mode));

       if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
        {
--
2.39.1

Reply via email to