On Fri, 26 Mar 2021 23:14:41 +0000 Patrick McGehearty via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
> diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c > index 9f993c4..c0d9e57 100644 > --- a/gcc/c-family/c-cppbuiltin.c > +++ b/gcc/c-family/c-cppbuiltin.c > @@ -1277,8 +1277,10 @@ c_cpp_builtins (cpp_reader *pfile) > { > scalar_float_mode mode = mode_iter.require (); > const char *name = GET_MODE_NAME (mode); > + const int name_len = strlen (name); strlen returns a size_t Funny that we do not have a pre-seeded mode_name_len array but call strlen on modes over and over again. > + char float_h_prefix[16] = ""; > char *macro_name > - = (char *) alloca (strlen (name) > + = (char *) alloca (name_len > + sizeof ("__LIBGCC__MANT_DIG__")); > sprintf (macro_name, "__LIBGCC_%s_MANT_DIG__", name); > builtin_define_with_int_value (macro_name, > @@ -1286,20 +1288,29 @@ c_cpp_builtins (cpp_reader *pfile) > if (!targetm.scalar_mode_supported_p (mode) > || !targetm.libgcc_floating_mode_supported_p (mode)) > continue; > - macro_name = (char *) alloca (strlen (name) > + macro_name = (char *) alloca (name_len > + sizeof ("__LIBGCC_HAS__MODE__")); > sprintf (macro_name, "__LIBGCC_HAS_%s_MODE__", name); > cpp_define (pfile, macro_name); > - macro_name = (char *) alloca (strlen (name) > + macro_name = (char *) alloca (name_len > + sizeof ("__LIBGCC__FUNC_EXT__")); > sprintf (macro_name, "__LIBGCC_%s_FUNC_EXT__", name); The above should have been split out as separate independent patchlet to get it out of the way. As noted already the use of alloca is a pre-existing (coding-style) bug and we should use XALLOCAVEC or appropriately sized fixed buffers to begin with. The amount of alloca in defining all these is amazing. > diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/cdivchkd.c > b/gcc/testsuite/gcc.c-torture/execute/ieee/cdivchkd.c > new file mode 100644 > index 0000000..409123f > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/cdivchkd.c > @@ -0,0 +1,126 @@ > +/* > + Program to test complex divide for correct results on selected values. > + Checking known failure points. > +*/ > + > +#include <float.h> > + > +extern void abort (); > +extern void exit (); As Joseph pointed out in the v8 review already, please use prototyped function declarations in all new tests. > diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/cdivchkld.c > b/gcc/testsuite/gcc.c-torture/execute/ieee/cdivchkld.c > new file mode 100644 > index 0000000..28d707d > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/cdivchkld.c > @@ -0,0 +1,167 @@ > +/* > + Program to test complex divide for correct results on selected values. > + Checking known failure points. > +*/ > + > +#include <float.h> > + > +extern void abort (); > +extern void exit (); Likewise. > +#if (LDBL_MAX_EXP < 2048) > + /* > + Test values when mantissa is 11 or fewer bits. Either LDBL is > + using DBL on this platform or we are using IBM extended double > + precision Test values will be automatically trucated the available > + precision. s/trucated/truncated/g; # with an 'n' I have trouble parsing the sentence nevertheless. There might be a missing "which" somewhere and maybe a "to"? > +#else > + /* > + Test values intended for either IEEE128 or Intel80 formats. In > + either case, 15 bits of exponent are available. Test values will > + be automatically trucated the available precision. > + */ again, truNcated and a couple of words missing? > diff --git a/libgcc/config/rs6000/_divkc3.c b/libgcc/config/rs6000/_divkc3.c > index d261f40..f57e14f 100644 > --- a/libgcc/config/rs6000/_divkc3.c > +++ b/libgcc/config/rs6000/_divkc3.c > @@ -37,31 +37,118 @@ see the files COPYING3 and COPYING.RUNTIME respectively. > If not, see > #define __divkc3 __divkc3_sw > #endif > > +#define RBIG (__LIBGCC_TF_MAX__ / 2) > +#define RMIN (__LIBGCC_TF_MIN__) > +#define RMIN2 (__LIBGCC_TF_EPSILON__) > +#define RMINSCAL (1 / __LIBGCC_TF_EPSILON__) > +#define RMAX2 (RBIG * RMIN2) > + > + > TCtype > __divkc3 (TFtype a, TFtype b, TFtype c, TFtype d) > { > TFtype denom, ratio, x, y; > TCtype res; > > - /* ??? We can get better behavior from logarithmic scaling instead of > - the division. But that would mean starting to link libgcc against > - libm. We could implement something akin to ldexp/frexp as gcc builtins > - fairly easily... */ > + /* long double has significant potential underflow/overflow errors than > + can be greatly reduced with a limited number of tests and adjustments. > + */ "than" doesn't parse. that? > else > { > + /* Prevent underflow when denominator is near max representable. */ > + if (FABS (c) >= RBIG) > + { > + a = a / 2; > + b = b / 2; > + c = c / 2; > + d = d / 2; > + } > + /* Avoid overflow/underflow issues when both c and d are small. > + Scaling up helps avoid some underflows. > + No new overflow possible since both c&d are less than RMIN2. */ > + if (FABS (c) < RMIN2) > + { > + a = a * RMINSCAL; > + b = b * RMINSCAL; > + c = c * RMINSCAL; > + d = d * RMINSCAL; > + } > + else > + { > + if (((FABS (a) < RMIN) && (FABS (b) < RMAX2) && (FABS (c) < RMAX2)) > + || ((FABS (b) < RMIN) && (FABS (a) < RMAX2) > + && (FABS (c) < RMAX2))) > + { > + a = a * RMINSCAL; > + b = b * RMINSCAL; > + c = c * RMINSCAL; > + d = d * RMINSCAL; > + } > + } > ratio = d / c; > denom = (d * ratio) + c; > - x = ((b * ratio) + a) / denom; > - y = (b - (a * ratio)) / denom; > + /* Choose alternate order of computation if ratio is subnormal. */ > + if (FABS (ratio) > RMIN) > + { > + x = ((b * ratio) + a) / denom; > + y = (b - (a * ratio)) / denom; > + } > + else > + { > + x = (a + (d * (b / c))) / denom; > + y = (b - (d * (a / c))) / denom; > + } > } > > + spurious whitespace change above. > /* Recover infinities and zeros that computed as NaN+iNaN; the only cases > are nonzero/zero, infinite/finite, and finite/infinite. */ > if (isnan (x) && isnan (y)) > diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c > index 17de0a7..42fd07a 100644 > --- a/libgcc/libgcc2.c > +++ b/libgcc/libgcc2.c > @@ -1860,33 +1860,57 @@ NAME (TYPE x, int m) > #if defined(L_mulhc3) || defined(L_divhc3) > # define MTYPE HFtype > # define CTYPE HCtype > +# define XMTYPE SFtype > +# define XCTYPE SCtype X sounds pretty extended while it's "just" SF. Doesn't matter much though. > # define MODE hc > # define CEXT __LIBGCC_HF_FUNC_EXT__ > # define NOTRUNC (!__LIBGCC_HF_EXCESS_PRECISION__) > #elif defined(L_mulsc3) || defined(L_divsc3) > # define MTYPE SFtype > # define CTYPE SCtype > +# define XMTYPE DFtype > +# define XCTYPE DCtype likewise. > @@ -1994,30 +2018,136 @@ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, > MTYPE d) > CTYPE > CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) > { > +#if defined(L_divhc3) \ > + || (defined(L_divsc3) && defined(__LIBGCC_HAVE_HWDBL__) ) > + > + /* Half precision is handled with float precision. > + float is handled with double precision when double precision > + hardware is available. > + Due to the additional precision, the simple complex divide > + method (without Smith's method) is sufficient to get accurate > + answers and runs slightly faster than Smith's method. */ > + > + XMTYPE aa, bb, cc, dd; > + XMTYPE denom; > + MTYPE x, y; > + CTYPE res; > + aa = a; > + bb = b; > + cc = c; > + dd = d; > + > + denom = (cc * cc) + (dd * dd); > + x = ((aa * cc) + (bb * dd)) / denom; > + y = ((bb * cc) - (aa * dd)) / denom; > + > +#else > MTYPE denom, ratio, x, y; > CTYPE res; > > - /* ??? We can get better behavior from logarithmic scaling instead of > - the division. But that would mean starting to link libgcc against > - libm. We could implement something akin to ldexp/frexp as gcc builtins > - fairly easily... */ > + /* double, extended, long double have significant potential > + underflow/overflow errors than can be greatly reduced with "than" ? thanks,