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

Reply via email to