Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 634458 - After updating Qt5 to 5.9.2, Qt5 applications fail to launch, looking for a missing f16c capability
Summary: After updating Qt5 to 5.9.2, Qt5 applications fail to launch, looking for a m...
Status: RESOLVED INVALID
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Linux bug wranglers
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-16 15:59 UTC by Adam Stylinski
Modified: 2018-03-24 19:50 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Stylinski 2017-10-16 15:59:49 UTC
There may be something wrong with the QT build process during feature detection, because this is what my CPU_FLAGS_X86 is defined as:

CPU_FLAGS_X86="aes avx mmx mmxext popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"

Now when I launch a Qt5 application I get the following: 

Incompatible processor. This Qt build requires the following features:
    f16c rdrand
Aborted. Incompatible processor: missing feature 0x60000000 - f16c.
Aborted

Of course, I have neither f16c nor rdrand, but f16c seems to come first.
Comment 1 Adam Stylinski 2017-10-16 16:18:13 UTC
So the problem seems to be that they are using an f16 intrinsic, but gcc neither 6 nor 7 are emitting f16c instructions:

eggsbenedict f16c # make
g++ -c -pipe -mf16c -O2 -w -fPIC  -I. -I/scratchdir/tmp/portage/dev-qt/qtcore-5.9.2/work/qtbase-opensource-src-5.9.2/mkspecs/linux-g++ -o main.o main.cpp
g++ -Wl,-O1 -fuse-ld=gold -o f16c main.o    
eggsbenedict f16c # ls
f16c  f16c.pro  main.cpp  main.o  Makefile
eggsbenedict f16c # ./f16c 
eggsbenedict f16c # echo $?
0

Objdump confirms this.  It seems to be because they are compiling with -O2 and the compiler is optimizing out the actual f16c tests in test program.  Forcing it to compile with -O0 for that test actually gave me an illegal instruction:

./f16c 
Illegal instruction
eggsbenedict f16c # objdump -dSRC f16c | grep -i vcvt
  40052d:	c4 e2 79 13 c0       	vcvtph2ps %xmm0,%xmm0
  400546:	c4 e2 7d 13 c0       	vcvtph2ps %xmm0,%ymm0

So, are we supplying this optimization flag for the tests in the build instructions or is Qt?  That will be the difference as to whether or not this is an upstream bug or a gentoo bug.
Comment 2 Adam Stylinski 2017-10-16 17:38:09 UTC
Yes, it appears this is an issue upstream, and an annoying one at that.  Because of the way gentoo subdivides the Qt packages, patching this requires patching every single qt ebuild.

I'm not entirely sure what the best fix is, it appears the test source code is autogenerated from a json file (ugh, why?) and doing #pragma GCC optimize() besides being non-portable to things outside of GCC (though still compileable most likely) doesn't work within function bodies (you'd have to declare it as an attribute to the main function or put it outside of the main function).  From the look of it, there's no obvious way to add an attribute to the main function declaration, as this appears to be some roll-your-own code generation.  Force -O0 in the compiler flags defined for the same block is possible, however you have to first remove an -Ox flags, as it seems to take whatever the last specified -Ox argument is.  I guess I could add some conditional in the source code body in the json to print on some condition that isn't possible to always evaluate to true, but even that might be difficult.  It's not impossible to make their trivial code non-trivial, perhaps this is the best solution.

Another solution may be to actually obey the CPU_FLAGS_X86 argument and pass them to the configure script with --{no}-cpufeaturename, but it appears not all of them are capable of being explicitly specified, some of these are only enabled by tests or some explicit cases of "all architectures that have this extension by association also have this extension".  So yeah, that might also be a tricky route, and a lot more work on the maintainer's part.  

Why couldn't Qt devs just had statically coded tests?  It looks like there are a few which are there when unpacked from the source archive anyway (confusingly), though they may be overwritten when the configure.json file is fed to their source generator thing.  

Would maintainers/upstream appreciate it if I made these tests non-trivially optimizable so that the tests fail when they should?
Comment 3 Adam Stylinski 2017-10-16 19:00:14 UTC
I filed a bug upstream as well:

https://bugreports.qt.io/browse/QTBUG-63813
Comment 4 Adam Stylinski 2017-10-16 19:35:06 UTC
After reading where the abort compares and reading other former bug reports, it would seem that the tests themselves are only supposed to check whether or not a compiler supports a CPU feature, not whether the running CPU supports it.  So for some reason the running Qt applications believe they were built with a version of Qt5 that didn't have this feature enabled in the binaries.  I'm still looking - hopefully upstream can clue me in.
Comment 5 Adam Stylinski 2017-10-16 19:51:50 UTC
Hmm, what's even stranger: if I force QT to disable a CPU feature I get the same error message.  So it really does think this Qt library has a runtime requirement for f16c and rdrand rather than the library complaining about support for such a feature not existing:

adam@eggsbenedict ~ $ QT_NO_CPU_FEATURE="rdrand f16c avx" x2goclient
Incompatible processor. This Qt build requires the following features:
    avx f16c rdrand
Aborted. Incompatible processor: missing feature 0x70000000 - avx.
Aborted
Comment 6 Adam Stylinski 2017-10-16 22:50:42 UTC
I'm really not entirely sure what's going on.  I think I understand the intent of the developers with this feature (maybe?) but it seems like the macros __F16C__ and __RDRND__ are being defined accidentally (despite AVX2 not explicitly being turned on anywhere) at compile time when being emerged.  I made this work by hacking out those features entirely in the header in the interim, but this is obviously not a fix and not the intention.

I really should try a standalone Qt5 build outside of portage just to make sure it's not strictly the ebuild causing this issue by erroneously switching on some CPU flag.  Though, when it's compile, I'm only seeing my $CXXFLAGS from portage and nothing else out of the ordinary.  There must be something defining this macro that shouldn't.
Comment 7 Adam Stylinski 2017-10-16 23:10:30 UTC
Ahhh, I figured it out.  Evidently -march=core-avx-i is not correct behavior for sandybridge despite things on the internet otherwise claiming so.  And actually if you look at the GCC documentation page, it makes a lot of sense why those two instructions are "missing".