LLVM  9.0.0svn
ARMInstructionSelector.cpp
Go to the documentation of this file.
1 //===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the InstructionSelector class for ARM.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #include "ARMRegisterBankInfo.h"
14 #include "ARMSubtarget.h"
15 #include "ARMTargetMachine.h"
20 #include "llvm/Support/Debug.h"
21 
22 #define DEBUG_TYPE "arm-isel"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 #define GET_GLOBALISEL_PREDICATE_BITSET
29 #include "ARMGenGlobalISel.inc"
30 #undef GET_GLOBALISEL_PREDICATE_BITSET
31 
32 class ARMInstructionSelector : public InstructionSelector {
33 public:
34  ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
35  const ARMRegisterBankInfo &RBI);
36 
37  bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
38  static const char *getName() { return DEBUG_TYPE; }
39 
40 private:
41  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
42 
43  struct CmpConstants;
44  struct InsertInfo;
45 
46  bool selectCmp(CmpConstants Helper, MachineInstrBuilder &MIB,
47  MachineRegisterInfo &MRI) const;
48 
49  // Helper for inserting a comparison sequence that sets \p ResReg to either 1
50  // if \p LHSReg and \p RHSReg are in the relationship defined by \p Cond, or
51  // \p PrevRes otherwise. In essence, it computes PrevRes OR (LHS Cond RHS).
52  bool insertComparison(CmpConstants Helper, InsertInfo I, unsigned ResReg,
53  ARMCC::CondCodes Cond, unsigned LHSReg, unsigned RHSReg,
54  unsigned PrevRes) const;
55 
56  // Set \p DestReg to \p Constant.
57  void putConstant(InsertInfo I, unsigned DestReg, unsigned Constant) const;
58 
59  bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
60  bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
61  bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const;
62 
63  // Check if the types match and both operands have the expected size and
64  // register bank.
65  bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
66  unsigned ExpectedSize, unsigned ExpectedRegBankID) const;
67 
68  // Check if the register has the expected size and register bank.
69  bool validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize,
70  unsigned ExpectedRegBankID) const;
71 
72  const ARMBaseInstrInfo &TII;
73  const ARMBaseRegisterInfo &TRI;
74  const ARMBaseTargetMachine &TM;
75  const ARMRegisterBankInfo &RBI;
76  const ARMSubtarget &STI;
77 
78  // FIXME: This is necessary because DAGISel uses "Subtarget->" and GlobalISel
79  // uses "STI." in the code generated by TableGen. If we want to reuse some of
80  // the custom C++ predicates written for DAGISel, we need to have both around.
81  const ARMSubtarget *Subtarget = &STI;
82 
83  // Store the opcodes that we might need, so we don't have to check what kind
84  // of subtarget (ARM vs Thumb) we have all the time.
85  struct OpcodeCache {
86  unsigned ZEXT16;
87  unsigned SEXT16;
88 
89  unsigned ZEXT8;
90  unsigned SEXT8;
91 
92  // Used for implementing ZEXT/SEXT from i1
93  unsigned AND;
94  unsigned RSB;
95 
96  unsigned STORE32;
97  unsigned LOAD32;
98 
99  unsigned STORE16;
100  unsigned LOAD16;
101 
102  unsigned STORE8;
103  unsigned LOAD8;
104 
105  unsigned ADDrr;
106  unsigned ADDri;
107 
108  // Used for G_ICMP
109  unsigned CMPrr;
110  unsigned MOVi;
111  unsigned MOVCCi;
112 
113  // Used for G_SELECT
114  unsigned MOVCCr;
115 
116  unsigned TSTri;
117  unsigned Bcc;
118 
119  // Used for G_GLOBAL_VALUE
120  unsigned MOVi32imm;
121  unsigned ConstPoolLoad;
122  unsigned MOV_ga_pcrel;
123  unsigned LDRLIT_ga_pcrel;
124  unsigned LDRLIT_ga_abs;
125 
126  OpcodeCache(const ARMSubtarget &STI);
127  } const Opcodes;
128 
129  // Select the opcode for simple extensions (that translate to a single SXT/UXT
130  // instruction). Extension operations more complicated than that should not
131  // invoke this. Returns the original opcode if it doesn't know how to select a
132  // better one.
133  unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) const;
134 
135  // Select the opcode for simple loads and stores. Returns the original opcode
136  // if it doesn't know how to select a better one.
137  unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
138  unsigned Size) const;
139 
140  void renderVFPF32Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
141  void renderVFPF64Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
142 
143 #define GET_GLOBALISEL_PREDICATES_DECL
144 #include "ARMGenGlobalISel.inc"
145 #undef GET_GLOBALISEL_PREDICATES_DECL
146 
147 // We declare the temporaries used by selectImpl() in the class to minimize the
148 // cost of constructing placeholder values.
149 #define GET_GLOBALISEL_TEMPORARIES_DECL
150 #include "ARMGenGlobalISel.inc"
151 #undef GET_GLOBALISEL_TEMPORARIES_DECL
152 };
153 } // end anonymous namespace
154 
155 namespace llvm {
158  const ARMSubtarget &STI,
159  const ARMRegisterBankInfo &RBI) {
160  return new ARMInstructionSelector(TM, STI, RBI);
161 }
162 }
163 
164 const unsigned zero_reg = 0;
165 
166 #define GET_GLOBALISEL_IMPL
167 #include "ARMGenGlobalISel.inc"
168 #undef GET_GLOBALISEL_IMPL
169 
170 ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
171  const ARMSubtarget &STI,
172  const ARMRegisterBankInfo &RBI)
173  : InstructionSelector(), TII(*STI.getInstrInfo()),
174  TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI), Opcodes(STI),
176 #include "ARMGenGlobalISel.inc"
179 #include "ARMGenGlobalISel.inc"
181 {
182 }
183 
184 static const TargetRegisterClass *guessRegClass(unsigned Reg,
186  const TargetRegisterInfo &TRI,
187  const RegisterBankInfo &RBI) {
188  const RegisterBank *RegBank = RBI.getRegBank(Reg, MRI, TRI);
189  assert(RegBank && "Can't get reg bank for virtual register");
190 
191  const unsigned Size = MRI.getType(Reg).getSizeInBits();
192  assert((RegBank->getID() == ARM::GPRRegBankID ||
193  RegBank->getID() == ARM::FPRRegBankID) &&
194  "Unsupported reg bank");
195 
196  if (RegBank->getID() == ARM::FPRRegBankID) {
197  if (Size == 32)
198  return &ARM::SPRRegClass;
199  else if (Size == 64)
200  return &ARM::DPRRegClass;
201  else if (Size == 128)
202  return &ARM::QPRRegClass;
203  else
204  llvm_unreachable("Unsupported destination size");
205  }
206 
207  return &ARM::GPRRegClass;
208 }
209 
211  MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
212  const RegisterBankInfo &RBI) {
213  unsigned DstReg = I.getOperand(0).getReg();
214  if (TargetRegisterInfo::isPhysicalRegister(DstReg))
215  return true;
216 
217  const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
218 
219  // No need to constrain SrcReg. It will get constrained when
220  // we hit another of its uses or its defs.
221  // Copies do not have constraints.
222  if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
223  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
224  << " operand\n");
225  return false;
226  }
227  return true;
228 }
229 
231  const ARMBaseInstrInfo &TII,
232  MachineRegisterInfo &MRI,
233  const TargetRegisterInfo &TRI,
234  const RegisterBankInfo &RBI) {
235  assert(TII.getSubtarget().hasVFP2Base() && "Can't select merge without VFP");
236 
237  // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
238  // into one DPR.
239  unsigned VReg0 = MIB->getOperand(0).getReg();
240  (void)VReg0;
241  assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
242  RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
243  "Unsupported operand for G_MERGE_VALUES");
244  unsigned VReg1 = MIB->getOperand(1).getReg();
245  (void)VReg1;
246  assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
247  RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
248  "Unsupported operand for G_MERGE_VALUES");
249  unsigned VReg2 = MIB->getOperand(2).getReg();
250  (void)VReg2;
251  assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
252  RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
253  "Unsupported operand for G_MERGE_VALUES");
254 
255  MIB->setDesc(TII.get(ARM::VMOVDRR));
256  MIB.add(predOps(ARMCC::AL));
257 
258  return true;
259 }
260 
262  const ARMBaseInstrInfo &TII,
263  MachineRegisterInfo &MRI,
264  const TargetRegisterInfo &TRI,
265  const RegisterBankInfo &RBI) {
266  assert(TII.getSubtarget().hasVFP2Base() &&
267  "Can't select unmerge without VFP");
268 
269  // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
270  // GPRs.
271  unsigned VReg0 = MIB->getOperand(0).getReg();
272  (void)VReg0;
273  assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
274  RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
275  "Unsupported operand for G_UNMERGE_VALUES");
276  unsigned VReg1 = MIB->getOperand(1).getReg();
277  (void)VReg1;
278  assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
279  RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
280  "Unsupported operand for G_UNMERGE_VALUES");
281  unsigned VReg2 = MIB->getOperand(2).getReg();
282  (void)VReg2;
283  assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
284  RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
285  "Unsupported operand for G_UNMERGE_VALUES");
286 
287  MIB->setDesc(TII.get(ARM::VMOVRRD));
288  MIB.add(predOps(ARMCC::AL));
289 
290  return true;
291 }
292 
293 ARMInstructionSelector::OpcodeCache::OpcodeCache(const ARMSubtarget &STI) {
294  bool isThumb = STI.isThumb();
295 
296  using namespace TargetOpcode;
297 
298 #define STORE_OPCODE(VAR, OPC) VAR = isThumb ? ARM::t2##OPC : ARM::OPC
299  STORE_OPCODE(SEXT16, SXTH);
300  STORE_OPCODE(ZEXT16, UXTH);
301 
302  STORE_OPCODE(SEXT8, SXTB);
303  STORE_OPCODE(ZEXT8, UXTB);
304 
305  STORE_OPCODE(AND, ANDri);
306  STORE_OPCODE(RSB, RSBri);
307 
308  STORE_OPCODE(STORE32, STRi12);
309  STORE_OPCODE(LOAD32, LDRi12);
310 
311  // LDRH/STRH are special...
312  STORE16 = isThumb ? ARM::t2STRHi12 : ARM::STRH;
313  LOAD16 = isThumb ? ARM::t2LDRHi12 : ARM::LDRH;
314 
315  STORE_OPCODE(STORE8, STRBi12);
316  STORE_OPCODE(LOAD8, LDRBi12);
317 
318  STORE_OPCODE(ADDrr, ADDrr);
319  STORE_OPCODE(ADDri, ADDri);
320 
321  STORE_OPCODE(CMPrr, CMPrr);
322  STORE_OPCODE(MOVi, MOVi);
323  STORE_OPCODE(MOVCCi, MOVCCi);
324 
325  STORE_OPCODE(MOVCCr, MOVCCr);
326 
327  STORE_OPCODE(TSTri, TSTri);
328  STORE_OPCODE(Bcc, Bcc);
329 
330  STORE_OPCODE(MOVi32imm, MOVi32imm);
331  ConstPoolLoad = isThumb ? ARM::t2LDRpci : ARM::LDRi12;
332  STORE_OPCODE(MOV_ga_pcrel, MOV_ga_pcrel);
333  LDRLIT_ga_pcrel = isThumb ? ARM::tLDRLIT_ga_pcrel : ARM::LDRLIT_ga_pcrel;
334  LDRLIT_ga_abs = isThumb ? ARM::tLDRLIT_ga_abs : ARM::LDRLIT_ga_abs;
335 #undef MAP_OPCODE
336 }
337 
338 unsigned ARMInstructionSelector::selectSimpleExtOpc(unsigned Opc,
339  unsigned Size) const {
340  using namespace TargetOpcode;
341 
342  if (Size != 8 && Size != 16)
343  return Opc;
344 
345  if (Opc == G_SEXT)
346  return Size == 8 ? Opcodes.SEXT8 : Opcodes.SEXT16;
347 
348  if (Opc == G_ZEXT)
349  return Size == 8 ? Opcodes.ZEXT8 : Opcodes.ZEXT16;
350 
351  return Opc;
352 }
353 
354 unsigned ARMInstructionSelector::selectLoadStoreOpCode(unsigned Opc,
355  unsigned RegBank,
356  unsigned Size) const {
357  bool isStore = Opc == TargetOpcode::G_STORE;
358 
359  if (RegBank == ARM::GPRRegBankID) {
360  switch (Size) {
361  case 1:
362  case 8:
363  return isStore ? Opcodes.STORE8 : Opcodes.LOAD8;
364  case 16:
365  return isStore ? Opcodes.STORE16 : Opcodes.LOAD16;
366  case 32:
367  return isStore ? Opcodes.STORE32 : Opcodes.LOAD32;
368  default:
369  return Opc;
370  }
371  }
372 
373  if (RegBank == ARM::FPRRegBankID) {
374  switch (Size) {
375  case 32:
376  return isStore ? ARM::VSTRS : ARM::VLDRS;
377  case 64:
378  return isStore ? ARM::VSTRD : ARM::VLDRD;
379  default:
380  return Opc;
381  }
382  }
383 
384  return Opc;
385 }
386 
387 // When lowering comparisons, we sometimes need to perform two compares instead
388 // of just one. Get the condition codes for both comparisons. If only one is
389 // needed, the second member of the pair is ARMCC::AL.
390 static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
392  std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
393  switch (Pred) {
394  case CmpInst::FCMP_ONE:
395  Preds = {ARMCC::GT, ARMCC::MI};
396  break;
397  case CmpInst::FCMP_UEQ:
398  Preds = {ARMCC::EQ, ARMCC::VS};
399  break;
400  case CmpInst::ICMP_EQ:
401  case CmpInst::FCMP_OEQ:
402  Preds.first = ARMCC::EQ;
403  break;
404  case CmpInst::ICMP_SGT:
405  case CmpInst::FCMP_OGT:
406  Preds.first = ARMCC::GT;
407  break;
408  case CmpInst::ICMP_SGE:
409  case CmpInst::FCMP_OGE:
410  Preds.first = ARMCC::GE;
411  break;
412  case CmpInst::ICMP_UGT:
413  case CmpInst::FCMP_UGT:
414  Preds.first = ARMCC::HI;
415  break;
416  case CmpInst::FCMP_OLT:
417  Preds.first = ARMCC::MI;
418  break;
419  case CmpInst::ICMP_ULE:
420  case CmpInst::FCMP_OLE:
421  Preds.first = ARMCC::LS;
422  break;
423  case CmpInst::FCMP_ORD:
424  Preds.first = ARMCC::VC;
425  break;
426  case CmpInst::FCMP_UNO:
427  Preds.first = ARMCC::VS;
428  break;
429  case CmpInst::FCMP_UGE:
430  Preds.first = ARMCC::PL;
431  break;
432  case CmpInst::ICMP_SLT:
433  case CmpInst::FCMP_ULT:
434  Preds.first = ARMCC::LT;
435  break;
436  case CmpInst::ICMP_SLE:
437  case CmpInst::FCMP_ULE:
438  Preds.first = ARMCC::LE;
439  break;
440  case CmpInst::FCMP_UNE:
441  case CmpInst::ICMP_NE:
442  Preds.first = ARMCC::NE;
443  break;
444  case CmpInst::ICMP_UGE:
445  Preds.first = ARMCC::HS;
446  break;
447  case CmpInst::ICMP_ULT:
448  Preds.first = ARMCC::LO;
449  break;
450  default:
451  break;
452  }
453  assert(Preds.first != ARMCC::AL && "No comparisons needed?");
454  return Preds;
455 }
456 
458  CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned SelectOpcode,
459  unsigned OpRegBank, unsigned OpSize)
460  : ComparisonOpcode(CmpOpcode), ReadFlagsOpcode(FlagsOpcode),
461  SelectResultOpcode(SelectOpcode), OperandRegBankID(OpRegBank),
462  OperandSize(OpSize) {}
463 
464  // The opcode used for performing the comparison.
465  const unsigned ComparisonOpcode;
466 
467  // The opcode used for reading the flags set by the comparison. May be
468  // ARM::INSTRUCTION_LIST_END if we don't need to read the flags.
469  const unsigned ReadFlagsOpcode;
470 
471  // The opcode used for materializing the result of the comparison.
472  const unsigned SelectResultOpcode;
473 
474  // The assumed register bank ID for the operands.
475  const unsigned OperandRegBankID;
476 
477  // The assumed size in bits for the operands.
478  const unsigned OperandSize;
479 };
480 
483  : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())),
484  DbgLoc(MIB->getDebugLoc()) {}
485 
488  const DebugLoc &DbgLoc;
489 };
490 
491 void ARMInstructionSelector::putConstant(InsertInfo I, unsigned DestReg,
492  unsigned Constant) const {
493  (void)BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Opcodes.MOVi))
494  .addDef(DestReg)
495  .addImm(Constant)
497  .add(condCodeOp());
498 }
499 
500 bool ARMInstructionSelector::validOpRegPair(MachineRegisterInfo &MRI,
501  unsigned LHSReg, unsigned RHSReg,
502  unsigned ExpectedSize,
503  unsigned ExpectedRegBankID) const {
504  return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
505  validReg(MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
506  validReg(MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
507 }
508 
509 bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg,
510  unsigned ExpectedSize,
511  unsigned ExpectedRegBankID) const {
512  if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) {
513  LLVM_DEBUG(dbgs() << "Unexpected size for register");
514  return false;
515  }
516 
517  if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) {
518  LLVM_DEBUG(dbgs() << "Unexpected register bank for register");
519  return false;
520  }
521 
522  return true;
523 }
524 
525 bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
526  MachineInstrBuilder &MIB,
527  MachineRegisterInfo &MRI) const {
528  const InsertInfo I(MIB);
529 
530  auto ResReg = MIB->getOperand(0).getReg();
531  if (!validReg(MRI, ResReg, 1, ARM::GPRRegBankID))
532  return false;
533 
534  auto Cond =
535  static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
536  if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) {
537  putConstant(I, ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0);
538  MIB->eraseFromParent();
539  return true;
540  }
541 
542  auto LHSReg = MIB->getOperand(2).getReg();
543  auto RHSReg = MIB->getOperand(3).getReg();
544  if (!validOpRegPair(MRI, LHSReg, RHSReg, Helper.OperandSize,
545  Helper.OperandRegBankID))
546  return false;
547 
548  auto ARMConds = getComparePreds(Cond);
549  auto ZeroReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
550  putConstant(I, ZeroReg, 0);
551 
552  if (ARMConds.second == ARMCC::AL) {
553  // Simple case, we only need one comparison and we're done.
554  if (!insertComparison(Helper, I, ResReg, ARMConds.first, LHSReg, RHSReg,
555  ZeroReg))
556  return false;
557  } else {
558  // Not so simple, we need two successive comparisons.
559  auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
560  if (!insertComparison(Helper, I, IntermediateRes, ARMConds.first, LHSReg,
561  RHSReg, ZeroReg))
562  return false;
563  if (!insertComparison(Helper, I, ResReg, ARMConds.second, LHSReg, RHSReg,
564  IntermediateRes))
565  return false;
566  }
567 
568  MIB->eraseFromParent();
569  return true;
570 }
571 
572 bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I,
573  unsigned ResReg,
574  ARMCC::CondCodes Cond,
575  unsigned LHSReg, unsigned RHSReg,
576  unsigned PrevRes) const {
577  // Perform the comparison.
578  auto CmpI =
579  BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Helper.ComparisonOpcode))
580  .addUse(LHSReg)
581  .addUse(RHSReg)
582  .add(predOps(ARMCC::AL));
583  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
584  return false;
585 
586  // Read the comparison flags (if necessary).
587  if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
588  auto ReadI = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
589  TII.get(Helper.ReadFlagsOpcode))
590  .add(predOps(ARMCC::AL));
591  if (!constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
592  return false;
593  }
594 
595  // Select either 1 or the previous result based on the value of the flags.
596  auto Mov1I = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
597  TII.get(Helper.SelectResultOpcode))
598  .addDef(ResReg)
599  .addUse(PrevRes)
600  .addImm(1)
601  .add(predOps(Cond, ARM::CPSR));
602  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
603  return false;
604 
605  return true;
606 }
607 
608 bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
609  MachineRegisterInfo &MRI) const {
610  if ((STI.isROPI() || STI.isRWPI()) && !STI.isTargetELF()) {
611  LLVM_DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n");
612  return false;
613  }
614 
615  auto GV = MIB->getOperand(1).getGlobal();
616  if (GV->isThreadLocal()) {
617  LLVM_DEBUG(dbgs() << "TLS variables not supported yet\n");
618  return false;
619  }
620 
621  auto &MBB = *MIB->getParent();
622  auto &MF = *MBB.getParent();
623 
624  bool UseMovt = STI.useMovt();
625 
626  unsigned Size = TM.getPointerSize(0);
627  unsigned Alignment = 4;
628 
629  auto addOpsForConstantPoolLoad = [&MF, Alignment,
631  const GlobalValue *GV, bool IsSBREL) {
632  assert((MIB->getOpcode() == ARM::LDRi12 ||
633  MIB->getOpcode() == ARM::t2LDRpci) &&
634  "Unsupported instruction");
635  auto ConstPool = MF.getConstantPool();
636  auto CPIndex =
637  // For SB relative entries we need a target-specific constant pool.
638  // Otherwise, just use a regular constant pool entry.
639  IsSBREL
640  ? ConstPool->getConstantPoolIndex(
641  ARMConstantPoolConstant::Create(GV, ARMCP::SBREL), Alignment)
642  : ConstPool->getConstantPoolIndex(GV, Alignment);
643  MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
644  .addMemOperand(MF.getMachineMemOperand(
645  MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
646  Size, Alignment));
647  if (MIB->getOpcode() == ARM::LDRi12)
648  MIB.addImm(0);
649  MIB.add(predOps(ARMCC::AL));
650  };
651 
652  auto addGOTMemOperand = [this, &MF, Alignment](MachineInstrBuilder &MIB) {
653  MIB.addMemOperand(MF.getMachineMemOperand(
654  MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad,
655  TM.getProgramPointerSize(), Alignment));
656  };
657 
658  if (TM.isPositionIndependent()) {
659  bool Indirect = STI.isGVIndirectSymbol(GV);
660 
661  // For ARM mode, we have different pseudoinstructions for direct accesses
662  // and indirect accesses, and the ones for indirect accesses include the
663  // load from GOT. For Thumb mode, we use the same pseudoinstruction for both
664  // direct and indirect accesses, and we need to manually generate the load
665  // from GOT.
666  bool UseOpcodeThatLoads = Indirect && !STI.isThumb();
667 
668  // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't
669  // support it yet. See PR28229.
670  unsigned Opc =
671  UseMovt && !STI.isTargetELF()
672  ? (UseOpcodeThatLoads ? (unsigned)ARM::MOV_ga_pcrel_ldr
673  : Opcodes.MOV_ga_pcrel)
674  : (UseOpcodeThatLoads ? (unsigned)ARM::LDRLIT_ga_pcrel_ldr
675  : Opcodes.LDRLIT_ga_pcrel);
676  MIB->setDesc(TII.get(Opc));
677 
678  int TargetFlags = ARMII::MO_NO_FLAG;
679  if (STI.isTargetDarwin())
680  TargetFlags |= ARMII::MO_NONLAZY;
681  if (STI.isGVInGOT(GV))
682  TargetFlags |= ARMII::MO_GOT;
683  MIB->getOperand(1).setTargetFlags(TargetFlags);
684 
685  if (Indirect) {
686  if (!UseOpcodeThatLoads) {
687  auto ResultReg = MIB->getOperand(0).getReg();
688  auto AddressReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
689 
690  MIB->getOperand(0).setReg(AddressReg);
691 
692  auto InsertBefore = std::next(MIB->getIterator());
693  auto MIBLoad = BuildMI(MBB, InsertBefore, MIB->getDebugLoc(),
694  TII.get(Opcodes.LOAD32))
695  .addDef(ResultReg)
696  .addReg(AddressReg)
697  .addImm(0)
698  .add(predOps(ARMCC::AL));
699  addGOTMemOperand(MIBLoad);
700 
701  if (!constrainSelectedInstRegOperands(*MIBLoad, TII, TRI, RBI))
702  return false;
703  } else {
704  addGOTMemOperand(MIB);
705  }
706  }
707 
708  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
709  }
710 
711  bool isReadOnly = STI.getTargetLowering()->isReadOnly(GV);
712  if (STI.isROPI() && isReadOnly) {
713  unsigned Opc = UseMovt ? Opcodes.MOV_ga_pcrel : Opcodes.LDRLIT_ga_pcrel;
714  MIB->setDesc(TII.get(Opc));
715  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
716  }
717  if (STI.isRWPI() && !isReadOnly) {
718  auto Offset = MRI.createVirtualRegister(&ARM::GPRRegClass);
719  MachineInstrBuilder OffsetMIB;
720  if (UseMovt) {
721  OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
722  TII.get(Opcodes.MOVi32imm), Offset);
723  OffsetMIB.addGlobalAddress(GV, /*Offset*/ 0, ARMII::MO_SBREL);
724  } else {
725  // Load the offset from the constant pool.
726  OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
727  TII.get(Opcodes.ConstPoolLoad), Offset);
728  addOpsForConstantPoolLoad(OffsetMIB, GV, /*IsSBREL*/ true);
729  }
730  if (!constrainSelectedInstRegOperands(*OffsetMIB, TII, TRI, RBI))
731  return false;
732 
733  // Add the offset to the SB register.
734  MIB->setDesc(TII.get(Opcodes.ADDrr));
735  MIB->RemoveOperand(1);
736  MIB.addReg(ARM::R9) // FIXME: don't hardcode R9
737  .addReg(Offset)
738  .add(predOps(ARMCC::AL))
739  .add(condCodeOp());
740 
741  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
742  }
743 
744  if (STI.isTargetELF()) {
745  if (UseMovt) {
746  MIB->setDesc(TII.get(Opcodes.MOVi32imm));
747  } else {
748  // Load the global's address from the constant pool.
749  MIB->setDesc(TII.get(Opcodes.ConstPoolLoad));
750  MIB->RemoveOperand(1);
751  addOpsForConstantPoolLoad(MIB, GV, /*IsSBREL*/ false);
752  }
753  } else if (STI.isTargetMachO()) {
754  if (UseMovt)
755  MIB->setDesc(TII.get(Opcodes.MOVi32imm));
756  else
757  MIB->setDesc(TII.get(Opcodes.LDRLIT_ga_abs));
758  } else {
759  LLVM_DEBUG(dbgs() << "Object format not supported yet\n");
760  return false;
761  }
762 
763  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
764 }
765 
766 bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
767  MachineRegisterInfo &MRI) const {
768  auto &MBB = *MIB->getParent();
769  auto InsertBefore = std::next(MIB->getIterator());
770  auto &DbgLoc = MIB->getDebugLoc();
771 
772  // Compare the condition to 1.
773  auto CondReg = MIB->getOperand(1).getReg();
774  assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) &&
775  "Unsupported types for select operation");
776  auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.TSTri))
777  .addUse(CondReg)
778  .addImm(1)
779  .add(predOps(ARMCC::AL));
780  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
781  return false;
782 
783  // Move a value into the result register based on the result of the
784  // comparison.
785  auto ResReg = MIB->getOperand(0).getReg();
786  auto TrueReg = MIB->getOperand(2).getReg();
787  auto FalseReg = MIB->getOperand(3).getReg();
788  assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
789  validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
790  "Unsupported types for select operation");
791  auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.MOVCCr))
792  .addDef(ResReg)
793  .addUse(TrueReg)
794  .addUse(FalseReg)
795  .add(predOps(ARMCC::EQ, ARM::CPSR));
796  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
797  return false;
798 
799  MIB->eraseFromParent();
800  return true;
801 }
802 
803 bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
804  MachineInstrBuilder &MIB) const {
805  assert(!STI.isThumb() && "Unsupported subtarget");
806  MIB->setDesc(TII.get(ARM::MOVsr));
807  MIB.addImm(ShiftOpc);
809  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
810 }
811 
812 void ARMInstructionSelector::renderVFPF32Imm(
813  MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
814  assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
815  "Expected G_FCONSTANT");
816 
817  APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
818  int FPImmEncoding = ARM_AM::getFP32Imm(FPImmValue);
819  assert(FPImmEncoding != -1 && "Invalid immediate value");
820 
821  NewInstBuilder.addImm(FPImmEncoding);
822 }
823 
824 void ARMInstructionSelector::renderVFPF64Imm(
825  MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
826  assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
827  "Expected G_FCONSTANT");
828 
829  APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
830  int FPImmEncoding = ARM_AM::getFP64Imm(FPImmValue);
831  assert(FPImmEncoding != -1 && "Invalid immediate value");
832 
833  NewInstBuilder.addImm(FPImmEncoding);
834 }
835 
836 bool ARMInstructionSelector::select(MachineInstr &I,
837  CodeGenCoverage &CoverageInfo) const {
838  assert(I.getParent() && "Instruction should be in a basic block!");
839  assert(I.getParent()->getParent() && "Instruction should be in a function!");
840 
841  auto &MBB = *I.getParent();
842  auto &MF = *MBB.getParent();
843  auto &MRI = MF.getRegInfo();
844 
845  if (!isPreISelGenericOpcode(I.getOpcode())) {
846  if (I.isCopy())
847  return selectCopy(I, TII, MRI, TRI, RBI);
848 
849  return true;
850  }
851 
852  using namespace TargetOpcode;
853 
854  if (selectImpl(I, CoverageInfo))
855  return true;
856 
857  MachineInstrBuilder MIB{MF, I};
858  bool isSExt = false;
859 
860  switch (I.getOpcode()) {
861  case G_SEXT:
862  isSExt = true;
864  case G_ZEXT: {
865  assert(MRI.getType(I.getOperand(0).getReg()).getSizeInBits() <= 32 &&
866  "Unsupported destination size for extension");
867 
868  LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
869  unsigned SrcSize = SrcTy.getSizeInBits();
870  switch (SrcSize) {
871  case 1: {
872  // ZExt boils down to & 0x1; for SExt we also subtract that from 0
873  I.setDesc(TII.get(Opcodes.AND));
875 
876  if (isSExt) {
877  unsigned SExtResult = I.getOperand(0).getReg();
878 
879  // Use a new virtual register for the result of the AND
880  unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
881  I.getOperand(0).setReg(AndResult);
882 
883  auto InsertBefore = std::next(I.getIterator());
884  auto SubI =
885  BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(Opcodes.RSB))
886  .addDef(SExtResult)
887  .addUse(AndResult)
888  .addImm(0)
890  .add(condCodeOp());
891  if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
892  return false;
893  }
894  break;
895  }
896  case 8:
897  case 16: {
898  unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
899  if (NewOpc == I.getOpcode())
900  return false;
901  I.setDesc(TII.get(NewOpc));
902  MIB.addImm(0).add(predOps(ARMCC::AL));
903  break;
904  }
905  default:
906  LLVM_DEBUG(dbgs() << "Unsupported source size for extension");
907  return false;
908  }
909  break;
910  }
911  case G_ANYEXT:
912  case G_TRUNC: {
913  // The high bits are undefined, so there's nothing special to do, just
914  // treat it as a copy.
915  auto SrcReg = I.getOperand(1).getReg();
916  auto DstReg = I.getOperand(0).getReg();
917 
918  const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
919  const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
920 
921  if (SrcRegBank.getID() == ARM::FPRRegBankID) {
922  // This should only happen in the obscure case where we have put a 64-bit
923  // integer into a D register. Get it out of there and keep only the
924  // interesting part.
925  assert(I.getOpcode() == G_TRUNC && "Unsupported operand for G_ANYEXT");
926  assert(DstRegBank.getID() == ARM::GPRRegBankID &&
927  "Unsupported combination of register banks");
928  assert(MRI.getType(SrcReg).getSizeInBits() == 64 && "Unsupported size");
929  assert(MRI.getType(DstReg).getSizeInBits() <= 32 && "Unsupported size");
930 
931  unsigned IgnoredBits = MRI.createVirtualRegister(&ARM::GPRRegClass);
932  auto InsertBefore = std::next(I.getIterator());
933  auto MovI =
934  BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::VMOVRRD))
935  .addDef(DstReg)
936  .addDef(IgnoredBits)
937  .addUse(SrcReg)
938  .add(predOps(ARMCC::AL));
939  if (!constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI))
940  return false;
941 
942  MIB->eraseFromParent();
943  return true;
944  }
945 
946  if (SrcRegBank.getID() != DstRegBank.getID()) {
947  LLVM_DEBUG(
948  dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
949  return false;
950  }
951 
952  if (SrcRegBank.getID() != ARM::GPRRegBankID) {
953  LLVM_DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
954  return false;
955  }
956 
957  I.setDesc(TII.get(COPY));
958  return selectCopy(I, TII, MRI, TRI, RBI);
959  }
960  case G_CONSTANT: {
961  if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) {
962  // Non-pointer constants should be handled by TableGen.
963  LLVM_DEBUG(dbgs() << "Unsupported constant type\n");
964  return false;
965  }
966 
967  auto &Val = I.getOperand(1);
968  if (Val.isCImm()) {
969  if (!Val.getCImm()->isZero()) {
970  LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
971  return false;
972  }
973  Val.ChangeToImmediate(0);
974  } else {
975  assert(Val.isImm() && "Unexpected operand for G_CONSTANT");
976  if (Val.getImm() != 0) {
977  LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
978  return false;
979  }
980  }
981 
982  assert(!STI.isThumb() && "Unsupported subtarget");
983  I.setDesc(TII.get(ARM::MOVi));
985  break;
986  }
987  case G_FCONSTANT: {
988  // Load from constant pool
989  unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits() / 8;
990  unsigned Alignment = Size;
991 
992  assert((Size == 4 || Size == 8) && "Unsupported FP constant type");
993  auto LoadOpcode = Size == 4 ? ARM::VLDRS : ARM::VLDRD;
994 
995  auto ConstPool = MF.getConstantPool();
996  auto CPIndex =
997  ConstPool->getConstantPoolIndex(I.getOperand(1).getFPImm(), Alignment);
998  MIB->setDesc(TII.get(LoadOpcode));
999  MIB->RemoveOperand(1);
1000  MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
1001  .addMemOperand(
1002  MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
1003  MachineMemOperand::MOLoad, Size, Alignment))
1004  .addImm(0)
1005  .add(predOps(ARMCC::AL));
1006  break;
1007  }
1008  case G_INTTOPTR:
1009  case G_PTRTOINT: {
1010  auto SrcReg = I.getOperand(1).getReg();
1011  auto DstReg = I.getOperand(0).getReg();
1012 
1013  const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
1014  const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1015 
1016  if (SrcRegBank.getID() != DstRegBank.getID()) {
1017  LLVM_DEBUG(
1018  dbgs()
1019  << "G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
1020  return false;
1021  }
1022 
1023  if (SrcRegBank.getID() != ARM::GPRRegBankID) {
1024  LLVM_DEBUG(
1025  dbgs() << "G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
1026  return false;
1027  }
1028 
1029  I.setDesc(TII.get(COPY));
1030  return selectCopy(I, TII, MRI, TRI, RBI);
1031  }
1032  case G_SELECT:
1033  return selectSelect(MIB, MRI);
1034  case G_ICMP: {
1035  CmpConstants Helper(Opcodes.CMPrr, ARM::INSTRUCTION_LIST_END,
1036  Opcodes.MOVCCi, ARM::GPRRegBankID, 32);
1037  return selectCmp(Helper, MIB, MRI);
1038  }
1039  case G_FCMP: {
1040  assert(STI.hasVFP2Base() && "Can't select fcmp without VFP");
1041 
1042  unsigned OpReg = I.getOperand(2).getReg();
1043  unsigned Size = MRI.getType(OpReg).getSizeInBits();
1044 
1045  if (Size == 64 && !STI.hasFP64()) {
1046  LLVM_DEBUG(dbgs() << "Subtarget only supports single precision");
1047  return false;
1048  }
1049  if (Size != 32 && Size != 64) {
1050  LLVM_DEBUG(dbgs() << "Unsupported size for G_FCMP operand");
1051  return false;
1052  }
1053 
1054  CmpConstants Helper(Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
1055  Opcodes.MOVCCi, ARM::FPRRegBankID, Size);
1056  return selectCmp(Helper, MIB, MRI);
1057  }
1058  case G_LSHR:
1059  return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
1060  case G_ASHR:
1061  return selectShift(ARM_AM::ShiftOpc::asr, MIB);
1062  case G_SHL: {
1063  return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
1064  }
1065  case G_GEP:
1066  I.setDesc(TII.get(Opcodes.ADDrr));
1067  MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
1068  break;
1069  case G_FRAME_INDEX:
1070  // Add 0 to the given frame index and hope it will eventually be folded into
1071  // the user(s).
1072  I.setDesc(TII.get(Opcodes.ADDri));
1073  MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
1074  break;
1075  case G_GLOBAL_VALUE:
1076  return selectGlobal(MIB, MRI);
1077  case G_STORE:
1078  case G_LOAD: {
1079  const auto &MemOp = **I.memoperands_begin();
1080  if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
1081  LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
1082  return false;
1083  }
1084 
1085  unsigned Reg = I.getOperand(0).getReg();
1086  unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
1087 
1088  LLT ValTy = MRI.getType(Reg);
1089  const auto ValSize = ValTy.getSizeInBits();
1090 
1091  assert((ValSize != 64 || STI.hasVFP2Base()) &&
1092  "Don't know how to load/store 64-bit value without VFP");
1093 
1094  const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
1095  if (NewOpc == G_LOAD || NewOpc == G_STORE)
1096  return false;
1097 
1098  if (ValSize == 1 && NewOpc == Opcodes.STORE8) {
1099  // Before storing a 1-bit value, make sure to clear out any unneeded bits.
1100  unsigned OriginalValue = I.getOperand(0).getReg();
1101 
1102  unsigned ValueToStore = MRI.createVirtualRegister(&ARM::GPRRegClass);
1103  I.getOperand(0).setReg(ValueToStore);
1104 
1105  auto InsertBefore = I.getIterator();
1106  auto AndI = BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(Opcodes.AND))
1107  .addDef(ValueToStore)
1108  .addUse(OriginalValue)
1109  .addImm(1)
1110  .add(predOps(ARMCC::AL))
1111  .add(condCodeOp());
1112  if (!constrainSelectedInstRegOperands(*AndI, TII, TRI, RBI))
1113  return false;
1114  }
1115 
1116  I.setDesc(TII.get(NewOpc));
1117 
1118  if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
1119  // LDRH has a funny addressing mode (there's already a FIXME for it).
1120  MIB.addReg(0);
1121  MIB.addImm(0).add(predOps(ARMCC::AL));
1122  break;
1123  }
1124  case G_MERGE_VALUES: {
1125  if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
1126  return false;
1127  break;
1128  }
1129  case G_UNMERGE_VALUES: {
1130  if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
1131  return false;
1132  break;
1133  }
1134  case G_BRCOND: {
1135  if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
1136  LLVM_DEBUG(dbgs() << "Unsupported condition register for G_BRCOND");
1137  return false;
1138  }
1139 
1140  // Set the flags.
1141  auto Test =
1142  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcodes.TSTri))
1143  .addReg(I.getOperand(0).getReg())
1144  .addImm(1)
1145  .add(predOps(ARMCC::AL));
1146  if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI))
1147  return false;
1148 
1149  // Branch conditionally.
1150  auto Branch =
1151  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcodes.Bcc))
1152  .add(I.getOperand(1))
1153  .add(predOps(ARMCC::NE, ARM::CPSR));
1154  if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
1155  return false;
1156  I.eraseFromParent();
1157  return true;
1158  }
1159  case G_PHI: {
1160  I.setDesc(TII.get(PHI));
1161 
1162  unsigned DstReg = I.getOperand(0).getReg();
1163  const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
1164  if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1165  break;
1166  }
1167 
1168  return true;
1169  }
1170  default:
1171  return false;
1172  }
1173 
1174  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1175 }
bool useMovt() const
const MachineInstrBuilder & add(const MachineOperand &MO) const
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
bool isThumb() const
Definition: ARMSubtarget.h:749
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const unsigned zero_reg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
const ARMTargetLowering * getTargetLowering() const override
Definition: ARMSubtarget.h:525
unsigned Reg
static uint64_t selectImpl(uint64_t CandidateMask, uint64_t &NextInSequenceMask)
#define DEBUG_TYPE
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
#define GET_GLOBALISEL_PREDICATES_INIT
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
InstructionSelector * createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI, const ARMRegisterBankInfo &RBI)
static bool isThumb(const MCSubtargetInfo &STI)
LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
bool isTargetELF() const
Definition: ARMSubtarget.h:694
Holds all the information related to register banks.
Definition: BitVector.h:937
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
Definition: ARMBaseInfo.h:266
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
const HexagonInstrInfo * TII
const ConstantFP * getFPImm() const
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
static StringRef getName(Value *V)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
static bool isStore(int Opcode)
This class provides the information for the target register banks.
bool isTargetDarwin() const
Definition: ARMSubtarget.h:684
const ARMSubtarget & getSubtarget() const
#define EQ(a, b)
Definition: regexec.c:112
bool isReadOnly(const GlobalValue *GV) const
static std::pair< ARMCC::CondCodes, ARMCC::CondCodes > getComparePreds(CmpInst::Predicate Pred)
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
static int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
This file declares the targeting of the RegisterBankInfo class for ARM.
This is an important base class in LLVM.
Definition: Constant.h:41
#define STORE_OPCODE(VAR, OPC)
const GlobalValue * getGlobal() const
bool isGVInGOT(const GlobalValue *GV) const
Returns the constant pool modifier needed to access the GV.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:732
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
self_iterator getIterator()
Definition: ilist_node.h:81
bool hasVFP2Base() const
Definition: ARMSubtarget.h:603
bool isCopy() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:50
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned SelectOpcode, unsigned OpRegBank, unsigned OpSize)
const APFloat & getValueAPF() const
Definition: Constants.h:302
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
bool hasFP64() const
Definition: ARMSubtarget.h:636
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:217
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition: Utils.cpp:113
This class implements the register bank concept.
Definition: RegisterBank.h:28
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
bool isROPI() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Section Relative (Windows TLS)
Provides the logic to select generic machine instructions.
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:411
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
#define I(x, y, z)
Definition: MD5.cpp:58
#define GET_GLOBALISEL_TEMPORARIES_INIT
uint32_t Size
Definition: Profile.cpp:46
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Instructions::iterator instr_iterator
bool isTargetMachO() const
Definition: ARMSubtarget.h:695
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel...
Definition: TargetOpcodes.h:30
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:250
static const Function * getParent(const Value *V)
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
Definition: ARMBaseInfo.h:284
bool isRWPI() const
const MachineBasicBlock::instr_iterator InsertBefore
IRTranslator LLVM IR MI
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:47
unsigned getPredicate() const