From 6a764e90d033923e947a311c026203faa4a1cb13 Mon Sep 17 00:00:00 2001 From: tevador Date: Wed, 6 May 2020 12:42:30 +0200 Subject: [PATCH 1/2] Preserve floating point state when calling randomx_calculate_hash --- src/randomx.cpp | 4 ++++ src/randomx.h | 2 ++ src/tests/tests.cpp | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/randomx.cpp b/src/randomx.cpp index 31289ff..75dfdfe 100644 --- a/src/randomx.cpp +++ b/src/randomx.cpp @@ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cpu.hpp" #include #include +#include extern "C" { @@ -349,6 +350,8 @@ extern "C" { assert(machine != nullptr); assert(inputSize == 0 || input != nullptr); assert(output != nullptr); + fenv_t fpstate; + fegetenv(&fpstate); alignas(16) uint64_t tempHash[8]; int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); assert(blakeResult == 0); @@ -361,6 +364,7 @@ extern "C" { } machine->run(&tempHash); machine->getFinalResult(output, RANDOMX_HASH_SIZE); + fesetenv(&fpstate); } void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize) { diff --git a/src/randomx.h b/src/randomx.h index 48aaf8e..64d1806 100644 --- a/src/randomx.h +++ b/src/randomx.h @@ -246,6 +246,8 @@ RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *inpu * and begin the calculation of the next hash. * randomx_calculate_hash_last will output the hash value of the previous input. * + * WARNING: These functions may alter the floating point rounding mode of the calling thread. + * * @param machine is a pointer to a randomx_vm structure. Must not be NULL. * @param input is a pointer to memory to be hashed. Must not be NULL. * @param inputSize is the number of bytes to be hashed. diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index b425f19..82404d4 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "utility.hpp" #include "../bytecode_machine.hpp" #include "../dataset.hpp" @@ -1051,6 +1052,10 @@ int main() { assert(cacheMemory[33554431] == 0x1f47f056d05cd99b); }); + if (cache != nullptr) + randomx_release_cache(cache); + cache = randomx_alloc_cache(RANDOMX_FLAG_DEFAULT); + runTest("Hash batch test", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() { char hash1[RANDOMX_HASH_SIZE]; char hash2[RANDOMX_HASH_SIZE]; @@ -1070,6 +1075,13 @@ int main() { assert(equalsHex(hash3, "c36d4ed4191e617309867ed66a443be4075014e2b061bcdaf9ce7b721d2b77a8")); }); + runTest("Preserve rounding mode", RANDOMX_FREQ_CFROUND > 0, []() { + fesetround(FE_TONEAREST); + char hash[RANDOMX_HASH_SIZE]; + calcStringHash("test key 000", "Lorem ipsum dolor sit amet", &hash); + assert(fegetround() == FE_TONEAREST); + }); + randomx_destroy_vm(vm); vm = nullptr; From 148b923f71f3954ceaa37e7aff896d105bb7faa5 Mon Sep 17 00:00:00 2001 From: tevador Date: Wed, 6 May 2020 13:48:53 +0200 Subject: [PATCH 2/2] fix test 92 not failing properly on GCC/amd64 --- src/instructions_portable.cpp | 15 +++++++++++++++ src/intrin_portable.h | 6 ++++++ src/tests/tests.cpp | 6 +++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/instructions_portable.cpp b/src/instructions_portable.cpp index d1253d8..d746727 100644 --- a/src/instructions_portable.cpp +++ b/src/instructions_portable.cpp @@ -157,6 +157,21 @@ void rx_set_rounding_mode(uint32_t mode) { } } +uint32_t rx_get_rounding_mode() { + switch (fegetround()) { + case FE_DOWNWARD: + return RoundDown; + case FE_UPWARD: + return RoundUp; + case FE_TOWARDZERO: + return RoundToZero; + case FE_TONEAREST: + return RoundToNearest; + default: + UNREACHABLE; + } +} + #endif #ifdef RANDOMX_USE_X87 diff --git a/src/intrin_portable.h b/src/intrin_portable.h index c9d4475..05f6cd3 100644 --- a/src/intrin_portable.h +++ b/src/intrin_portable.h @@ -173,6 +173,10 @@ FORCE_INLINE void rx_set_rounding_mode(uint32_t mode) { _mm_setcsr(rx_mxcsr_default | (mode << 13)); } +FORCE_INLINE uint32_t rx_get_rounding_mode() { + return (_mm_getcsr() >> 13) & 3; +} + #elif defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) //sadly only POWER7 and newer will be able to use SIMD acceleration. Earlier processors cant use doubles or 64 bit integers with SIMD #include #include @@ -736,6 +740,8 @@ void rx_reset_float_state(); void rx_set_rounding_mode(uint32_t mode); +uint32_t rx_get_rounding_mode(); + #endif double loadDoublePortable(const void* addr); diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 82404d4..75daaba 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -4,7 +4,6 @@ #include #include -#include #include "utility.hpp" #include "../bytecode_machine.hpp" #include "../dataset.hpp" @@ -1076,10 +1075,11 @@ int main() { }); runTest("Preserve rounding mode", RANDOMX_FREQ_CFROUND > 0, []() { - fesetround(FE_TONEAREST); + rx_set_rounding_mode(RoundToNearest); char hash[RANDOMX_HASH_SIZE]; calcStringHash("test key 000", "Lorem ipsum dolor sit amet", &hash); - assert(fegetround() == FE_TONEAREST); + assert(equalsHex(hash, "300a0adb47603dedb42228ccb2b211104f4da45af709cd7547cd049e9489c969")); + assert(rx_get_rounding_mode() == RoundToNearest); }); randomx_destroy_vm(vm);