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)