[libc-commits] [libc] [libc] Change rand implementation so all tests pass in both 32- and 64-bit systems (PR #98692)
Mikhail R. Gadelha via libc-commits
libc-commits at lists.llvm.org
Mon Jul 15 09:02:29 PDT 2024
https://github.com/mikhailramalho updated https://github.com/llvm/llvm-project/pull/98692
>From 6ea6bde7de0ce370f8361a6cd6c473e4ef40978e Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Fri, 12 Jul 2024 17:32:17 -0300
Subject: [PATCH] [libc] Change rand implementation so all tests pass in both
32- and 64-bit systems
This patch makes rand select different algorithms depending on the arch.
This is needed to avoid a test failure in 32-bit systems where the LSB
of rand was not uniform enough when the 64-bit constants are used in
32-bit systems.
---
libc/src/stdlib/rand.cpp | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/libc/src/stdlib/rand.cpp b/libc/src/stdlib/rand.cpp
index 1931727e2d9d1..ff029945830d5 100644
--- a/libc/src/stdlib/rand.cpp
+++ b/libc/src/stdlib/rand.cpp
@@ -14,20 +14,30 @@
namespace LIBC_NAMESPACE_DECL {
-// An implementation of the xorshift64star pseudo random number generator. This
+// An implementation of the xorshift pseudo random number generator. This
// is a good general purpose generator for most non-cryptographics applications.
-LLVM_LIBC_FUNCTION(int, rand, (void)) {
+static unsigned long xorshift(unsigned long a, unsigned long b, unsigned long c,
+ unsigned long d) {
unsigned long orig = rand_next.load(cpp::MemoryOrder::RELAXED);
for (;;) {
unsigned long x = orig;
- x ^= x >> 12;
- x ^= x << 25;
- x ^= x >> 27;
+ x ^= x >> a;
+ x ^= x << b;
+ x ^= x >> c;
if (rand_next.compare_exchange_strong(orig, x, cpp::MemoryOrder::ACQUIRE,
cpp::MemoryOrder::RELAXED))
- return static_cast<int>((x * 0x2545F4914F6CDD1Dul) >> 32) & RAND_MAX;
+ return x * d;
sleep_briefly();
}
}
+LLVM_LIBC_FUNCTION(int, rand, (void)) {
+ int res;
+ if constexpr (sizeof(void *) == sizeof(uint64_t))
+ res = static_cast<int>(xorshift(12, 25, 27, 0x2545F4914F6CDD1Dul) >> 32);
+ else
+ res = static_cast<int>(xorshift(13, 17, 5, 1597334677ul));
+ return res & RAND_MAX;
+}
+
} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list