python-numba/numba-pr7748-random32bitwidth.patch
2022-01-15 13:04:10 +00:00

59 lines
2.4 KiB
Diff

From e6df66d52152156ba8bcda64b37f4995bda72d2f Mon Sep 17 00:00:00 2001
From: Graham Markall <gmarkall@nvidia.com>
Date: Fri, 14 Jan 2022 21:24:40 +0000
Subject: [PATCH] Fix #7713: Ensure _prng_random_hash return has correct
bitwidth
When the hash width is 32 bits, get_next_int32 needs to be used because
that returns a 32-bit integer, as opposed to get_next_int, which returns
a 64-bit integer regardless of the supplied bitwidth.
This commit also alters the signature of _prng_random_hash to use
_Py_hash_t as the return type - it will be equal to types.intp, but the
intent should be clearer.
---
numba/cpython/hashing.py | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/numba/cpython/hashing.py b/numba/cpython/hashing.py
index 5a8673b04b..227fc4e1c5 100644
--- a/numba/cpython/hashing.py
+++ b/numba/cpython/hashing.py
@@ -18,7 +18,8 @@
from numba.core import errors
from numba.core import types, utils
from numba.core.unsafe.bytes import grab_byte, grab_uint64_t
-from numba.cpython.randomimpl import get_state_ptr, get_next_int, const_int
+from numba.cpython.randomimpl import (const_int, get_next_int, get_next_int32,
+ get_state_ptr)
_py38_or_later = utils.PYVERSION >= (3, 8)
_py310_or_later = utils.PYVERSION >= (3, 10)
@@ -137,11 +138,23 @@ def _prng_random_hash(tyctx):
def impl(cgctx, builder, signature, args):
state_ptr = get_state_ptr(cgctx, builder, "internal")
- bits = const_int(types.intp.bitwidth)
- value = get_next_int(cgctx, builder, state_ptr, bits, False)
+ bits = const_int(_hash_width)
+
+ # Why not just use get_next_int() with the correct bitwidth?
+ # get_next_int() always returns an i64, because the bitwidth it is
+ # passed may not be a compile-time constant, so it needs to allocate
+ # the largest unit of storage that may be required. Therefore, if the
+ # hash width is 32, then we need to use get_next_int32() to ensure we
+ # don't return a wider-than-expected hash, even if everything above
+ # the low 32 bits would have been zero.
+ if _hash_width == 32:
+ value = get_next_int32(cgctx, builder, state_ptr)
+ else:
+ value = get_next_int(cgctx, builder, state_ptr, bits, False)
+
return value
- sig = types.intp()
+ sig = _Py_hash_t()
return sig, impl