[llvm-branch-commits] [libc] [libc][wctype] Upstream fastrand from PtrHash-cc prototype to LLVM libc (PR #174851)

Muhammad Bassiouni via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 9 14:00:44 PST 2026


https://github.com/bassiounix updated https://github.com/llvm/llvm-project/pull/174851

>From 70936a9a4ed3c1dffb01ca16308de4a09454834c Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Wed, 7 Jan 2026 21:30:07 +0200
Subject: [PATCH] [libc][wctype] Upstream fastrand from PtrHash-cc prototype to
 LLVM libc

---
 .../wctype/conversion/CMakeLists.txt          |  1 +
 .../wctype/conversion/random/CMakeLists.txt   |  7 ++
 .../wctype/conversion/random/fastrand.h       | 78 +++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 libc/src/__support/wctype/conversion/random/CMakeLists.txt
 create mode 100644 libc/src/__support/wctype/conversion/random/fastrand.h

diff --git a/libc/src/__support/wctype/conversion/CMakeLists.txt b/libc/src/__support/wctype/conversion/CMakeLists.txt
index 512d2b1553c8c..b247ddda89042 100644
--- a/libc/src/__support/wctype/conversion/CMakeLists.txt
+++ b/libc/src/__support/wctype/conversion/CMakeLists.txt
@@ -1 +1,2 @@
+add_subdirectory(random)
 add_subdirectory(utils)
diff --git a/libc/src/__support/wctype/conversion/random/CMakeLists.txt b/libc/src/__support/wctype/conversion/random/CMakeLists.txt
new file mode 100644
index 0000000000000..dd9d577e4cd8b
--- /dev/null
+++ b/libc/src/__support/wctype/conversion/random/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_header_library(
+  fastrand
+  HDRS
+    fastrand.h
+  DEPENDS
+    libc.src.__support.wctype.conversion.utils.utils
+)
diff --git a/libc/src/__support/wctype/conversion/random/fastrand.h b/libc/src/__support/wctype/conversion/random/fastrand.h
new file mode 100644
index 0000000000000..a85c937138276
--- /dev/null
+++ b/libc/src/__support/wctype/conversion/random/fastrand.h
@@ -0,0 +1,78 @@
+//===-- Fast random number gen method - wctype conversion -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_WCTYPE_CONVERSION_RANDOM_FASTRAND_H
+#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_CONVERSION_RANDOM_FASTRAND_H
+
+#include "src/__support/wctype/conversion/utils/utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace wctype_internal {
+
+namespace random {
+
+namespace fastrand {
+
+// This seed value is very important for different inputs. Bad values are known
+// to cause compilation errors and/or incorrect computations in some cases.
+// Defaulted to `0xEF6F79ED30BA75A` at first, but this value is not sufficient.
+// Candidate seeds are taken directly from the resulted computation of the
+// original Rust code, this is important for reproduction until a parallel
+// generator is written for LLVM libc!
+// `0x64a727ea04c46a32` is another viable seed.
+LIBC_INLINE_VAR constexpr uint64_t DEFAULT_RNG_SEED = 0xeec13c9f1362aa74;
+
+class Rng {
+public:
+  LIBC_INLINE constexpr Rng() : Rng(DEFAULT_RNG_SEED) {}
+
+  LIBC_INLINE constexpr Rng(uint64_t seed) : seed(seed) {}
+  LIBC_INLINE constexpr Rng(const Rng &) = default;
+  LIBC_INLINE constexpr Rng(Rng &&) = default;
+
+  LIBC_INLINE constexpr Rng &operator=(const Rng &) = default;
+  LIBC_INLINE constexpr Rng &operator=(Rng &&) = default;
+
+  LIBC_INLINE constexpr uint64_t gen() const {
+    constexpr uint64_t WY_CONST_0 = 0x2d35'8dcc'aa6c'78a5;
+    constexpr uint64_t WY_CONST_1 = 0x8bb8'4b93'962e'acc9;
+
+    auto s = conversion_utils::wrapping_add(this->seed, WY_CONST_0);
+    this->seed = s;
+    auto const t =
+        static_cast<UInt128>(s) * static_cast<UInt128>(s ^ WY_CONST_1);
+    return static_cast<uint64_t>(t) ^ static_cast<uint64_t>(t >> 64);
+  }
+
+  LIBC_INLINE constexpr uint8_t gen_byte() const {
+    return static_cast<uint8_t>(this->gen());
+  }
+
+  LIBC_INLINE constexpr Rng fork() const { return Rng(this->gen()); }
+  LIBC_INLINE constexpr void set(uint64_t i) const { this->seed = i; }
+
+  LIBC_INLINE constexpr Rng replace(Rng &&n) const {
+    auto ret = this->seed;
+    this->seed = n.seed;
+    return ret;
+  }
+
+private:
+  mutable uint64_t seed;
+};
+
+} // namespace fastrand
+
+} // namespace random
+
+} // namespace wctype_internal
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_WCTYPE_CONVERSION_RANDOM_FASTRAND_H



More information about the llvm-branch-commits mailing list