https://gcc.gnu.org/g:8ef8f0714336e02565dc9c4981afe2f987669fdb
commit r15-11327-g8ef8f0714336e02565dc9c4981afe2f987669fdb Author: Jakub Jelinek <[email protected]> Date: Mon Jun 29 13:06:06 2026 +0200 i386: Fix up *add<mode>_1<nf_name> [PR125469] I've debugged this now on the 16 branch where my patch is not present. The (define_split [(set (match_operand:SWI 0 "register_operand") (plus:SWI (match_operand:SWI 1 "register_operand") (match_operand:SWI 2 "<nonmemory_operand>")))] "TARGET_APX_NF && reload_completed && ix86_lea_for_add_ok (insn, operands)" [(set (match_dup 0) (plus:<LEAMODE> (match_dup 1) (match_dup 2)))] { if (<MODE>mode != <LEAMODE>mode) { operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]); } }) splitter there is matched, including ix86_lea_for_add_ok on (insn 12 10 13 2 (set (reg:DI 2 cx [108]) (plus:DI (reg:DI 0 ax [orig:104 s ] [104]) (reg:DI 5 di [ _2+8 ]))) "apx-nf-pr125469.c":10:5 288 {*adddi_1_nf} (nil)) But then goes into: rtx_insn * gen_split_138 (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands) { if (dump_file) fprintf (dump_file, "Splitting with gen_split_138 (i386.md:7136)\n"); start_sequence (); #define FAIL return (end_sequence (), nullptr) #define DONE return end_sequence () #line 7144 "../../gcc/config/i386/i386.md" { if (DImode != DImode) { operands[0] = gen_lowpart (DImode, operands[0]); operands[1] = gen_lowpart (DImode, operands[1]); operands[2] = gen_lowpart (DImode, operands[2]); } } #undef DONE #undef FAIL static const uint8_t expand_encoding[] = { 0x01, 0x1f, 0x01, 0x00, 0x3b, 0x12, 0x01, 0x01, 0x01, 0x02 }; return complete_seq (expand_encoding, operands); } That returns (insn 37 0 0 (set (reg:DI 2 cx [108]) (plus:DI (reg:DI 0 ax [orig:104 s ] [104]) (reg:DI 5 di [ _2+8 ]))) -1 (nil)) But then in try_split we have: /* Avoid infinite loop if any insn of the result matches the original pattern. */ insn_last = seq; while (1) { if (INSN_P (insn_last) && rtx_equal_p (PATTERN (insn_last), pat)) return trial; which is a must, otherwise we'd try to split the newly created insn again and again succeed in splitting it and so forth forever. So, this patch instead sets INSN_CODE to -1 in the splitter to indicate that it needs to be re-recognized. 2026-06-29 Jakub Jelinek <[email protected]> PR target/125469 * config/i386/i386.md (*add<mode>_1<nf_name>): Revert 2026-05-28 changes. (define_split from *add<mode>_1_nf to *lea<mode>): Set INSN_CODE to -1 if <LEAMODE> and <MODE> are the same. Reviewed-by: Uros Bizjak <[email protected]> (cherry picked from commit c474154437b7ea4e3c3570c045f2e9e737ac8b9e) Diff: --- gcc/config/i386/i386.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 857dc315a4f9..408eebb2af19 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6679,10 +6679,7 @@ if (TARGET_APX_NDD && <nf_applied>) return "%{nf%} add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"; else - { - operands[3] = gen_rtx_PLUS (<MODE>mode, operands[1], operands[2]); - return "lea{<imodesuffix>}\t{%E3, %0|%0, %E3}"; - } + return "#"; case TYPE_INCDEC: if (operands[2] == const1_rtx) @@ -7163,6 +7160,11 @@ operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]); } + else + /* *lea<mode> and *add<mode>_1_nf have the same pattern, try_split + refuses to split an insn into itself, so just request + a new recog which will match *lea<mode> which comes first. */ + INSN_CODE (curr_insn) = -1; }) ;; Convert add to the lea pattern to avoid flags dependency.
