The Floating-Point Register-to-Integer Bypass Penalty: Why Moving FP Values to GPRs Costs You Cycles

2026-07-05

Modern CPUs keep floating-point and integer values in separate physical register files — but sometimes you need to move a value between them. Extracting an FP bit pattern for hashing, checking a float's sign bit with integer ops, or reinterpreting an integer as a float via memcpy — all of these cross the FP/integer boundary. That crossing is not free.

The problem is domain crossing latency. FP and integer execution units live in physically separate clusters on the die, often with their own bypass networks. A value produced in the FP domain has to traverse extra wiring, cross a clock-domain-like boundary, and land in an integer register file port. On Intel's Skylake through Alder Lake, a MOVD or MOVQ from XMM to GPR costs 2-3 cycles, versus 1 cycle for a plain integer move. On AMD Zen, it's similar — 2-4 cycles depending on direction.

The direction matters too. Integer-to-FP is often cheaper than FP-to-integer, because FP execution tolerates a bit more latency in operand delivery (FP ops are already 3-5 cycles), while integer ALUs are latency-sensitive at 1 cycle and a slow operand delivery blows up your dependency chain.

Concrete example: A common trick in hash functions is to reinterpret a double as a uint64_t to hash its bits:

Rule of thumb: Every FP↔GPR move costs ~2 cycles of extra latency on top of the nominal 1-cycle move. If you do it once per iteration in a loop with a 4-cycle body, expect a ~50% throughput hit. If you can restructure to stay in one domain — even by using SIMD integer instructions on FP-domain registers — do it.

Compilers know about this but can't always avoid it: type-punning through memcpy, calling conventions that return floats in XMM but need them in RAX for further integer work, and hand-written intrinsics that mix domains all force the crossing.

Key Takeaway: Moving a value between FP and integer register files costs 2-3 extra cycles per crossing because the domains have separate physical files and bypass networks — restructure code to stay in one domain when it sits on a hot loop's critical path.

All newsletters