On Thu, May 28, 2026 at 9:45 AM Jakub Jelinek <[email protected]> wrote:
>
> Hi!
>
> 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.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/16/15?
>
> 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.

OK. I also wonder if the check in ix86_validate_address_register can
be removed, there were many RA improvements in the last ... decade
(?).

Thanks,
Uros.

>
> --- gcc/config/i386/i386.md.jj  2026-05-20 14:05:56.000000000 +0200
> +++ gcc/config/i386/i386.md     2026-05-27 18:12:47.265960379 +0200
> @@ -6749,7 +6749,10 @@ (define_insn "*add<mode>_1<nf_name>"
>        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)
> --- gcc/testsuite/gcc.target/i386/apx-nf-pr125469.c.jj  2026-05-27 
> 18:29:26.227640333 +0200
> +++ gcc/testsuite/gcc.target/i386/apx-nf-pr125469.c     2026-05-27 
> 18:28:58.745979258 +0200
> @@ -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;
> +}
>
>         Jakub
>

Reply via email to