Well, if we don't adjust gimple_call_return_type() to handle built-ins
with no LHS, then we must adjust the callers.

The attached patch fixes gimple_expr_type() per it's documentation:

/* Return the type of the main expression computed by STMT.  Return
   void_type_node if the statement computes nothing.  */

Currently gimple_expr_type is ICEing because it calls gimple_call_return_type.

I still think gimple_call_return_type should return void_type_node
instead of ICEing, but this will also fix my problem.

Anyone have a problem with this?

Aldy

On Thu, Jun 24, 2021 at 3:57 PM Andrew MacLeod via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On 6/24/21 9:45 AM, Jakub Jelinek wrote:
> > On Thu, Jun 24, 2021 at 09:31:13AM -0400, Andrew MacLeod via Gcc-patches 
> > wrote:
> >> We'll still compute values for statements that don't have a LHS.. there's
> >> nothing inherently wrong with that.  The primary example is
> >>
> >> if (x_2 < y_3)
> >>
> >> we will compute [0,0] [1,1] or [0,1] for that statement, without a LHS.  It
> >> primarily becomes a generic way to ask for the range of each of the 
> >> operands
> >> of the statement, and process it regardless of the presence of a LHS.  I
> >> don't know, maybe there is (or will be)  an internal function that doesn't
> >> have a LHS but which can be folded away/rewritten if the operands are
> >> certain values.
> > There are many internal functions that aren't ECF_CONST or ECF_PURE.  Some
> > of them, like IFN*STORE* I think never have an lhs, others have them, but
> > if the lhs is unused, various optimization passes can just remove those lhs
> > from the internal fn calls (if they'd be ECF_CONST or ECF_PURE, the calls
> > would be DCEd).
> >
> > I think generally, if a call doesn't have lhs, there is no point in
> > computing a value range for that missing lhs.  It won't be useful for the
> > call arguments to lhs direction (nothing would care about that value) and
> > it won't be useful on the direction from the lhs to the call arguments
> > either.  Say if one has
> >    p_23 = __builtin_memcpy (p_75, q_23, 16);
> > then one can imply from ~[0, 0] range on p_75 that p_23 has that range too
> > (and vice versa), but if one has
> >    __builtin_memcpy (p_125, q_23, 16);
> > none of that makes sense.
> >
> > So instead of punting when gimple_call_return_type returns NULL IMHO the
> > code should punt when gimple_call_lhs is NULL.
> >
> >
>
> Well, we are going to punt anyway, because the call type, whether it is
> NULL or VOIDmode is not supported by irange.   It was more just a matter
> of figuring out whether us checking for internal call or the
> gimple_function_return_type call should do the check...   Ultimately in
> the end it doesnt matter.. just seemed like something someone else could
> trip across if we didnt strengthen gimple_call_return_type to not ice.
>
> Andrew
>
commit 2717e79f571b23f74bb438c27ad1551de8eb9a4d
Author: Aldy Hernandez <al...@redhat.com>
Date:   Thu Jul 15 12:47:26 2021 +0200

    Handle built-ins with no return TYPE in gimple_expr_type.
    
    Since gimple_call_return_type ICE's, on built-ins with no return types,
    all callers must be adjusted.
    
    gcc/ChangeLog:
    
            * gimple-range-fold.cc (fold_using_range::range_of_call):
            * gimple.h (gimple_expr_type):

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index eff5d1f89f2..7d20c6b4b04 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -780,7 +780,7 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
 bool
 fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src)
 {
-  tree type = gimple_call_return_type (call);
+  tree type = gimple_expr_type (call);
   tree lhs = gimple_call_lhs (call);
   bool strict_overflow_p;
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index acf572b81be..395257eb312 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -6633,6 +6633,13 @@ gimple_expr_type (const gimple *stmt)
 	  default:
 	    break;
 	  }
+
+      // ?? The call to gimple_call_return_type below will ICE on
+      // built-ins with no LHS.  An alternative would be to return
+      // void_type_node from it insteadl.
+      if (!gimple_call_lhs (call_stmt) && gimple_call_internal_p (call_stmt))
+	return void_type_node;
+
       return gimple_call_return_type (call_stmt);
     }
   else if (code == GIMPLE_ASSIGN)

Reply via email to