"Kewen.Lin" <li...@linux.ibm.com> writes:
> 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

This part looks good to me FWIW, but what's the correct behaviour of:

      if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
        {
          if (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
              && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
            /* libgcc implements just __trunchfbf2, not __extendhfbf2.  */
            tab = trunc_optab;
          else
            /* Conversion between decimal float and binary float, same
               size.  */
            tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;

for the new pairing?  The intent for bfloat/half seems to be that bfloat
is treated as arbitrarily “lesser than” half, so half->bfloat is a
truncation and bfloat->half is an extension.  It seems like it would be
good to do something similar for the new pair, so that the float modes
still form a total order in terms of extension & truncation.

Thanks,
Richard

Reply via email to