diff options
| author | Jessica Paquette <jpaquette@apple.com> | 2019-05-28 22:52:49 +0000 |
|---|---|---|
| committer | Jessica Paquette <jpaquette@apple.com> | 2019-05-28 22:52:49 +0000 |
| commit | b73ea75b384df86d6db36aff02e7f5e5f744c48d (patch) | |
| tree | dd2d0ab0306e574ac4f5fb476d05c2cfab5f0cae /llvm/lib | |
| parent | 1efbe67414fd66e74050fb02100f04265e0a51ae (diff) | |
| download | bcm5719-llvm-b73ea75b384df86d6db36aff02e7f5e5f744c48d.tar.gz bcm5719-llvm-b73ea75b384df86d6db36aff02e7f5e5f744c48d.zip | |
[AArch64][GlobalISel] Select FCMPSri/FCMPDri when comparing against 0.0
Add support for selecting FCMPSri and FCMPDri when comparing against 0.0, and
factor out opcode selection for G_FCMP into its own function.
Add a test to show that we don't do this with other immediates.
Differential Revision: https://reviews.llvm.org/D62539
llvm-svn: 361888
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index bb878ef2f5c..5fc272707f5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -741,6 +741,20 @@ static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) { return GenericOpc; } +/// Helper function to select the opcode for a G_FCMP. +static unsigned selectFCMPOpc(MachineInstr &I, MachineRegisterInfo &MRI) { + // If this is a compare against +0.0, then we don't have to explicitly + // materialize a constant. + const ConstantFP *FPImm = getConstantFPVRegVal(I.getOperand(3).getReg(), MRI); + bool ShouldUseImm = FPImm && (FPImm->isZero() && !FPImm->isNegative()); + unsigned OpSize = MRI.getType(I.getOperand(2).getReg()).getSizeInBits(); + if (OpSize != 32 && OpSize != 64) + return 0; + unsigned CmpOpcTbl[2][2] = {{AArch64::FCMPSrr, AArch64::FCMPDrr}, + {AArch64::FCMPSri, AArch64::FCMPDri}}; + return CmpOpcTbl[ShouldUseImm][OpSize == 64]; +} + static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) { switch (P) { default: @@ -1845,15 +1859,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I, return false; } - unsigned CmpOpc = 0; - LLT CmpTy = MRI.getType(I.getOperand(2).getReg()); - if (CmpTy == LLT::scalar(32)) { - CmpOpc = AArch64::FCMPSrr; - } else if (CmpTy == LLT::scalar(64)) { - CmpOpc = AArch64::FCMPDrr; - } else { + unsigned CmpOpc = selectFCMPOpc(I, MRI); + if (!CmpOpc) return false; - } // FIXME: regbank @@ -1861,9 +1869,16 @@ bool AArch64InstructionSelector::select(MachineInstr &I, changeFCMPPredToAArch64CC( (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2); - MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) - .addUse(I.getOperand(2).getReg()) - .addUse(I.getOperand(3).getReg()); + // Partially build the compare. Decide if we need to add a use for the + // third operand based off whether or not we're comparing against 0.0. + auto CmpMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) + .addUse(I.getOperand(2).getReg()); + + // If we don't have an immediate compare, then we need to add a use of the + // register which wasn't used for the immediate. + // Note that the immediate will always be the last operand. + if (CmpOpc != AArch64::FCMPSri && CmpOpc != AArch64::FCMPDri) + CmpMI = CmpMI.addUse(I.getOperand(3).getReg()); const unsigned DefReg = I.getOperand(0).getReg(); unsigned Def1Reg = DefReg; @@ -1893,8 +1908,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I, constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI); constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI); } - - constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI); + constrainSelectedInstRegOperands(*CmpMI, TII, TRI, RBI); constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI); I.eraseFromParent(); |

