[Bug target/125469] ICE: in final_scan_insn_1, at final.cc:2823 could not split insn {*adddi_1_nf} with -Ofast -mapx-features=nf
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Jun 29 11:44:11 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125469
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:d2e6ca510a713db8cfefb1bc8d3a3fa1b9402f2f
commit r16-9188-gd2e6ca510a713db8cfefb1bc8d3a3fa1b9402f2f
Author: Jakub Jelinek <jakub@redhat.com>
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 <jakub@redhat.com>
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 <ubizjak@gmail.com>
(cherry picked from commit c474154437b7ea4e3c3570c045f2e9e737ac8b9e)
More information about the Gcc-bugs
mailing list