https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107898

Andrew Macleod <amacleod at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amacleod at redhat dot com

--- Comment #3 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to Richard Biener from comment #1)

> I'm not sure why we have to require compatible ranges on intersection
> of irange though?  Since we don't have anti-ranges there's no implicit

Its doesnt require compatible types, it requires compatible precisions. From
gimple-range-fold.h:

static inline bool
range_compatible_p (tree type1, tree type2)
{
  // types_compatible_p requires conversion in both directions to be useless.
  // GIMPLE only requires a cast one way in order to be compatible.
  // Ranges really only need the sign and precision to be the same.
  return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
          && TYPE_SIGN (type1) == TYPE_SIGN (type2)); 
}



> 
> Unfortunately there's no conversion operator or operator> for irange,
> we just want to ask if (r > max_size) (and have max_size converted to
> the type of r with saturation).

You can cast an irange to another type using range_cast. ie something like

diff --git a/gcc/gimple-ssa-warn-alloca.cc b/gcc/gimple-ssa-warn-alloca.cc
index 83a241a3a4b..0502c433f93 100644
--- a/gcc/gimple-ssa-warn-alloca.cc
+++ b/gcc/gimple-ssa-warn-alloca.cc
@@ -225,6 +225,8 @@ alloca_call_type (gimple *stmt, bool is_vla)
                                  build_int_cst (size_type_node, max_size),
                                  VR_ANTI_RANGE);

+      if (!types_compatible_p (r.type (), invalid_range.type ()))
+       range_cast (invalid_range, r.type ());
       r.intersect (invalid_range);
       if (r.undefined_p ())
        return alloca_type_and_limit (ALLOCA_OK)

We decided to force something like this to be explicit by the caller rather
than make assumptions in intersect/union and silently do conversions.  We've
caught a number of bugs along the way because of this.

Another option would be to simply create the invalid_range with the same type
upfront instead of assuming size_type_node. ie:

@@ -221,8 +221,8 @@ alloca_call_type (gimple *stmt, bool is_vla)
       && !r.varying_p ())
     {
       // The invalid bits are anything outside of [0, MAX_SIZE].
-      int_range<2> invalid_range (build_int_cst (size_type_node, 0),
-                                 build_int_cst (size_type_node, max_size),
+      int_range<2> invalid_range (build_int_cst (r.type (), 0),
+                                 build_int_cst (r.type (), max_size),
                                  VR_ANTI_RANGE);

       r.intersect (invalid_range);

As long as r.type () is irange::supports_p (r.type ())

Reply via email to