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.

Reply via email to