https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92791
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- We have in the documentation: For a named pattern, the condition may not depend on the data in the insn being matched, but only the target-machine-type flags. The compiler needs to test these conditions during initialization in order to learn exactly which named instructions are available in a particular run. and while optimize_function_for_size_p (cfun) doesn't depend on data in the insn being matched, it can't be said to be target-machine-type flags either. As -m32 -O2 -march=i686 testcase below shows, while I can't reproduce the ICE on a short testcase yet (i.e. the case when init_all_optabs is called while optimize_function_for_size_p (cfun) is true, but this_fn_optabs is later used in a function where it is full, this testcase shows the other case, where the optab is initialized while it is false, but is used when it is true, so this testcase doesn't use movstrictqi even when it should. struct S { S (void *a, bool b) : x (a), y (b) {} void *x; bool y; }; void bar (S); __attribute__((noipa, cold, optimize ("Os"))) void foo (void *x) { S sbuf_it (x, x == nullptr); bar (sbuf_it); } __attribute__((noipa, hot)) void bar (S x) { asm volatile ("" : : "r" (x.x), "q" (x.y) : "memory"); } __attribute__((noipa, hot)) void baz (void *x) { S sbuf_it (x, x == nullptr); bar (sbuf_it); } __attribute__((noipa, cold, optimize ("Os"))) void qux (void *x) { S sbuf_it (x, x == nullptr); bar (sbuf_it); } int main () { foo (nullptr); for (int i = 0; i < 100000; i++) baz (nullptr); qux (nullptr); return 0; } Seems movstrict{qi,hi} are the only i386 patterns that in init_all_optabs (as verified by preprocessing insn-opinit.c) where something depends on size or speed optimization of current function. Thus, I think we should go with a patch like: 2019-12-04 Jakub Jelinek <ja...@redhat.com> PR target/92791 * config/i386/i386.md (movstrict<mode>): Move test for TARGET_PARTIAL_REG_STALL and not optimizing for size from expander's condition to the body - FAIL; in that case. --- gcc/config/i386/i386.md.jj 2019-12-03 09:22:17.421777187 +0100 +++ gcc/config/i386/i386.md 2019-12-04 16:35:34.193669660 +0100 @@ -2801,10 +2801,11 @@ (define_peephole2 (define_expand "movstrict<mode>" [(set (strict_low_part (match_operand:SWI12 0 "register_operand")) (match_operand:SWI12 1 "general_operand"))] - "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "" { gcc_assert (SUBREG_P (operands[0])); - if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) + if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) + || GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) FAIL; }) which fixes the #c0 ICE and improves the above testcase (makes the Os optimized functions shorter).