[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