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

--- Comment #13 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:8154fc95f097a146f9c80edcaafb2baff73065b5

commit r16-1398-g8154fc95f097a146f9c80edcaafb2baff73065b5
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Jun 10 20:04:52 2025 +0200

    expand, ranger: Use ranger during expansion [PR120434]

    As the following testcase shows, during expansion we use value range info
    in lots of places, but sadly currently use only the global ranges.
    It is mostly through get_range_pos_neg function, which uses
    get_global_range_query ()->range_of_expr (arg1, arg2)
    but other spots use it directly.

    On the testcase at the end of the patch, in foo we don't know range of x,
    so emit the at least on x86_64 less efficient signed division in that case.
    In bar, the default def SSA_NAME has global range and we try to expand
    the division both as signed and unsigned because the range proves they will
    have the same result and choose the cheaper one.
    And finally in baz, we have VARYING in global range, but can do better if
    we ask for range at the statement we're expanding.

    The main problem of using the ranger during expansion is that things are in
    flux, the already expanded basic blocks switch their IL from gimple to RTL
    (bb->flags & BB_RTL) and the gimple stmts are gone, PHI nodes even earlier,
    etc.

    The patch attempts to make the ranger usable by keeping (bb->flags &
BB_RTL)
    == 0 on basic blocks for longer, in particular until the last
    expand_gimple_basic_block call for the function.  Instead of changing the
    IL right away, it uses a vector indexed by bb->index to hold the
    future BB_HEAD/BB_END.  I had to do a few changes on the ranger side and
    maybe testing in the wild will show a few extra cases, but I think those
    are tolerable and can be guarded with currently_expanding_to_rtl so that
    we don't punt on consistency checks on normal GIMPLE.
    In particular, even with the patch there will still be some BB_RTL
    bbs in the IL, e.g. the initial block after ENTRY, ENTRY and EXIT blocks
    and from time to time others as well, but those should never contain
    anything intreresting from the ranger POV.  And switch expansion can drop
    the default edge if it is __builtin_unreachable.

    Also, had to change the internal call TER expansion, the current way
    of temporarily changing gimple_call_lhs ICEd badly in the ranger, so I'm
    instead temporarily changing SSA_NAME_VAR of the SSA_NAME.

    2025-06-10  Jakub Jelinek  <ja...@redhat.com>

            PR middle-end/120434
            * cfgrtl.h (update_bb_for_insn_chain): Declare.
            * cfgrtl.cc (update_bb_for_insn_chain): No longer static.
            * cfgexpand.h (expand_remove_edge): Declare.
            * cfgexpand.cc: Include "gimple-range.h".
            (head_end_for_bb): New variable.
            (label_rtx_for_bb): Drop ATTRIBUTE_UNUSED from bb argument.
            Use head_end_for_bb if possible for non-BB_RTL bbs.
            (expand_remove_edge): New function.
            (maybe_cleanup_end_of_block): Use it instead of remove_edge.
            (expand_gimple_cond): Don't clear EDGE_TRUE_VALUE and
            EDGE_FALSE_VALUE just yet.  Use head_end_for_bb elts instead
            of BB_END and update_bb_for_insn_chain instead of
update_bb_for_insn.
            (expand_gimple_tailcall): Use expand_remove_edge instead of
            remove_edge.  Use head_end_for_bb elts instead of BB_END and
            update_bb_for_insn_chain instead of update_bb_for_insn.
            (expand_gimple_basic_block): Don't change bb to BB_RTL here,
instead
            use head_end_for_bb elts instead of BB_HEAD and BB_END.  Use
            update_bb_for_insn_chain instead of update_bb_for_insn.
            (pass_expand::execute): Enable ranger before
expand_gimple_basic_block
            calls and create head_end_for_bb vector.  Disable ranger after
            those calls, turn still non-BB_RTL blocks into BB_RTL and set their
            BB_HEAD and BB_END from head_end_for_bb elts, and clear
EDGE_TRUE_VALUE
            and EDGE_FALSE_VALUE flags on edges.  Release head_end_for_bb
            vector.
            * tree-outof-ssa.cc (expand_phi_nodes): Don't clear phi nodes here.
            * tree.h (get_range_pos_neg): Add gimple * argument defaulted to
NULL.
            * tree.cc (get_range_pos_neg): Add stmt argument.  Use
            get_range_query (cfun) instead of get_global_range_query () and
pass
            stmt as third argument to range_of_expr.
            * expr.cc (expand_expr_divmod): Pass
currently_expanding_gimple_stmt
            to get_range_pos_neg.
            (expand_expr_real_1) <case SSA_NAME>: Change internal fn handling
            to avoid temporarily overwriting gimple_call_lhs of ifn, instead
            temporarily overwrite SSA_NAME_VAR of its lhs.
            (maybe_optimize_pow2p_mod_cmp): Pass
currently_expanding_gimple_stmt
            to get_range_pos_neg.
            (maybe_optimize_mod_cmp): Likewise.
            * internal-fn.cc (get_min_precision): Likewise.  Use
            get_range_query (cfun) instead of get_global_range_query () and
pass
            currently_expanding_gimple_stmt as third argument to range_of_expr.
            Pass g to get_range_pos_neg.
            (expand_addsub_overflow): Pass currently_expanding_gimple_stmt
            to get_range_pos_neg.
            (expand_mul_overflow): Likewise.
            (expand_arith_overflow): Pass stmt to get_range_pos_neg.
            * gimple-range-edge.cc: Include rtl.h.
            (gimple_outgoing_range_stmt_p): Return NULL for BB_RTL bbs.
            (gimple_outgoing_range::calc_switch_range): If default_edge is
NULL,
            assert currently_expanding_to_rtl and return before trying to
            set range on that edge.
            * builtins.cc (expand_builtin_strnlen): Use get_range_query (cfun)
            instead of get_global_range_query () and pass
            currently_expanding_gimple_stmt as third argument to range_of_expr.
            (determine_block_size): Likewise.
            * gimple-range.cc (gimple_ranger::range_on_exit): Set s to NULL
            instead of last_nondebug_stmt for BB_RTL bbs.
            * stmt.cc: Include cfgexpand.h.
            (expand_case): Use expand_remove_edge instead of remove_edge.

            * gcc.target/i386/pr120434-1.c: New test.

Reply via email to