Message ID | 20220516134753.152672-1-christophe.lyon@arm.com |
---|---|
State | New |
Headers | show |
Series | None | expand |
Hi Joseph, May I ping you on this version? (I've moved the tests to gcc.dg/torture/ and checked they work on aarch64 and x86_64. Thanks, Christophe On 5/16/22 15:47, Christophe Lyon wrote: > This patch adds support for trunc and extend operations between HF > mode (_Float16) and Decimal Floating Point formats (_Decimal32, > _Decimal64 and _Decimal128). > > For simplicity we rely on the implicit conversions inserted by the > compiler between HF and SD/DF/TF modes. The existing bid*_to_binary* > and binary*_to_bid* functions are non-trivial and at this stage it is > not clear if there is a performance-critical use case involving _Float16 > and _Decimal* formats. > > The patch also adds two executable tests, to make sure the right > functions are called, available (link phase) and functional. > > Tested on aarch64 and x86_86. The number of symbol matches in the > testcases includes the .global XXX to avoid having to match different > call instructions for different targets. > > 2022-05-04 Christophe Lyon <christophe.lyon@arm.com> > > libgcc/ChangeLog: > > * Makefile.in (D32PBIT_FUNCS): Add _hf_to_sd and _sd_to_hf. > (D64PBIT_FUNCS): Add _hf_to_dd and _dd_to_hf. > (D128PBIT_FUNCS): Add _hf_to_td _td_to_hf. > > libgcc/config/libbid/ChangeLog: > > * bid_gcc_intrinsics.h (LIBGCC2_HAS_HF_MODE): Define according to > __LIBGCC_HAS_HF_MODE__. > (BID_HAS_HF_MODE): Define. > (HFtype): Define. > (__bid_extendhfsd): New prototype. > (__bid_extendhfdd): Likewise. > (__bid_extendhftd): Likewise. > (__bid_truncsdhf): Likewise. > (__bid_truncddhf): Likewise. > (__bid_trunctdhf): Likewise. > * _dd_to_hf.c: New file. > * _hf_to_dd.c: New file. > * _hf_to_sd.c: New file. > * _hf_to_td.c: New file. > * _sd_to_hf.c: New file. > * _td_to_hf.c: New file. > > gcc/testsuite/ChangeLog: > > * gcc.dg/torture/convert-dfp-2.c: New test. > * gcc.dg/torture/convert-dfp.c: New test. > --- > gcc/testsuite/gcc.dg/torture/convert-dfp-2.c | 45 ++++++++++++++ > gcc/testsuite/gcc.dg/torture/convert-dfp.c | 63 ++++++++++++++++++++ > libgcc/Makefile.in | 9 ++- > libgcc/config/libbid/_dd_to_hf.c | 38 ++++++++++++ > libgcc/config/libbid/_hf_to_dd.c | 36 +++++++++++ > libgcc/config/libbid/_hf_to_sd.c | 36 +++++++++++ > libgcc/config/libbid/_hf_to_td.c | 36 +++++++++++ > libgcc/config/libbid/_sd_to_hf.c | 38 ++++++++++++ > libgcc/config/libbid/_td_to_hf.c | 38 ++++++++++++ > libgcc/config/libbid/bid_gcc_intrinsics.h | 30 +++++++++- > 10 files changed, 364 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/convert-dfp-2.c > create mode 100644 gcc/testsuite/gcc.dg/torture/convert-dfp.c > create mode 100644 libgcc/config/libbid/_dd_to_hf.c > create mode 100644 libgcc/config/libbid/_hf_to_dd.c > create mode 100644 libgcc/config/libbid/_hf_to_sd.c > create mode 100644 libgcc/config/libbid/_hf_to_td.c > create mode 100644 libgcc/config/libbid/_sd_to_hf.c > create mode 100644 libgcc/config/libbid/_td_to_hf.c > > diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c > new file mode 100644 > index 00000000000..3e4ecb57ba6 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c > @@ -0,0 +1,45 @@ > +/* { dg-do run } */ > +/* { dg-require-effective-target float16_runtime } */ > +/* { dg-require-effective-target dfprt } */ > +/* { dg-options "-save-temps" } */ > +/* { dg-add-options float16 } */ > + > +/* Test conversions from DFP to smaller types. */ > + > +_Decimal32 var32; > +_Decimal64 var64; > +_Decimal128 var128; > +_Float16 var16; > + > +void __attribute__ ((__noinline__)) foo32 (_Decimal32 param32) > +{ > + var16 = param32; > +} > + > +void __attribute__ ((__noinline__)) foo64 (_Decimal64 param64) > +{ > + var16 = param64; > + var32 = param64; > +} > + > +void __attribute__ ((__noinline__)) foo128 (_Decimal128 param128) > +{ > + var16 = param128; > + var32 = param128; > + var64 = param128; > +} > + > +int main () > +{ > + foo32 (var32); > + foo64 (var64); > + foo128 (var128); > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\t__bid_truncsdhf} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_truncddhf} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_truncddsd2} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_trunctdhf} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_trunctdsd2} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_trunctddd2} 2 { target { dfp_bid } } } } */ > diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp.c b/gcc/testsuite/gcc.dg/torture/convert-dfp.c > new file mode 100644 > index 00000000000..ec136896ca7 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp.c > @@ -0,0 +1,63 @@ > +/* { dg-do run } */ > +/* { dg-require-effective-target float16_runtime } */ > +/* { dg-require-effective-target dfprt } */ > +/* { dg-options "-save-temps" } */ > +/* { dg-add-options float16 } */ > + > +/* Test conversions to/from DFP values. */ > + > +extern void abort (); > + > +_Decimal32 var32 = 1.2df; > + > +int __attribute__ ((__noinline__)) foo32 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) > +{ > + return (param32 == var32) > + + (param64 == var32) > + + (param128 == var32) > + /* Small enough relative difference? */ > + + ((((_Decimal32)param16 - var32) / var32) < 0.002df); > +} > + > +_Decimal64 var64 = 1.2dd; > + > +int __attribute__ ((__noinline__)) foo64 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) > +{ > + return (param32 == var64) > + + (param64 == var64) > + + (param128 == var64) > + /* Small enough relative difference? */ > + + ((((_Decimal64)param16 - var64) / var64) < 0.002dd); > +} > + > +_Decimal128 var128 = 1.2dl; > + > +int __attribute__ ((__noinline__)) foo128 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) > +{ > + return (param32 == var128) > + + (param64 == var128) > + + (param128 == var128) > + /* Small enough relative difference? */ > + + ((((_Decimal128)param16 - var128) / var128) < 0.002dl); > +} > + > +int main() > +{ > + if (foo32 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) > + abort (); > + > + if (foo64 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) > + abort (); > + > + if (foo128 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) > + abort (); > + > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\t__bid_extendsddd2} 3 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_extendsdtd2} 3 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_extendddtd2} 3 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_extendhfsd} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_extendhfdd} 2 { target { dfp_bid } } } } */ > +/* { dg-final { scan-assembler-times {\t__bid_extendhftd} 2 { target { dfp_bid } } } } */ > diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in > index 09b3ec8bc2e..1fe708a93f7 100644 > --- a/libgcc/Makefile.in > +++ b/libgcc/Makefile.in > @@ -677,7 +677,8 @@ D32PBIT_FUNCS = _addsub_sd _div_sd _mul_sd _plus_sd _minus_sd \ > _si_to_sd _di_to_sd _usi_to_sd _udi_to_sd \ > _sd_to_sf _sd_to_df _sd_to_xf _sd_to_tf \ > _sf_to_sd _df_to_sd _xf_to_sd _tf_to_sd \ > - _sd_to_dd _sd_to_td _unord_sd _conv_sd > + _sd_to_dd _sd_to_td _unord_sd _conv_sd \ > + _hf_to_sd _sd_to_hf > > D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \ > _eq_dd _ne_dd _lt_dd _gt_dd _le_dd _ge_dd \ > @@ -685,7 +686,8 @@ D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \ > _si_to_dd _di_to_dd _usi_to_dd _udi_to_dd \ > _dd_to_sf _dd_to_df _dd_to_xf _dd_to_tf \ > _sf_to_dd _df_to_dd _xf_to_dd _tf_to_dd \ > - _dd_to_sd _dd_to_td _unord_dd _conv_dd > + _dd_to_sd _dd_to_td _unord_dd _conv_dd \ > + _hf_to_dd _dd_to_hf > > D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \ > _eq_td _ne_td _lt_td _gt_td _le_td _ge_td \ > @@ -693,7 +695,8 @@ D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \ > _si_to_td _di_to_td _usi_to_td _udi_to_td \ > _td_to_sf _td_to_df _td_to_xf _td_to_tf \ > _sf_to_td _df_to_td _xf_to_td _tf_to_td \ > - _td_to_sd _td_to_dd _unord_td _conv_td > + _td_to_sd _td_to_dd _unord_td _conv_td \ > + _hf_to_td _td_to_hf > > ifeq ($(enable_decimal_float),bid) > ifneq ($(D32PBIT),) > diff --git a/libgcc/config/libbid/_dd_to_hf.c b/libgcc/config/libbid/_dd_to_hf.c > new file mode 100644 > index 00000000000..5e58288391e > --- /dev/null > +++ b/libgcc/config/libbid/_dd_to_hf.c > @@ -0,0 +1,38 @@ > +/* Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +#include "bid_conf.h" > +#include "bid_functions.h" > +#include "bid_gcc_intrinsics.h" > + > +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE > +HFtype > +__bid_truncddhf (_Decimal64 x) { > + HFtype res; > + union decimal64 ux; > + > + ux.d = x; > + res = __bid64_to_binary32 (ux.i); > + return (res); > +} > +#endif > diff --git a/libgcc/config/libbid/_hf_to_dd.c b/libgcc/config/libbid/_hf_to_dd.c > new file mode 100644 > index 00000000000..f85100e24f8 > --- /dev/null > +++ b/libgcc/config/libbid/_hf_to_dd.c > @@ -0,0 +1,36 @@ > +/* Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +#include "bid_conf.h" > +#include "bid_functions.h" > +#include "bid_gcc_intrinsics.h" > + > +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE > +_Decimal64 > +__bid_extendhfdd (HFtype x) { > + union decimal64 res; > + SFtype xsf = x; > + res.i = __binary32_to_bid64 (xsf); > + return (res.d); > +} > +#endif > diff --git a/libgcc/config/libbid/_hf_to_sd.c b/libgcc/config/libbid/_hf_to_sd.c > new file mode 100644 > index 00000000000..285b80c6e05 > --- /dev/null > +++ b/libgcc/config/libbid/_hf_to_sd.c > @@ -0,0 +1,36 @@ > +/* Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +#include "bid_conf.h" > +#include "bid_functions.h" > +#include "bid_gcc_intrinsics.h" > + > +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE > +_Decimal32 > +__bid_extendhfsd (HFtype x) { > + union decimal32 res; > + SFtype xsf = x; > + res.i = __binary32_to_bid32 (xsf); > + return (res.d); > +} > +#endif > diff --git a/libgcc/config/libbid/_hf_to_td.c b/libgcc/config/libbid/_hf_to_td.c > new file mode 100644 > index 00000000000..99b661ec727 > --- /dev/null > +++ b/libgcc/config/libbid/_hf_to_td.c > @@ -0,0 +1,36 @@ > +/* Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +#include "bid_conf.h" > +#include "bid_functions.h" > +#include "bid_gcc_intrinsics.h" > + > +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE > +_Decimal128 > +__bid_extendhftd (HFtype x) { > + union decimal128 res; > + SFtype xsf = x; > + res.i = __binary32_to_bid128 (xsf); > + return (res.d); > +} > +#endif > diff --git a/libgcc/config/libbid/_sd_to_hf.c b/libgcc/config/libbid/_sd_to_hf.c > new file mode 100644 > index 00000000000..e4e3125d49b > --- /dev/null > +++ b/libgcc/config/libbid/_sd_to_hf.c > @@ -0,0 +1,38 @@ > +/* Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +#include "bid_conf.h" > +#include "bid_functions.h" > +#include "bid_gcc_intrinsics.h" > + > +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE > +HFtype > +__bid_truncsdhf (_Decimal32 x) { > + HFtype res; > + union decimal32 ux; > + > + ux.d = x; > + res = __bid32_to_binary32 (ux.i); > + return (res); > +} > +#endif > diff --git a/libgcc/config/libbid/_td_to_hf.c b/libgcc/config/libbid/_td_to_hf.c > new file mode 100644 > index 00000000000..c4ebe586db0 > --- /dev/null > +++ b/libgcc/config/libbid/_td_to_hf.c > @@ -0,0 +1,38 @@ > +/* Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +#include "bid_conf.h" > +#include "bid_functions.h" > +#include "bid_gcc_intrinsics.h" > + > +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE > +HFtype > +__bid_trunctdhf (_Decimal128 x) { > + HFtype res; > + union decimal128 ux; > + > + ux.d = x; > + res = __bid128_to_binary32 (ux.i); > + return (res); > +} > +#endif > diff --git a/libgcc/config/libbid/bid_gcc_intrinsics.h b/libgcc/config/libbid/bid_gcc_intrinsics.h > index b0a23debc15..15c050764ac 100644 > --- a/libgcc/config/libbid/bid_gcc_intrinsics.h > +++ b/libgcc/config/libbid/bid_gcc_intrinsics.h > @@ -31,6 +31,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > #include "tm.h" > #include "libgcc_tm.h" > > +#ifdef __LIBGCC_HAS_HF_MODE__ > +#define LIBGCC2_HAS_HF_MODE 1 > +#else > +#define LIBGCC2_HAS_HF_MODE 0 > +#endif > + > #ifdef __LIBGCC_HAS_XF_MODE__ > #define LIBGCC2_HAS_XF_MODE 1 > #else > @@ -43,6 +49,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > #define LIBGCC2_HAS_TF_MODE 0 > #endif > > +#ifndef BID_HAS_HF_MODE > +#define BID_HAS_HF_MODE LIBGCC2_HAS_HF_MODE > +#endif > + > #ifndef BID_HAS_XF_MODE > #define BID_HAS_XF_MODE LIBGCC2_HAS_XF_MODE > #endif > @@ -53,6 +63,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > > /* Some handy typedefs. */ > > +#if LIBGCC2_HAS_HF_MODE > +typedef float HFtype __attribute__ ((mode (HF))); > +#endif /* LIBGCC2_HAS_HF_MODE */ > typedef float SFtype __attribute__ ((mode (SF))); > typedef float DFtype __attribute__ ((mode (DF))); > #if LIBGCC2_HAS_XF_MODE > @@ -98,6 +111,12 @@ typedef __attribute__ ((aligned(16))) struct > #endif > #endif > > +#if BID_HAS_HF_MODE > +#ifndef HFtype > +#define HFtype _Float16 > +#endif > +#endif > + > #ifndef SFtype > #define SFtype float > #endif > @@ -110,8 +129,7 @@ typedef __attribute__ ((aligned(16))) struct > #ifndef XFtype > #define XFtype long double > #endif > - > -#endif /* IN_LIBGCC2 */ > +#endif > > #if BID_HAS_TF_MODE > #ifndef TFtype > @@ -249,6 +267,14 @@ extern _Decimal128 __bid_extendxftd (XFtype); > extern int isinfd32 (_Decimal32); > extern int isinfd64 (_Decimal64); > extern int isinfd128 (_Decimal128); > +#if BID_HAS_HF_MODE > +extern _Decimal32 __bid_extendhfsd (HFtype); > +extern _Decimal64 __bid_extendhfdd (HFtype); > +extern _Decimal128 __bid_extendhftd (HFtype); > +extern HFtype __bid_truncsdhf (_Decimal32); > +extern HFtype __bid_truncddhf (_Decimal64); > +extern HFtype __bid_trunctdhf (_Decimal128); > +#endif > #endif /* BID_HAS_GCC_DECIMAL_INTRINSICS */ > > extern void __dfp_set_round (int);
On Thu, 19 May 2022, Christophe Lyon via Gcc-patches wrote: > Hi Joseph, > > May I ping you on this version? (I've moved the tests to gcc.dg/torture/ and > checked they work on aarch64 and x86_64. This version is OK, given a bug report filed in Bugzilla for the double-rounding issues with conversions from DFP modes to HFmode.
On 5/19/22 21:35, Joseph Myers wrote: > On Thu, 19 May 2022, Christophe Lyon via Gcc-patches wrote: > >> Hi Joseph, >> >> May I ping you on this version? (I've moved the tests to gcc.dg/torture/ and >> checked they work on aarch64 and x86_64. > > This version is OK, given a bug report filed in Bugzilla for the > double-rounding issues with conversions from DFP modes to HFmode. > Thanks! I've filed PR 105669. Christophe
diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c new file mode 100644 index 00000000000..3e4ecb57ba6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-require-effective-target dfprt } */ +/* { dg-options "-save-temps" } */ +/* { dg-add-options float16 } */ + +/* Test conversions from DFP to smaller types. */ + +_Decimal32 var32; +_Decimal64 var64; +_Decimal128 var128; +_Float16 var16; + +void __attribute__ ((__noinline__)) foo32 (_Decimal32 param32) +{ + var16 = param32; +} + +void __attribute__ ((__noinline__)) foo64 (_Decimal64 param64) +{ + var16 = param64; + var32 = param64; +} + +void __attribute__ ((__noinline__)) foo128 (_Decimal128 param128) +{ + var16 = param128; + var32 = param128; + var64 = param128; +} + +int main () +{ + foo32 (var32); + foo64 (var64); + foo128 (var128); + return 0; +} + +/* { dg-final { scan-assembler-times {\t__bid_truncsdhf} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_truncddhf} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_truncddsd2} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_trunctdhf} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_trunctdsd2} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_trunctddd2} 2 { target { dfp_bid } } } } */ diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp.c b/gcc/testsuite/gcc.dg/torture/convert-dfp.c new file mode 100644 index 00000000000..ec136896ca7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp.c @@ -0,0 +1,63 @@ +/* { dg-do run } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-require-effective-target dfprt } */ +/* { dg-options "-save-temps" } */ +/* { dg-add-options float16 } */ + +/* Test conversions to/from DFP values. */ + +extern void abort (); + +_Decimal32 var32 = 1.2df; + +int __attribute__ ((__noinline__)) foo32 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) +{ + return (param32 == var32) + + (param64 == var32) + + (param128 == var32) + /* Small enough relative difference? */ + + ((((_Decimal32)param16 - var32) / var32) < 0.002df); +} + +_Decimal64 var64 = 1.2dd; + +int __attribute__ ((__noinline__)) foo64 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) +{ + return (param32 == var64) + + (param64 == var64) + + (param128 == var64) + /* Small enough relative difference? */ + + ((((_Decimal64)param16 - var64) / var64) < 0.002dd); +} + +_Decimal128 var128 = 1.2dl; + +int __attribute__ ((__noinline__)) foo128 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) +{ + return (param32 == var128) + + (param64 == var128) + + (param128 == var128) + /* Small enough relative difference? */ + + ((((_Decimal128)param16 - var128) / var128) < 0.002dl); +} + +int main() +{ + if (foo32 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) + abort (); + + if (foo64 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) + abort (); + + if (foo128 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler-times {\t__bid_extendsddd2} 3 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendsdtd2} 3 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendddtd2} 3 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendhfsd} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendhfdd} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendhftd} 2 { target { dfp_bid } } } } */ diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 09b3ec8bc2e..1fe708a93f7 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -677,7 +677,8 @@ D32PBIT_FUNCS = _addsub_sd _div_sd _mul_sd _plus_sd _minus_sd \ _si_to_sd _di_to_sd _usi_to_sd _udi_to_sd \ _sd_to_sf _sd_to_df _sd_to_xf _sd_to_tf \ _sf_to_sd _df_to_sd _xf_to_sd _tf_to_sd \ - _sd_to_dd _sd_to_td _unord_sd _conv_sd + _sd_to_dd _sd_to_td _unord_sd _conv_sd \ + _hf_to_sd _sd_to_hf D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \ _eq_dd _ne_dd _lt_dd _gt_dd _le_dd _ge_dd \ @@ -685,7 +686,8 @@ D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \ _si_to_dd _di_to_dd _usi_to_dd _udi_to_dd \ _dd_to_sf _dd_to_df _dd_to_xf _dd_to_tf \ _sf_to_dd _df_to_dd _xf_to_dd _tf_to_dd \ - _dd_to_sd _dd_to_td _unord_dd _conv_dd + _dd_to_sd _dd_to_td _unord_dd _conv_dd \ + _hf_to_dd _dd_to_hf D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \ _eq_td _ne_td _lt_td _gt_td _le_td _ge_td \ @@ -693,7 +695,8 @@ D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \ _si_to_td _di_to_td _usi_to_td _udi_to_td \ _td_to_sf _td_to_df _td_to_xf _td_to_tf \ _sf_to_td _df_to_td _xf_to_td _tf_to_td \ - _td_to_sd _td_to_dd _unord_td _conv_td + _td_to_sd _td_to_dd _unord_td _conv_td \ + _hf_to_td _td_to_hf ifeq ($(enable_decimal_float),bid) ifneq ($(D32PBIT),) diff --git a/libgcc/config/libbid/_dd_to_hf.c b/libgcc/config/libbid/_dd_to_hf.c new file mode 100644 index 00000000000..5e58288391e --- /dev/null +++ b/libgcc/config/libbid/_dd_to_hf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "bid_conf.h" +#include "bid_functions.h" +#include "bid_gcc_intrinsics.h" + +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE +HFtype +__bid_truncddhf (_Decimal64 x) { + HFtype res; + union decimal64 ux; + + ux.d = x; + res = __bid64_to_binary32 (ux.i); + return (res); +} +#endif diff --git a/libgcc/config/libbid/_hf_to_dd.c b/libgcc/config/libbid/_hf_to_dd.c new file mode 100644 index 00000000000..f85100e24f8 --- /dev/null +++ b/libgcc/config/libbid/_hf_to_dd.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "bid_conf.h" +#include "bid_functions.h" +#include "bid_gcc_intrinsics.h" + +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE +_Decimal64 +__bid_extendhfdd (HFtype x) { + union decimal64 res; + SFtype xsf = x; + res.i = __binary32_to_bid64 (xsf); + return (res.d); +} +#endif diff --git a/libgcc/config/libbid/_hf_to_sd.c b/libgcc/config/libbid/_hf_to_sd.c new file mode 100644 index 00000000000..285b80c6e05 --- /dev/null +++ b/libgcc/config/libbid/_hf_to_sd.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "bid_conf.h" +#include "bid_functions.h" +#include "bid_gcc_intrinsics.h" + +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE +_Decimal32 +__bid_extendhfsd (HFtype x) { + union decimal32 res; + SFtype xsf = x; + res.i = __binary32_to_bid32 (xsf); + return (res.d); +} +#endif diff --git a/libgcc/config/libbid/_hf_to_td.c b/libgcc/config/libbid/_hf_to_td.c new file mode 100644 index 00000000000..99b661ec727 --- /dev/null +++ b/libgcc/config/libbid/_hf_to_td.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "bid_conf.h" +#include "bid_functions.h" +#include "bid_gcc_intrinsics.h" + +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE +_Decimal128 +__bid_extendhftd (HFtype x) { + union decimal128 res; + SFtype xsf = x; + res.i = __binary32_to_bid128 (xsf); + return (res.d); +} +#endif diff --git a/libgcc/config/libbid/_sd_to_hf.c b/libgcc/config/libbid/_sd_to_hf.c new file mode 100644 index 00000000000..e4e3125d49b --- /dev/null +++ b/libgcc/config/libbid/_sd_to_hf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "bid_conf.h" +#include "bid_functions.h" +#include "bid_gcc_intrinsics.h" + +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE +HFtype +__bid_truncsdhf (_Decimal32 x) { + HFtype res; + union decimal32 ux; + + ux.d = x; + res = __bid32_to_binary32 (ux.i); + return (res); +} +#endif diff --git a/libgcc/config/libbid/_td_to_hf.c b/libgcc/config/libbid/_td_to_hf.c new file mode 100644 index 00000000000..c4ebe586db0 --- /dev/null +++ b/libgcc/config/libbid/_td_to_hf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "bid_conf.h" +#include "bid_functions.h" +#include "bid_gcc_intrinsics.h" + +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE +HFtype +__bid_trunctdhf (_Decimal128 x) { + HFtype res; + union decimal128 ux; + + ux.d = x; + res = __bid128_to_binary32 (ux.i); + return (res); +} +#endif diff --git a/libgcc/config/libbid/bid_gcc_intrinsics.h b/libgcc/config/libbid/bid_gcc_intrinsics.h index b0a23debc15..15c050764ac 100644 --- a/libgcc/config/libbid/bid_gcc_intrinsics.h +++ b/libgcc/config/libbid/bid_gcc_intrinsics.h @@ -31,6 +31,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "tm.h" #include "libgcc_tm.h" +#ifdef __LIBGCC_HAS_HF_MODE__ +#define LIBGCC2_HAS_HF_MODE 1 +#else +#define LIBGCC2_HAS_HF_MODE 0 +#endif + #ifdef __LIBGCC_HAS_XF_MODE__ #define LIBGCC2_HAS_XF_MODE 1 #else @@ -43,6 +49,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define LIBGCC2_HAS_TF_MODE 0 #endif +#ifndef BID_HAS_HF_MODE +#define BID_HAS_HF_MODE LIBGCC2_HAS_HF_MODE +#endif + #ifndef BID_HAS_XF_MODE #define BID_HAS_XF_MODE LIBGCC2_HAS_XF_MODE #endif @@ -53,6 +63,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Some handy typedefs. */ +#if LIBGCC2_HAS_HF_MODE +typedef float HFtype __attribute__ ((mode (HF))); +#endif /* LIBGCC2_HAS_HF_MODE */ typedef float SFtype __attribute__ ((mode (SF))); typedef float DFtype __attribute__ ((mode (DF))); #if LIBGCC2_HAS_XF_MODE @@ -98,6 +111,12 @@ typedef __attribute__ ((aligned(16))) struct #endif #endif +#if BID_HAS_HF_MODE +#ifndef HFtype +#define HFtype _Float16 +#endif +#endif + #ifndef SFtype #define SFtype float #endif @@ -110,8 +129,7 @@ typedef __attribute__ ((aligned(16))) struct #ifndef XFtype #define XFtype long double #endif - -#endif /* IN_LIBGCC2 */ +#endif #if BID_HAS_TF_MODE #ifndef TFtype @@ -249,6 +267,14 @@ extern _Decimal128 __bid_extendxftd (XFtype); extern int isinfd32 (_Decimal32); extern int isinfd64 (_Decimal64); extern int isinfd128 (_Decimal128); +#if BID_HAS_HF_MODE +extern _Decimal32 __bid_extendhfsd (HFtype); +extern _Decimal64 __bid_extendhfdd (HFtype); +extern _Decimal128 __bid_extendhftd (HFtype); +extern HFtype __bid_truncsdhf (_Decimal32); +extern HFtype __bid_truncddhf (_Decimal64); +extern HFtype __bid_trunctdhf (_Decimal128); +#endif #endif /* BID_HAS_GCC_DECIMAL_INTRINSICS */ extern void __dfp_set_round (int);