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.