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.
