LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMInstructionSelector.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 283 349 81.1 %
Date: 2018-10-20 13:21:21 Functions: 10 17 58.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : /// This file implements the targeting of the InstructionSelector class for ARM.
      11             : /// \todo This should be generated by TableGen.
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "ARMRegisterBankInfo.h"
      15             : #include "ARMSubtarget.h"
      16             : #include "ARMTargetMachine.h"
      17             : #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
      18             : #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
      19             : #include "llvm/CodeGen/MachineConstantPool.h"
      20             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      21             : #include "llvm/Support/Debug.h"
      22             : 
      23             : #define DEBUG_TYPE "arm-isel"
      24             : 
      25             : using namespace llvm;
      26             : 
      27             : namespace {
      28             : 
      29             : #define GET_GLOBALISEL_PREDICATE_BITSET
      30             : #include "ARMGenGlobalISel.inc"
      31             : #undef GET_GLOBALISEL_PREDICATE_BITSET
      32             : 
      33             : class ARMInstructionSelector : public InstructionSelector {
      34             : public:
      35             :   ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
      36             :                          const ARMRegisterBankInfo &RBI);
      37             : 
      38             :   bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
      39             :   static const char *getName() { return DEBUG_TYPE; }
      40             : 
      41             : private:
      42             :   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
      43             : 
      44             :   struct CmpConstants;
      45             :   struct InsertInfo;
      46             : 
      47             :   bool selectCmp(CmpConstants Helper, MachineInstrBuilder &MIB,
      48             :                  MachineRegisterInfo &MRI) const;
      49             : 
      50             :   // Helper for inserting a comparison sequence that sets \p ResReg to either 1
      51             :   // if \p LHSReg and \p RHSReg are in the relationship defined by \p Cond, or
      52             :   // \p PrevRes otherwise. In essence, it computes PrevRes OR (LHS Cond RHS).
      53             :   bool insertComparison(CmpConstants Helper, InsertInfo I, unsigned ResReg,
      54             :                         ARMCC::CondCodes Cond, unsigned LHSReg, unsigned RHSReg,
      55             :                         unsigned PrevRes) const;
      56             : 
      57             :   // Set \p DestReg to \p Constant.
      58             :   void putConstant(InsertInfo I, unsigned DestReg, unsigned Constant) const;
      59             : 
      60             :   bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
      61             :   bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
      62             :   bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const;
      63             : 
      64             :   // Check if the types match and both operands have the expected size and
      65             :   // register bank.
      66             :   bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
      67             :                       unsigned ExpectedSize, unsigned ExpectedRegBankID) const;
      68             : 
      69             :   // Check if the register has the expected size and register bank.
      70             :   bool validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize,
      71             :                 unsigned ExpectedRegBankID) const;
      72             : 
      73             :   const ARMBaseInstrInfo &TII;
      74             :   const ARMBaseRegisterInfo &TRI;
      75             :   const ARMBaseTargetMachine &TM;
      76             :   const ARMRegisterBankInfo &RBI;
      77             :   const ARMSubtarget &STI;
      78             : 
      79             : #define GET_GLOBALISEL_PREDICATES_DECL
      80             : #include "ARMGenGlobalISel.inc"
      81             : #undef GET_GLOBALISEL_PREDICATES_DECL
      82             : 
      83             : // We declare the temporaries used by selectImpl() in the class to minimize the
      84             : // cost of constructing placeholder values.
      85             : #define GET_GLOBALISEL_TEMPORARIES_DECL
      86             : #include "ARMGenGlobalISel.inc"
      87             : #undef GET_GLOBALISEL_TEMPORARIES_DECL
      88             : };
      89             : } // end anonymous namespace
      90             : 
      91             : namespace llvm {
      92             : InstructionSelector *
      93        5050 : createARMInstructionSelector(const ARMBaseTargetMachine &TM,
      94             :                              const ARMSubtarget &STI,
      95             :                              const ARMRegisterBankInfo &RBI) {
      96        5050 :   return new ARMInstructionSelector(TM, STI, RBI);
      97             : }
      98             : }
      99             : 
     100             : const unsigned zero_reg = 0;
     101             : 
     102             : #define GET_GLOBALISEL_IMPL
     103             : #include "ARMGenGlobalISel.inc"
     104             : #undef GET_GLOBALISEL_IMPL
     105             : 
     106        5050 : ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
     107             :                                                const ARMSubtarget &STI,
     108        5050 :                                                const ARMRegisterBankInfo &RBI)
     109        5050 :     : InstructionSelector(), TII(*STI.getInstrInfo()),
     110        5050 :       TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI),
     111             : #define GET_GLOBALISEL_PREDICATES_INIT
     112             : #include "ARMGenGlobalISel.inc"
     113             : #undef GET_GLOBALISEL_PREDICATES_INIT
     114             : #define GET_GLOBALISEL_TEMPORARIES_INIT
     115             : #include "ARMGenGlobalISel.inc"
     116             : #undef GET_GLOBALISEL_TEMPORARIES_INIT
     117             : {
     118        5050 : }
     119             : 
     120         730 : static const TargetRegisterClass *guessRegClass(unsigned Reg,
     121             :                                                 MachineRegisterInfo &MRI,
     122             :                                                 const TargetRegisterInfo &TRI,
     123             :                                                 const RegisterBankInfo &RBI) {
     124         730 :   const RegisterBank *RegBank = RBI.getRegBank(Reg, MRI, TRI);
     125             :   assert(RegBank && "Can't get reg bank for virtual register");
     126             : 
     127         730 :   const unsigned Size = MRI.getType(Reg).getSizeInBits();
     128             :   assert((RegBank->getID() == ARM::GPRRegBankID ||
     129             :           RegBank->getID() == ARM::FPRRegBankID) &&
     130             :          "Unsupported reg bank");
     131             : 
     132         730 :   if (RegBank->getID() == ARM::FPRRegBankID) {
     133         143 :     if (Size == 32)
     134             :       return &ARM::SPRRegClass;
     135          63 :     else if (Size == 64)
     136             :       return &ARM::DPRRegClass;
     137           0 :     else if (Size == 128)
     138             :       return &ARM::QPRRegClass;
     139             :     else
     140           0 :       llvm_unreachable("Unsupported destination size");
     141             :   }
     142             : 
     143             :   return &ARM::GPRRegClass;
     144             : }
     145             : 
     146           0 : static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
     147             :                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
     148             :                        const RegisterBankInfo &RBI) {
     149           0 :   unsigned DstReg = I.getOperand(0).getReg();
     150           0 :   if (TargetRegisterInfo::isPhysicalRegister(DstReg))
     151           0 :     return true;
     152             : 
     153           0 :   const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
     154             : 
     155             :   // No need to constrain SrcReg. It will get constrained when
     156             :   // we hit another of its uses or its defs.
     157             :   // Copies do not have constraints.
     158           0 :   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
     159             :     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
     160             :                       << " operand\n");
     161           0 :     return false;
     162             :   }
     163             :   return true;
     164             : }
     165             : 
     166           0 : static bool selectMergeValues(MachineInstrBuilder &MIB,
     167             :                               const ARMBaseInstrInfo &TII,
     168             :                               MachineRegisterInfo &MRI,
     169             :                               const TargetRegisterInfo &TRI,
     170             :                               const RegisterBankInfo &RBI) {
     171             :   assert(TII.getSubtarget().hasVFP2() && "Can't select merge without VFP");
     172             : 
     173             :   // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
     174             :   // into one DPR.
     175           0 :   unsigned VReg0 = MIB->getOperand(0).getReg();
     176             :   (void)VReg0;
     177             :   assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
     178             :          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
     179             :          "Unsupported operand for G_MERGE_VALUES");
     180             :   unsigned VReg1 = MIB->getOperand(1).getReg();
     181             :   (void)VReg1;
     182             :   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
     183             :          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
     184             :          "Unsupported operand for G_MERGE_VALUES");
     185             :   unsigned VReg2 = MIB->getOperand(2).getReg();
     186             :   (void)VReg2;
     187             :   assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
     188             :          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
     189             :          "Unsupported operand for G_MERGE_VALUES");
     190             : 
     191           0 :   MIB->setDesc(TII.get(ARM::VMOVDRR));
     192           0 :   MIB.add(predOps(ARMCC::AL));
     193             : 
     194           0 :   return true;
     195             : }
     196             : 
     197           0 : static bool selectUnmergeValues(MachineInstrBuilder &MIB,
     198             :                                 const ARMBaseInstrInfo &TII,
     199             :                                 MachineRegisterInfo &MRI,
     200             :                                 const TargetRegisterInfo &TRI,
     201             :                                 const RegisterBankInfo &RBI) {
     202             :   assert(TII.getSubtarget().hasVFP2() && "Can't select unmerge without VFP");
     203             : 
     204             :   // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
     205             :   // GPRs.
     206           0 :   unsigned VReg0 = MIB->getOperand(0).getReg();
     207             :   (void)VReg0;
     208             :   assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
     209             :          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
     210             :          "Unsupported operand for G_UNMERGE_VALUES");
     211             :   unsigned VReg1 = MIB->getOperand(1).getReg();
     212             :   (void)VReg1;
     213             :   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
     214             :          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
     215             :          "Unsupported operand for G_UNMERGE_VALUES");
     216             :   unsigned VReg2 = MIB->getOperand(2).getReg();
     217             :   (void)VReg2;
     218             :   assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
     219             :          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
     220             :          "Unsupported operand for G_UNMERGE_VALUES");
     221             : 
     222           0 :   MIB->setDesc(TII.get(ARM::VMOVRRD));
     223           0 :   MIB.add(predOps(ARMCC::AL));
     224             : 
     225           0 :   return true;
     226             : }
     227             : 
     228             : /// Select the opcode for simple extensions (that translate to a single SXT/UXT
     229             : /// instruction). Extension operations more complicated than that should not
     230             : /// invoke this. Returns the original opcode if it doesn't know how to select a
     231             : /// better one.
     232             : static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
     233             :   using namespace TargetOpcode;
     234             : 
     235           2 :   if (Size != 8 && Size != 16)
     236             :     return Opc;
     237             : 
     238           2 :   if (Opc == G_SEXT)
     239           1 :     return Size == 8 ? ARM::SXTB : ARM::SXTH;
     240             : 
     241           1 :   if (Opc == G_ZEXT)
     242           1 :     return Size == 8 ? ARM::UXTB : ARM::UXTH;
     243             : 
     244             :   return Opc;
     245             : }
     246             : 
     247             : /// Select the opcode for simple loads and stores. For types smaller than 32
     248             : /// bits, the value will be zero extended. Returns the original opcode if it
     249             : /// doesn't know how to select a better one.
     250         123 : static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
     251             :                                       unsigned Size) {
     252             :   bool isStore = Opc == TargetOpcode::G_STORE;
     253             : 
     254         123 :   if (RegBank == ARM::GPRRegBankID) {
     255         119 :     switch (Size) {
     256           4 :     case 1:
     257             :     case 8:
     258           6 :       return isStore ? ARM::STRBi12 : ARM::LDRBi12;
     259           3 :     case 16:
     260           4 :       return isStore ? ARM::STRH : ARM::LDRH;
     261         112 :     case 32:
     262         221 :       return isStore ? ARM::STRi12 : ARM::LDRi12;
     263             :     default:
     264             :       return Opc;
     265             :     }
     266             :   }
     267             : 
     268           4 :   if (RegBank == ARM::FPRRegBankID) {
     269           4 :     switch (Size) {
     270           2 :     case 32:
     271           3 :       return isStore ? ARM::VSTRS : ARM::VLDRS;
     272           2 :     case 64:
     273           3 :       return isStore ? ARM::VSTRD : ARM::VLDRD;
     274             :     default:
     275             :       return Opc;
     276             :     }
     277             :   }
     278             : 
     279             :   return Opc;
     280             : }
     281             : 
     282             : // When lowering comparisons, we sometimes need to perform two compares instead
     283             : // of just one. Get the condition codes for both comparisons. If only one is
     284             : // needed, the second member of the pair is ARMCC::AL.
     285             : static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
     286          47 : getComparePreds(CmpInst::Predicate Pred) {
     287             :   std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
     288          47 :   switch (Pred) {
     289           3 :   case CmpInst::FCMP_ONE:
     290             :     Preds = {ARMCC::GT, ARMCC::MI};
     291           3 :     break;
     292           2 :   case CmpInst::FCMP_UEQ:
     293             :     Preds = {ARMCC::EQ, ARMCC::VS};
     294           2 :     break;
     295           4 :   case CmpInst::ICMP_EQ:
     296             :   case CmpInst::FCMP_OEQ:
     297             :     Preds.first = ARMCC::EQ;
     298           4 :     break;
     299           7 :   case CmpInst::ICMP_SGT:
     300             :   case CmpInst::FCMP_OGT:
     301             :     Preds.first = ARMCC::GT;
     302           7 :     break;
     303           3 :   case CmpInst::ICMP_SGE:
     304             :   case CmpInst::FCMP_OGE:
     305             :     Preds.first = ARMCC::GE;
     306           3 :     break;
     307           3 :   case CmpInst::ICMP_UGT:
     308             :   case CmpInst::FCMP_UGT:
     309             :     Preds.first = ARMCC::HI;
     310           3 :     break;
     311           2 :   case CmpInst::FCMP_OLT:
     312             :     Preds.first = ARMCC::MI;
     313           2 :     break;
     314           3 :   case CmpInst::ICMP_ULE:
     315             :   case CmpInst::FCMP_OLE:
     316             :     Preds.first = ARMCC::LS;
     317           3 :     break;
     318           2 :   case CmpInst::FCMP_ORD:
     319             :     Preds.first = ARMCC::VC;
     320           2 :     break;
     321           2 :   case CmpInst::FCMP_UNO:
     322             :     Preds.first = ARMCC::VS;
     323           2 :     break;
     324           2 :   case CmpInst::FCMP_UGE:
     325             :     Preds.first = ARMCC::PL;
     326           2 :     break;
     327           5 :   case CmpInst::ICMP_SLT:
     328             :   case CmpInst::FCMP_ULT:
     329             :     Preds.first = ARMCC::LT;
     330           5 :     break;
     331           3 :   case CmpInst::ICMP_SLE:
     332             :   case CmpInst::FCMP_ULE:
     333             :     Preds.first = ARMCC::LE;
     334           3 :     break;
     335           4 :   case CmpInst::FCMP_UNE:
     336             :   case CmpInst::ICMP_NE:
     337             :     Preds.first = ARMCC::NE;
     338           4 :     break;
     339           1 :   case CmpInst::ICMP_UGE:
     340             :     Preds.first = ARMCC::HS;
     341           1 :     break;
     342           1 :   case CmpInst::ICMP_ULT:
     343             :     Preds.first = ARMCC::LO;
     344           1 :     break;
     345             :   default:
     346             :     break;
     347             :   }
     348             :   assert(Preds.first != ARMCC::AL && "No comparisons needed?");
     349          47 :   return Preds;
     350             : }
     351             : 
     352             : struct ARMInstructionSelector::CmpConstants {
     353             :   CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned OpRegBank,
     354             :                unsigned OpSize)
     355          51 :       : ComparisonOpcode(CmpOpcode), ReadFlagsOpcode(FlagsOpcode),
     356          51 :         OperandRegBankID(OpRegBank), OperandSize(OpSize) {}
     357             : 
     358             :   // The opcode used for performing the comparison.
     359             :   const unsigned ComparisonOpcode;
     360             : 
     361             :   // The opcode used for reading the flags set by the comparison. May be
     362             :   // ARM::INSTRUCTION_LIST_END if we don't need to read the flags.
     363             :   const unsigned ReadFlagsOpcode;
     364             : 
     365             :   // The assumed register bank ID for the operands.
     366             :   const unsigned OperandRegBankID;
     367             : 
     368             :   // The assumed size in bits for the operands.
     369             :   const unsigned OperandSize;
     370             : };
     371             : 
     372             : struct ARMInstructionSelector::InsertInfo {
     373             :   InsertInfo(MachineInstrBuilder &MIB)
     374          51 :       : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())),
     375         102 :         DbgLoc(MIB->getDebugLoc()) {}
     376             : 
     377             :   MachineBasicBlock &MBB;
     378             :   const MachineBasicBlock::instr_iterator InsertBefore;
     379             :   const DebugLoc &DbgLoc;
     380             : };
     381             : 
     382           0 : void ARMInstructionSelector::putConstant(InsertInfo I, unsigned DestReg,
     383             :                                          unsigned Constant) const {
     384           0 :   (void)BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(ARM::MOVi))
     385             :       .addDef(DestReg)
     386           0 :       .addImm(Constant)
     387           0 :       .add(predOps(ARMCC::AL))
     388           0 :       .add(condCodeOp());
     389           0 : }
     390             : 
     391          47 : bool ARMInstructionSelector::validOpRegPair(MachineRegisterInfo &MRI,
     392             :                                             unsigned LHSReg, unsigned RHSReg,
     393             :                                             unsigned ExpectedSize,
     394             :                                             unsigned ExpectedRegBankID) const {
     395          47 :   return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
     396          94 :          validReg(MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
     397          47 :          validReg(MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
     398             : }
     399             : 
     400           0 : bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg,
     401             :                                       unsigned ExpectedSize,
     402             :                                       unsigned ExpectedRegBankID) const {
     403           0 :   if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) {
     404             :     LLVM_DEBUG(dbgs() << "Unexpected size for register");
     405           0 :     return false;
     406             :   }
     407             : 
     408           0 :   if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) {
     409             :     LLVM_DEBUG(dbgs() << "Unexpected register bank for register");
     410           0 :     return false;
     411             :   }
     412             : 
     413             :   return true;
     414             : }
     415             : 
     416          51 : bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
     417             :                                        MachineInstrBuilder &MIB,
     418             :                                        MachineRegisterInfo &MRI) const {
     419             :   const InsertInfo I(MIB);
     420             : 
     421          51 :   auto ResReg = MIB->getOperand(0).getReg();
     422          51 :   if (!validReg(MRI, ResReg, 1, ARM::GPRRegBankID))
     423             :     return false;
     424             : 
     425             :   auto Cond =
     426          51 :       static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
     427          51 :   if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) {
     428           6 :     putConstant(I, ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0);
     429           4 :     MIB->eraseFromParent();
     430           4 :     return true;
     431             :   }
     432             : 
     433          47 :   auto LHSReg = MIB->getOperand(2).getReg();
     434          47 :   auto RHSReg = MIB->getOperand(3).getReg();
     435          47 :   if (!validOpRegPair(MRI, LHSReg, RHSReg, Helper.OperandSize,
     436          47 :                       Helper.OperandRegBankID))
     437             :     return false;
     438             : 
     439          47 :   auto ARMConds = getComparePreds(Cond);
     440          47 :   auto ZeroReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
     441          47 :   putConstant(I, ZeroReg, 0);
     442             : 
     443          47 :   if (ARMConds.second == ARMCC::AL) {
     444             :     // Simple case, we only need one comparison and we're done.
     445          42 :     if (!insertComparison(Helper, I, ResReg, ARMConds.first, LHSReg, RHSReg,
     446             :                           ZeroReg))
     447             :       return false;
     448             :   } else {
     449             :     // Not so simple, we need two successive comparisons.
     450           5 :     auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
     451           5 :     if (!insertComparison(Helper, I, IntermediateRes, ARMConds.first, LHSReg,
     452             :                           RHSReg, ZeroReg))
     453             :       return false;
     454           5 :     if (!insertComparison(Helper, I, ResReg, ARMConds.second, LHSReg, RHSReg,
     455             :                           IntermediateRes))
     456             :       return false;
     457             :   }
     458             : 
     459          47 :   MIB->eraseFromParent();
     460          47 :   return true;
     461             : }
     462             : 
     463           0 : bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I,
     464             :                                               unsigned ResReg,
     465             :                                               ARMCC::CondCodes Cond,
     466             :                                               unsigned LHSReg, unsigned RHSReg,
     467             :                                               unsigned PrevRes) const {
     468             :   // Perform the comparison.
     469             :   auto CmpI =
     470           0 :       BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Helper.ComparisonOpcode))
     471             :           .addUse(LHSReg)
     472             :           .addUse(RHSReg)
     473           0 :           .add(predOps(ARMCC::AL));
     474           0 :   if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
     475           0 :     return false;
     476             : 
     477             :   // Read the comparison flags (if necessary).
     478           0 :   if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
     479             :     auto ReadI = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
     480           0 :                          TII.get(Helper.ReadFlagsOpcode))
     481           0 :                      .add(predOps(ARMCC::AL));
     482           0 :     if (!constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
     483           0 :       return false;
     484             :   }
     485             : 
     486             :   // Select either 1 or the previous result based on the value of the flags.
     487           0 :   auto Mov1I = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(ARM::MOVCCi))
     488             :                    .addDef(ResReg)
     489             :                    .addUse(PrevRes)
     490             :                    .addImm(1)
     491           0 :                    .add(predOps(Cond, ARM::CPSR));
     492           0 :   if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
     493           0 :     return false;
     494             : 
     495             :   return true;
     496             : }
     497             : 
     498         101 : bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
     499             :                                           MachineRegisterInfo &MRI) const {
     500         101 :   if ((STI.isROPI() || STI.isRWPI()) && !STI.isTargetELF()) {
     501             :     LLVM_DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n");
     502             :     return false;
     503             :   }
     504             : 
     505         101 :   auto GV = MIB->getOperand(1).getGlobal();
     506         101 :   if (GV->isThreadLocal()) {
     507             :     LLVM_DEBUG(dbgs() << "TLS variables not supported yet\n");
     508             :     return false;
     509             :   }
     510             : 
     511          96 :   auto &MBB = *MIB->getParent();
     512          96 :   auto &MF = *MBB.getParent();
     513             : 
     514          96 :   bool UseMovt = STI.useMovt(MF);
     515             : 
     516          96 :   unsigned Size = TM.getPointerSize(0);
     517             :   unsigned Alignment = 4;
     518             : 
     519             :   auto addOpsForConstantPoolLoad = [&MF, Alignment,
     520             :                                     Size](MachineInstrBuilder &MIB,
     521             :                                           const GlobalValue *GV, bool IsSBREL) {
     522             :     assert(MIB->getOpcode() == ARM::LDRi12 && "Unsupported instruction");
     523             :     auto ConstPool = MF.getConstantPool();
     524             :     auto CPIndex =
     525             :         // For SB relative entries we need a target-specific constant pool.
     526             :         // Otherwise, just use a regular constant pool entry.
     527             :         IsSBREL
     528             :             ? ConstPool->getConstantPoolIndex(
     529             :                   ARMConstantPoolConstant::Create(GV, ARMCP::SBREL), Alignment)
     530             :             : ConstPool->getConstantPoolIndex(GV, Alignment);
     531             :     MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
     532             :         .addMemOperand(
     533             :             MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
     534             :                                     MachineMemOperand::MOLoad, Size, Alignment))
     535             :         .addImm(0)
     536             :         .add(predOps(ARMCC::AL));
     537          96 :   };
     538             : 
     539          96 :   if (TM.isPositionIndependent()) {
     540          32 :     bool Indirect = STI.isGVIndirectSymbol(GV);
     541             :     // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't
     542             :     // support it yet. See PR28229.
     543             :     unsigned Opc =
     544          32 :         UseMovt && !STI.isTargetELF()
     545          48 :             ? (Indirect ? ARM::MOV_ga_pcrel_ldr : ARM::MOV_ga_pcrel)
     546             :             : (Indirect ? ARM::LDRLIT_ga_pcrel_ldr : ARM::LDRLIT_ga_pcrel);
     547          32 :     MIB->setDesc(TII.get(Opc));
     548             : 
     549             :     int TargetFlags = ARMII::MO_NO_FLAG;
     550          32 :     if (STI.isTargetDarwin())
     551             :       TargetFlags |= ARMII::MO_NONLAZY;
     552          32 :     if (STI.isGVInGOT(GV))
     553           8 :       TargetFlags |= ARMII::MO_GOT;
     554          32 :     MIB->getOperand(1).setTargetFlags(TargetFlags);
     555             : 
     556          32 :     if (Indirect)
     557             :       MIB.addMemOperand(MF.getMachineMemOperand(
     558             :           MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad,
     559          32 :           TM.getProgramPointerSize(), Alignment));
     560             : 
     561          32 :     return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
     562             :   }
     563             : 
     564          64 :   bool isReadOnly = STI.getTargetLowering()->isReadOnly(GV);
     565          64 :   if (STI.isROPI() && isReadOnly) {
     566          16 :     unsigned Opc = UseMovt ? ARM::MOV_ga_pcrel : ARM::LDRLIT_ga_pcrel;
     567          16 :     MIB->setDesc(TII.get(Opc));
     568          16 :     return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
     569             :   }
     570          48 :   if (STI.isRWPI() && !isReadOnly) {
     571          16 :     auto Offset = MRI.createVirtualRegister(&ARM::GPRRegClass);
     572          16 :     MachineInstrBuilder OffsetMIB;
     573          16 :     if (UseMovt) {
     574             :       OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
     575          24 :                           TII.get(ARM::MOVi32imm), Offset);
     576             :       OffsetMIB.addGlobalAddress(GV, /*Offset*/ 0, ARMII::MO_SBREL);
     577             :     } else {
     578             :       // Load the offset from the constant pool.
     579             :       OffsetMIB =
     580          24 :           BuildMI(MBB, *MIB, MIB->getDebugLoc(), TII.get(ARM::LDRi12), Offset);
     581           8 :       addOpsForConstantPoolLoad(OffsetMIB, GV, /*IsSBREL*/ true);
     582             :     }
     583          16 :     if (!constrainSelectedInstRegOperands(*OffsetMIB, TII, TRI, RBI))
     584             :       return false;
     585             : 
     586             :     // Add the offset to the SB register.
     587          16 :     MIB->setDesc(TII.get(ARM::ADDrr));
     588          16 :     MIB->RemoveOperand(1);
     589          16 :     MIB.addReg(ARM::R9) // FIXME: don't hardcode R9
     590          16 :         .addReg(Offset)
     591          16 :         .add(predOps(ARMCC::AL))
     592          16 :         .add(condCodeOp());
     593             : 
     594          16 :     return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
     595             :   }
     596             : 
     597          64 :   if (STI.isTargetELF()) {
     598          24 :     if (UseMovt) {
     599          12 :       MIB->setDesc(TII.get(ARM::MOVi32imm));
     600             :     } else {
     601             :       // Load the global's address from the constant pool.
     602          12 :       MIB->setDesc(TII.get(ARM::LDRi12));
     603          12 :       MIB->RemoveOperand(1);
     604          12 :       addOpsForConstantPoolLoad(MIB, GV, /*IsSBREL*/ false);
     605             :     }
     606           8 :   } else if (STI.isTargetMachO()) {
     607           8 :     if (UseMovt)
     608           4 :       MIB->setDesc(TII.get(ARM::MOVi32imm));
     609             :     else
     610           4 :       MIB->setDesc(TII.get(ARM::LDRLIT_ga_abs));
     611             :   } else {
     612             :     LLVM_DEBUG(dbgs() << "Object format not supported yet\n");
     613             :     return false;
     614             :   }
     615             : 
     616          32 :   return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
     617             : }
     618             : 
     619           0 : bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
     620             :                                           MachineRegisterInfo &MRI) const {
     621           0 :   auto &MBB = *MIB->getParent();
     622           0 :   auto InsertBefore = std::next(MIB->getIterator());
     623             :   auto &DbgLoc = MIB->getDebugLoc();
     624             : 
     625             :   // Compare the condition to 0.
     626           0 :   auto CondReg = MIB->getOperand(1).getReg();
     627             :   assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) &&
     628             :          "Unsupported types for select operation");
     629           0 :   auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri))
     630             :                   .addUse(CondReg)
     631             :                   .addImm(0)
     632           0 :                   .add(predOps(ARMCC::AL));
     633           0 :   if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
     634           0 :     return false;
     635             : 
     636             :   // Move a value into the result register based on the result of the
     637             :   // comparison.
     638           0 :   auto ResReg = MIB->getOperand(0).getReg();
     639           0 :   auto TrueReg = MIB->getOperand(2).getReg();
     640           0 :   auto FalseReg = MIB->getOperand(3).getReg();
     641             :   assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
     642             :          validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
     643             :          "Unsupported types for select operation");
     644           0 :   auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr))
     645             :                    .addDef(ResReg)
     646             :                    .addUse(TrueReg)
     647             :                    .addUse(FalseReg)
     648           0 :                    .add(predOps(ARMCC::EQ, ARM::CPSR));
     649           0 :   if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
     650           0 :     return false;
     651             : 
     652           0 :   MIB->eraseFromParent();
     653           0 :   return true;
     654             : }
     655             : 
     656          81 : bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
     657             :                                          MachineInstrBuilder &MIB) const {
     658          81 :   MIB->setDesc(TII.get(ARM::MOVsr));
     659          81 :   MIB.addImm(ShiftOpc);
     660          81 :   MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
     661          81 :   return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
     662             : }
     663             : 
     664        2400 : bool ARMInstructionSelector::select(MachineInstr &I,
     665             :                                     CodeGenCoverage &CoverageInfo) const {
     666             :   assert(I.getParent() && "Instruction should be in a basic block!");
     667             :   assert(I.getParent()->getParent() && "Instruction should be in a function!");
     668             : 
     669        2400 :   auto &MBB = *I.getParent();
     670        2400 :   auto &MF = *MBB.getParent();
     671        2400 :   auto &MRI = MF.getRegInfo();
     672             : 
     673        4800 :   if (!isPreISelGenericOpcode(I.getOpcode())) {
     674        1694 :     if (I.isCopy())
     675        1182 :       return selectCopy(I, TII, MRI, TRI, RBI);
     676             : 
     677             :     return true;
     678             :   }
     679             : 
     680             :   using namespace TargetOpcode;
     681             : 
     682         706 :   if (selectImpl(I, CoverageInfo))
     683             :     return true;
     684             : 
     685             :   MachineInstrBuilder MIB{MF, I};
     686             :   bool isSExt = false;
     687             : 
     688         946 :   switch (I.getOpcode()) {
     689           2 :   case G_SEXT:
     690             :     isSExt = true;
     691             :     LLVM_FALLTHROUGH;
     692          52 :   case G_ZEXT: {
     693          52 :     LLT DstTy = MRI.getType(I.getOperand(0).getReg());
     694             :     // FIXME: Smaller destination sizes coming soon!
     695          52 :     if (DstTy.getSizeInBits() != 32) {
     696             :       LLVM_DEBUG(dbgs() << "Unsupported destination size for extension");
     697           0 :       return false;
     698             :     }
     699             : 
     700          52 :     LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
     701          52 :     unsigned SrcSize = SrcTy.getSizeInBits();
     702             :     switch (SrcSize) {
     703          50 :     case 1: {
     704             :       // ZExt boils down to & 0x1; for SExt we also subtract that from 0
     705          50 :       I.setDesc(TII.get(ARM::ANDri));
     706          50 :       MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
     707             : 
     708          50 :       if (isSExt) {
     709           1 :         unsigned SExtResult = I.getOperand(0).getReg();
     710             : 
     711             :         // Use a new virtual register for the result of the AND
     712           1 :         unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
     713           1 :         I.getOperand(0).setReg(AndResult);
     714             : 
     715           1 :         auto InsertBefore = std::next(I.getIterator());
     716             :         auto SubI =
     717           2 :             BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
     718             :                 .addDef(SExtResult)
     719             :                 .addUse(AndResult)
     720             :                 .addImm(0)
     721           1 :                 .add(predOps(ARMCC::AL))
     722           1 :                 .add(condCodeOp());
     723           1 :         if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
     724           0 :           return false;
     725             :       }
     726             :       break;
     727             :     }
     728           2 :     case 8:
     729             :     case 16: {
     730             :       unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
     731           2 :       if (NewOpc == I.getOpcode())
     732             :         return false;
     733           2 :       I.setDesc(TII.get(NewOpc));
     734           2 :       MIB.addImm(0).add(predOps(ARMCC::AL));
     735           2 :       break;
     736             :     }
     737             :     default:
     738             :       LLVM_DEBUG(dbgs() << "Unsupported source size for extension");
     739             :       return false;
     740             :     }
     741          52 :     break;
     742             :   }
     743          25 :   case G_ANYEXT:
     744             :   case G_TRUNC: {
     745             :     // The high bits are undefined, so there's nothing special to do, just
     746             :     // treat it as a copy.
     747          25 :     auto SrcReg = I.getOperand(1).getReg();
     748          25 :     auto DstReg = I.getOperand(0).getReg();
     749             : 
     750          25 :     const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
     751          25 :     const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
     752             : 
     753          25 :     if (SrcRegBank.getID() == ARM::FPRRegBankID) {
     754             :       // This should only happen in the obscure case where we have put a 64-bit
     755             :       // integer into a D register. Get it out of there and keep only the
     756             :       // interesting part.
     757             :       assert(I.getOpcode() == G_TRUNC && "Unsupported operand for G_ANYEXT");
     758             :       assert(DstRegBank.getID() == ARM::GPRRegBankID &&
     759             :              "Unsupported combination of register banks");
     760             :       assert(MRI.getType(SrcReg).getSizeInBits() == 64 && "Unsupported size");
     761             :       assert(MRI.getType(DstReg).getSizeInBits() <= 32 && "Unsupported size");
     762             : 
     763           1 :       unsigned IgnoredBits = MRI.createVirtualRegister(&ARM::GPRRegClass);
     764           1 :       auto InsertBefore = std::next(I.getIterator());
     765             :       auto MovI =
     766           2 :           BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::VMOVRRD))
     767             :               .addDef(DstReg)
     768             :               .addDef(IgnoredBits)
     769             :               .addUse(SrcReg)
     770           1 :               .add(predOps(ARMCC::AL));
     771           1 :       if (!constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI))
     772             :         return false;
     773             : 
     774           1 :       MIB->eraseFromParent();
     775           1 :       return true;
     776             :     }
     777             : 
     778          24 :     if (SrcRegBank.getID() != DstRegBank.getID()) {
     779             :       LLVM_DEBUG(
     780             :           dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
     781             :       return false;
     782             :     }
     783             : 
     784          24 :     if (SrcRegBank.getID() != ARM::GPRRegBankID) {
     785             :       LLVM_DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
     786             :       return false;
     787             :     }
     788             : 
     789          24 :     I.setDesc(TII.get(COPY));
     790          24 :     return selectCopy(I, TII, MRI, TRI, RBI);
     791             :   }
     792           2 :   case G_CONSTANT: {
     793           2 :     if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) {
     794             :       // Non-pointer constants should be handled by TableGen.
     795             :       LLVM_DEBUG(dbgs() << "Unsupported constant type\n");
     796           0 :       return false;
     797             :     }
     798             : 
     799             :     auto &Val = I.getOperand(1);
     800           2 :     if (Val.isCImm()) {
     801           4 :       if (!Val.getCImm()->isZero()) {
     802             :         LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
     803             :         return false;
     804             :       }
     805           2 :       Val.ChangeToImmediate(0);
     806             :     } else {
     807             :       assert(Val.isImm() && "Unexpected operand for G_CONSTANT");
     808           0 :       if (Val.getImm() != 0) {
     809             :         LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
     810             :         return false;
     811             :       }
     812             :     }
     813             : 
     814           2 :     I.setDesc(TII.get(ARM::MOVi));
     815           2 :     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
     816           2 :     break;
     817             :   }
     818           2 :   case G_INTTOPTR:
     819             :   case G_PTRTOINT: {
     820           2 :     auto SrcReg = I.getOperand(1).getReg();
     821           2 :     auto DstReg = I.getOperand(0).getReg();
     822             : 
     823           2 :     const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
     824           2 :     const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
     825             : 
     826           2 :     if (SrcRegBank.getID() != DstRegBank.getID()) {
     827             :       LLVM_DEBUG(
     828             :           dbgs()
     829             :           << "G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
     830             :       return false;
     831             :     }
     832             : 
     833           2 :     if (SrcRegBank.getID() != ARM::GPRRegBankID) {
     834             :       LLVM_DEBUG(
     835             :           dbgs() << "G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
     836             :       return false;
     837             :     }
     838             : 
     839           2 :     I.setDesc(TII.get(COPY));
     840           2 :     return selectCopy(I, TII, MRI, TRI, RBI);
     841             :   }
     842           4 :   case G_SELECT:
     843           4 :     return selectSelect(MIB, MRI);
     844             :   case G_ICMP: {
     845             :     CmpConstants Helper(ARM::CMPrr, ARM::INSTRUCTION_LIST_END,
     846             :                         ARM::GPRRegBankID, 32);
     847          17 :     return selectCmp(Helper, MIB, MRI);
     848             :   }
     849          34 :   case G_FCMP: {
     850             :     assert(STI.hasVFP2() && "Can't select fcmp without VFP");
     851             : 
     852          34 :     unsigned OpReg = I.getOperand(2).getReg();
     853          34 :     unsigned Size = MRI.getType(OpReg).getSizeInBits();
     854             : 
     855          34 :     if (Size == 64 && STI.isFPOnlySP()) {
     856             :       LLVM_DEBUG(dbgs() << "Subtarget only supports single precision");
     857             :       return false;
     858             :     }
     859          34 :     if (Size != 32 && Size != 64) {
     860             :       LLVM_DEBUG(dbgs() << "Unsupported size for G_FCMP operand");
     861             :       return false;
     862             :     }
     863             : 
     864             :     CmpConstants Helper(Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
     865          34 :                         ARM::FPRRegBankID, Size);
     866          34 :     return selectCmp(Helper, MIB, MRI);
     867             :   }
     868           3 :   case G_LSHR:
     869           3 :     return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
     870          39 :   case G_ASHR:
     871          39 :     return selectShift(ARM_AM::ShiftOpc::asr, MIB);
     872          39 :   case G_SHL: {
     873          39 :     return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
     874             :   }
     875           1 :   case G_GEP:
     876           1 :     I.setDesc(TII.get(ARM::ADDrr));
     877           1 :     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
     878           1 :     break;
     879           8 :   case G_FRAME_INDEX:
     880             :     // Add 0 to the given frame index and hope it will eventually be folded into
     881             :     // the user(s).
     882           8 :     I.setDesc(TII.get(ARM::ADDri));
     883           8 :     MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
     884           8 :     break;
     885         101 :   case G_GLOBAL_VALUE:
     886         101 :     return selectGlobal(MIB, MRI);
     887             :   case G_STORE:
     888             :   case G_LOAD: {
     889         123 :     const auto &MemOp = **I.memoperands_begin();
     890         123 :     if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
     891             :       LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
     892           0 :       return false;
     893             :     }
     894             : 
     895         123 :     unsigned Reg = I.getOperand(0).getReg();
     896         123 :     unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
     897             : 
     898         123 :     LLT ValTy = MRI.getType(Reg);
     899         123 :     const auto ValSize = ValTy.getSizeInBits();
     900             : 
     901             :     assert((ValSize != 64 || STI.hasVFP2()) &&
     902             :            "Don't know how to load/store 64-bit value without VFP");
     903             : 
     904         123 :     const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
     905         123 :     if (NewOpc == G_LOAD || NewOpc == G_STORE)
     906             :       return false;
     907             : 
     908         123 :     I.setDesc(TII.get(NewOpc));
     909             : 
     910         123 :     if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
     911             :       // LDRH has a funny addressing mode (there's already a FIXME for it).
     912           3 :       MIB.addReg(0);
     913         123 :     MIB.addImm(0).add(predOps(ARMCC::AL));
     914         123 :     break;
     915             :   }
     916          11 :   case G_MERGE_VALUES: {
     917          11 :     if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
     918             :       return false;
     919             :     break;
     920             :   }
     921           6 :   case G_UNMERGE_VALUES: {
     922           6 :     if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
     923             :       return false;
     924             :     break;
     925             :   }
     926           4 :   case G_BRCOND: {
     927           4 :     if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
     928             :       LLVM_DEBUG(dbgs() << "Unsupported condition register for G_BRCOND");
     929             :       return false;
     930             :     }
     931             : 
     932             :     // Set the flags.
     933           8 :     auto Test = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::TSTri))
     934           4 :                     .addReg(I.getOperand(0).getReg())
     935             :                     .addImm(1)
     936           4 :                     .add(predOps(ARMCC::AL));
     937           4 :     if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI))
     938             :       return false;
     939             : 
     940             :     // Branch conditionally.
     941           8 :     auto Branch = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::Bcc))
     942           4 :                       .add(I.getOperand(1))
     943           4 :                       .add(predOps(ARMCC::NE, ARM::CPSR));
     944           4 :     if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
     945             :       return false;
     946           4 :     I.eraseFromParent();
     947           4 :     return true;
     948             :   }
     949           2 :   case G_PHI: {
     950           2 :     I.setDesc(TII.get(PHI));
     951             : 
     952           2 :     unsigned DstReg = I.getOperand(0).getReg();
     953           2 :     const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
     954           2 :     if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
     955             :       break;
     956             :     }
     957             : 
     958             :     return true;
     959             :   }
     960             :   default:
     961             :     return false;
     962             :   }
     963             : 
     964         203 :   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
     965             : }

Generated by: LCOV version 1.13