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.