https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126556
Drea Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Last reconfirmed| |2026-08-01
Keywords| |ice-on-valid-code
Status|UNCONFIRMED |NEW
Target Milestone|--- |15.4
--- Comment #1 from Drea Pinski <pinskia at gcc dot gnu.org> ---
/* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
CONST_INT is not valid, because after the replacement, the
original mode would be gone. Unfortunately, we can't tell
when do_SUBST is called to replace the operand thereof, so we
perform this test on oldval instead, checking whether an
invalid replacement took place before we got here. */
gcc_assert (!(GET_CODE (oldval) == SUBREG
&& CONST_INT_P (SUBREG_REG (oldval))));
gcc_assert (!(GET_CODE (oldval) == ZERO_EXTEND
&& CONST_INT_P (XEXP (oldval, 0))));
(gdb) p debug_rtx(oldval)
(zero_extend:DI (const_int 0 [0]))
ext_dce goes from:
(insn 34 33 5 2 (set (reg/v:SI 104 [ bb8 ])
(const_int 0 [0])) :17:10 -1
(nil))
...
(insn 6 5 7 2 (set (subreg:DI (reg:QI 108) 0)
(zero_extract:DI (subreg:DI (reg/v:SI 104 [ bb8 ]) 0)
(const_int 8 [0x8])
(const_int 24 [0x18]))) 817 {*extzvdi}
(expr_list:REG_DEAD (reg/v:SI 104 [ bb8 ])
(nil)))
(insn 7 6 10 2 (set (reg:SI 105 [ _6 ])
(subreg:SI (reg:QI 108) 0)) 69 {*movsi_aarch64}
(nil))
(insn 10 7 11 2 (set (reg:SI 110 [ _6 ])
(sign_extend:SI (reg:QI 108))) :19:21 110 {*extendqisi2_aarch64}
(expr_list:REG_DEAD (reg:QI 108)
(nil)))
to:
(insn 34 33 5 2 (set (reg/v:SI 104 [ bb8 ])
(const_int 0 [0])) :17:10 -1
(nil))
...
(insn 6 5 7 2 (set (subreg:DI (reg:QI 108) 0)
(zero_extract:DI (subreg:DI (reg/v:SI 104 [ bb8 ]) 0)
(const_int 8 [0x8])
(const_int 24 [0x18]))) 817 {*extzvdi}
(expr_list:REG_DEAD (reg/v:SI 104 [ bb8 ])
(nil)))
(insn 7 6 10 2 (set (reg:SI 105 [ _6 ])
(zero_extend:SI (reg:QI 108))) 114 {*zero_extendqisi2_aarch64}
(nil))
(insn 10 7 11 2 (set (reg:SI 110 [ _6 ])
(sign_extend:SI (reg:QI 108))) :19:21 110 {*extendqisi2_aarch64}
(expr_list:REG_DEAD (reg:QI 108)
(nil)))
Which seems like a very much valid thing to do but combine does not like it.
combine is doing:
Trying 10 -> 11:
10: r110:SI=0
11: cc:CC=cmp(r110:SI,0)
REG_DEAD r110:SI
which actually combines in insn 12 because cc here:
(insn 12 11 14 2 (set (reg:SI 111 [ _2 ])
(gt:SI (reg:CC 66 cc)
(const_int 0 [0]))) :19:21 443 {aarch64_cstoresi}
(expr_list:REG_DEAD (reg:CC 66 cc)
(nil)))
And combine produces:
(insn 12 11 14 2 (set (reg:DI 111 [ _2 ])
(zero_extend:DI (const_int 0 [0]))) :19:21 449 {*cstoresi_insn_uxtw}
(expr_list:REG_DEAD (reg:CC 66 cc)
(nil)))