diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-05-07 21:30:21 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2024-05-07 21:30:21 +0200 |
commit | 28ee13db2e9d995bd3728c4ff3a3545e24b39cd2 (patch) | |
tree | ae551eb6c017592229ea6c85e0b2bf6c9b904701 /gcc/expr.cc | |
parent | d4e25cf4f7c1f51a8824cc62bbb85a81a41b829a (diff) | |
download | gcc-28ee13db2e9d995bd3728c4ff3a3545e24b39cd2.zip gcc-28ee13db2e9d995bd3728c4ff3a3545e24b39cd2.tar.gz gcc-28ee13db2e9d995bd3728c4ff3a3545e24b39cd2.tar.bz2 |
expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907]
The HF and BF modes have the same size/precision and neither is
a subset nor superset of the other.
So, using either __extendhfbf2 or __trunchfbf2 is weird.
The expansion apparently emits __extendhfbf2, but on the libgcc side
we apparently have __trunchfbf2 implemented.
I think it is easier to switch to using what is available rather than
adding new entrypoints to libgcc, even alias, because this is backportable.
2024-05-07 Jakub Jelinek <jakub@redhat.com>
PR middle-end/114907
* expr.cc (convert_mode_scalar): Use trunc_optab rather than
sext_optab for HF->BF conversions.
* optabs-libfuncs.cc (gen_trunc_conv_libfunc): Likewise.
* gcc.dg/pr114907.c: New test.
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r-- | gcc/expr.cc | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc index d4414e2..9f66d47 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -355,8 +355,16 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp) && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)); if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode)) - /* Conversion between decimal float and binary float, same size. */ - tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + { + 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; + } else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)) tab = sext_optab; else |