[libc-commits] [libc] [libc][stdfix] Implement sqrtfx for remaining fixed point types (PR #214741)
via libc-commits
libc-commits at lists.llvm.org
Thu Aug 13 16:02:44 PDT 2026
================
@@ -181,31 +200,67 @@ sqrt_core(typename Config::Type x_frac) {
template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T> sqrt(T x) {
- using BitType = typename FXRep<T>::StorageType;
- BitType x_bit = cpp::bit_cast<BitType>(x);
-
- if (LIBC_UNLIKELY(x_bit == 0))
- return FXRep<T>::ZERO();
-
- int leading_zeros = cpp::countl_zero(x_bit);
- constexpr int STORAGE_LENGTH = sizeof(BitType) * CHAR_BIT;
- constexpr int EXP_ADJUSTMENT = STORAGE_LENGTH - FXRep<T>::FRACTION_LEN - 1;
- // x_exp is the real exponent of the leading bit of x.
- int x_exp = EXP_ADJUSTMENT - leading_zeros;
- int shift = EXP_ADJUSTMENT - 1 - (x_exp & (~1));
- // Normalize.
- x_bit <<= shift;
- using FracType = typename internal::SqrtConfig<T>::Type;
- FracType x_frac = cpp::bit_cast<FracType>(x_bit);
-
- // Compute sqrt(x_frac) using Newton-method.
- FracType r = sqrt_core<internal::SqrtConfig<T>>(x_frac);
-
- // Re-scaling
- r >>= EXP_ADJUSTMENT - (x_exp >> 1);
-
- // Return result.
- return cpp::bit_cast<T>(r);
+ if constexpr (FXRep<T>::SIGN_LEN > 0) {
+ LIBC_CRASH_ON_VALUE(x < FXRep<T>::ZERO(), true);
+ return static_cast<T>(
+ sqrt(static_cast<typename internal::FXUnsigned<T>::Type>(x)));
----------------
PiJoules wrote:
I think if `LIBC_CRASH_ON_VALUE` would resolve to nothing then this would bring in another version of `sqrt` (either the unsigned version or maybe the double version). I don't think we fully fleshed out the semantics for fx `sqrt` on a negative number, but I think it would be fine to just have something similar to what we have now where the caller should just be careful to avoid UB. In this case, we can probably just return a junk value from the resulting arithmetic. What you have now would suffice with that, but the only concern I have is that on some space-constrained device this call would prevent `--gc-sections` from removing an actual unused version of `sqrt`.
https://github.com/llvm/llvm-project/pull/214741
More information about the libc-commits
mailing list