[Bug rtl-optimization/98439] [11 Regression] ICE in final_scan_insn_1, at final.c:3096

ubizjak at gmail dot com gcc-bugzilla@gcc.gnu.org
Sun Dec 27 18:46:20 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98439

Uroš Bizjak <ubizjak at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|target                      |rtl-optimization
   Last reconfirmed|                            |2020-12-27
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Uroš Bizjak <ubizjak at gmail dot com> ---
Confirmed as rtl-optimization problem.

Before sched2 pass, we have:

(insn 26 7 8 2 (set (reg:SI 0 ax [85])
        (reg:SI 20 xmm0 [89])) "pr98439.c":9:10 75 {*movsi_internal}

(insn 8 26 39 2 (set (mem:SI (pre_modify:DI (reg/f:DI 7 sp)
                (plus:DI (reg/f:DI 7 sp)
                    (const_int -8 [0xfffffffffffffff8]))) [0  S4 A32])
        (reg:SI 0 ax [85])) "pr98439.c":9:10 53 {*pushsi2_rex64}

which is transformed by sched2 pass to:

(insn:TI 46 44 26 2 (set (mem:SI (pre_modify:DI (reg/f:DI 7 sp)
                (plus:DI (reg/f:DI 7 sp)
                    (const_int -8 [0xfffffffffffffff8]))) [0  S4 A32])
        (reg:SI 20 xmm0 [89])) 53 {*pushsi2_rex64}

(insn 26 46 15 2 (set (reg:SI 0 ax [85])
        (reg:SI 20 xmm0 [89])) "pr98439.c":9:10 75 {*movsi_internal}

(insn 46) is defined in i386.md as:

(define_insn "*pushsi2_rex64"
  [(set (match_operand:SI 0 "push_operand" "=X,X")
        (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
  "TARGET_64BIT"
  "@
   push{q}\t%q1
   #"
  [(set_attr "type" "push,multi")
   (set_attr "mode" "DI")])

xmm0 is allowed by *v constraint, but the insn has to be split. Since sched2
pass comes after split3 pass, we hit the assert in final_scan_insn_1:

        /* If the template is the string "#", it means that this insn must
           be split.  */
        if (templ[0] == '#' && templ[1] == '\0')
          {
            rtx_insn *new_rtx = try_split (body, insn, 0);

            /* If we didn't split the insn, go away.  */
            if (new_rtx == insn && PATTERN (new_rtx) == body)
              fatal_insn ("could not split insn", insn);

            /* If we have a length attribute, this instruction should have
               been split in shorten_branches, to ensure that we would have
               valid length info for the splitees.  */
-->         gcc_assert (!HAVE_ATTR_length);

            return new_rtx;
          }

As the comment says, this insn should have been split in shorten_branches, but:

      /* The placement of the splitting that we do for shorten_branches
         depends on whether regstack is used by the target or not.  */
#if HAVE_ATTR_length && !defined (STACK_REGS)
      return true;
#else
      return false;
#endif

and nothing splits insns after sched2, because:

bool
pass_split_before_regstack::gate (function *)
{
#if HAVE_ATTR_length && defined (STACK_REGS)
  /* If flow2 creates new instructions which need splitting
     and scheduling after reload is not done, they might not be
     split until final which doesn't allow splitting
     if HAVE_ATTR_length.  */
  return !enable_split_before_sched2 ();
#else
  return false;
#endif
}

and finally:

static bool
enable_split_before_sched2 (void)
{
#ifdef INSN_SCHEDULING
  return optimize > 0 && flag_schedule_insns_after_reload;
#else
  return false;
#endif
}


More information about the Gcc-bugs mailing list