On 10/12/26 8:51 PM, Vineet Gupta wrote:
hoist_code inserts a hoisted expression at the end of the target block,
which insert_insn_end_basic_block places before the block's final jump.
If that jump modifies one of the expression's operands, as an asm goto
does for its outputs and, with a "memory" clobber, for memory, the
hoisted expression reads the value from before the jump.  Skip such
expressions.

Bootstrapped and regression tested on x86_64-linux-gnu and aarch64-linux-gnu
(Full disclosure: the testing was with combined fixes for 3 other PRs).

        PR rtl-optimization/127847

gcc/ChangeLog:

        * gcse.cc (hoist_code): Don't hoist an expression into a block
        whose final jump insn modifies one of its operands.

gcc/testsuite/ChangeLog:

        * gcc.dg/torture/asm-goto-hoist-1.c: New test.
        * gcc.target/aarch64/asm-goto-hoist-2.c: New test.
        * gcc.target/aarch64/asm-goto-hoist-3.c: New test.
        * gcc.target/aarch64/asm-goto-hoist-4.c: New test.
        * gcc.target/i386/asm-goto-hoist-2.c: New test.
        * gcc.target/i386/asm-goto-hoist-3.c: New test.
        * gcc.target/i386/asm-goto-hoist-4.c: New test.

Signed-off-by: Vineet Gupta <[email protected]>
Something seems off here.  Yes, the problem is real (and we've fought a closely related battle since the introduction of RTL GCSE/PRE back in the late 90s.

In general we should be inserting on edges.  The exception is abnormal critical edges (which can't be split) and in those cases we try to fall back to a correct, though perhaps partially redundant insertion point.

We also prune expressions from the hash tables that cause problems over these edges.

One of those two mechanisms is more likely where we want to be fixing this problem and I'd guess the latter is the more appropriate place to fix.  Look in gcse.cc for prune_expressions.  If there's a hard reason why that approach doesn't work, then something like what's done in this patch starts to become more appropriate.

Jeff


Reply via email to