From 0de4f0dcc3cae4f535a5604933e7d44212a159d4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 5 May 2020 17:03:28 -0700 Subject: [PATCH] Fix build of rdrand & rdseed with ICC on Linux qsimd.cpp(636): error: argument of type "qregisteruint={quint64={unsigned long long}} *" is incompatible with parameter of type "unsigned long *" Pick-To: 5.15 Change-Id: I99ab0f318b1c43b89888fffd160c4785c98adc4d Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Lars Knoll --- src/corelib/global/qsimd.cpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qsimd.cpp b/src/corelib/global/qsimd.cpp index 75c380ee8a..6ad6795fec 100644 --- a/src/corelib/global/qsimd.cpp +++ b/src/corelib/global/qsimd.cpp @@ -38,6 +38,9 @@ ** ****************************************************************************/ +// we need ICC to define the prototype for _rdseed64_step +#define __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES + #include "qsimd_p.h" #include "qalgorithms.h" #include @@ -605,6 +608,15 @@ void qDumpCPUFeatures() # define _rdseedXX_step _rdseed32_step # endif +// The parameter to _rdrand64_step & _rdseed64_step is unsigned long long for +// Clang and GCC but unsigned __int64 for MSVC and ICC, which is unsigned long +// long on Windows, but unsigned long on Linux. +namespace { +template struct ExtractParameter; +template struct ExtractParameter { using Type = T; }; +using randuint = ExtractParameter::Type; +} + # if QT_COMPILER_SUPPORTS_HERE(RDSEED) static QT_FUNCTION_TARGET(RDSEED) unsigned *qt_random_rdseed(unsigned *ptr, unsigned *end) noexcept { @@ -613,13 +625,13 @@ static QT_FUNCTION_TARGET(RDSEED) unsigned *qt_random_rdseed(unsigned *ptr, unsi // If the independent bit generator used by RDSEED is out of entropy, it // may take time to replenish. // https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide - while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) { - if (_rdseedXX_step(reinterpret_cast(ptr)) == 0) + while (ptr + sizeof(randuint)/sizeof(*ptr) <= end) { + if (_rdseedXX_step(reinterpret_cast(ptr)) == 0) goto out; - ptr += sizeof(qregisteruint)/sizeof(*ptr); + ptr += sizeof(randuint)/sizeof(*ptr); } - if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) { + if (sizeof(*ptr) != sizeof(randuint) && ptr != end) { if (_rdseed32_step(ptr) == 0) goto out; ++ptr; @@ -638,14 +650,14 @@ static unsigned *qt_random_rdseed(unsigned *ptr, unsigned *) static QT_FUNCTION_TARGET(RDRND) unsigned *qt_random_rdrnd(unsigned *ptr, unsigned *end) noexcept { int retries = 10; - while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) { - if (_rdrandXX_step(reinterpret_cast(ptr))) - ptr += sizeof(qregisteruint)/sizeof(*ptr); + while (ptr + sizeof(randuint)/sizeof(*ptr) <= end) { + if (_rdrandXX_step(reinterpret_cast(ptr))) + ptr += sizeof(randuint)/sizeof(*ptr); else if (--retries == 0) goto out; } - while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) { + while (sizeof(*ptr) != sizeof(randuint) && ptr != end) { bool ok = _rdrand32_step(ptr); if (!ok && --retries) continue;