https://gcc.gnu.org/g:3518a4892d0dd65ca841b82519832147d626ca2e
commit r17-5185-g3518a4892d0dd65ca841b82519832147d626ca2e Author: Jin Ma <[email protected]> Date: Tue Oct 13 14:03:49 2026 +0800 sched: Avoid creating fusion groups during selective scheduling Selective scheduling builds its instruction expressions after the initial Haifa dependency analysis. Reanalyzing instructions later can set SCHED_GROUP_P without updating VINSN_UNIQUE_P or the group links. This can make sel_rank_for_schedule violate comparator antisymmetry and trigger an ICE with checking enabled. Only create macro-fusion groups during Haifa dependency analysis, including the initial Haifa emulation used by selective scheduling. Add RTL regressions using the existing XiangShan zero-extension fusion rules. Check that initial grouping still runs and that scheduling does not create a new group for initially separated shifts. A loop variant reproduces the comparator ICE during software pipelining. The regression tests were generated with LLM assistance. gcc/ChangeLog: * sched-deps.cc (sched_analyze_insn): Restrict macro-fusion grouping to Haifa dependency analysis. gcc/testsuite/ChangeLog: * gcc.target/riscv/sched-fusion-selective.c: New test. * gcc.target/riscv/sched-fusion-selective-ice.c: Likewise. Signed-off-by: Jin Ma <[email protected]> Diff: --- gcc/sched-deps.cc | 1 + .../gcc.target/riscv/sched-fusion-selective-ice.c | 60 ++++++++++++++++++++++ .../gcc.target/riscv/sched-fusion-selective.c | 42 +++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/gcc/sched-deps.cc b/gcc/sched-deps.cc index 24b76a3ad891..d1e69af1e816 100644 --- a/gcc/sched-deps.cc +++ b/gcc/sched-deps.cc @@ -2944,6 +2944,7 @@ sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn) /* Group compare and branch insns for macro-fusion. */ if (!deps->readonly + && (!sel_sched_p () || sched_emulate_haifa_p) && targetm.sched.macro_fusion_p && targetm.sched.macro_fusion_p ()) sched_macro_fuse_insns (insn); diff --git a/gcc/testsuite/gcc.target/riscv/sched-fusion-selective-ice.c b/gcc/testsuite/gcc.target/riscv/sched-fusion-selective-ice.c new file mode 100644 index 000000000000..bc5f8e863201 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sched-fusion-selective-ice.c @@ -0,0 +1,60 @@ +/* Verify that macro fusion does not cause an ICE in selective scheduling. */ + +/* { dg-do compile { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-O[sgz]" "-flto" } } */ +/* { dg-options "-O2 -fselective-scheduling2 -fsel-sched-pipelining" } */ +/* { dg-additional-options "-march=rv64gc -mabi=lp64d" } */ +/* { dg-additional-options "-mtune=xiangshan-nanhu -fchecking=2" } */ + +long __RTL (startwith ("sched2")) +sched_fusion_selective_ice (void) +{ +(function "sched_fusion_selective_ice" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cnote 2 NOTE_INSN_FUNCTION_BEG) + (edge-to 3 (flags "FALLTHRU")) + ) + (block 3 + (edge-from 2 (flags "FALLTHRU")) + (edge-from 3) + (clabel 3 2) + (cnote 4 [bb 3] NOTE_INSN_BASIC_BLOCK) + (cinsn 5 (set (reg:DI a2) + (ashift:DI (reg:DI a2) (const_int 48)))) + (cinsn 6 (set (reg:DI a1) + (mult:DI (reg:DI a1) (reg:DI a4)))) + (cinsn 7 (set (reg:DI a2) + (lshiftrt:DI (reg:DI a2) (const_int 48)))) + (cinsn 8 (set (reg:DI a0) + (ashift:DI (reg:DI a0) (const_int 32)))) + (cinsn 9 (set (reg:DI a0) + (lshiftrt:DI (reg:DI a0) (const_int 32)))) + (cinsn 10 (set (reg:DI a0) + (plus:DI (reg:DI a0) (reg:DI a1)))) + (cinsn 11 (set (reg:DI a0) + (plus:DI (reg:DI a0) (reg:DI a2)))) + (cinsn 12 (set (reg:DI a3) + (plus:DI (reg:DI a3) (reg:DI a0)))) + (cjump_insn 13 (set (pc) + (if_then_else (ne (reg:DI a3) (const_int 0)) + (label_ref 3) (pc)))) + (edge-to 3) + (edge-to 4 (flags "FALLTHRU")) + ) + (block 4 + (edge-from 3 (flags "FALLTHRU")) + (cnote 14 [bb 4] NOTE_INSN_BASIC_BLOCK) + (cinsn 15 (use (reg:DI a0))) + (cjump_insn 16 (simple_return)) + (edge-to exit) + ) + (cbarrier 17) + ) + (crtl + (return_rtx (reg/i:DI a0)) + ) +) +} diff --git a/gcc/testsuite/gcc.target/riscv/sched-fusion-selective.c b/gcc/testsuite/gcc.target/riscv/sched-fusion-selective.c new file mode 100644 index 000000000000..39368bc817e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sched-fusion-selective.c @@ -0,0 +1,42 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-O[sgz]" "-flto" } } */ +/* { dg-options "-O2 -fselective-scheduling2 -fdump-rtl-sched2" } */ +/* { dg-additional-options "-march=rv64gc -mabi=lp64d" } */ +/* { dg-additional-options "-mtune=xiangshan-nanhu -fchecking=2" } */ +/* { dg-final { scan-rtl-dump "RISCV_FUSE_ZEXTW" "sched2" } } */ +/* { dg-final { scan-rtl-dump-not "RISCV_FUSE_ZEXTH" "sched2" } } */ + +long __RTL (startwith ("sched2")) +sched_fusion_selective (void) +{ +(function "sched_fusion_selective" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cnote 2 NOTE_INSN_FUNCTION_BEG) + (cinsn 5 (set (reg:DI a2) + (ashift:DI (reg:DI a2) (const_int 48)))) + (cinsn 6 (set (reg:DI a1) + (mult:DI (reg:DI a1) (reg:DI a4)))) + (cinsn 7 (set (reg:DI a2) + (lshiftrt:DI (reg:DI a2) (const_int 48)))) + (cinsn 8 (set (reg:DI a0) + (ashift:DI (reg:DI a0) (const_int 32)))) + (cinsn 9 (set (reg:DI a0) + (lshiftrt:DI (reg:DI a0) (const_int 32)))) + (cinsn 10 (set (reg:DI a0) + (plus:DI (reg:DI a0) (reg:DI a1)))) + (cinsn 11 (set (reg:DI a0) + (plus:DI (reg:DI a0) (reg:DI a2)))) + (cinsn 15 (use (reg:DI a0))) + (cjump_insn 16 (simple_return)) + (edge-to exit) + ) + (cbarrier 17) + ) + (crtl + (return_rtx (reg/i:DI a0)) + ) +) +}
