[all-commits] [llvm/llvm-project] b254c2: [libc++] Fix `uniform_int_distribution` for 128-bi...
FabianWolff via All-commits
all-commits at lists.llvm.org
Wed Dec 1 08:03:53 PST 2021
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: b254c2e2c4aa3298655282b8db37860129bcd7b6
https://github.com/llvm/llvm-project/commit/b254c2e2c4aa3298655282b8db37860129bcd7b6
Author: Fabian Wolff <fabian.wolff at alumni.ethz.ch>
Date: 2021-12-01 (Wed, 01 Dec 2021)
Changed paths:
M libcxx/include/__random/log2.h
M libcxx/include/__random/uniform_int_distribution.h
A libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/int128.pass.cpp
Log Message:
-----------
[libc++] Fix `uniform_int_distribution` for 128-bit result type
Fixes https://llvm.org/PR51520. The problem is that `uniform_int_distribution`
currently uses an unsigned integer with at most 64 bits internally, which
is then casted to the desired result type. If the result type is `int64_t`,
this will produce a negative number if the most significant bit is set,
but if the result type is `__int128_t`, the value remains non-negative
and will be out of bounds for the example in PR#51520. (The reason why
it also seems to work if the upper or lower bound is changed is
because the branch at [1] will then no longer be taken, and proper
rejection sampling takes place.)
The bigger issue here is probably that `uniform_int_distribution` can be
instantiated with `__int128_t` but will silently produce incorrect results
(only the lowest 64 bits can ever be set). libstdc++ also supports `__int128_t`
as a result type, so I have simply extended the maximum width of the
internal intermediate result type.
[1]: https://github.com/llvm/llvm-project/blob/6d28dffb6/libcxx/include/__random/uniform_int_distribution.h#L266-L267
Differential Revision: https://reviews.llvm.org/D114129
More information about the All-commits
mailing list