Use the right floating point load/store instructions in PPCInstrInfo::foldMemoryOperandImpl().
The PowerPC floating point registers can represent both f32 and f64 via the
two register classes F4RC and F8RC. F8RC is considered a subclass of F4RC to
allow cross-class coalescing. This coalescing only affects whether registers
are spilled as f32 or f64.
Spill slots must be accessed with load/store instructions corresponding to the
class of the spilled register. PPCInstrInfo::foldMemoryOperandImpl was looking
at the instruction opcode which is wrong.
X86 has similar floating point register classes, but doesn't try to fold
memory operands, so there is no problem there.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97262 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp
index 3db623a..01d684b 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -19,6 +19,7 @@
#include "PPCTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -688,12 +689,21 @@
getUndefRegState(isUndef)),
FrameIndex);
}
- } else if (Opc == PPC::FMRD) {
+ } else if (Opc == PPC::FMRD || Opc == PPC::FMRS || Opc == PPC::FMRSD) {
+ // The register may be F4RC or F8RC, and that determines the memory op.
+ unsigned OrigReg = MI->getOperand(OpNum).getReg();
+ // We cannot tell the register class from a physreg alone.
+ if (TargetRegisterInfo::isPhysicalRegister(OrigReg))
+ return NULL;
+ const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(OrigReg);
+ const bool is64 = RC == PPC::F8RCRegisterClass;
+
if (OpNum == 0) { // move -> store
unsigned InReg = MI->getOperand(1).getReg();
bool isKill = MI->getOperand(1).isKill();
bool isUndef = MI->getOperand(1).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFD))
+ NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(),
+ get(is64 ? PPC::STFD : PPC::STFS))
.addReg(InReg,
getKillRegState(isKill) |
getUndefRegState(isUndef)),
@@ -702,28 +712,8 @@
unsigned OutReg = MI->getOperand(0).getReg();
bool isDead = MI->getOperand(0).isDead();
bool isUndef = MI->getOperand(0).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFD))
- .addReg(OutReg,
- RegState::Define |
- getDeadRegState(isDead) |
- getUndefRegState(isUndef)),
- FrameIndex);
- }
- } else if (Opc == PPC::FMRS) {
- if (OpNum == 0) { // move -> store
- unsigned InReg = MI->getOperand(1).getReg();
- bool isKill = MI->getOperand(1).isKill();
- bool isUndef = MI->getOperand(1).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFS))
- .addReg(InReg,
- getKillRegState(isKill) |
- getUndefRegState(isUndef)),
- FrameIndex);
- } else { // move -> load
- unsigned OutReg = MI->getOperand(0).getReg();
- bool isDead = MI->getOperand(0).isDead();
- bool isUndef = MI->getOperand(0).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFS))
+ NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(),
+ get(is64 ? PPC::LFD : PPC::LFS))
.addReg(OutReg,
RegState::Define |
getDeadRegState(isDead) |