Disable CPUID checking with GCC 4.2 or older

This is not the first time that GCC 4.2 on Mac has produced bad code
surrounding the CPUID instruction (see also commit 81d1f79a7f).
So declare it broken beyond repair and don't run the instruction at all.

Instead, initialise the set of features found to be exactly that which
we detected at compile-time. For that reason, we can also disable the
runtime checking of the processor (minFeatures == detected features).

At the time of this commit, only the draw helpers and one QImage
helper make use of the runtime detection. Since the detection now
switches to compile-time, QtGui will start carrying dead code for GCC
4.2 and earlier: it will never run the SSE2/SSSE3 code on 32-bit
builds. (GCC 4.2 does not support AVX, so that code won't be built)

Note: all Clang versions report that they are GCC 4.2, so we need to
exclude it from the test; ICC reports the same version as the system's
GCC.

Change-Id: I43f168a9480a2479c6444eea175782b2eadc2ab2
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
This commit is contained in:
Thiago Macieira 2012-08-14 14:07:31 +02:00 committed by Qt by Nokia
parent 555e4e05f4
commit 732fc614da

View File

@ -379,6 +379,28 @@ QBasicAtomicInt qt_cpu_features = Q_BASIC_ATOMIC_INITIALIZER(0);
void qDetectCpuFeatures()
{
#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
# if (__GNUC__ * 100 + __GNUC_MINOR__) < 403
// GCC 4.2 (at least the one that comes with Apple's XCode, on Mac) is
// known to be broken beyond repair in dealing with the inline assembly
// above. It will generate bad code that could corrupt important registers
// like the PIC register. The behaviour of code after this function would
// be totally unpredictable.
//
// For that reason, simply forego the CPUID check at all and return the set
// of features that we found at compile time, through the #defines from the
// compiler. This should at least allow code to execute, even if none of
// the specialised code found in QtGui and elsewhere will ever be enabled
// (it's the user's fault for using a broken compiler).
//
// This also disables the runtime checking that the processor actually
// contains all the features that the code required. Qt 4 ran for years
// like that, so it shouldn't be a problem.
qt_cpu_features.store(minFeature | QSimdInitialized);
return;
# endif
#endif
uint f = detectProcessorFeatures();
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
if (!disable.isEmpty()) {