This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Builtin fadd variants folding implementation


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  <tejasjoshi9673@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  <tejasjoshi9673@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;
> +}
> +


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]