https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85414
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is likely with the caching of ix86_compute_frame_layout results, at least if I call this function at the beginning of ix86_expand_prologue, it doesn't ICE anymore. What changes in particular is ix86_nsaved_regs () on this testcase, during lra -> lra_eliminate -> update_reg_eliminate it still returns 1, but during pro_and_epilogue already 2. The difference is in register 41. What happens is: 1) fwprop1 adds a REG_EQUAL to the umulditi3_1 instruction: (insn 13 12 111 3 (parallel [ (set (reg:TI 99) (mult:TI (zero_extend:TI (subreg/s/v:DI (reg:TI 94) 0)) (zero_extend:TI (reg:DI 100)))) (clobber (reg:CC 17 flags)) ]) "pr85414.c":5 366 {*umulditi3_1} (expr_list:REG_EQUAL (mult:TI (zero_extend:TI (subreg/s/v:DI (reg:TI 94) 0)) (const_int 59 [0x3b])) (expr_list:REG_DEAD (reg:DI 100) (expr_list:REG_DEAD (reg:TI 94) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))))) 2) then probably based on the /s/v flags on the subreg that indicate SUBREG_PROMOTED_VAR_P and SUBREG_PROMOTED_UNSIGNED_P, the cse_local pass "optimizes" the REG_EQUAL note to (mult:TI (subreg:TI (subreg/s/v:DI (reg:TI 94) 0) 0) (const_int 59 [0x3b])) That actually looks to me like invalid RTL, subreg of a subreg is not valid. I guess it should have been just (mult:TI (reg:TI 94) (const_int 59 [0x3b])). 3) then the subreg2 pass just replaces uses of (reg:TI 94) subregs with (reg:DI 146) 4) during LRA we have (mult:TI (subreg:TI (reg:DI 40 r11 [146]) 0) (const_int 59 [0x3b])) and that refers to the r12 too, but nothing earlier recognized it as used (nor it is actually used in the insn).