Index: include/llvm/Support/RandomNumberGenerator.h =================================================================== --- include/llvm/Support/RandomNumberGenerator.h +++ include/llvm/Support/RandomNumberGenerator.h @@ -31,9 +31,20 @@ /// Module::createRNG to create a new RNG instance for use with that /// module. class RandomNumberGenerator { + + // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000 + // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine + // This RNG is deterministically portable across C++11 + // implementations. + using generator_type = std::mt19937_64; + public: + using result_type = generator_type::result_type; + /// Returns a random number in the range [0, Max). - uint_fast64_t operator()(); + result_type operator()(); + static constexpr result_type min() { return generator_type::min(); } + static constexpr result_type max() { return generator_type::max(); } private: /// Seeds and salts the underlying RNG engine. @@ -42,11 +53,7 @@ /// Module::createRNG to create a new RNG salted with the Module ID. RandomNumberGenerator(StringRef Salt); - // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000 - // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine - // This RNG is deterministically portable across C++11 - // implementations. - std::mt19937_64 Generator; + generator_type Generator; // Noncopyable. RandomNumberGenerator(const RandomNumberGenerator &other) = delete; Index: lib/Support/RandomNumberGenerator.cpp =================================================================== --- lib/Support/RandomNumberGenerator.cpp +++ lib/Support/RandomNumberGenerator.cpp @@ -57,7 +57,7 @@ Generator.seed(SeedSeq); } -uint_fast64_t RandomNumberGenerator::operator()() { +RandomNumberGenerator::result_type RandomNumberGenerator::operator()() { return Generator(); } Index: unittests/IR/ModuleTest.cpp =================================================================== --- unittests/IR/ModuleTest.cpp +++ unittests/IR/ModuleTest.cpp @@ -9,8 +9,11 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Module.h" +#include "llvm/Support/RandomNumberGenerator.h" #include "gtest/gtest.h" +#include + using namespace llvm; namespace { @@ -45,4 +48,27 @@ } } +TEST(ModuleTest, randomNumberGenerator) { + LLVMContext Context; + static char ID; + struct DummyPass : ModulePass { + DummyPass() : ModulePass(ID) {} + bool runOnModule(Module&) { return true;} + } DP; + + Module M("R", Context); + + std::uniform_int_distribution dist; + constexpr std::size_t NBCheck = 10; + + std::array RandomStreams[2]; + for(auto& RandomStream : RandomStreams) { + std::unique_ptr RNG{M.createRNG(&DP)}; + std::generate(RandomStream.begin(), RandomStream.end(), + [&]() { return dist(*RNG); }); + } + + EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(), RandomStreams[1].begin())); +} + } // end namespace