https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115877
--- Comment #14 from Xi Ruoyao <xry111 at gcc dot gnu.org> --- When I'm testing a LoongArch patch, ext_dce seems removing a zero extension in libcpp/expr.cc, causing stage 2 GCC miscompiled. Before ext_dce: (insn 110 108 115 14 (set (reg:DI 91 [ num$17 ]) (zero_extend:DI (subreg:QI (reg:SI 134) 0))) "../../gcc/libcpp/expr.cc":1968:17 discrim 6 129 {zero_extendqidi2} (expr_list:REG_DEAD (reg:SI 134) (nil))) (insn 3472 1254 1255 145 (set (reg:DI 1530) (reg:DI 294 [ num$17 ])) "../../gcc/libcpp/expr.cc":1565:33 158 {*movdi_64bit} (nil)) (insn 1259 1258 134 145 (set (reg:DI 329 [ prephitmp_444 ]) (zero_extend:DI (subreg/s/v:QI (reg:DI 1530) 0))) "../../gcc/libcpp/expr.cc":1681:22 129 {zero_extendqidi2} (expr_list:REG_DEAD (reg:DI 1530) (nil))) But during ext_dce: Processing insn: 110: r91:DI=zero_extend(r134:SI#0) REG_DEAD r134:SI Trying to simplify pattern: (zero_extend:DI (subreg:QI (reg:SI 134) 0)) rescanning insn with uid = 110. Successfully transformed to: (subreg:DI (reg:SI 134) 0) So insn 110 becomes: (insn 110 108 115 14 (set (reg:DI 91 [ num$17 ]) (subreg:DI (reg:SI 134) 0)) "../../gcc/libcpp/expr.cc":1968:17 discrim 6 158 {*movdi_64bit} (expr_list:REG_DEAD (reg:SI 134) (nil))) But insn 3472 and 1259 are not changed (i.e. in 1259 the SUBREG_PROMOTED_VAR_P, printed as "/s" isn't removed). Subsequently the combine pass optimizes 1259 to: (insn 1259 1258 134 145 (set (reg:DI 329 [ prephitmp_444 ]) (reg:DI 294 [ num$17 ])) "../../gcc/libcpp/expr.cc":1681:22 158 {*movdi_64bit} (expr_list:REG_DEAD (reg:DI 294 [ num$17 ]) (nil))) And now we are doomed. Either insn 110 shouldn't be changed or SUBREG_PROMOTED_VAR_P in 1259 should be removed. I see some code in ext-dce.cc removing SUBREG_PROMOTED_VAR_P but it seems this case isn't caught. I tried to make a reduced test case but failed.