On Sun, Jun 14, 2026 at 11:09 PM Roger Sayle <[email protected]> wrote:
>
>
> This patch fixes a poor interaction between the splitters for SSE
> floating point abs/neg in the i386 backend, and the late-combine pass.
> Before reload, these patterns exist as a PARALLEL containing the USE
> of a value (pseudo) holding the sign-bit.  Currently late-combine
> propagates this sign-bit mask from the constant pool, changing the
> USE of a REG to the USE of a MEM.  This unCSE is reasonable if this
> MEM is used only once, but less than optimal if this MEM is accessed
> many times.
>
> The problem is that this USE doesn't currently have a cost in
> ix86_insn_cost, so propagating this load from memory into the USE
> makes if free (to combine's profitable replacement calculation).
> This patch improve things by providing a nominal cost for USEs of
> MEM.
>
> As an example, consider the following function:
>
> float x, y, z;
> void foo()
> {
>   x = -x;
>   y = -y;
>   z = -z;
> }
>
> Currently with -O2 GCC generates three loads from the constant pool:
>
>         movss   x(%rip), %xmm0
>         xorps   .LC0(%rip), %xmm0
>         movss   %xmm0, x(%rip)
>         movss   y(%rip), %xmm0
>         xorps   .LC0(%rip), %xmm0
>         movss   %xmm0, y(%rip)
>         movss   z(%rip), %xmm0
>         xorps   .LC0(%rip), %xmm0
>         movss   %xmm0, z(%rip)
>         ret
>
> With the patch below, this load remains CSEd.
>
>         movss   x(%rip), %xmm0
>         movss   .LC0(%rip), %xmm1
>         xorps   %xmm1, %xmm0
>         movss   %xmm0, x(%rip)
>         movss   y(%rip), %xmm0
>         xorps   %xmm1, %xmm0
>         movss   %xmm0, y(%rip)
>         movss   z(%rip), %xmm0
>         xorps   %xmm1, %xmm0
>         movss   %xmm0, z(%rip)
>         ret
>
> Note this is one more instruction, but code size is smaller and
> the total cost (as calculated by the i386 backend) is lower.
> For a single neg/abs the memory address is still propagated.
>
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check, both with and without --target_board=unix{-m32}
> with no new failures.  Ok for mainline?
>
>
> 2026-06-14  Roger Sayle  <[email protected]>
>
> gcc/ChangeLog
>         * config/i386/i386.cc (ix86_insn_cost): Add a suitable penalty
>         for USE of a MEM in a PARALLEL (for *<absneg>[sd]f2_1 splitter).
>
> gcc/testsuite/ChangeLog
>         * gcc.target/i386/fabsneg-2.c: New test case.

OK.

Thanks,
Uros.

Reply via email to