[Bug target/92791] [10 Regression] ICE in extract_insn, at recog.c:2311 since r278645

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Dec 4 15:54:00 GMT 2019


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  <jakub@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).


More information about the Gcc-bugs mailing list