Hi Joseph, could you please have a look at this latest version of the patch introducing fadd et al.? There already is a pre-approved folllow-up somewhere expanding it on power but we need to get this in first.
Thanks, Martin On Wed, Sep 11 2019, Tejas Joshi wrote: > Hi. > This patch includes implementation of fadd, faddl, daddl functions. > The patch boostraps on x86_64-linux-gnu and passes regression tests. > > Thanks, > Tejas > > gcc/ChangeLog: > > 2019-09-11 Tejas Joshi <tejasjoshi9...@gmail.com> > > * builtin-types.def: Define narrowing function types. > * builtins.def: Define fadd variants builtin functions. > * fold-const-call.c (fold_const_narrow_binary): New. Folding calls > and conditions for standard arithmetic functions. > (fold_const_call): Add case for fadd variants. > > gcc/testsuite/ChangeLog: > > 2019-09-11 Tejas Joshi <tejasjoshi9...@gmail.com> > > * gcc.dg/builtin-fadd-1.c: New test. > * gcc.dg/builtin-fadd-2.c: New test. > * gcc.dg/builtin-fadd-3.c: New test. > * gcc.dg/builtin-fadd-4.c: New test. > * gcc.dg/builtin-fadd-5.c: New test. > * gcc.dg/builtin-fadd-6.c: New test. > diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def > index e5c9e063c48..6bc552fa71a 100644 > --- a/gcc/builtin-types.def > +++ b/gcc/builtin-types.def > @@ -387,8 +387,14 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_PTR, > BT_VOID, BT_UINT, BT_PTR) > DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOAT, > BT_FLOAT, BT_FLOAT, BT_FLOAT) > +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_DOUBLE_DOUBLE, > + BT_FLOAT, BT_DOUBLE, BT_DOUBLE) > +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_LONGDOUBLE_LONGDOUBLE, > + BT_FLOAT, BT_LONGDOUBLE, BT_LONGDOUBLE) > DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE, > BT_DOUBLE, BT_DOUBLE, BT_DOUBLE) > +DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_LONGDOUBLE_LONGDOUBLE, > + BT_DOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE) > DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, > BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE) > DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT16_FLOAT16_FLOAT16, > diff --git a/gcc/builtins.def b/gcc/builtins.def > index 8bb7027aac7..2df616c477e 100644 > --- a/gcc/builtins.def > +++ b/gcc/builtins.def > @@ -355,6 +355,9 @@ DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", > FABS_TYPE, ATTR_CONST_NOT > DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", > BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", > BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", > BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) > +DEF_EXT_LIB_BUILTIN (BUILT_IN_FADD, "fadd", BT_FN_FLOAT_DOUBLE_DOUBLE, > ATTR_CONST_NOTHROW_LEAF_LIST) > +DEF_EXT_LIB_BUILTIN (BUILT_IN_FADDL, "faddl", > BT_FN_FLOAT_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) > +DEF_EXT_LIB_BUILTIN (BUILT_IN_DADDL, "daddl", > BT_FN_DOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) > DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, > ATTR_MATHFN_FPROUNDING_ERRNO) > DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, > ATTR_MATHFN_FPROUNDING_ERRNO) > DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", > BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) > diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c > index 3a14d2a41c1..f6b4508a101 100644 > --- a/gcc/fold-const-call.c > +++ b/gcc/fold-const-call.c > @@ -570,6 +570,44 @@ fold_const_nextafter (real_value *result, const > real_value *arg0, > return true; > } > > +/* Try to evaluate: > + > + *RESULT = add (*ARG0, *ARG1) > + > + in format FORMAT. Return true on success. */ > + > +static bool > +fold_const_narrow_binary (real_value *result, const real_value *arg0, > + int icode, const real_value *arg1, > + const real_format *format) > +{ > + if (REAL_VALUE_ISSIGNALING_NAN (*arg0) > + || REAL_VALUE_ISSIGNALING_NAN (*arg1)) > + return false; > + > + real_arithmetic (result, icode, arg0, arg1); > + /* Underflow condition. */ > + if (flag_errno_math > + && result->cl == rvc_normal > + && REAL_EXP (result) < format->emin) > + return false; > + > + if (!exact_real_truncate (format, result) > + && (flag_rounding_math || flag_trapping_math)) > + return false; > + > + real_convert (result, format, result); > + /* Overflow condition. */ > + if (!real_isfinite (result) && flag_errno_math) > + return false; > + > + if (REAL_VALUE_ISNAN (*result) > + && (flag_errno_math || flag_trapping_math)) > + return false; > + > + return true; > +} > + > /* Try to evaluate: > > *RESULT = ldexp (*ARG0, ARG1) > @@ -1674,6 +1712,25 @@ fold_const_call (combined_fn fn, tree type, tree arg0, > tree arg1) > case CFN_FOLD_LEFT_PLUS: > return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR); > > + case CFN_BUILT_IN_FADD: > + case CFN_BUILT_IN_FADDL: > + case CFN_BUILT_IN_DADDL: > + { > + if (real_cst_p (arg0) > + && real_cst_p (arg1)) > + { > + machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); > + gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); > + REAL_VALUE_TYPE result; > + machine_mode mode = TYPE_MODE (type); > + if (fold_const_narrow_binary (&result, TREE_REAL_CST_PTR (arg0), > + PLUS_EXPR, TREE_REAL_CST_PTR (arg1), > + REAL_MODE_FORMAT (mode))) > + return build_real (type, result); > + } > + } > + return NULL_TREE; > + > default: > return fold_const_call_1 (fn, type, arg0, arg1); > } > diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-1.c > b/gcc/testsuite/gcc.dg/builtin-fadd-1.c > new file mode 100644 > index 00000000000..66280e9f72b > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/builtin-fadd-1.c > @@ -0,0 +1,54 @@ > +/* { dg-do link } */ > +/* { dg-options "-O2 -fno-trapping-math" } */ > + > +extern int link_error (int); > + > +#define TEST(FN, VAL1, VAL2, RESULT) \ > + if (__builtin_##FN (VAL1, VAL2) != RESULT) link_error (__LINE__); > + > +int > +main (void) > +{ > + TEST(fadd, 0, 0, 0.0F); > + TEST(fadd, 1, -1, 0.0F); > + TEST(fadd, -1, -1.5, -2.5F); > + TEST(fadd, 1.4, 1.6, 3.0F); > + TEST(fadd, 2.5, 1.5, 4.0F); > + > + TEST(fadd, 1, 1.1, 2.1F); > + TEST(fadd, 2, 4.3, 6.3F); > + TEST(fadd, -3, -3.6, -6.6F); > + TEST(fadd, 8, 0.8, 8.8F); > + > + if (__builtin_fadd (0x1.000001p0, __FLT_MIN__) > + == (float) (0x1.000001p0 + __FLT_MIN__)) > + link_error (__LINE__); > + > + TEST(faddl, 0.0L, 0.0L, 0.0F); > + TEST(faddl, 1.0L, -1.0L, 0.0F); > + TEST(faddl, -1.0L, -1.5L, -2.5F); > + TEST(faddl, 1.4L, 1.6L, 3.0F); > + TEST(faddl, 2.5L, 1.5L, 4.0F); > + > + TEST(faddl, 1.0L, 1.1L, 2.1F); > + TEST(faddl, 2.0L, 4.3L, 6.3F); > + TEST(faddl, -3.0L, -3.6L, -6.6F); > + TEST(faddl, 8.0L, 0.8L, 8.8F); > + > + if (__builtin_faddl (0x1.000001p0, __FLT_MIN__) > + == (float) (0x1.000001p0 + __FLT_MIN__)) > + link_error (__LINE__); > + > + TEST(daddl, 0L, 0L, 0.0); > + TEST(daddl, 1.0L, -1.0L, 0.0); > + TEST(daddl, -1.0L, -1.5L, -2.5); > + TEST(daddl, 1.4L, 1.6L, 3.0); > + TEST(daddl, 2.5L, 1.5L, 4.0); > + > + TEST(daddl, 1.0L, 1.1L, 2.1); > + TEST(daddl, 2.0L, 4.3L, 6.3); > + TEST(daddl, -3.0L, -3.6L, -6.6); > + TEST(daddl, 8.0L, 0.8L, 8.8); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-2.c > b/gcc/testsuite/gcc.dg/builtin-fadd-2.c > new file mode 100644 > index 00000000000..006f1c6d21b > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/builtin-fadd-2.c > @@ -0,0 +1,29 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ > +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ > +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ > + > +#define TEST(FN, VAL1, VAL2, RESULT) \ > + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); > + > +int > +main (void) > +{ > + TEST(fadd, 1, 1.1, 2.1F); > + TEST(fadd, 2, 4.3, 6.3F); > + TEST(fadd, -3, -3.6, -6.6F); > + TEST(fadd, 8, 0.8, 8.8F); > + > + TEST(faddl, 1.0L, 1.1L, 2.1F); > + TEST(faddl, 2.0L, 4.3L, 6.3F); > + TEST(faddl, -3.0L, -3.6L, -6.6F); > + TEST(faddl, 8.0L, 0.8L, 8.8F); > + > + TEST(daddl, 1.0L, 1.1L, 2.1); > + TEST(daddl, 2.0L, 4.3L, 6.3); > + TEST(daddl, -3.0L, -3.6L, -6.6); > + TEST(daddl, 8.0L, 0.8L, 8.8); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-3.c > b/gcc/testsuite/gcc.dg/builtin-fadd-3.c > new file mode 100644 > index 00000000000..dd8a2040cb7 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/builtin-fadd-3.c > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-trapping-math -frounding-math > -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ > +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ > +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ > + > +#define TEST(FN, VAL1, VAL2, RESULT) \ > + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); > + > +#include "builtin-fadd-2.c" > diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-4.c > b/gcc/testsuite/gcc.dg/builtin-fadd-4.c > new file mode 100644 > index 00000000000..9091be49b9b > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/builtin-fadd-4.c > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -frounding-math -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ > +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ > +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ > + > +#define TEST(FN, VAL1, VAL2, RESULT) \ > + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); > + > +#include "builtin-fadd-2.c" > diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-5.c > b/gcc/testsuite/gcc.dg/builtin-fadd-5.c > new file mode 100644 > index 00000000000..ac3b547724c > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/builtin-fadd-5.c > @@ -0,0 +1,26 @@ > +/* { dg-do link } */ > +/* { dg-options "-O2 -fno-trapping-math -fno-math-errno" } */ > + > +extern int link_error (int); > + > +#define TEST(FN, VAL1, VAL2, RESULT) \ > + if (__builtin_##FN (VAL1, VAL2) != RESULT) link_error (__LINE__); > + > +int > +main (void) > +{ > + TEST(fadd, __DBL_MAX__, __DBL_MAX__, __builtin_inff()); > + TEST(fadd, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); > + TEST(fadd, __DBL_MIN__, __DBL_MIN__, 0.0); > + > + TEST(faddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inff()); > + TEST(faddl, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); > + TEST(faddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); > + > + TEST(daddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inf()); > + TEST(daddl, __DBL_MAX__, __DBL_MAX__, __builtin_inf()); > + TEST(daddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); > + > + return 0; > +} > + > diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-6.c > b/gcc/testsuite/gcc.dg/builtin-fadd-6.c > new file mode 100644 > index 00000000000..11c63f06463 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/builtin-fadd-6.c > @@ -0,0 +1,27 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-trapping-math -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ > +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ > +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ > + > +#define TEST(FN, VAL1, VAL2, RESULT) \ > + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); > + > +int > +main (void) > +{ > + TEST(fadd, __DBL_MAX__, __DBL_MAX__, __builtin_inff()); > + TEST(fadd, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); > + TEST(fadd, __DBL_MIN__, __DBL_MIN__, 0.0); > + > + TEST(faddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inff()); > + TEST(faddl, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); > + TEST(faddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); > + > + TEST(daddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inf()); > + TEST(daddl, __DBL_MAX__, __DBL_MAX__, __builtin_inf()); > + TEST(daddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); > + > + return 0; > +} > +