public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* TYPE_{MIN/MAX}_VALUE for floats?
@ 2022-09-22 15:02 Aldy Hernandez
  2022-09-22 15:22 ` Jakub Jelinek
  0 siblings, 1 reply; 3+ messages in thread
From: Aldy Hernandez @ 2022-09-22 15:02 UTC (permalink / raw)
  To: Richard Biener, Jakub Jelinek, gcc-patches, MacLeod, Andrew

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

It has always irritated me that we don't have TYPE_MIN_VALUE and
TYPE_MAX_VALUE for floats (and for pointers for that matter).  This
means, we have to recalculate it ad-nauseum in vrp_val_min and
vrp_val_max.

I know we have dconstinf and dconstninf for floats, which we can just
wrap around a TREE_REAL_CST, but it still seems like we should be more
consistent here.  If we know the endpoint for a type, we should cache
it in it.

Furthermore, just the way we're chopping off NANs in the frange::set()
routine, we should be able to chop off things outside the min/max
representable range, at least for -ffinite-math-only.  For example,
the endpoints to VR_VARYING for a float in -ffinite-math-only should
be real_{min/max}_representable(), which REAL_VALUE_TYPE already
provides.   I am testing a patch to do this, but am unhappy that we
have recalculate things.

Is there a reason we can't store these in the type?

I tried the naive attached approach, but I quickly ran into LTO woes:

FAIL: gcc.c-torture/execute/ieee/20001122-1.c compilation,  -O2 -flto
-fno-use-linker-plugin -flto-partition=none
 (internal compiler error: 'verify_type' failed)

$ ./xgcc -B./ a.c -O2 -flto -w
lto1: error: type variant differs by TYPE_MAX_VALUE

So I clearly don't know what I'm doing.

Would folks be ok with filling TYPE_MIN_VALUE and friends for floats,
and if so, could someone give me a hand here?  What am I missing?

Thanks.
Aldy

p.s. Now that we're onto this subject, in the distant future, I'd
actually like to store a vrange in the tree type.  I mean, they are
first class citizens in the SSA name now, and we have a typeless way
of storing ranges in GC space.  Anywho, that's for the future, cause I
like the pain... just wanted to gauge the temperature on that one as
well.

[-- Attachment #2: float-endpoints.patch --]
[-- Type: text/x-patch, Size: 2702 bytes --]

diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc
index 88923c4136b..98f268d9f5a 100644
--- a/gcc/stor-layout.cc
+++ b/gcc/stor-layout.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "debug.h"
 #include "calls.h"
+#include "real.h"
 
 /* Data type for the expressions representing sizes of data types.
    It is the first integer type laid out.  */
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 4165cbd7c3b..7a1fc6c4888 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -7620,6 +7620,31 @@ build_offset_type (tree basetype, tree type)
   return t;
 }
 
+/* Create a floating point type with PRECISION.  */
+
+tree
+build_float_type (unsigned precision)
+{
+  tree type = make_node (REAL_TYPE);
+  TYPE_PRECISION (type) = precision;
+  layout_type (type);
+
+  if (flag_finite_math_only)
+    {
+      REAL_VALUE_TYPE min, max;
+      real_min_representable (&min, type);
+      real_max_representable (&max, type);
+      TYPE_MIN_VALUE (type) = build_real (type, min);
+      TYPE_MAX_VALUE (type) = build_real (type, max);
+    }
+  else
+    {
+      TYPE_MIN_VALUE (type) = build_real (type, dconstninf);
+      TYPE_MAX_VALUE (type) = build_real (type, dconstinf);
+    }
+  return type;
+}
+
 /* Create a complex type whose components are COMPONENT_TYPE.
 
    If NAMED is true, the type is given a TYPE_NAME.  We do not always
@@ -9427,17 +9452,9 @@ build_common_tree_nodes (bool signed_char)
 
   pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
 
-  float_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
-  layout_type (float_type_node);
-
-  double_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
-  layout_type (double_type_node);
-
-  long_double_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
-  layout_type (long_double_type_node);
+  float_type_node = build_float_type (FLOAT_TYPE_SIZE);
+  double_type_node = build_float_type (DOUBLE_TYPE_SIZE);
+  long_double_type_node = build_float_type (LONG_DOUBLE_TYPE_SIZE);
 
   for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
     {
diff --git a/gcc/tree.h b/gcc/tree.h
index 266e24a0563..b83fac17f1a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4729,6 +4729,7 @@ extern tree build_varargs_function_type_array (tree, int, tree *);
 extern tree build_method_type_directly (tree, tree, tree);
 extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
+extern tree build_float_type (unsigned);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts (const_tree);
 

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

* Re: TYPE_{MIN/MAX}_VALUE for floats?
  2022-09-22 15:02 TYPE_{MIN/MAX}_VALUE for floats? Aldy Hernandez
@ 2022-09-22 15:22 ` Jakub Jelinek
  2022-09-22 15:45   ` Aldy Hernandez
  0 siblings, 1 reply; 3+ messages in thread
From: Jakub Jelinek @ 2022-09-22 15:22 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Richard Biener, gcc-patches, MacLeod, Andrew

On Thu, Sep 22, 2022 at 05:02:19PM +0200, Aldy Hernandez wrote:
> It has always irritated me that we don't have TYPE_MIN_VALUE and
> TYPE_MAX_VALUE for floats (and for pointers for that matter).  This
> means, we have to recalculate it ad-nauseum in vrp_val_min and
> vrp_val_max.
> 
> I know we have dconstinf and dconstninf for floats, which we can just
> wrap around a TREE_REAL_CST, but it still seems like we should be more
> consistent here.  If we know the endpoint for a type, we should cache
> it in it.

This looks problematic.
While for !MODE_HAS_INFINITIES there are clear values, otherwise
the flag_finite_math_only flag has Optimization keyword, so it can change
between different functions, while a type is a global entity that can be
used by both __attribute__((optimize ("Ofast"))) and standard floating point
functions.
In some sense it is similar to TYPE_MODE which for vectors needs to be
actually a function call that decides based on the current function.
But then, having it in TYPE_*_VALUE doesn't have the benefits you want from
it...

	Jakub


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

* Re: TYPE_{MIN/MAX}_VALUE for floats?
  2022-09-22 15:22 ` Jakub Jelinek
@ 2022-09-22 15:45   ` Aldy Hernandez
  0 siblings, 0 replies; 3+ messages in thread
From: Aldy Hernandez @ 2022-09-22 15:45 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Richard Biener, gcc-patches, MacLeod, Andrew

On Thu, Sep 22, 2022 at 5:22 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Thu, Sep 22, 2022 at 05:02:19PM +0200, Aldy Hernandez wrote:
> > It has always irritated me that we don't have TYPE_MIN_VALUE and
> > TYPE_MAX_VALUE for floats (and for pointers for that matter).  This
> > means, we have to recalculate it ad-nauseum in vrp_val_min and
> > vrp_val_max.
> >
> > I know we have dconstinf and dconstninf for floats, which we can just
> > wrap around a TREE_REAL_CST, but it still seems like we should be more
> > consistent here.  If we know the endpoint for a type, we should cache
> > it in it.
>
> This looks problematic.
> While for !MODE_HAS_INFINITIES there are clear values, otherwise
> the flag_finite_math_only flag has Optimization keyword, so it can change
> between different functions, while a type is a global entity that can be
> used by both __attribute__((optimize ("Ofast"))) and standard floating point
> functions.

Oh...it can have different values in different functions?  Yeah,
that's not gonna work.  Oh well, thanks.

Aldy


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

end of thread, other threads:[~2022-09-22 15:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-22 15:02 TYPE_{MIN/MAX}_VALUE for floats? Aldy Hernandez
2022-09-22 15:22 ` Jakub Jelinek
2022-09-22 15:45   ` Aldy Hernandez

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