https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127870

            Bug ID: 127870
           Summary: Reassociation of __int128 sum costs a callee-saved
                    register on x86-64
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jdh863 at gmail dot com
  Target Milestone: ---

Created attachment 65826
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65826&action=edit
Reproducer and performance evidence

Missed optimization. With -O3 -march=alderlake -fno-pie, reassoc2 regroups
the three-term unsigned __int128 sum below from (P + Q) + R to (Q + R) + P,
and the function then saves and restores rbx (75 bytes of .text versus 65
with -fno-tree-reassoc or -fdisable-tree-reassoc2). On an i9-14900K the
reassociated version has 27.4% higher throughput time and 1.2% lower
latency time. gcc version 17.0.0 20261006 (experimental), x86_64-linux-gnu;
GCC 15.2.0 behaves the same way.

typedef unsigned long long u64;
typedef unsigned __int128 u128;
u128 kernel(u128 a, u128 b)
{
  return (a >> 64) * (b >> 64)
       + (((u128)(u64)a * (b >> 64)) >> 64)
       + (((a >> 64) * (u64)b) >> 64)
       - (b & (-(a >> 127)));
}

gcc -O3 -march=alderlake -fno-pie -S -masm=intel repro.c
gcc -O3 -march=alderlake -fno-pie -fno-tree-reassoc -S -masm=intel repro.c

Reproducer, gcc -v, both disassemblies, reassoc dumps, benchmark driver and
raw timings are attached. Possibly related: PR 124654, PR 125585, PR 125586,
PR 50557.

Reply via email to