diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-01-26 19:38:20 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-01-27 23:04:52 +0000 |
commit | 72f49ef46a3426471b3c2102566d7d04390217d2 (patch) | |
tree | 48bb4d41669c74c8067f76072763ad378919a837 /src/corelib/tools/qalgorithms.h | |
parent | 099f2868701932ee99b60d19429d9c43f96dcadc (diff) |
MSVC: Fix use of POPCNT instruction without CPU check
The __popcnt family of intrinsics with MSVC generates directly the
POPCNT instruction and are documented to do so:
https://msdn.microsoft.com/en-us/library/bb385231.aspx
So we can't use __popcnt unless the target processor supports it.
[ChangeLog][Windows] Fixed a bug that caused applications to crash with
"Illegal instruction" faults when compiled with Visual Studio and run on
some older processors.
Task-number: QTBUG-58446
Change-Id: I445bb15619f6401494e8fffd149d83bd2a7e3376
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/corelib/tools/qalgorithms.h')
-rw-r--r-- | src/corelib/tools/qalgorithms.h | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index fb7031ce71..c0f7709fec 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -638,6 +638,17 @@ Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) Q_DECL_NOTHROW { return qt_builtin_clz(v) - 16U; } + +// Neither MSVC nor the Intel compiler define a macro for the POPCNT processor +// feature, so we're using either the SSE4.2 or the AVX macro as a proxy (Clang +// does define the macro). It's incorrect for two reasons: +// 1. It's a separate bit in CPUID, so a processor could implement SSE4.2 and +// not POPCNT, but that's unlikely to happen. +// 2. There are processors that support POPCNT but not AVX (Intel Nehalem +// architecture), but unlike the other compilers, MSVC has no option +// to generate code for those processors. +// So it's an acceptable compromise. +#if defined(__AVX__) || defined(__SSE4_2__) || defined(__POPCNT__) #define QALGORITHMS_USE_BUILTIN_POPCOUNT Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) Q_DECL_NOTHROW { @@ -658,6 +669,8 @@ Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) Q_DECL_NOTHROW return __popcnt64(v); } #endif // MSVC 64bit +#endif // __AVX__ || __SSE4_2__ || __POPCNT__ + #endif // MSVC #endif // QT_HAS_CONSTEXPR_BUILTINS |