[libc-commits] [libc] [libc] Improve nearest_integer for non-AVX x86 targets. (PR #230529)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Mon Oct 12 02:43:06 PDT 2026


================
@@ -26,18 +26,36 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
 
+// Without AVX, `roundss` and `roundsd` are 2-operand instructions that preserve
+// the upper bits of the destination XMM register. Because only lane 0 of
+// `_mm_round_ss(xmm, xmm, 8)` / `_mm_round_sd(xmm, xmm, 8)` is used, the
+// compiler may ignore the first operand and allocate a different destination
+// register, creating a false dependency on its previous value. Using inline
+// assembly with `"+x"(x)` forces identical source and destination registers
+// without the extra lane-zeroing instructions required by `_mm_round_ps` /
+// `_mm_round_pd`.
 LIBC_INLINE float nearest_integer(float x) {
+#ifdef __AVX__
   __m128 xmm = _mm_set_ss(x); // NOLINT
   __m128 ymm =
       _mm_round_ss(xmm, xmm, _MM_ROUND_NEAREST | _MM_FROUND_NO_EXC); // NOLINT
   return ymm[0];
+#else
+  LIBC_INLINE_ASM("roundss $0x8, %0, %0" : "+x"(x));
----------------
labath wrote:

```suggestion
  LIBC_INLINE_ASM("roundss %1, %0, %0" : "+x"(x) : "i"(_MM_ROUND_NEAREST | _MM_FROUND_NO_EXC));
```

https://github.com/llvm/llvm-project/pull/230529


More information about the libc-commits mailing list