https://gcc.gnu.org/g:896c822afed0aad4c0ca761777cdc5f0085bbce0
commit r17-890-g896c822afed0aad4c0ca761777cdc5f0085bbce0 Author: Jakub Jelinek <[email protected]> Date: Thu May 28 10:28:12 2026 +0200 i386: Fix up *add<mode>_1<nf_name> [PR125469] The following testcase ICEs, because combine matches (set (reg:DI 108) (plus:DI (reg:DI 104 [ s ]) (subreg:DI (reg:TI 103 [ _2 ]) 8))) Now, because ix86_validate_address_register has: 12038 /* Don't allow SUBREGs that span more than a word. It can 12039 lead to spill failures when the register is one word out 12040 of a two word structure. */ 12041 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) 12042 return NULL_RTX; this isn't recognized as *leadi, but is recognized as *adddi_1_nf pattern instead. Now, later on the RA turns it into: (set (reg:DI 2 cx [108]) (plus:DI (reg:DI 0 ax [orig:104 s ] [104]) (reg:DI 5 di [ _2+8 ]))) which would be valid *leadi, but given that INSN_CODE is already set to the *adddi_1_nf and that also satisfies it, nothing re-recognizes it as *leadi. But in that case without TARGET_APX_NDD the pattern has return "#"; That is a bug, because there is no splitter to split that (set (reg:DI 2 cx [108]) (plus:DI (reg:DI 0 ax [orig:104 s ] [104]) (reg:DI 5 di [ _2+8 ]))) into itself so that it is re-recognized as *leadi, so it just ICEs. I think having a splitter to split to the same thing would be just weird, so this just outputs lea insn directly. 2026-05-28 Jakub Jelinek <[email protected]> PR target/125469 * config/i386/i386.md (*add<mode>_1<nf_name>): Don't return "#" for the lea non-TARGET_APX_NDD case, instead emit a lea directly. * gcc.target/i386/apx-nf-pr125469.c: New test. Reviewed-by: Uros Bizjak <[email protected]> Diff: --- gcc/config/i386/i386.md | 5 ++++- gcc/testsuite/gcc.target/i386/apx-nf-pr125469.c | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 063e14cb2c17..20d57c69bd3b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6749,7 +6749,10 @@ if (TARGET_APX_NDD && <nf_applied>) return "%{nf%} add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"; else - return "#"; + { + operands[3] = gen_rtx_PLUS (<MODE>mode, operands[1], operands[2]); + return "lea{<imodesuffix>}\t{%E3, %0|%0, %E3}"; + } case TYPE_INCDEC: if (operands[2] == const1_rtx) diff --git a/gcc/testsuite/gcc.target/i386/apx-nf-pr125469.c b/gcc/testsuite/gcc.target/i386/apx-nf-pr125469.c new file mode 100644 index 000000000000..dc9f1c241abe --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-nf-pr125469.c @@ -0,0 +1,11 @@ +/* PR target/125469 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-Ofast -mapx-features=nf" } */ + +int s; + +void +foo () +{ + s /= ((__int128) 0x33333333333333333333333333333333uwb) + 1i; +}
