https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128445
Bug ID: 128445
Summary: x86-64: xchg reg,reg high latency on IA platform with
dependency chain.
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: hongyuw at gcc dot gnu.org
Target Milestone: ---
cat xchg-dep.c:
#include <stdio.h>
#include <x86intrin.h>
typedef unsigned long u64; typedef unsigned __int128 u128;
#define K 0x9ddfea08eb382d69UL
__attribute__((noipa)) u128 h (u64 x)
{
u64 l = x * x;
l *= l;
l *= l;
l *= K;
return ((u128) x << 64) | l;
}
__attribute__((noipa)) u128 f (u64 x)
{
u128 r = h (x);
return (r << 64) | (r >> 64);
}
int main (void)
{
u64 x = 1, n = 100000000, t = __rdtsc ();
for (u64 i = 0; i < n; i++)
x = (u64) f (x) + 1; /* depend on the early half. */
// x = (u64) (f (x) >> 64) + 1; /* depend on the late half. */
t = __rdtsc () - t;
printf ("%.2f TSC ticks/iter (x=%lx)\n", (double) t / n, x);
return 0;
}
Compile with gcc -O2 and run on Alderlake (i9-12900k):
./xchg.out
18.00 TSC ticks/iter
By changing the xchg to 3 movs:
./3mov.out
5.73 TSC ticks/iter
For AMD Zen5 the result has no difference. So ideally we'd want a peephole to
switch the swapdi back to 3 mov sequences under speed gate under a tune.