[PowerPC] Wrong fast-isel codegen for VSX floating-point loads
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 5 Aug 2016 15:22:05 +0000 (15:22 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 5 Aug 2016 15:22:05 +0000 (15:22 +0000)
commitc3b495a649e54acc766a57b606d4fa75a87d48e8
tree5ee2a98b163e5ca35e1ae7b544aa4e0df36a8f0a
parent8d3f29759fc9e1450fb9f2b789b4900d59809223
[PowerPC] Wrong fast-isel codegen for VSX floating-point loads

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.
This can ccause invalid registers to be used in certain cases, like:
   lfd 36, ...
instead of using a VSX load instruction.  The wrong register number gets
silently truncated, causing invalid code to be generated.

The first place is PPCFastISel::PPCEmitLoad, which had multiple problems:

1.) The IsVSSRC and IsVSFRC flags are not initialized correctly, since they
are computed from resultReg, which is still zero at this point in many cases.
Fixed by changing the helper routines to operate on a register class instead
of a register and passing in UseRC.

2.) Even with this fixed, Is64VSXLoad is still wrong due to a typo:

bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
bool Is64VSXLoad = IsVSSRC && Opc == PPC::LFD;

The second line needs to use isVSFRC (like PPCEmitStore does).

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.

Fixes: https://llvm.org/bugs/show_bug.cgi?id=28630

Differential Revision: https://reviews.llvm.org/D22632

llvm-svn: 277823
llvm/lib/Target/PowerPC/PPCFastISel.cpp
llvm/test/CodeGen/PowerPC/pr28630.ll [new file with mode: 0644]