See https://llvm.org/bugs/show_bug.cgi?id=28630 for a description of the problem.
There were two locations where fast-isel would generate a LFD instruction with a target register class VSFRC instead of F8RC when VSX was enabled. The first is PPCFastISel::PPCEmitLoad, which had multiple problems:
1.) Typo in the definition of is64VSXLoad:
bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS; bool Is64VSXLoad = IsVSSRC && Opc == PPC::LFD;
The second line needs to use isVSFRC (like PPCEmitStore does)
2.) Move creation of resultReg. Even if the above typo is fixed, IsVSFRC would often be wrong, because it is computed from resultReg -- but in many cases, resultReg was still zero at this point.
3.) Once both the above are fixed, we're now generating a VSX instruction -- but an incorrect one, since generation of an indexed instruction with null index is wrong. Fixed by copying the code handling the same issue in PPCEmitStore.
The second place is PPCFastISel::PPCMaterializeFP, where we would emit an LFD to load a constant from the literal pool, and use the wrong result register class. Fixed by hardcoding a F8RC class even on systems supporting VSX.
Should these two utility routines now change?
In particular, don't need to check for ResultReg != 0, since that should never happen. They can also get the register class ID from the UseRC variable directly, instead of having to look it up through the MRI (lines 149, 152).