https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77416
--- Comment #5 from Peter Bergner <bergner at gcc dot gnu.org> --- So this is a latent bug in LRA's rematerialization code. For this test case, we have insn: Basic BlocK 6: ... (insn 179 178 92 6 (parallel [ (set (reg/v:SI 175 [ pD.2425 ]) (plus:SI (reg/v:SI 271 [orig:179 p2D.2421 ] [179]) (reg:SI 76 ca))) (clobber (reg:SI 76 ca)) ]) t.i:23 96 {addsi3_carry_in_0} (expr_list:REG_DEAD (reg:SI 76 ca) (expr_list:REG_UNUSED (reg:SI 76 ca) (nil)))) ... BB6 ends in a conditional branch. Basic Block 7 (fall through from BB6) (insn 99 98 100 7 (set (reg:SI 3 3) (reg/v:SI 175 [ pD.2425 ])) t.i:26 464 {*movsi_internal1} (expr_list:REG_DEAD (reg/v:SI 175 [ pD.2425 ]) (nil))) ... Pseudo r175 is marked for spilling and LRA thinks it can remat r175 in insn 99 because it thinks its operands have not changed. The problem is that insn 179 not only uses the CA, it also clobbers it making remat illegal. The do_remat() routine does check whether the candidate remat insn's operands are still ok. The bug is that it isn't actually checking ALL of the insn's operands. The code in lra_update_insn_regno_info() which computes which regs are used in the insn uses the recog n_operands to determine the number of operands in the insn, but in the pattern for this insn, we have a hard coded use of the CA reg so it doesn't get counted in the n_operands: (define_insn "add<mode>3_carry_in_0" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") (reg:GPR CA_REGNO))) (clobber (reg:GPR CA_REGNO))] So this pattern only has 2 operands[] entries, but the CA really is an operand. Looking at i386.md, they have lots of hardcoded registers in their machine description files, so I'm not sure why they are not hitting this. Vlad, I assume in lra_update_insn_regno_info(), we have to be more careful about pulling out the used registers being used in the insn? Or do you know of another way we can fix this?