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

            Bug ID: 115613
           Summary: xtensa: splits dependent on can_create_pseudo_p
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rsandifo at gcc dot gnu.org
                CC: jcmvbkbc at gcc dot gnu.org
  Target Milestone: ---
            Target: xtensa-*-*

The late-combine pass is disabled by default for xtensa:

  /* One of the late-combine passes runs after register allocation
     and can match define_insn_and_splits that were previously used
     only before register allocation.  Some of those define_insn_and_splits
     require the split to take place, but have a split condition of
     can_create_pseudo_p, and so matching after RA will give an
     unsplittable instruction.  Disable late-combine by default until
     the define_insn_and_splits are fixed.  */
  if (!OPTION_SET_P (flag_late_combine_instructions))
    flag_late_combine_instructions = 0;

For example, compiling gcc.c-torture/compile/bx.c with -Os -flate-combine
gives:

(insn 53 21 27 4 (set (reg/i:SI 2 a2)
        (and:SI (not:SI (reg:SI 8 a8 [orig:44 _10 ] [44]))
            (reg:SI 2 a2 [55])))
"/home/ricsan01/gcc/git/gcc/gcc/testsuite/gcc.c-torture/compile/bx.c":5:1 36
{*andsi3_bitcmpl}
     (expr_list:REG_DEAD (reg:SI 8 a8 [orig:44 _10 ] [44])
        (nil)))
during RTL pass: final
.../gcc.c-torture/compile/bx.c:5:1: internal compiler error: in
final_scan_insn_1, at final.cc:2807
0xe331b7 _fatal_insn(char const*, rtx_def const*, char const*, int, char
const*)
       .././src/gcc/rtl-error.cc:108
0x9e5667 final_scan_insn_1
       .././src/gcc/final.cc:2807
0x9e5877 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
       .././src/gcc/final.cc:2886
0x9e659f final_1
       .././src/gcc/final.cc:1977
0x9e689f rest_of_handle_final
       .././src/gcc/final.cc:4239
0x9e689f execute
       .././src/gcc/final.cc:4317

The associated define_insn_and_split is:

(define_insn_and_split "*andsi3_bitcmpl"
  [(set (match_operand:SI 0 "register_operand" "=a")
        (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
                (match_operand:SI 2 "register_operand" "r")))]
  ""
  "#"
  "&& can_create_pseudo_p ()"
  [(set (match_dup 3)
        (and:SI (match_dup 1)
                (match_dup 2)))
   (set (match_dup 0)
        (xor:SI (match_dup 3)
                (match_dup 2)))]
{
  operands[3] = gen_reg_rtx (SImode);
}
  [(set_attr "type"     "arith")
   (set_attr "mode"     "SI")
   (set_attr "length"   "6")])

The define_insn can be matched before or after register allocation, but the "&&
can_create_pseudo_p ()" condition means that the split can only happen before
RA.  And the "#" means that the split must happen: there is no assembly
fallback.  Matching the define_insn after register allocation therefore leads
to an ICE.

See: https://gcc.gnu.org/pipermail/gcc-patches/2024-June/655446.html for more
discussion.

Reply via email to