public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [GSoC-19] Implementing narrowing functions like fadd
@ 2019-07-03 12:53 Tejas Joshi
  2019-07-06 12:53 ` Tejas Joshi
  0 siblings, 1 reply; 11+ messages in thread
From: Tejas Joshi @ 2019-07-03 12:53 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

Hello.
Functions like fadd, faddl take two arguments, do the addition and
return the answer in narrower precision than the argument type. The
thing that might be helpful is using the do_add function directly, if
appropriate?
The thing to consider about narrowed down return type is how it can be
achieved. The functions that operate on real numbers like real_round
and so on, do not consider the return type and do calculations on the
entire real number representation. So just defining these functions
and their return type in builtins.def and other appropriate places
would do the trick?
like:
BT_FN_FLOAT_DOUBLE_DOUBLE as return and argument type for FADD

Or it has to be narrowed down by zeroing down the trailing
out-of-precision bits?
Also, if the addition or any one of the argument exceeds the return
size, the integer part of the addition would not fit in the narrowed
type. Like, 2^32 would easily fit in double but will lose its least
significant bit in float and become 2^31. How these types are supposed
to be handled?

Thanks,
-Tejas

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-03 12:53 [GSoC-19] Implementing narrowing functions like fadd Tejas Joshi
@ 2019-07-06 12:53 ` Tejas Joshi
  2019-07-10 11:28   ` Tejas Joshi
  0 siblings, 1 reply; 11+ messages in thread
From: Tejas Joshi @ 2019-07-06 12:53 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

[-- Attachment #1: Type: text/plain, Size: 1859 bytes --]

Hello.
I am trying to add fadd function variants and as fadd takes two
arguments, the function should be called from fold_const_call_sss ().
The function is closely modeled on function calls and cases according
to real_nextafter (), also used gdb to look at backtrace. Although I
have made changes according to real_nextafter, the function real_fadd
is not called by the test program but real_nextafter does get called.
I cant find any other places to add calls for fadd. What is missing?
The patch is attached herewith.

int
main ()
{
  float x;
  x = __builtin_fadd (3.5,1.4);
}

Also, fadd function should not have faddf variant, but is introduced
only for the sake.

Thanks,
-Tejas

On Wed, 3 Jul 2019 at 18:29, Tejas Joshi <tejasjoshi9673@gmail.com> wrote:
>
> Hello.
> Functions like fadd, faddl take two arguments, do the addition and
> return the answer in narrower precision than the argument type. The
> thing that might be helpful is using the do_add function directly, if
> appropriate?
> The thing to consider about narrowed down return type is how it can be
> achieved. The functions that operate on real numbers like real_round
> and so on, do not consider the return type and do calculations on the
> entire real number representation. So just defining these functions
> and their return type in builtins.def and other appropriate places
> would do the trick?
> like:
> BT_FN_FLOAT_DOUBLE_DOUBLE as return and argument type for FADD
>
> Or it has to be narrowed down by zeroing down the trailing
> out-of-precision bits?
> Also, if the addition or any one of the argument exceeds the return
> size, the integer part of the addition would not fit in the narrowed
> type. Like, 2^32 would easily fit in double but will lose its least
> significant bit in float and become 2^31. How these types are supposed
> to be handled?
>
> Thanks,
> -Tejas

[-- Attachment #2: fadd.diff --]
[-- Type: text/x-patch, Size: 4221 bytes --]

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index e5c9e063c48..47cb81006e0 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -387,6 +387,8 @@ 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_DOUBLE_DOUBLE_DOUBLE,
 		     BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 85a945877a4..371fb62b645 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2035,6 +2035,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..1d065eae345 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -352,6 +352,9 @@ 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_FADDF, "faddf", BT_FN_FLOAT_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_FADDL, "faddl", BT_FN_FLOAT_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 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..ee939f85005 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;
     }
diff --git a/gcc/real.c b/gcc/real.c
index ab71430709f..6379cd0bcdc 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5093,6 +5093,17 @@ 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);
+  fprintf (stderr, "\nin real_fadd\n");
+  return false;
+}
+
 /* Set the sign of R to the sign of X.  */
 
 void
@@ -5138,6 +5149,7 @@ bool
 real_nextafter (REAL_VALUE_TYPE *r, format_helper fmt,
 		const REAL_VALUE_TYPE *x, const REAL_VALUE_TYPE *y)
 {
+  fprintf (stderr, "\nin nextafter\n");
   int cmp = do_compare (x, y, 2);
   /* If either operand is NaN, return qNaN.  */
   if (cmp == 2)
diff --git a/gcc/real.h b/gcc/real.h
index 76889bff0ea..708d821534b 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 *);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-06 12:53 ` Tejas Joshi
@ 2019-07-10 11:28   ` Tejas Joshi
  2019-07-10 12:33     ` Richard Sandiford
  0 siblings, 1 reply; 11+ messages in thread
From: Tejas Joshi @ 2019-07-10 11:28 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

[-- Attachment #1: Type: text/plain, Size: 2853 bytes --]

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.

Thanks,
-Tejas

On Sat, 6 Jul 2019 at 18:29, Tejas Joshi <tejasjoshi9673@gmail.com> wrote:
>
> Hello.
> I am trying to add fadd function variants and as fadd takes two
> arguments, the function should be called from fold_const_call_sss ().
> The function is closely modeled on function calls and cases according
> to real_nextafter (), also used gdb to look at backtrace. Although I
> have made changes according to real_nextafter, the function real_fadd
> is not called by the test program but real_nextafter does get called.
> I cant find any other places to add calls for fadd. What is missing?
> The patch is attached herewith.
>
> int
> main ()
> {
>   float x;
>   x = __builtin_fadd (3.5,1.4);
> }
>
> Also, fadd function should not have faddf variant, but is introduced
> only for the sake.
>
> Thanks,
> -Tejas
>
> On Wed, 3 Jul 2019 at 18:29, Tejas Joshi <tejasjoshi9673@gmail.com> wrote:
> >
> > Hello.
> > Functions like fadd, faddl take two arguments, do the addition and
> > return the answer in narrower precision than the argument type. The
> > thing that might be helpful is using the do_add function directly, if
> > appropriate?
> > The thing to consider about narrowed down return type is how it can be
> > achieved. The functions that operate on real numbers like real_round
> > and so on, do not consider the return type and do calculations on the
> > entire real number representation. So just defining these functions
> > and their return type in builtins.def and other appropriate places
> > would do the trick?
> > like:
> > BT_FN_FLOAT_DOUBLE_DOUBLE as return and argument type for FADD
> >
> > Or it has to be narrowed down by zeroing down the trailing
> > out-of-precision bits?
> > Also, if the addition or any one of the argument exceeds the return
> > size, the integer part of the addition would not fit in the narrowed
> > type. Like, 2^32 would easily fit in double but will lose its least
> > significant bit in float and become 2^31. How these types are supposed
> > to be handled?
> >
> > Thanks,
> > -Tejas

[-- Attachment #2: fadd.diff --]
[-- Type: text/x-patch, Size: 4050 bytes --]

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index e5c9e063c48..87ecd2e9218 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -387,6 +387,10 @@ 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_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
diff --git a/gcc/builtins.c b/gcc/builtins.c
index f61f10422fd..471c7918abb 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..afc482f38dc 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -352,6 +352,9 @@ 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_FADDF, "faddf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_FADDL, "faddl", BT_FN_FLOAT_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 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..ee939f85005 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;
     }
diff --git a/gcc/real.c b/gcc/real.c
index ab71430709f..6379cd0bcdc 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5093,6 +5093,17 @@ 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);
+  fprintf (stderr, "\nin real_fadd\n");
+  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..708d821534b 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 *);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-10 11:28   ` Tejas Joshi
@ 2019-07-10 12:33     ` Richard Sandiford
  2019-07-23 17:05       ` Tejas Joshi
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Sandiford @ 2019-07-10 12:33 UTC (permalink / raw)
  To: Tejas Joshi; +Cc: gcc, Martin Jambor, hubicka, joseph

Tejas Joshi <tejasjoshi9673@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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-10 12:33     ` Richard Sandiford
@ 2019-07-23 17:05       ` Tejas Joshi
  2019-07-24 16:23         ` Joseph Myers
       [not found]         ` <ri68ssk1znm.fsf@suse.cz>
  0 siblings, 2 replies; 11+ messages in thread
From: Tejas Joshi @ 2019-07-23 17:05 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

[-- Attachment #1: Type: text/plain, Size: 2375 bytes --]

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.sandiford@arm.com> wrote:
>
> Tejas Joshi <tejasjoshi9673@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

[-- Attachment #2: fadd.diff --]
[-- Type: text/x-patch, Size: 4989 bytes --]

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 *);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-23 17:05       ` Tejas Joshi
@ 2019-07-24 16:23         ` Joseph Myers
       [not found]         ` <ri68ssk1znm.fsf@suse.cz>
  1 sibling, 0 replies; 11+ messages in thread
From: Joseph Myers @ 2019-07-24 16:23 UTC (permalink / raw)
  To: Tejas Joshi; +Cc: gcc, Martin Jambor, hubicka

On Tue, 23 Jul 2019, Tejas Joshi wrote:

> 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.

You'll need something different from CASE_MATHFN - these are a different 
kind of functions that need handling in a different way, because they are 
parametrized over certain *pairs* of types, rather than over a single 
type.

(The main case for these being built-in is probably not folding for 
constant arguments - it's generating appropriate instructions when 
building with -fno-math-errno for processors that have appropriate 
narrowing instructions, such as Power ISA 2.07 or later, which I think 
means POWER8 or later.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
       [not found]         ` <ri68ssk1znm.fsf@suse.cz>
@ 2019-07-27  6:16           ` Tejas Joshi
  2019-07-29 17:17             ` Martin Jambor
  0 siblings, 1 reply; 11+ messages in thread
From: Tejas Joshi @ 2019-07-27  6:16 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

[-- Attachment #1: Type: text/plain, Size: 7034 bytes --]

Hello.

>> You'll need something different from CASE_MATHFN - these are a different
>> kind of functions that need handling in a different way, because they are
>> parametrized over certain *pairs* of types, rather than over a single
>> type.
> first phase, please just directly test for in the code for
> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL and process
> those here to get a prototype working.  When you add support for more

Thanks for the inputs. I have used CFN_BUILT_IN_FADD, etc in this
following patch and function is getting folded.
My question is that how the addition and narrowing should be performed
(is it ok to use do_add for addition?). As functions in real.c does
not operate on any specific precision, just defining the return type
as float would do the trick? Or do I need to make trailing
out-of-precision bits zero? If yes, having functions like
double_to_float would then be useful or such functions already exist
to do the conversion?

Thanks,
Tejas


On Fri, 26 Jul 2019 at 22:49, Martin Jambor <mjambor@suse.cz> wrote:
>
> Hello Tejas,
>
> On Tue, Jul 23 2019, Tejas Joshi wrote:
> > 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.
>
> They are different so as Joseph pointed out, they need to be handled
> differently, don't feel too constrained by the patterns already in gcc.
> For now you can even just just use directly the constants
> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL in the code to
> get a prototype working and then set out to create a macro to wrap this
> in, perhaps even only after you added support for two or more such
> narrowing instructions so that you see how the common parts look like.
>
>
> > 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)
>
> This does not seem to be necessary for folding, or am I wrong?  If it is
> intended for expansion, I'd drop it from this patch and move to the one
> where it is required.
>
>
>
> > 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
>
> This results into definitions like BUILT_IN_FADDF32 (what would that
> do?)  and BUILT_IN_FADDF64 or BUILT_IN_FADDF128 (which I don't think we
> want, Joseph?).  Perhaps you can just simply drop this use of
> DEF_EXT_LIB_FLOATN_NX_BUILTINS?
>
> >  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);
> > +
>
> As you have pointed out, this does not work, this is not expanded into a
> macro and is just as an unused label for which you get a warning.
> Moreover...
>
> >      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)))
>
> ...I don't think you want to stuff handling narrowing functions into
> fold_const_call_sss, that is for operations with matching type.  In the
> first phase, please just directly test for in the code for
> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL and process
> those here to get a prototype working.  When you add support for more
> narrowing functions we can then move their processing into a new
> separate function.
>
> At leat that is how I would proceed with folding.
>
> Thanks,
>
> Martin

[-- Attachment #2: fadd-1.diff --]
[-- Type: text/x-patch, Size: 4554 bytes --]

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 d9b546e6803..374fe517bd6 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)
@@ -1644,6 +1654,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_fadd (&result, TREE_REAL_CST_PTR (arg0),
+			       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/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 *);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-27  6:16           ` Tejas Joshi
@ 2019-07-29 17:17             ` Martin Jambor
  2019-07-31  6:30               ` Tejas Joshi
  0 siblings, 1 reply; 11+ messages in thread
From: Martin Jambor @ 2019-07-29 17:17 UTC (permalink / raw)
  To: Tejas Joshi, gcc; +Cc: hubicka, joseph

Hi,

On Sat, Jul 27 2019, Tejas Joshi wrote:
> Hello.
>
>>> You'll need something different from CASE_MATHFN - these are a different
>>> kind of functions that need handling in a different way, because they are
>>> parametrized over certain *pairs* of types, rather than over a single
>>> type.
>> first phase, please just directly test for in the code for
>> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL and process
>> those here to get a prototype working.  When you add support for more
>
> Thanks for the inputs. I have used CFN_BUILT_IN_FADD, etc in this
> following patch and function is getting folded.

good.  Please add comments to functions which miss them (real_fadd and
fold_const_fadd), for example I am not sure what the return values are
supposed to mean, and add a run-time testcase(s) and I'd say you are
done for now - after you implement fsub, fmul and fdiv(?) you might want
to re-structure some common bits to make the code prettier.

> My question is that how the addition and narrowing should be performed
> (is it ok to use do_add for addition?).

I don't see a reason why it would not be.

> As functions in real.c does
> not operate on any specific precision, just defining the return type
> as float would do the trick? Or do I need to make trailing
> out-of-precision bits zero? If yes, having functions like
> double_to_float would then be useful or such functions already exist
> to do the conversion?

I am not sure I understand your question, you have used real_convert in
real_fadd and it seems to be doing exactly that?  As you know I am not
too familiar with this area of gcc but reading the code suggests that
and a simple debugging session seems to confirm that (some unimportant
gdb output omitted):

----------------------------------------------------------------------
$ ~/gcc/gsoc/inst/bin/gcc -Ofast -S fadd-fold.c -wrapper gdb,--args
GNU gdb (GDB; openSUSE Tumbleweed) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

(gdb) b real_fadd
Breakpoint 1 at 0x108215b: file /home/mjambor/gcc/gsoc/src/gcc/real.c, line 5100.
(gdb) r
Starting program: /home/mjambor/gcc/gsoc/inst/lib/gcc/x86_64-pc-linux-gnu/10.0.0/cc1 -quiet fadd-fold.c -quiet -dumpbase fadd-fold.c -mtune=generic -march=x86-64 -auxbase fadd-fold -Ofast -o fadd-fold.s

Breakpoint 1, real_fadd (r=0x7fffffffc580, fmt=..., x=0x7ffff7800060, y=0x7ffff7800080)
    at /home/mjambor/gcc/gsoc/src/gcc/real.c:5100
5100      do_add (r, x, y, 0);
(gdb) n
5101      if (fmt)
(gdb) p *r
$1 = {cl = 1, decimal = 0, sign = 0, signalling = 0, canonical = 0, uexp = 5, sig = {0, 0, 
    10549231767152649216}}
(gdb) p/x r->sig[2]
$2 = 0x9266666666666400
(gdb) n
5102        real_convert (r, fmt, r);
(gdb) 
5103      return false;
(gdb) p/x r->sig[2]
$3 = 0x9266660000000000
----------------------------------------------------------------------

Thanks,

Martin


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-29 17:17             ` Martin Jambor
@ 2019-07-31  6:30               ` Tejas Joshi
  2019-08-02 10:34                 ` Tejas Joshi
  0 siblings, 1 reply; 11+ messages in thread
From: Tejas Joshi @ 2019-07-31  6:30 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

Hello.

> fold_const_fadd), for example I am not sure what the return values are
> supposed to mean, and add a run-time testcase(s) and I'd say you are
> done for now

I modeled real_fadd function on a similar function, real_nextafter
which would take three arguments. Just as overflow and underflow
conditions are handled there, I thought similarly if exact/inexact and
overflow/underflow conditions would be handled by fold_const_fadd for
real_fadd. As these conditions are still need to be addressed (so
current function is prototypish), is real_nextafter a good model to
refer?

> I am not sure I understand your question, you have used real_convert in
> real_fadd and it seems to be doing exactly that?  As you know I am not

Looking at different comments where real_convert is used, I guessed it
formats GCC's floating point format to a target format rather than
converting to return type. Its still unclear to me but its good if it
does convert to return type like it seems. I am working on these
conditions now and will try to come up with testcases.

Thanks,
Tejas


On Mon, 29 Jul 2019 at 22:47, Martin Jambor <mjambor@suse.cz> wrote:
>
> Hi,
>
> On Sat, Jul 27 2019, Tejas Joshi wrote:
> > Hello.
> >
> >>> You'll need something different from CASE_MATHFN - these are a different
> >>> kind of functions that need handling in a different way, because they are
> >>> parametrized over certain *pairs* of types, rather than over a single
> >>> type.
> >> first phase, please just directly test for in the code for
> >> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL and process
> >> those here to get a prototype working.  When you add support for more
> >
> > Thanks for the inputs. I have used CFN_BUILT_IN_FADD, etc in this
> > following patch and function is getting folded.
>
> good.  Please add comments to functions which miss them (real_fadd and
> fold_const_fadd), for example I am not sure what the return values are
> supposed to mean, and add a run-time testcase(s) and I'd say you are
> done for now - after you implement fsub, fmul and fdiv(?) you might want
> to re-structure some common bits to make the code prettier.
>
> > My question is that how the addition and narrowing should be performed
> > (is it ok to use do_add for addition?).
>
> I don't see a reason why it would not be.
>
> > As functions in real.c does
> > not operate on any specific precision, just defining the return type
> > as float would do the trick? Or do I need to make trailing
> > out-of-precision bits zero? If yes, having functions like
> > double_to_float would then be useful or such functions already exist
> > to do the conversion?
>
> I am not sure I understand your question, you have used real_convert in
> real_fadd and it seems to be doing exactly that?  As you know I am not
> too familiar with this area of gcc but reading the code suggests that
> and a simple debugging session seems to confirm that (some unimportant
> gdb output omitted):
>
> ----------------------------------------------------------------------
> $ ~/gcc/gsoc/inst/bin/gcc -Ofast -S fadd-fold.c -wrapper gdb,--args
> GNU gdb (GDB; openSUSE Tumbleweed) 8.3
> Copyright (C) 2019 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
>
> (gdb) b real_fadd
> Breakpoint 1 at 0x108215b: file /home/mjambor/gcc/gsoc/src/gcc/real.c, line 5100.
> (gdb) r
> Starting program: /home/mjambor/gcc/gsoc/inst/lib/gcc/x86_64-pc-linux-gnu/10.0.0/cc1 -quiet fadd-fold.c -quiet -dumpbase fadd-fold.c -mtune=generic -march=x86-64 -auxbase fadd-fold -Ofast -o fadd-fold.s
>
> Breakpoint 1, real_fadd (r=0x7fffffffc580, fmt=..., x=0x7ffff7800060, y=0x7ffff7800080)
>     at /home/mjambor/gcc/gsoc/src/gcc/real.c:5100
> 5100      do_add (r, x, y, 0);
> (gdb) n
> 5101      if (fmt)
> (gdb) p *r
> $1 = {cl = 1, decimal = 0, sign = 0, signalling = 0, canonical = 0, uexp = 5, sig = {0, 0,
>     10549231767152649216}}
> (gdb) p/x r->sig[2]
> $2 = 0x9266666666666400
> (gdb) n
> 5102        real_convert (r, fmt, r);
> (gdb)
> 5103      return false;
> (gdb) p/x r->sig[2]
> $3 = 0x9266660000000000
> ----------------------------------------------------------------------
>
> Thanks,
>
> Martin
>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-07-31  6:30               ` Tejas Joshi
@ 2019-08-02 10:34                 ` Tejas Joshi
  2019-08-06 15:40                   ` Tejas Joshi
  0 siblings, 1 reply; 11+ messages in thread
From: Tejas Joshi @ 2019-08-02 10:34 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

[-- Attachment #1: Type: text/plain, Size: 5526 bytes --]

Hello.
I have made this patch strictly considering the following points
Joseph mentioned in his initial email :

> * The narrowing functions, e.g. fadd, faddl, daddl, are a bit different
> from most other built-in math.h functions because the return type is
> different from the argument types.  You could start by adding them to
> builtins.def similarly to roundeven (with new macros to handle adding such
> functions for relevant pairs of _FloatN, _FloatNx types).  These functions
> could be folded for constant arguments only if the result is exact, or if
> -fno-rounding-math -fno-trapping-math (and -fno-math-errno if the result
> involves overflow / underflow).

I am trying to come up with testcases which would work around
-fno-rounding-math -fno-trapping-math and -fno-math-errno while
considering inexact and overlfow/underflow cases. I will try them as
soon as possible and send another patch with them and after regression
testing. Apart from that, am I missing something in this patch?

Thanks,
Tejas


On Wed, 31 Jul 2019 at 12:06, Tejas Joshi <tejasjoshi9673@gmail.com> wrote:
>
> Hello.
>
> > fold_const_fadd), for example I am not sure what the return values are
> > supposed to mean, and add a run-time testcase(s) and I'd say you are
> > done for now
>
> I modeled real_fadd function on a similar function, real_nextafter
> which would take three arguments. Just as overflow and underflow
> conditions are handled there, I thought similarly if exact/inexact and
> overflow/underflow conditions would be handled by fold_const_fadd for
> real_fadd. As these conditions are still need to be addressed (so
> current function is prototypish), is real_nextafter a good model to
> refer?
>
> > I am not sure I understand your question, you have used real_convert in
> > real_fadd and it seems to be doing exactly that?  As you know I am not
>
> Looking at different comments where real_convert is used, I guessed it
> formats GCC's floating point format to a target format rather than
> converting to return type. Its still unclear to me but its good if it
> does convert to return type like it seems. I am working on these
> conditions now and will try to come up with testcases.
>
> Thanks,
> Tejas
>
>
> On Mon, 29 Jul 2019 at 22:47, Martin Jambor <mjambor@suse.cz> wrote:
> >
> > Hi,
> >
> > On Sat, Jul 27 2019, Tejas Joshi wrote:
> > > Hello.
> > >
> > >>> You'll need something different from CASE_MATHFN - these are a different
> > >>> kind of functions that need handling in a different way, because they are
> > >>> parametrized over certain *pairs* of types, rather than over a single
> > >>> type.
> > >> first phase, please just directly test for in the code for
> > >> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL and process
> > >> those here to get a prototype working.  When you add support for more
> > >
> > > Thanks for the inputs. I have used CFN_BUILT_IN_FADD, etc in this
> > > following patch and function is getting folded.
> >
> > good.  Please add comments to functions which miss them (real_fadd and
> > fold_const_fadd), for example I am not sure what the return values are
> > supposed to mean, and add a run-time testcase(s) and I'd say you are
> > done for now - after you implement fsub, fmul and fdiv(?) you might want
> > to re-structure some common bits to make the code prettier.
> >
> > > My question is that how the addition and narrowing should be performed
> > > (is it ok to use do_add for addition?).
> >
> > I don't see a reason why it would not be.
> >
> > > As functions in real.c does
> > > not operate on any specific precision, just defining the return type
> > > as float would do the trick? Or do I need to make trailing
> > > out-of-precision bits zero? If yes, having functions like
> > > double_to_float would then be useful or such functions already exist
> > > to do the conversion?
> >
> > I am not sure I understand your question, you have used real_convert in
> > real_fadd and it seems to be doing exactly that?  As you know I am not
> > too familiar with this area of gcc but reading the code suggests that
> > and a simple debugging session seems to confirm that (some unimportant
> > gdb output omitted):
> >
> > ----------------------------------------------------------------------
> > $ ~/gcc/gsoc/inst/bin/gcc -Ofast -S fadd-fold.c -wrapper gdb,--args
> > GNU gdb (GDB; openSUSE Tumbleweed) 8.3
> > Copyright (C) 2019 Free Software Foundation, Inc.
> > License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> >
> > (gdb) b real_fadd
> > Breakpoint 1 at 0x108215b: file /home/mjambor/gcc/gsoc/src/gcc/real.c, line 5100.
> > (gdb) r
> > Starting program: /home/mjambor/gcc/gsoc/inst/lib/gcc/x86_64-pc-linux-gnu/10.0.0/cc1 -quiet fadd-fold.c -quiet -dumpbase fadd-fold.c -mtune=generic -march=x86-64 -auxbase fadd-fold -Ofast -o fadd-fold.s
> >
> > Breakpoint 1, real_fadd (r=0x7fffffffc580, fmt=..., x=0x7ffff7800060, y=0x7ffff7800080)
> >     at /home/mjambor/gcc/gsoc/src/gcc/real.c:5100
> > 5100      do_add (r, x, y, 0);
> > (gdb) n
> > 5101      if (fmt)
> > (gdb) p *r
> > $1 = {cl = 1, decimal = 0, sign = 0, signalling = 0, canonical = 0, uexp = 5, sig = {0, 0,
> >     10549231767152649216}}
> > (gdb) p/x r->sig[2]
> > $2 = 0x9266666666666400
> > (gdb) n
> > 5102        real_convert (r, fmt, r);
> > (gdb)
> > 5103      return false;
> > (gdb) p/x r->sig[2]
> > $3 = 0x9266660000000000
> > ----------------------------------------------------------------------
> >
> > Thanks,
> >
> > Martin
> >
> >

[-- Attachment #2: fadd.diff --]
[-- Type: text/x-patch, Size: 5276 bytes --]

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 d9b546e6803..f895c89de96 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -570,6 +570,32 @@ fold_const_nextafter (real_value *result, const real_value *arg0,
   return true;
 }
 
+/* Try to evaluate:
+
+      *RESULT = fadd (*ARG0, *ARG1)
+
+   in format FORMAT.  Return true on success.  */
+
+static bool
+fold_const_fadd (real_value *result, const real_value *arg0,
+		 const real_value *arg1, const real_format *format)
+{
+  if (REAL_VALUE_ISSIGNALING_NAN (*arg0)
+      || REAL_VALUE_ISSIGNALING_NAN (*arg1))
+    return false;
+
+  if (real_fadd (result, format, arg0, arg1)
+      && !flag_errno_math)
+    return false;
+
+  if (!exact_real_truncate (format, result)
+      && !(flag_rounding_math && flag_trapping_math))
+    return false;
+
+  real_convert (result, format, result);
+  return true;
+}
+
 /* Try to evaluate:
 
       *RESULT = ldexp (*ARG0, ARG1)
@@ -1644,6 +1670,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_fadd (&result, TREE_REAL_CST_PTR (arg0),
+			       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/real.c b/gcc/real.c
index ab71430709f..280e434e897 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5093,6 +5093,30 @@ real_roundeven (REAL_VALUE_TYPE *r, format_helper fmt,
     real_round (r, fmt, x);
 }
 
+/* Perform addition of X and Y and place the result in R to narrowed
+   down type. Return TRUE if result involves overflow/underflow.  */
+
+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);
+
+  /* Overflow/underflow check.  */
+  if (REAL_EXP (r) > fmt->emax)
+  {
+    get_inf (r, r->sign);
+    return true;
+  }
+  if (REAL_EXP (r) < fmt->emin)
+  {
+    get_zero (r, r->sign);
+    return true;
+  }
+
+  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 *);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [GSoC-19] Implementing narrowing functions like fadd
  2019-08-02 10:34                 ` Tejas Joshi
@ 2019-08-06 15:40                   ` Tejas Joshi
  0 siblings, 0 replies; 11+ messages in thread
From: Tejas Joshi @ 2019-08-06 15:40 UTC (permalink / raw)
  To: gcc; +Cc: Martin Jambor, hubicka, joseph

[-- Attachment #1: Type: text/plain, Size: 6128 bytes --]

Hello.
I have come up with the testcases for fadd variants and the following
patch comes with them. Again, the patch follows the points mentioned
above and if good to go, I will post it to the gcc-patches. The patch
bootstraps and survives regression tests.

Thanks,
Tejas

On Fri, 2 Aug 2019 at 16:10, Tejas Joshi <tejasjoshi9673@gmail.com> wrote:
>
> Hello.
> I have made this patch strictly considering the following points
> Joseph mentioned in his initial email :
>
> > * The narrowing functions, e.g. fadd, faddl, daddl, are a bit different
> > from most other built-in math.h functions because the return type is
> > different from the argument types.  You could start by adding them to
> > builtins.def similarly to roundeven (with new macros to handle adding such
> > functions for relevant pairs of _FloatN, _FloatNx types).  These functions
> > could be folded for constant arguments only if the result is exact, or if
> > -fno-rounding-math -fno-trapping-math (and -fno-math-errno if the result
> > involves overflow / underflow).
>
> I am trying to come up with testcases which would work around
> -fno-rounding-math -fno-trapping-math and -fno-math-errno while
> considering inexact and overlfow/underflow cases. I will try them as
> soon as possible and send another patch with them and after regression
> testing. Apart from that, am I missing something in this patch?
>
> Thanks,
> Tejas
>
>
> On Wed, 31 Jul 2019 at 12:06, Tejas Joshi <tejasjoshi9673@gmail.com> wrote:
> >
> > Hello.
> >
> > > fold_const_fadd), for example I am not sure what the return values are
> > > supposed to mean, and add a run-time testcase(s) and I'd say you are
> > > done for now
> >
> > I modeled real_fadd function on a similar function, real_nextafter
> > which would take three arguments. Just as overflow and underflow
> > conditions are handled there, I thought similarly if exact/inexact and
> > overflow/underflow conditions would be handled by fold_const_fadd for
> > real_fadd. As these conditions are still need to be addressed (so
> > current function is prototypish), is real_nextafter a good model to
> > refer?
> >
> > > I am not sure I understand your question, you have used real_convert in
> > > real_fadd and it seems to be doing exactly that?  As you know I am not
> >
> > Looking at different comments where real_convert is used, I guessed it
> > formats GCC's floating point format to a target format rather than
> > converting to return type. Its still unclear to me but its good if it
> > does convert to return type like it seems. I am working on these
> > conditions now and will try to come up with testcases.
> >
> > Thanks,
> > Tejas
> >
> >
> > On Mon, 29 Jul 2019 at 22:47, Martin Jambor <mjambor@suse.cz> wrote:
> > >
> > > Hi,
> > >
> > > On Sat, Jul 27 2019, Tejas Joshi wrote:
> > > > Hello.
> > > >
> > > >>> You'll need something different from CASE_MATHFN - these are a different
> > > >>> kind of functions that need handling in a different way, because they are
> > > >>> parametrized over certain *pairs* of types, rather than over a single
> > > >>> type.
> > > >> first phase, please just directly test for in the code for
> > > >> CFN_BUILT_IN_FADD, CFN_BUILT_IN_FADDL, CFN_BUILT_IN_DADDL and process
> > > >> those here to get a prototype working.  When you add support for more
> > > >
> > > > Thanks for the inputs. I have used CFN_BUILT_IN_FADD, etc in this
> > > > following patch and function is getting folded.
> > >
> > > good.  Please add comments to functions which miss them (real_fadd and
> > > fold_const_fadd), for example I am not sure what the return values are
> > > supposed to mean, and add a run-time testcase(s) and I'd say you are
> > > done for now - after you implement fsub, fmul and fdiv(?) you might want
> > > to re-structure some common bits to make the code prettier.
> > >
> > > > My question is that how the addition and narrowing should be performed
> > > > (is it ok to use do_add for addition?).
> > >
> > > I don't see a reason why it would not be.
> > >
> > > > As functions in real.c does
> > > > not operate on any specific precision, just defining the return type
> > > > as float would do the trick? Or do I need to make trailing
> > > > out-of-precision bits zero? If yes, having functions like
> > > > double_to_float would then be useful or such functions already exist
> > > > to do the conversion?
> > >
> > > I am not sure I understand your question, you have used real_convert in
> > > real_fadd and it seems to be doing exactly that?  As you know I am not
> > > too familiar with this area of gcc but reading the code suggests that
> > > and a simple debugging session seems to confirm that (some unimportant
> > > gdb output omitted):
> > >
> > > ----------------------------------------------------------------------
> > > $ ~/gcc/gsoc/inst/bin/gcc -Ofast -S fadd-fold.c -wrapper gdb,--args
> > > GNU gdb (GDB; openSUSE Tumbleweed) 8.3
> > > Copyright (C) 2019 Free Software Foundation, Inc.
> > > License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> > >
> > > (gdb) b real_fadd
> > > Breakpoint 1 at 0x108215b: file /home/mjambor/gcc/gsoc/src/gcc/real.c, line 5100.
> > > (gdb) r
> > > Starting program: /home/mjambor/gcc/gsoc/inst/lib/gcc/x86_64-pc-linux-gnu/10.0.0/cc1 -quiet fadd-fold.c -quiet -dumpbase fadd-fold.c -mtune=generic -march=x86-64 -auxbase fadd-fold -Ofast -o fadd-fold.s
> > >
> > > Breakpoint 1, real_fadd (r=0x7fffffffc580, fmt=..., x=0x7ffff7800060, y=0x7ffff7800080)
> > >     at /home/mjambor/gcc/gsoc/src/gcc/real.c:5100
> > > 5100      do_add (r, x, y, 0);
> > > (gdb) n
> > > 5101      if (fmt)
> > > (gdb) p *r
> > > $1 = {cl = 1, decimal = 0, sign = 0, signalling = 0, canonical = 0, uexp = 5, sig = {0, 0,
> > >     10549231767152649216}}
> > > (gdb) p/x r->sig[2]
> > > $2 = 0x9266666666666400
> > > (gdb) n
> > > 5102        real_convert (r, fmt, r);
> > > (gdb)
> > > 5103      return false;
> > > (gdb) p/x r->sig[2]
> > > $3 = 0x9266660000000000
> > > ----------------------------------------------------------------------
> > >
> > > Thanks,
> > >
> > > Martin
> > >
> > >

[-- Attachment #2: fadd-2.diff --]
[-- Type: text/x-patch, Size: 7602 bytes --]

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 d9b546e6803..f895c89de96 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -570,6 +570,32 @@ fold_const_nextafter (real_value *result, const real_value *arg0,
   return true;
 }
 
+/* Try to evaluate:
+
+      *RESULT = fadd (*ARG0, *ARG1)
+
+   in format FORMAT.  Return true on success.  */
+
+static bool
+fold_const_fadd (real_value *result, const real_value *arg0,
+		 const real_value *arg1, const real_format *format)
+{
+  if (REAL_VALUE_ISSIGNALING_NAN (*arg0)
+      || REAL_VALUE_ISSIGNALING_NAN (*arg1))
+    return false;
+
+  if (real_fadd (result, format, arg0, arg1)
+      && !flag_errno_math)
+    return false;
+
+  if (!exact_real_truncate (format, result)
+      && !(flag_rounding_math && flag_trapping_math))
+    return false;
+
+  real_convert (result, format, result);
+  return true;
+}
+
 /* Try to evaluate:
 
       *RESULT = ldexp (*ARG0, ARG1)
@@ -1644,6 +1670,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_fadd (&result, TREE_REAL_CST_PTR (arg0),
+			       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/real.c b/gcc/real.c
index ab71430709f..280e434e897 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5093,6 +5093,30 @@ real_roundeven (REAL_VALUE_TYPE *r, format_helper fmt,
     real_round (r, fmt, x);
 }
 
+/* Perform addition of X and Y and place the result in R to narrowed
+   down type. Return TRUE if result involves overflow/underflow.  */
+
+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);
+
+  /* Overflow/underflow check.  */
+  if (REAL_EXP (r) > fmt->emax)
+  {
+    get_inf (r, r->sign);
+    return true;
+  }
+  if (REAL_EXP (r) < fmt->emin)
+  {
+    get_zero (r, r->sign);
+    return true;
+  }
+
+  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 *);
 
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..958d5a019d7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-fadd-1.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define TEST(FN, VAL1, VAL2, RESULT) \
+  if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort ();
+
+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, __FLT_MAX__, __FLT_MAX__/2, 3*__FLT_MAX__/2);
+  
+  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, __FLT_MAX__, __FLT_MAX__/2, 3*__FLT_MAX__/2);
+
+  TEST(daddl, 0L, 0L, 0.0);
+  TEST(daddl, 1L, -1L, 0.0);
+  TEST(daddl, -1L, -1.5L, -2.5);
+  TEST(daddl, 1.4L, 1.6L, 3.0);
+  TEST(daddl, 2.5L, 1.5L, 4.0);
+  TEST(daddl, __DBL_MAX__, __DBL_MAX__/2, 3*__DBL_MAX__/2);
+  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..76c81ae0470
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-fadd-2.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -frounding-math" } */
+
+#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, 3, 4.2, 7.2F);
+  TEST(fadd, 2, 4.3, 6.3F);
+  TEST(fadd, -2, -2.4, -4.4F);
+  TEST(fadd, -3, -3.6, -6.6F); 
+  TEST(fadd, -5.3, -5.4, -10.7F);
+  TEST(fadd, 8, 0.8, 8.8F);
+  TEST(fadd, 0.5, 0.4, 0.9F);
+
+  TEST(faddl, 1.0L, 1.1L, 2.1F);
+  TEST(faddl, 3.0L, 4.2L, 7.2F);
+  TEST(faddl, 2.0L, 4.3L, 6.3F);
+  TEST(faddl, -2.0L, -2.4L, -4.4F);
+  TEST(faddl, -3.0L, -3.6L, -6.6F); 
+  TEST(faddl, -5.3L, -5.4L, -10.7F);
+  TEST(faddl, 8.0L, 0.8L, 8.8F);
+  TEST(faddl, 0.5L, 0.4L, 0.9F);
+
+  TEST(daddl, 1.0L, 1.1L, 2.1);
+  TEST(daddl, 3.0L, 4.2L, 7.2);
+  TEST(daddl, 2.0L, 4.3L, 6.3);
+  TEST(daddl, -2.0L, -2.4L, -4.4);
+  TEST(daddl, -3.0L, -3.6L, -6.6); 
+  TEST(daddl, -5.3L, -5.4L, -10.7);
+  TEST(daddl, 8.0L, 0.8L, 8.8);
+  TEST(daddl, 0.5L, 0.4L, 0.9);
+
+  return 0;
+} 

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-08-06 15:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-03 12:53 [GSoC-19] Implementing narrowing functions like fadd Tejas Joshi
2019-07-06 12:53 ` Tejas Joshi
2019-07-10 11:28   ` Tejas Joshi
2019-07-10 12:33     ` Richard Sandiford
2019-07-23 17:05       ` Tejas Joshi
2019-07-24 16:23         ` Joseph Myers
     [not found]         ` <ri68ssk1znm.fsf@suse.cz>
2019-07-27  6:16           ` Tejas Joshi
2019-07-29 17:17             ` Martin Jambor
2019-07-31  6:30               ` Tejas Joshi
2019-08-02 10:34                 ` Tejas Joshi
2019-08-06 15:40                   ` Tejas Joshi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).