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.

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

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

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

> blocks to visit, just to make it less random.

        Jakub

Reply via email to