On 9/22/26 3:33 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

An RTL basic block that ends in a tablejump cannot normally be duplicated.
The instructions that compute the table address can be outside the block, so
copying and retargeting the table is not reliable.

Let an opted-in pass keep one table instead.  Before duplication, one jump
owns the adjacent table:

   jump A -> label T -> addr_diff_vec

After duplication, both jumps name the same label and table:

   jump A --\
              label T -> addr_diff_vec
   jump B --/

Mark the table with the sticky JUMP_TABLE_SHARED_P flag.  A shared table is
immutable because each entry describes a successor of every dispatch that
uses it.  Block deletion can remove one dispatch but must retain the table for
the others.

Add PROP_rtl_allow_tablejump_duplication as a function property.  The RTL hook
uses it to permit the copy, retain JUMP_LABEL, and mark the table.  A pass can
set the property while it is prepared for the table to become immutable.

Guard the RTL redirection, deletion, fall-through, merge, and cross-jump paths
that assume one owner or physical adjacency.  Add checking assertions for
bulk deletion and verify every shared dispatch against the table successors.

Treat shared tablejumps as nonregular for interblock scheduling.  This prevents
selective scheduling from splitting shared-table edges to create loop
preheaders or bookkeeping blocks.

No pass opts in in this patch, so it does not change generated code by
itself.

gcc/ChangeLog:

        PR middle-end/126236
        * tree-pass.h (PROP_rtl_allow_tablejump_duplication): New property.
        * cfgcleanup.cc (outgoing_edges_match): Reject matches involving a
        shared jump table.
        * cfgrtl.cc (shared_jump_table_component_p): New function.
        (shared_jump_table_between_p): Likewise.
        (delete_insn_chain): Assert that the range does not contain a shared
        jump table.
        (can_fallthru, rtl_can_merge_blocks, rtl_tidy_fallthru_edge): Do not
        remove or cross a shared jump table between basic blocks.
        (cfg_layout_can_duplicate_bb_p): Allow a tablejump when the new
        property is set.
        (duplicate_insn_chain): Retain a copied tablejump's table and mark it
        shared.
        (patch_jump_insn): Refuse to redirect through a shared table.
        (try_redirect_by_replacing_jump): Do not delete a shared table.
        (get_last_bb_insn): Do not treat a shared table as part of one block.
        (force_nonfallthru_and_redirect): Likewise.
        (rtl_verify_edges): Check each shared table against the successors of
        each dispatch that uses it.
        * jump.cc (delete_related_insns): Do not delete a shared table.
        * rtl.h (JUMP_TABLE_SHARED_P): New macro.
        (rtx_def): Document the shared-table use of the unchanging flag.
        * sched-rgn.cc (is_cfg_nonregular): Reject shared tablejumps.
        * doc/cfg.texi: Document shared jump tables.
        * doc/md.texi: Likewise.
        * doc/rtl.texi: Likewise.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
So high level question.  For ADDR_DIFF_VEC, I think we also have to be careful that the implementation doesn't use a pc-relative jump under the hood.  The PA used to work like that until circa 2013 (I didn't realize it'd been rewritten until I started looking at it's code and didn't see what I expected to see).  I can't speak for other ports.  I probably should have included this in the audit request I did the first time around.  However the PA may be using mfia rather than a blr which may result in it still being pc-relative, just not in the way I expected to find.


I think the assumption is the we're doing a pc-relative jump using the table element to get hte difference between the jump site and the final label (with some minor delta).  That has worked because the table follows the pc-relative indirect jump immediately in the insn stream.  I don't think it's going to work if we share jump tables on targets that use ADDR_DIFF_VEC.

I would look very closely at cris, vax, sh, stormy16, hppa, c6x, nds32, s390, ft32, mips (16), arm/thumb2, csky, mn103 and csky. Using pc-relative in and of itself isn't a problem, but instead a signal that there may be some implicit dependency on the jump table immediately following the jump itself.

Jeff


Reply via email to