diff options
author | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2017-03-27 16:35:31 +0000 |
---|---|---|
committer | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2017-03-27 16:35:31 +0000 |
commit | 641cb203b6f1ea2d92d17a99a04c8d971f2103e5 (patch) | |
tree | 10a2a9dce8fdd3ece2719cd082e234f5ca4ee2c2 /llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | |
parent | 2d29998f22b8b22019da8ca4ef58be9397be14f2 (diff) | |
download | bcm5719-llvm-641cb203b6f1ea2d92d17a99a04c8d971f2103e5.tar.gz bcm5719-llvm-641cb203b6f1ea2d92d17a99a04c8d971f2103e5.zip |
[GlobalISel][AArch64] Select CBZ.
CBZ/CBNZ represent a substantial portion of all conditional branches.
Look through G_ICMP to select them.
We can't use tablegen yet because the existing patterns match an
AArch64ISD node.
llvm-svn: 298856
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index 6490d88a3c8..2e199d9c0d9 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -448,6 +448,50 @@ static void changeFCMPPredToAArch64CC(CmpInst::Predicate P, } } +bool AArch64InstructionSelector::selectCompareBranch( + MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { + + const unsigned CondReg = I.getOperand(0).getReg(); + MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); + MachineInstr *CCMI = MRI.getVRegDef(CondReg); + if (CCMI->getOpcode() != TargetOpcode::G_ICMP) + return false; + + unsigned LHS = CCMI->getOperand(2).getReg(); + unsigned RHS = CCMI->getOperand(3).getReg(); + if (!getConstantVRegVal(RHS, MRI)) + std::swap(RHS, LHS); + + const auto RHSImm = getConstantVRegVal(RHS, MRI); + if (!RHSImm || *RHSImm != 0) + return false; + + const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI); + if (RB.getID() != AArch64::GPRRegBankID) + return false; + + const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate(); + if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ) + return false; + + const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits(); + unsigned CBOpc = 0; + if (CmpWidth <= 32) + CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW); + else if (CmpWidth == 64) + CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX); + else + return false; + + auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc)) + .addUse(LHS) + .addMBB(DestMBB); + + constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI); + I.eraseFromParent(); + return true; +} + bool AArch64InstructionSelector::selectVaStartAAPCS( MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { return false; @@ -556,6 +600,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { const unsigned CondReg = I.getOperand(0).getReg(); MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); + if (selectCompareBranch(I, MF, MRI)) + return true; + auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW)) .addUse(CondReg) .addImm(/*bit offset=*/0) |