https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86108
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- It is not about crossing or not crossing, but rather about EH predecessors mixed with non-{EH,abnormal} edges or so. Without the patch we have: ;; basic block 289, loop depth 0, count 0, probably never executed ;; prev block 288, next block 290, flags: (REACHABLE, COLD_PARTITION, RTL, MODIFIED) ;; pred: 285 [always] count:0 (CROSSING) ;; 288 [never] count:0 (FALLTHRU) ;; 282 [always] count:0 ;; 280 [always] count:0 (CROSSING) ... ;; bb 289 artificial_defs: { } ;; bb 289 artificial_uses: { u-1(6){ }u-1(7){ }} ;; lr in 0 [ax] 1 [dx] 6 [bp] 7 [sp] 16 [argp] 20 [frame] ;; lr use 0 [ax] 1 [dx] 6 [bp] 7 [sp] ;; lr def 3 [bx] 43 [r14] ;; live in 0 [ax] 1 [dx] 6 [bp] 7 [sp] 20 [frame] ;; live gen 3 [bx] 43 [r14] ;; live kill (code_label 1443 2474 1444 289 1738 (nil) [28 uses]) (note 1444 1443 1445 289 [bb 289] NOTE_INSN_BASIC_BLOCK) (insn 1445 1444 1446 289 (set (reg:DI 43 r14 [464]) (reg:DI 0 ax [468])) 85 {*movdi_internal} (expr_list:REG_DEAD (reg:DI 0 ax [468]) (nil))) (insn 1446 1445 2297 289 (set (reg:DI 3 bx [466]) (reg:DI 1 dx [470])) 85 {*movdi_internal} (expr_list:REG_DEAD (reg:DI 1 dx [470]) (nil))) (jump_insn 2297 1446 2298 289 (set (pc) (label_ref 1447)) 683 {jump} (nil) -> 1447) ;; succ: 291 [always] count:0 ;; lr out 3 [bx] 6 [bp] 7 [sp] 16 [argp] 20 [frame] 43 [r14] ;; live out 3 [bx] 6 [bp] 7 [sp] 20 [frame] 43 [r14] ;; basic block 290, loop depth 0, count 0, probably never executed ;; prev block 289, next block 291, flags: (REACHABLE, COLD_PARTITION, RTL, MODIFIED) ;; pred: 311 [always] count:0 (CROSSING) ;; 94 [never] count:0 (ABNORMAL,ABNORMAL_CALL,EH) ;; bb 290 artificial_defs: { d32(0){ }d384(1){ }} ;; bb 290 artificial_uses: { u-1(6){ }u-1(7){ }u-1(16){ }u-1(20){ }} ;; lr in 6 [bp] 7 [sp] 16 [argp] 20 [frame] ;; lr use 6 [bp] 7 [sp] 16 [argp] 20 [frame] ;; lr def 0 [ax] 1 [dx] 3 [bx] 43 [r14] ;; live in 6 [bp] 7 [sp] 20 [frame] ;; live gen 0 [ax] 1 [dx] 3 [bx] 43 [r14] ;; live kill (code_label/s 1739 2298 1744 290 1798 (nil) [2 uses]) (note 1744 1739 1740 290 [bb 290] NOTE_INSN_BASIC_BLOCK) (insn 1740 1744 1741 290 (set (reg:DI 43 r14 [464]) (reg:DI 0 ax)) 85 {*movdi_internal} (expr_list:REG_DEAD (reg:DI 0 ax) (nil))) (insn 1741 1740 1447 290 (set (reg:DI 3 bx [466]) (reg:DI 1 dx)) 85 {*movdi_internal} (expr_list:REG_DEAD (reg:DI 1 dx) (nil))) ;; succ: 291 [always] count:0 (FALLTHRU) ;; lr out 3 [bx] 6 [bp] 7 [sp] 16 [argp] 20 [frame] 43 [r14] ;; live out 3 [bx] 6 [bp] 7 [sp] 20 [frame] 43 [r14] and ;; basic block 311, loop depth 0, count 0, probably never executed ;; prev block 310, next block 1, flags: (REACHABLE, HOT_PARTITION, RTL, MODIFIED) ;; pred: 77 [never] count:0 (ABNORMAL,ABNORMAL_CALL,EH) ;; 80 [never] count:0 (ABNORMAL,ABNORMAL_CALL,EH) ;; 95 [never] count:0 (ABNORMAL,ABNORMAL_CALL,EH) ;; bb 311 artificial_defs: { d1(0){ }d359(1){ }} ;; bb 311 artificial_uses: { u-1(6){ }u-1(7){ }u-1(16){ }u-1(20){ }} ;; lr in 6 [bp] 7 [sp] 16 [argp] 20 [frame] ;; lr use 6 [bp] 7 [sp] 16 [argp] 20 [frame] ;; lr def 0 [ax] 1 [dx] ;; live in 6 [bp] 7 [sp] 20 [frame] ;; live gen 0 [ax] 1 [dx] ;; live kill (code_label/s 2028 2505 2030 311 1833 (nil) [1 uses]) (note 2030 2028 2029 311 [bb 311] NOTE_INSN_BASIC_BLOCK) (jump_insn/j 2029 2030 2031 311 (set (pc) (label_ref 1739)) 683 {jump} (nil) -> 1739) ;; succ: 290 [always] count:0 (CROSSING) ;; lr out 6 [bp] 7 [sp] 16 [argp] 20 [frame] ;; live out 6 [bp] 7 [sp] 20 [frame] so the fact that ax and dx need to be live on the edge from bb 311 to bb 290 is not visible to DF and if cross-jumping decides to cross-jump bb 289 to 290, DF will think the ax/dx registers are artificially generated at the start of that bb, which is the case when arriving there from the EH edges, but not the case when arriving there from other edges.