Hi all, I have some doubts regarding narrowing functions. Functions like fadd have different variants like fadd, faddl and daddl. These functions differs from general floating point functions which have float and long double argument types. These functions are defined in builtins.def like floor, floorf and floorl with their respective macros BUILT_IN_FLOOR, BUILT_IN_FLOORF and BUILT_IN_FLOORL. But for fadd, fsub, fmul variants, float is not supposed to be one of the argument types.
Also, CASE_MATHFN and CASE_MATHFN_FLOATN cases in builtins.c expand normal, F and L variants which are assigned to respective fcode built_in_function. This makes any function defined in builtins.def to have F and L variants mandatory. How these narrowing functions are supposed to be handled? Do we define another macro expansion like CASE_MATHFN or have a manual case handling in mathfn_built_in_2? Attached patch is what I have tried so far. Thanks, Tejas On Wed, 10 Jul 2019 at 18:03, Richard Sandiford <richard.sandif...@arm.com> wrote: > > Tejas Joshi <tejasjoshi9...@gmail.com> writes: > > Hello. > > I have added fadd variants in builtins.def. For fadd and faddl > > variants, I had to introduce builtin function types in > > builtin-types.def : > > > > +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) > > > > and used them to define function in builtins.def. At this point, only > > faddf variant is getting called by test program : > > > > int main () > > { > > double z = __builtin_faddf (3.5, 1.4); > > } > > faddf variant is using BT_FN_FLOAT_FLOAT_FLOAT which is already > > defined in builtin-types.def means I need not to introduce it. Why > > fadd and faddl are not getting called in this patch? I don't find any > > other place where these function types needs to be added. > > This is because of: > > if (mode == arg0_mode > && real_cst_p (arg0) > && real_cst_p (arg1)) > > in fold_const_call_1. The reason for that check is that usually > the format passed in to fold_const_call_sss applies to both arguments > and the return type. There's already an exception for CASE_CFN_NEXTTOWARD > though. I guess you'll need something similar here. > > Thanks, > Richard
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.c b/gcc/builtins.c index 8ceb077b0bf..37c4206ec65 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2006,6 +2006,7 @@ mathfn_built_in_2 (tree type, combined_fn fn) CASE_MATHFN (EXP2) CASE_MATHFN (EXPM1) CASE_MATHFN (FABS) + CASE_MATHFN (FADD) CASE_MATHFN (FDIM) CASE_MATHFN_FLOATN (FLOOR) CASE_MATHFN_FLOATN (FMA) diff --git a/gcc/builtins.def b/gcc/builtins.def index 8bb7027aac7..2e749f038be 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -352,6 +352,12 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, AT #define FABS_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) #undef FABS_TYPE +DEF_EXT_LIB_BUILTIN (BUILT_IN_FADD, "fadd", BT_FN_FLOAT_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DADDL, "daddl", BT_FN_DOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FADDL, "faddl", BT_FN_FLOAT_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +#define FADD_TYPE(F) BT_FN_##F##_##F##_##F +DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FADD, "fadd", FADD_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) +#undef FADD_TYPE 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) diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index d9b546e6803..9f0e5510514 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -570,6 +570,16 @@ fold_const_nextafter (real_value *result, const real_value *arg0, return true; } +static bool +fold_const_fadd (real_value* result, const real_value *arg0, + const real_value *arg1, const real_format *format) +{ + if (!real_fadd(result, format, arg0, arg1)) + return true; + else + return false; +} + /* Try to evaluate: *RESULT = ldexp (*ARG0, ARG1) @@ -1366,6 +1376,9 @@ fold_const_call_sss (real_value *result, combined_fn fn, CASE_CFN_NEXTTOWARD: return fold_const_nextafter (result, arg0, arg1, format); + CASE_CFN_FADD: + return fold_const_fadd (result, arg0, arg1, format); + default: return false; } @@ -1500,6 +1513,20 @@ fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1) } return NULL_TREE; } + else if (mode != arg0_mode + && real_cst_p (arg0) + && real_cst_p (arg1)) + { + gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); + REAL_VALUE_TYPE result; + if (arg0_mode == arg1_mode) + { + if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0), + TREE_REAL_CST_PTR (arg1), + REAL_MODE_FORMAT (mode))) + return build_real (type, result); + } + } if (real_cst_p (arg0) && integer_cst_p (arg1)) diff --git a/gcc/real.c b/gcc/real.c index ab71430709f..444ab2e27fc 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -5093,6 +5093,16 @@ real_roundeven (REAL_VALUE_TYPE *r, format_helper fmt, real_round (r, fmt, x); } +bool +real_fadd (REAL_VALUE_TYPE *r, format_helper fmt, + const REAL_VALUE_TYPE *x, const REAL_VALUE_TYPE *y) +{ + do_add (r, x, y, 0); + if (fmt) + real_convert (r, fmt, r); + return false; +} + /* Set the sign of R to the sign of X. */ void diff --git a/gcc/real.h b/gcc/real.h index 76889bff0ea..f9d388f491b 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -510,6 +510,10 @@ extern void real_round (REAL_VALUE_TYPE *, format_helper, extern void real_roundeven (REAL_VALUE_TYPE *, format_helper, const REAL_VALUE_TYPE *); +/* Narrowing type standard math operations functions. */ +extern bool real_fadd (REAL_VALUE_TYPE *, format_helper, + const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); + /* Set the sign of R to the sign of X. */ extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);