From b45eb9fd275f857788cabb15ef8aabf0ff5907cc Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Wed, 8 May 2013 12:16:14 +0000 Subject: [PATCH] PPCInstrInfo::optimizeCompareInstr should not optimize FP compares The floating-point record forms on PPC don't set the condition register bits based on a comparison with zero (like the integer record forms do), but rather based on the exception status bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181423 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCInstrInfo.cpp | 29 +++++++++++------------------ test/CodeGen/PowerPC/optcmp.ll | 4 ++-- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index e6dac83e849..d94acde101e 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1096,8 +1096,11 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, int OpC = CmpInstr->getOpcode(); unsigned CRReg = CmpInstr->getOperand(0).getReg(); - bool isFP = OpC == PPC::FCMPUS || OpC == PPC::FCMPUD; - unsigned CRRecReg = isFP ? PPC::CR1 : PPC::CR0; + + // FP record forms set CR1 based on the execption status bits, not a + // comparison with zero. + if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD) + return false; // The record forms set the condition register based on a signed comparison // with zero (so says the ISA manual). This is not as straightforward as it @@ -1140,9 +1143,9 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, equalityOnly = true; } else return false; - } else if (!isFP) + } else equalityOnly = is64BitUnsignedCompare; - } else if (!isFP) + } else equalityOnly = is32BitUnsignedCompare; if (equalityOnly) { @@ -1211,8 +1214,8 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, unsigned IOpC = Instr.getOpcode(); if (&*I != CmpInstr && ( - Instr.modifiesRegister(CRRecReg, TRI) || - Instr.readsRegister(CRRecReg, TRI))) + Instr.modifiesRegister(PPC::CR0, TRI) || + Instr.readsRegister(PPC::CR0, TRI))) // This instruction modifies or uses the record condition register after // the one we want to change. While we could do this transformation, it // would likely not be profitable. This transformation removes one @@ -1232,15 +1235,6 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, break; } - if (isFP && (IOpC == PPC::FSUB || IOpC == PPC::FSUBS) && - ((Instr.getOperand(1).getReg() == SrcReg && - Instr.getOperand(2).getReg() == SrcReg2) || - (Instr.getOperand(1).getReg() == SrcReg2 && - Instr.getOperand(2).getReg() == SrcReg))) { - Sub = &*I; - break; - } - if (I == B) // The 'and' is below the comparison instruction. return false; @@ -1286,8 +1280,7 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, // The operands to subf are the opposite of sub, so only in the fixed-point // case, invert the order. - if (!isFP) - ShouldSwap = !ShouldSwap; + ShouldSwap = !ShouldSwap; } if (ShouldSwap) @@ -1326,7 +1319,7 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, MachineBasicBlock::iterator MII = MI; BuildMI(*MI->getParent(), llvm::next(MII), MI->getDebugLoc(), get(TargetOpcode::COPY), CRReg) - .addReg(CRRecReg, MIOpC != NewOpC ? RegState::Kill : 0); + .addReg(PPC::CR0, MIOpC != NewOpC ? RegState::Kill : 0); if (MIOpC != NewOpC) { // We need to be careful here: we're replacing one instruction with diff --git a/test/CodeGen/PowerPC/optcmp.ll b/test/CodeGen/PowerPC/optcmp.ll index 1fce464dd33..523f329303b 100644 --- a/test/CodeGen/PowerPC/optcmp.ll +++ b/test/CodeGen/PowerPC/optcmp.ll @@ -118,7 +118,7 @@ entry: ret double %cond ; CHECK: @food -; CHECK: fsub. 0, 1, 2 +; CHECK-NOT: fsub. 0, 1, 2 ; CHECK: stfd 0, 0(5) } @@ -131,7 +131,7 @@ entry: ret float %cond ; CHECK: @foof -; CHECK: fsubs. 0, 1, 2 +; CHECK-NOT: fsubs. 0, 1, 2 ; CHECK: stfs 0, 0(5) }