On Mon, 9 Jun 2025, Jakub Jelinek wrote: > On Sun, Jun 08, 2025 at 10:49:44AM +0200, Richard Biener wrote: > > I'm also a bit nervous about this given during RTL expansion the IL is > > neither fully GIMPLE nor fully RTL. Given we do not perform many > > range queries we might be just lucky to not run into any issues? > > So, I've added following incremental patch: > > --- gcc/expr.cc.jj 2025-06-09 15:07:38.882265627 +0200 > +++ gcc/expr.cc 2025-06-09 16:18:26.988947027 +0200 > @@ -66,6 +66,7 @@ along with GCC; see the file COPYING3. > #include "tree-pretty-print.h" > #include "flags.h" > #include "internal-fn.h" > +#include "value-query.h" > > > /* If this is nonzero, we do not bother generating VOLATILE > @@ -11348,6 +11348,25 @@ expand_expr_real_1 (tree exp, rtx target > LAST_VIRTUAL_REGISTER + 1); > } > > + { > + gimple *cg = currently_expanding_gimple_stmt; > + if (INTEGRAL_TYPE_P (TREE_TYPE (exp))) > + { > + int_range_max vr; > + get_range_query (cfun)->range_of_expr (vr, exp, cg); > + } > + else if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (exp))) > + { > + frange vr; > + get_range_query (cfun)->range_of_expr (vr, exp, cg); > + } > + else if (POINTER_TYPE_P (TREE_TYPE (exp))) > + { > + prange vr; > + get_range_query (cfun)->range_of_expr (vr, exp, cg); > + } > + } > + > g = get_gimple_for_ssa_name (exp); > /* For EXPAND_INITIALIZER try harder to get something simpler. */ > if (g == NULL > > (in first attempt this was guarded with if (flag_checking), but that > was a bad idea, because it then causes bootstrap comparison failure, > one stage built with -fno-checking, another with -fchecking and the > different range queries result in different answers from the other range > queries). I don't think we want to guard that with #if CHECKING_P either > though, if it can cause different code generation (I think there were about > 15 .bad_compare files on x86_64 and none on i686), then we'd be testing for > months something that we'll actually not release afterwards. > > And the only issue it found (in x86_64 and i686-linux bootstraps/regtests) > is that the 4 remove_edge calls done during expansion will not remove > phi arguments and so ranger can then ICE. > > With the following incremental patch I don't see other problems.
OK, that's re-assuring. When we remove edges we change the CFG - does the ranger cache need any updating for this? > --- gcc/cfgexpand.h.jj 2025-04-08 14:08:48.481320427 +0200 > +++ gcc/cfgexpand.h 2025-06-09 15:01:52.946766978 +0200 > @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. > > extern tree gimple_assign_rhs_to_tree (gimple *); > extern HOST_WIDE_INT estimated_stack_frame_size (struct cgraph_node *); > +extern void expand_remove_edge (edge); > extern void set_parm_rtl (tree, rtx); > > > --- gcc/cfgexpand.cc.jj 2025-06-09 14:18:56.000000000 +0200 > +++ gcc/cfgexpand.cc 2025-06-09 15:01:36.423981975 +0200 > @@ -2818,6 +2818,19 @@ label_rtx_for_bb (basic_block bb) > } > > > +/* Wrapper around remove_edge during expansion. */ > + > +void > +expand_remove_edge (edge e) > +{ > + if (current_ir_type () != IR_GIMPLE > + && (e->dest->flags & BB_RTL) == 0 > + && !gimple_seq_empty_p (phi_nodes (e->dest))) > + remove_phi_args (e); > + remove_edge (e); > +} > + > + > /* A subroutine of expand_gimple_cond. Given E, a fallthrough edge > of a basic block where we just expanded the conditional at the end, > possibly clean up the CFG and instruction sequence. LAST is the > @@ -2840,7 +2853,7 @@ maybe_cleanup_end_of_block (edge e, rtx_ > if (BARRIER_P (get_last_insn ())) > { > rtx_insn *insn; > - remove_edge (e); > + expand_remove_edge (e); > /* Now, we have a single successor block, if we have insns to > insert on the remaining edge we potentially will insert > it at the end of this block (if the dest block isn't feasible) > @@ -4460,7 +4473,7 @@ expand_gimple_tailcall (basic_block bb, > if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) > e->dest->count -= e->count (); > probability += e->probability; > - remove_edge (e); > + expand_remove_edge (e); > } > else > ei_next (&ei); > @@ -7311,7 +7324,7 @@ pass_expand::execute (function *fun) > In the future we should get this fixed properly. */ > if ((e->flags & EDGE_ABNORMAL) > && !(e->flags & EDGE_SIBCALL)) > - remove_edge (e); > + expand_remove_edge (e); > else > ei_next (&ei); > } > --- gcc/stmt.cc.jj 2025-04-08 14:09:00.253156547 +0200 > +++ gcc/stmt.cc 2025-06-09 15:18:30.714708828 +0200 > @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. > #include "tree-cfg.h" > #include "dumpfile.h" > #include "builtins.h" > +#include "cfgexpand.h" > > > /* Functions and data structures for expanding case statements. */ > @@ -1025,7 +1026,7 @@ expand_case (gswitch *stmt) > && gimple_seq_unreachable_p (bb_seq (default_edge->dest))) > { > default_label = NULL; > - remove_edge (default_edge); > + expand_remove_edge (default_edge); > default_edge = NULL; > } > > > Another option would be to add to the > IR_GIMPLE, > IR_RTL_CFGRTL, > IR_RTL_CFGLAYOUT > cases add IR_EXPAND which would be something in between IR_GIMPLE > and IR_RTL_CFGRTL, the IL is mostly GIMPLE, but new basic blocks > are created as BB_RTL and stuff like edge removal would check if > e->dest->flags & BB_RTL or not. And e.g. edge insertions are RTL > instead of GIMPLE. Perhaps cleaner but might be too much work. Yeah. Likewise the idea I had on IRC to expand to a new CFG and keep the GIMPLE CFG unmodified. You'd have to pass "the cfg" around everywhere (instead of the function via cfun). > > Can we maybe try forcing a range query for all SSA names we expand > > to increase coverage? I'll also note that > > > > get_global_range_query ()->range_of_expr (arg1, arg2) > > > > does not use any context, but only context for defs when querying up > > the chain. Context should generally be the current stmt we expand, > > Sure, that is why the patch replaces those with > !get_range_query (cfun)->range_of_expr (\arg1, arg2, stmt) > where stmt is in the end usually currently_expanding_gimple_stmt. Ah, OK. I obviously did not look at most of the actual patch yet. > > That said, I'd be a little less nervous if we'd process basic-blocks > > in dominator order instead of in the way we do now. IIRC we do not > > create new basic-blocks up to the first expand_gimple_basic_block? > > We do create them. E.g. the init_block (new successor of ENTRY bb). > There are others created during the expand_gimple_basic_block calls. > And something perhaps changeable but not changed by me is that > ENTRY and EXIT are changed to BB_RTL early as well (but they don't > contain instructions, so it isn't that big deal). > > > So using, say, get_all_dominated_blocks (we free dominators, possibly > > PHI expansion might insert on edges) to get a PRE ordered set of > > I think PHI expansion does insert on edges. Yes, it must (but we expand those separately, so we could tear down ranger then). So apart from ICEing I wonder how ranger (and it's cache) deals with basic blocks being added, edges vanishing (we kill off all abnormal edges - those ranger usually "stops" at, for correctness), edges being added (find_many_sub_basic_blocks), etc. - are we sure we get correct range answers when the cache was from a "different" CFG (the set of CFG manipulations are of course constrained, but this isn't very well documented and also not very well ordered/isolated) Richard. > > blocks to visit, just to make it less random. > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)