https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85300
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/combine.c.jj 2018-03-15 08:36:28.756776703 +0100 +++ gcc/combine.c 2018-04-09 19:33:40.782844115 +0200 @@ -5574,12 +5574,13 @@ subst (rtx x, rtx from, rtx to, int in_d if (! x) x = gen_rtx_CLOBBER (mode, const0_rtx); } - else if (CONST_SCALAR_INT_P (new_rtx) - && GET_CODE (x) == ZERO_EXTEND) + else if (CONST_SCALAR_INT_P (new_rtx) && UNARY_P (x)) { - x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), - new_rtx, GET_MODE (XEXP (x, 0))); - gcc_assert (x); + x = simplify_unary_operation (GET_CODE (x), GET_MODE (x), + new_rtx, + GET_MODE (XEXP (x, 0))); + if (!x) + return gen_rtx_CLOBBER (VOIDmode, const0_rtx); } else SUBST (XEXP (x, i), new_rtx); fixes this, by preventing creation of the invalid RTL where the RTL sharing and propagate_for_debug might make it reappear somewhere in the IL. We already did this for SUBREG and ZERO_EXTEND (strangely not for SIGN_EXTEND), wonder how are the other unary ops different.