LLVM  8.0.0svn
X86InstructionSelector.cpp
Go to the documentation of this file.
1 //===- X86InstructionSelector.cpp -----------------------------------------===//
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
11 /// X86.
12 /// \todo This should be generated by TableGen.
13 //===----------------------------------------------------------------------===//
14 
16 #include "X86InstrBuilder.h"
17 #include "X86InstrInfo.h"
18 #include "X86RegisterBankInfo.h"
19 #include "X86RegisterInfo.h"
20 #include "X86Subtarget.h"
21 #include "X86TargetMachine.h"
36 #include "llvm/IR/DataLayout.h"
37 #include "llvm/IR/InstrTypes.h"
39 #include "llvm/Support/CodeGen.h"
40 #include "llvm/Support/Debug.h"
45 #include <cassert>
46 #include <cstdint>
47 #include <tuple>
48 
49 #define DEBUG_TYPE "X86-isel"
50 
51 using namespace llvm;
52 
53 namespace {
54 
55 #define GET_GLOBALISEL_PREDICATE_BITSET
56 #include "X86GenGlobalISel.inc"
57 #undef GET_GLOBALISEL_PREDICATE_BITSET
58 
59 class X86InstructionSelector : public InstructionSelector {
60 public:
61  X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
62  const X86RegisterBankInfo &RBI);
63 
64  bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
65  static const char *getName() { return DEBUG_TYPE; }
66 
67 private:
68  /// tblgen-erated 'select' implementation, used as the initial selector for
69  /// the patterns that don't require complex C++.
70  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
71 
72  // TODO: remove after supported by Tablegen-erated instruction selection.
73  unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
74  uint64_t Alignment) const;
75 
76  bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
77  MachineFunction &MF) const;
78  bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
79  MachineFunction &MF) const;
80  bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
81  MachineFunction &MF) const;
82  bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
83  MachineFunction &MF) const;
84  bool selectTruncOrPtrToInt(MachineInstr &I, MachineRegisterInfo &MRI,
85  MachineFunction &MF) const;
86  bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
87  MachineFunction &MF) const;
88  bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
89  MachineFunction &MF) const;
90  bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
91  MachineFunction &MF) const;
92  bool selectFCmp(MachineInstr &I, MachineRegisterInfo &MRI,
93  MachineFunction &MF) const;
94  bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
95  MachineFunction &MF) const;
96  bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
98  MachineFunction &MF,
99  CodeGenCoverage &CoverageInfo) const;
101  MachineFunction &MF,
102  CodeGenCoverage &CoverageInfo) const;
103  bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
104  MachineFunction &MF) const;
105  bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
106  MachineFunction &MF) const;
107  bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
108  MachineFunction &MF) const;
109  bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
110  const unsigned DstReg,
111  const TargetRegisterClass *DstRC,
112  const unsigned SrcReg,
113  const TargetRegisterClass *SrcRC) const;
114  bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
115  MachineFunction &MF) const;
116  bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
117  bool selectShift(MachineInstr &I, MachineRegisterInfo &MRI,
118  MachineFunction &MF) const;
119  bool selectDivRem(MachineInstr &I, MachineRegisterInfo &MRI,
120  MachineFunction &MF) const;
121  bool selectIntrinsicWSideEffects(MachineInstr &I, MachineRegisterInfo &MRI,
122  MachineFunction &MF) const;
123 
124  // emit insert subreg instruction and insert it before MachineInstr &I
125  bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
126  MachineRegisterInfo &MRI, MachineFunction &MF) const;
127  // emit extract subreg instruction and insert it before MachineInstr &I
128  bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
129  MachineRegisterInfo &MRI, MachineFunction &MF) const;
130 
131  const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
132  const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
133  MachineRegisterInfo &MRI) const;
134 
135  const X86TargetMachine &TM;
136  const X86Subtarget &STI;
137  const X86InstrInfo &TII;
138  const X86RegisterInfo &TRI;
139  const X86RegisterBankInfo &RBI;
140 
141 #define GET_GLOBALISEL_PREDICATES_DECL
142 #include "X86GenGlobalISel.inc"
143 #undef GET_GLOBALISEL_PREDICATES_DECL
144 
145 #define GET_GLOBALISEL_TEMPORARIES_DECL
146 #include "X86GenGlobalISel.inc"
147 #undef GET_GLOBALISEL_TEMPORARIES_DECL
148 };
149 
150 } // end anonymous namespace
151 
152 #define GET_GLOBALISEL_IMPL
153 #include "X86GenGlobalISel.inc"
154 #undef GET_GLOBALISEL_IMPL
155 
156 X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
157  const X86Subtarget &STI,
158  const X86RegisterBankInfo &RBI)
159  : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
160  TRI(*STI.getRegisterInfo()), RBI(RBI),
162 #include "X86GenGlobalISel.inc"
165 #include "X86GenGlobalISel.inc"
167 {
168 }
169 
170 // FIXME: This should be target-independent, inferred from the types declared
171 // for each class in the bank.
172 const TargetRegisterClass *
174  if (RB.getID() == X86::GPRRegBankID) {
175  if (Ty.getSizeInBits() <= 8)
176  return &X86::GR8RegClass;
177  if (Ty.getSizeInBits() == 16)
178  return &X86::GR16RegClass;
179  if (Ty.getSizeInBits() == 32)
180  return &X86::GR32RegClass;
181  if (Ty.getSizeInBits() == 64)
182  return &X86::GR64RegClass;
183  }
184  if (RB.getID() == X86::VECRRegBankID) {
185  if (Ty.getSizeInBits() == 32)
186  return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
187  if (Ty.getSizeInBits() == 64)
188  return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
189  if (Ty.getSizeInBits() == 128)
190  return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
191  if (Ty.getSizeInBits() == 256)
192  return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
193  if (Ty.getSizeInBits() == 512)
194  return &X86::VR512RegClass;
195  }
196 
197  llvm_unreachable("Unknown RegBank!");
198 }
199 
200 const TargetRegisterClass *
202  MachineRegisterInfo &MRI) const {
203  const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
204  return getRegClass(Ty, RegBank);
205 }
206 
207 static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
208  unsigned SubIdx = X86::NoSubRegister;
209  if (RC == &X86::GR32RegClass) {
210  SubIdx = X86::sub_32bit;
211  } else if (RC == &X86::GR16RegClass) {
212  SubIdx = X86::sub_16bit;
213  } else if (RC == &X86::GR8RegClass) {
214  SubIdx = X86::sub_8bit;
215  }
216 
217  return SubIdx;
218 }
219 
220 static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) {
221  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
222  if (X86::GR64RegClass.contains(Reg))
223  return &X86::GR64RegClass;
224  if (X86::GR32RegClass.contains(Reg))
225  return &X86::GR32RegClass;
226  if (X86::GR16RegClass.contains(Reg))
227  return &X86::GR16RegClass;
228  if (X86::GR8RegClass.contains(Reg))
229  return &X86::GR8RegClass;
230 
231  llvm_unreachable("Unknown RegClass for PhysReg!");
232 }
233 
234 // Set X86 Opcode and constrain DestReg.
236  MachineRegisterInfo &MRI) const {
237  unsigned DstReg = I.getOperand(0).getReg();
238  const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
239  const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
240 
241  unsigned SrcReg = I.getOperand(1).getReg();
242  const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
243  const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
244 
245  if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
246  assert(I.isCopy() && "Generic operators do not allow physical registers");
247 
248  if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
249  DstRegBank.getID() == X86::GPRRegBankID) {
250 
251  const TargetRegisterClass *SrcRC =
252  getRegClass(MRI.getType(SrcReg), SrcRegBank);
253  const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
254 
255  if (SrcRC != DstRC) {
256  // This case can be generated by ABI lowering, performe anyext
257  unsigned ExtSrc = MRI.createVirtualRegister(DstRC);
258  BuildMI(*I.getParent(), I, I.getDebugLoc(),
259  TII.get(TargetOpcode::SUBREG_TO_REG))
260  .addDef(ExtSrc)
261  .addImm(0)
262  .addReg(SrcReg)
263  .addImm(getSubRegIndex(SrcRC));
264 
265  I.getOperand(1).setReg(ExtSrc);
266  }
267  }
268 
269  return true;
270  }
271 
272  assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
273  "No phys reg on generic operators");
274  assert((DstSize == SrcSize ||
275  // Copies are a mean to setup initial types, the number of
276  // bits may not exactly match.
277  (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
278  DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
279  "Copy with different width?!");
280 
281  const TargetRegisterClass *DstRC =
282  getRegClass(MRI.getType(DstReg), DstRegBank);
283 
284  if (SrcRegBank.getID() == X86::GPRRegBankID &&
285  DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
286  TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
287  // Change the physical register to performe truncate.
288 
289  const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
290 
291  if (DstRC != SrcRC) {
292  I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
293  I.getOperand(1).substPhysReg(SrcReg, TRI);
294  }
295  }
296 
297  // No need to constrain SrcReg. It will get constrained when
298  // we hit another of its use or its defs.
299  // Copies do not have constraints.
300  const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
301  if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
302  if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
303  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
304  << " operand\n");
305  return false;
306  }
307  }
308  I.setDesc(TII.get(X86::COPY));
309  return true;
310 }
311 
312 bool X86InstructionSelector::select(MachineInstr &I,
313  CodeGenCoverage &CoverageInfo) const {
314  assert(I.getParent() && "Instruction should be in a basic block!");
315  assert(I.getParent()->getParent() && "Instruction should be in a function!");
316 
317  MachineBasicBlock &MBB = *I.getParent();
318  MachineFunction &MF = *MBB.getParent();
319  MachineRegisterInfo &MRI = MF.getRegInfo();
320 
321  unsigned Opcode = I.getOpcode();
322  if (!isPreISelGenericOpcode(Opcode)) {
323  // Certain non-generic instructions also need some special handling.
324 
325  if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
326  return false;
327 
328  if (I.isCopy())
329  return selectCopy(I, MRI);
330 
331  return true;
332  }
333 
335  "Generic instruction has unexpected implicit operands\n");
336 
337  if (selectImpl(I, CoverageInfo))
338  return true;
339 
340  LLVM_DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
341 
342  // TODO: This should be implemented by tblgen.
343  switch (I.getOpcode()) {
344  default:
345  return false;
346  case TargetOpcode::G_STORE:
347  case TargetOpcode::G_LOAD:
348  return selectLoadStoreOp(I, MRI, MF);
349  case TargetOpcode::G_GEP:
350  case TargetOpcode::G_FRAME_INDEX:
351  return selectFrameIndexOrGep(I, MRI, MF);
352  case TargetOpcode::G_GLOBAL_VALUE:
353  return selectGlobalValue(I, MRI, MF);
354  case TargetOpcode::G_CONSTANT:
355  return selectConstant(I, MRI, MF);
356  case TargetOpcode::G_FCONSTANT:
357  return materializeFP(I, MRI, MF);
358  case TargetOpcode::G_PTRTOINT:
359  case TargetOpcode::G_TRUNC:
360  return selectTruncOrPtrToInt(I, MRI, MF);
361  case TargetOpcode::G_INTTOPTR:
362  return selectCopy(I, MRI);
363  case TargetOpcode::G_ZEXT:
364  return selectZext(I, MRI, MF);
365  case TargetOpcode::G_ANYEXT:
366  return selectAnyext(I, MRI, MF);
367  case TargetOpcode::G_ICMP:
368  return selectCmp(I, MRI, MF);
369  case TargetOpcode::G_FCMP:
370  return selectFCmp(I, MRI, MF);
371  case TargetOpcode::G_UADDE:
372  return selectUadde(I, MRI, MF);
373  case TargetOpcode::G_UNMERGE_VALUES:
374  return selectUnmergeValues(I, MRI, MF, CoverageInfo);
375  case TargetOpcode::G_MERGE_VALUES:
376  case TargetOpcode::G_CONCAT_VECTORS:
377  return selectMergeValues(I, MRI, MF, CoverageInfo);
378  case TargetOpcode::G_EXTRACT:
379  return selectExtract(I, MRI, MF);
380  case TargetOpcode::G_INSERT:
381  return selectInsert(I, MRI, MF);
382  case TargetOpcode::G_BRCOND:
383  return selectCondBranch(I, MRI, MF);
384  case TargetOpcode::G_IMPLICIT_DEF:
385  case TargetOpcode::G_PHI:
386  return selectImplicitDefOrPHI(I, MRI);
387  case TargetOpcode::G_SHL:
388  case TargetOpcode::G_ASHR:
389  case TargetOpcode::G_LSHR:
390  return selectShift(I, MRI, MF);
391  case TargetOpcode::G_SDIV:
392  case TargetOpcode::G_UDIV:
393  case TargetOpcode::G_SREM:
394  case TargetOpcode::G_UREM:
395  return selectDivRem(I, MRI, MF);
396  case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
397  return selectIntrinsicWSideEffects(I, MRI, MF);
398  }
399 
400  return false;
401 }
402 
403 unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
404  const RegisterBank &RB,
405  unsigned Opc,
406  uint64_t Alignment) const {
407  bool Isload = (Opc == TargetOpcode::G_LOAD);
408  bool HasAVX = STI.hasAVX();
409  bool HasAVX512 = STI.hasAVX512();
410  bool HasVLX = STI.hasVLX();
411 
412  if (Ty == LLT::scalar(8)) {
413  if (X86::GPRRegBankID == RB.getID())
414  return Isload ? X86::MOV8rm : X86::MOV8mr;
415  } else if (Ty == LLT::scalar(16)) {
416  if (X86::GPRRegBankID == RB.getID())
417  return Isload ? X86::MOV16rm : X86::MOV16mr;
418  } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
419  if (X86::GPRRegBankID == RB.getID())
420  return Isload ? X86::MOV32rm : X86::MOV32mr;
421  if (X86::VECRRegBankID == RB.getID())
422  return Isload ? (HasAVX512 ? X86::VMOVSSZrm
423  : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
424  : (HasAVX512 ? X86::VMOVSSZmr
425  : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
426  } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
427  if (X86::GPRRegBankID == RB.getID())
428  return Isload ? X86::MOV64rm : X86::MOV64mr;
429  if (X86::VECRRegBankID == RB.getID())
430  return Isload ? (HasAVX512 ? X86::VMOVSDZrm
431  : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm)
432  : (HasAVX512 ? X86::VMOVSDZmr
433  : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr);
434  } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
435  if (Alignment >= 16)
436  return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
437  : HasAVX512
438  ? X86::VMOVAPSZ128rm_NOVLX
439  : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
440  : (HasVLX ? X86::VMOVAPSZ128mr
441  : HasAVX512
442  ? X86::VMOVAPSZ128mr_NOVLX
443  : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
444  else
445  return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
446  : HasAVX512
447  ? X86::VMOVUPSZ128rm_NOVLX
448  : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
449  : (HasVLX ? X86::VMOVUPSZ128mr
450  : HasAVX512
451  ? X86::VMOVUPSZ128mr_NOVLX
452  : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
453  } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
454  if (Alignment >= 32)
455  return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
456  : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
457  : X86::VMOVAPSYrm)
458  : (HasVLX ? X86::VMOVAPSZ256mr
459  : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
460  : X86::VMOVAPSYmr);
461  else
462  return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
463  : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
464  : X86::VMOVUPSYrm)
465  : (HasVLX ? X86::VMOVUPSZ256mr
466  : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
467  : X86::VMOVUPSYmr);
468  } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
469  if (Alignment >= 64)
470  return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
471  else
472  return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
473  }
474  return Opc;
475 }
476 
477 // Fill in an address from the given instruction.
478 static void X86SelectAddress(const MachineInstr &I,
479  const MachineRegisterInfo &MRI,
480  X86AddressMode &AM) {
481  assert(I.getOperand(0).isReg() && "unsupported opperand.");
482  assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
483  "unsupported type.");
484 
485  if (I.getOpcode() == TargetOpcode::G_GEP) {
486  if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) {
487  int64_t Imm = *COff;
488  if (isInt<32>(Imm)) { // Check for displacement overflow.
489  AM.Disp = static_cast<int32_t>(Imm);
490  AM.Base.Reg = I.getOperand(1).getReg();
491  return;
492  }
493  }
494  } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) {
495  AM.Base.FrameIndex = I.getOperand(1).getIndex();
496  AM.BaseType = X86AddressMode::FrameIndexBase;
497  return;
498  }
499 
500  // Default behavior.
501  AM.Base.Reg = I.getOperand(0).getReg();
502 }
503 
504 bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
505  MachineRegisterInfo &MRI,
506  MachineFunction &MF) const {
507  unsigned Opc = I.getOpcode();
508 
509  assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
510  "unexpected instruction");
511 
512  const unsigned DefReg = I.getOperand(0).getReg();
513  LLT Ty = MRI.getType(DefReg);
514  const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
515 
516  auto &MemOp = **I.memoperands_begin();
517  if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
518  LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
519  return false;
520  }
521 
522  unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
523  if (NewOpc == Opc)
524  return false;
525 
526  X86AddressMode AM;
527  X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM);
528 
529  I.setDesc(TII.get(NewOpc));
530  MachineInstrBuilder MIB(MF, I);
531  if (Opc == TargetOpcode::G_LOAD) {
532  I.RemoveOperand(1);
533  addFullAddress(MIB, AM);
534  } else {
535  // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
536  I.RemoveOperand(1);
537  I.RemoveOperand(0);
538  addFullAddress(MIB, AM).addUse(DefReg);
539  }
540  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
541 }
542 
543 static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
544  if (Ty == LLT::pointer(0, 64))
545  return X86::LEA64r;
546  else if (Ty == LLT::pointer(0, 32))
547  return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
548  else
549  llvm_unreachable("Can't get LEA opcode. Unsupported type.");
550 }
551 
552 bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
553  MachineRegisterInfo &MRI,
554  MachineFunction &MF) const {
555  unsigned Opc = I.getOpcode();
556 
557  assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) &&
558  "unexpected instruction");
559 
560  const unsigned DefReg = I.getOperand(0).getReg();
561  LLT Ty = MRI.getType(DefReg);
562 
563  // Use LEA to calculate frame index and GEP
564  unsigned NewOpc = getLeaOP(Ty, STI);
565  I.setDesc(TII.get(NewOpc));
566  MachineInstrBuilder MIB(MF, I);
567 
568  if (Opc == TargetOpcode::G_FRAME_INDEX) {
569  addOffset(MIB, 0);
570  } else {
571  MachineOperand &InxOp = I.getOperand(2);
572  I.addOperand(InxOp); // set IndexReg
573  InxOp.ChangeToImmediate(1); // set Scale
574  MIB.addImm(0).addReg(0);
575  }
576 
577  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
578 }
579 
580 bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
581  MachineRegisterInfo &MRI,
582  MachineFunction &MF) const {
583  assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
584  "unexpected instruction");
585 
586  auto GV = I.getOperand(1).getGlobal();
587  if (GV->isThreadLocal()) {
588  return false; // TODO: we don't support TLS yet.
589  }
590 
591  // Can't handle alternate code models yet.
592  if (TM.getCodeModel() != CodeModel::Small)
593  return false;
594 
595  X86AddressMode AM;
596  AM.GV = GV;
597  AM.GVOpFlags = STI.classifyGlobalReference(GV);
598 
599  // TODO: The ABI requires an extra load. not supported yet.
601  return false;
602 
603  // TODO: This reference is relative to the pic base. not supported yet.
605  return false;
606 
607  if (STI.isPICStyleRIPRel()) {
608  // Use rip-relative addressing.
609  assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
610  AM.Base.Reg = X86::RIP;
611  }
612 
613  const unsigned DefReg = I.getOperand(0).getReg();
614  LLT Ty = MRI.getType(DefReg);
615  unsigned NewOpc = getLeaOP(Ty, STI);
616 
617  I.setDesc(TII.get(NewOpc));
618  MachineInstrBuilder MIB(MF, I);
619 
620  I.RemoveOperand(1);
621  addFullAddress(MIB, AM);
622 
623  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
624 }
625 
626 bool X86InstructionSelector::selectConstant(MachineInstr &I,
627  MachineRegisterInfo &MRI,
628  MachineFunction &MF) const {
629  assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
630  "unexpected instruction");
631 
632  const unsigned DefReg = I.getOperand(0).getReg();
633  LLT Ty = MRI.getType(DefReg);
634 
635  if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
636  return false;
637 
638  uint64_t Val = 0;
639  if (I.getOperand(1).isCImm()) {
640  Val = I.getOperand(1).getCImm()->getZExtValue();
641  I.getOperand(1).ChangeToImmediate(Val);
642  } else if (I.getOperand(1).isImm()) {
643  Val = I.getOperand(1).getImm();
644  } else
645  llvm_unreachable("Unsupported operand type.");
646 
647  unsigned NewOpc;
648  switch (Ty.getSizeInBits()) {
649  case 8:
650  NewOpc = X86::MOV8ri;
651  break;
652  case 16:
653  NewOpc = X86::MOV16ri;
654  break;
655  case 32:
656  NewOpc = X86::MOV32ri;
657  break;
658  case 64:
659  // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
660  if (isInt<32>(Val))
661  NewOpc = X86::MOV64ri32;
662  else
663  NewOpc = X86::MOV64ri;
664  break;
665  default:
666  llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
667  }
668 
669  I.setDesc(TII.get(NewOpc));
670  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
671 }
672 
673 // Helper function for selectTruncOrPtrToInt and selectAnyext.
674 // Returns true if DstRC lives on a floating register class and
675 // SrcRC lives on a 128-bit vector class.
676 static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC,
677  const TargetRegisterClass *SrcRC) {
678  return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
679  DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
680  (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
681 }
682 
683 bool X86InstructionSelector::selectTurnIntoCOPY(
684  MachineInstr &I, MachineRegisterInfo &MRI, const unsigned DstReg,
685  const TargetRegisterClass *DstRC, const unsigned SrcReg,
686  const TargetRegisterClass *SrcRC) const {
687 
688  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
689  !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
690  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
691  << " operand\n");
692  return false;
693  }
694  I.setDesc(TII.get(X86::COPY));
695  return true;
696 }
697 
698 bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
699  MachineRegisterInfo &MRI,
700  MachineFunction &MF) const {
701  assert((I.getOpcode() == TargetOpcode::G_TRUNC ||
702  I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
703  "unexpected instruction");
704 
705  const unsigned DstReg = I.getOperand(0).getReg();
706  const unsigned SrcReg = I.getOperand(1).getReg();
707 
708  const LLT DstTy = MRI.getType(DstReg);
709  const LLT SrcTy = MRI.getType(SrcReg);
710 
711  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
712  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
713 
714  if (DstRB.getID() != SrcRB.getID()) {
715  LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode())
716  << " input/output on different banks\n");
717  return false;
718  }
719 
720  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
721  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
722 
723  if (!DstRC || !SrcRC)
724  return false;
725 
726  // If that's truncation of the value that lives on the vector class and goes
727  // into the floating class, just replace it with copy, as we are able to
728  // select it as a regular move.
729  if (canTurnIntoCOPY(DstRC, SrcRC))
730  return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
731 
732  if (DstRB.getID() != X86::GPRRegBankID)
733  return false;
734 
735  unsigned SubIdx;
736  if (DstRC == SrcRC) {
737  // Nothing to be done
738  SubIdx = X86::NoSubRegister;
739  } else if (DstRC == &X86::GR32RegClass) {
740  SubIdx = X86::sub_32bit;
741  } else if (DstRC == &X86::GR16RegClass) {
742  SubIdx = X86::sub_16bit;
743  } else if (DstRC == &X86::GR8RegClass) {
744  SubIdx = X86::sub_8bit;
745  } else {
746  return false;
747  }
748 
749  SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
750 
751  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
752  !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
753  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
754  << "\n");
755  return false;
756  }
757 
758  I.getOperand(1).setSubReg(SubIdx);
759 
760  I.setDesc(TII.get(X86::COPY));
761  return true;
762 }
763 
764 bool X86InstructionSelector::selectZext(MachineInstr &I,
765  MachineRegisterInfo &MRI,
766  MachineFunction &MF) const {
767  assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
768 
769  const unsigned DstReg = I.getOperand(0).getReg();
770  const unsigned SrcReg = I.getOperand(1).getReg();
771 
772  const LLT DstTy = MRI.getType(DstReg);
773  const LLT SrcTy = MRI.getType(SrcReg);
774 
775  assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(32)) &&
776  "8=>32 Zext is handled by tablegen");
777  assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(32)) &&
778  "16=>32 Zext is handled by tablegen");
779 
780  const static struct ZextEntry {
781  LLT SrcTy;
782  LLT DstTy;
783  unsigned MovOp;
784  bool NeedSubregToReg;
785  } OpTable[] = {
786  {LLT::scalar(8), LLT::scalar(16), X86::MOVZX16rr8, false}, // i8 => i16
787  {LLT::scalar(8), LLT::scalar(64), X86::MOVZX32rr8, true}, // i8 => i64
788  {LLT::scalar(16), LLT::scalar(64), X86::MOVZX32rr16, true}, // i16 => i64
789  {LLT::scalar(32), LLT::scalar(64), 0, true} // i32 => i64
790  };
791 
792  auto ZextEntryIt =
793  std::find_if(std::begin(OpTable), std::end(OpTable),
794  [SrcTy, DstTy](const ZextEntry &El) {
795  return El.DstTy == DstTy && El.SrcTy == SrcTy;
796  });
797 
798  // Here we try to select Zext into a MOVZ and/or SUBREG_TO_REG instruction.
799  if (ZextEntryIt != std::end(OpTable)) {
800  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
801  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
802  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
803  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
804 
805  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
806  !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
807  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
808  << " operand\n");
809  return false;
810  }
811 
812  unsigned TransitRegTo = DstReg;
813  unsigned TransitRegFrom = SrcReg;
814  if (ZextEntryIt->MovOp) {
815  // If we select Zext into MOVZ + SUBREG_TO_REG, we need to have
816  // a transit register in between: create it here.
817  if (ZextEntryIt->NeedSubregToReg) {
818  TransitRegFrom = MRI.createVirtualRegister(
819  getRegClass(LLT::scalar(32), DstReg, MRI));
820  TransitRegTo = TransitRegFrom;
821  }
822 
823  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ZextEntryIt->MovOp))
824  .addDef(TransitRegTo)
825  .addReg(SrcReg);
826  }
827  if (ZextEntryIt->NeedSubregToReg) {
828  BuildMI(*I.getParent(), I, I.getDebugLoc(),
829  TII.get(TargetOpcode::SUBREG_TO_REG))
830  .addDef(DstReg)
831  .addImm(0)
832  .addReg(TransitRegFrom)
833  .addImm(X86::sub_32bit);
834  }
835  I.eraseFromParent();
836  return true;
837  }
838 
839  if (SrcTy != LLT::scalar(1))
840  return false;
841 
842  unsigned AndOpc;
843  if (DstTy == LLT::scalar(8))
844  AndOpc = X86::AND8ri;
845  else if (DstTy == LLT::scalar(16))
846  AndOpc = X86::AND16ri8;
847  else if (DstTy == LLT::scalar(32))
848  AndOpc = X86::AND32ri8;
849  else if (DstTy == LLT::scalar(64))
850  AndOpc = X86::AND64ri8;
851  else
852  return false;
853 
854  unsigned DefReg = SrcReg;
855  if (DstTy != LLT::scalar(8)) {
856  DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
857  BuildMI(*I.getParent(), I, I.getDebugLoc(),
858  TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
859  .addImm(0)
860  .addReg(SrcReg)
861  .addImm(X86::sub_8bit);
862  }
863 
864  MachineInstr &AndInst =
865  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
866  .addReg(DefReg)
867  .addImm(1);
868 
869  constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
870 
871  I.eraseFromParent();
872  return true;
873 }
874 
875 bool X86InstructionSelector::selectAnyext(MachineInstr &I,
876  MachineRegisterInfo &MRI,
877  MachineFunction &MF) const {
878  assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
879 
880  const unsigned DstReg = I.getOperand(0).getReg();
881  const unsigned SrcReg = I.getOperand(1).getReg();
882 
883  const LLT DstTy = MRI.getType(DstReg);
884  const LLT SrcTy = MRI.getType(SrcReg);
885 
886  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
887  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
888 
889  assert(DstRB.getID() == SrcRB.getID() &&
890  "G_ANYEXT input/output on different banks\n");
891 
892  assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
893  "G_ANYEXT incorrect operand size");
894 
895  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
896  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
897 
898  // If that's ANY_EXT of the value that lives on the floating class and goes
899  // into the vector class, just replace it with copy, as we are able to select
900  // it as a regular move.
901  if (canTurnIntoCOPY(SrcRC, DstRC))
902  return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC);
903 
904  if (DstRB.getID() != X86::GPRRegBankID)
905  return false;
906 
907  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
908  !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
909  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
910  << " operand\n");
911  return false;
912  }
913 
914  if (SrcRC == DstRC) {
915  I.setDesc(TII.get(X86::COPY));
916  return true;
917  }
918 
919  BuildMI(*I.getParent(), I, I.getDebugLoc(),
920  TII.get(TargetOpcode::SUBREG_TO_REG))
921  .addDef(DstReg)
922  .addImm(0)
923  .addReg(SrcReg)
924  .addImm(getSubRegIndex(SrcRC));
925 
926  I.eraseFromParent();
927  return true;
928 }
929 
930 bool X86InstructionSelector::selectCmp(MachineInstr &I,
931  MachineRegisterInfo &MRI,
932  MachineFunction &MF) const {
933  assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
934 
935  X86::CondCode CC;
936  bool SwapArgs;
937  std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
939  unsigned OpSet = X86::getSETFromCond(CC);
940 
941  unsigned LHS = I.getOperand(2).getReg();
942  unsigned RHS = I.getOperand(3).getReg();
943 
944  if (SwapArgs)
945  std::swap(LHS, RHS);
946 
947  unsigned OpCmp;
948  LLT Ty = MRI.getType(LHS);
949 
950  switch (Ty.getSizeInBits()) {
951  default:
952  return false;
953  case 8:
954  OpCmp = X86::CMP8rr;
955  break;
956  case 16:
957  OpCmp = X86::CMP16rr;
958  break;
959  case 32:
960  OpCmp = X86::CMP32rr;
961  break;
962  case 64:
963  OpCmp = X86::CMP64rr;
964  break;
965  }
966 
968  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
969  .addReg(LHS)
970  .addReg(RHS);
971 
972  MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
973  TII.get(OpSet), I.getOperand(0).getReg());
974 
975  constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
976  constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
977 
978  I.eraseFromParent();
979  return true;
980 }
981 
982 bool X86InstructionSelector::selectFCmp(MachineInstr &I,
983  MachineRegisterInfo &MRI,
984  MachineFunction &MF) const {
985  assert((I.getOpcode() == TargetOpcode::G_FCMP) && "unexpected instruction");
986 
987  unsigned LhsReg = I.getOperand(2).getReg();
988  unsigned RhsReg = I.getOperand(3).getReg();
991 
992  // FCMP_OEQ and FCMP_UNE cannot be checked with a single instruction.
993  static const uint16_t SETFOpcTable[2][3] = {
994  {X86::SETEr, X86::SETNPr, X86::AND8rr},
995  {X86::SETNEr, X86::SETPr, X86::OR8rr}};
996  const uint16_t *SETFOpc = nullptr;
997  switch (Predicate) {
998  default:
999  break;
1000  case CmpInst::FCMP_OEQ:
1001  SETFOpc = &SETFOpcTable[0][0];
1002  break;
1003  case CmpInst::FCMP_UNE:
1004  SETFOpc = &SETFOpcTable[1][0];
1005  break;
1006  }
1007 
1008  // Compute the opcode for the CMP instruction.
1009  unsigned OpCmp;
1010  LLT Ty = MRI.getType(LhsReg);
1011  switch (Ty.getSizeInBits()) {
1012  default:
1013  return false;
1014  case 32:
1015  OpCmp = X86::UCOMISSrr;
1016  break;
1017  case 64:
1018  OpCmp = X86::UCOMISDrr;
1019  break;
1020  }
1021 
1022  unsigned ResultReg = I.getOperand(0).getReg();
1023  RBI.constrainGenericRegister(
1024  ResultReg,
1025  *getRegClass(LLT::scalar(8), *RBI.getRegBank(ResultReg, MRI, TRI)), MRI);
1026  if (SETFOpc) {
1028  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
1029  .addReg(LhsReg)
1030  .addReg(RhsReg);
1031 
1032  unsigned FlagReg1 = MRI.createVirtualRegister(&X86::GR8RegClass);
1033  unsigned FlagReg2 = MRI.createVirtualRegister(&X86::GR8RegClass);
1034  MachineInstr &Set1 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1035  TII.get(SETFOpc[0]), FlagReg1);
1036  MachineInstr &Set2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1037  TII.get(SETFOpc[1]), FlagReg2);
1038  MachineInstr &Set3 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1039  TII.get(SETFOpc[2]), ResultReg)
1040  .addReg(FlagReg1)
1041  .addReg(FlagReg2);
1042  constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
1046 
1047  I.eraseFromParent();
1048  return true;
1049  }
1050 
1051  X86::CondCode CC;
1052  bool SwapArgs;
1053  std::tie(CC, SwapArgs) = X86::getX86ConditionCode(Predicate);
1054  assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
1055  unsigned Opc = X86::getSETFromCond(CC);
1056 
1057  if (SwapArgs)
1058  std::swap(LhsReg, RhsReg);
1059 
1060  // Emit a compare of LHS/RHS.
1062  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
1063  .addReg(LhsReg)
1064  .addReg(RhsReg);
1065 
1066  MachineInstr &Set =
1067  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc), ResultReg);
1068  constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
1070  I.eraseFromParent();
1071  return true;
1072 }
1073 
1074 bool X86InstructionSelector::selectUadde(MachineInstr &I,
1075  MachineRegisterInfo &MRI,
1076  MachineFunction &MF) const {
1077  assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction");
1078 
1079  const unsigned DstReg = I.getOperand(0).getReg();
1080  const unsigned CarryOutReg = I.getOperand(1).getReg();
1081  const unsigned Op0Reg = I.getOperand(2).getReg();
1082  const unsigned Op1Reg = I.getOperand(3).getReg();
1083  unsigned CarryInReg = I.getOperand(4).getReg();
1084 
1085  const LLT DstTy = MRI.getType(DstReg);
1086 
1087  if (DstTy != LLT::scalar(32))
1088  return false;
1089 
1090  // find CarryIn def instruction.
1091  MachineInstr *Def = MRI.getVRegDef(CarryInReg);
1092  while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
1093  CarryInReg = Def->getOperand(1).getReg();
1094  Def = MRI.getVRegDef(CarryInReg);
1095  }
1096 
1097  unsigned Opcode;
1098  if (Def->getOpcode() == TargetOpcode::G_UADDE) {
1099  // carry set by prev ADD.
1100 
1101  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
1102  .addReg(CarryInReg);
1103 
1104  if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
1105  return false;
1106 
1107  Opcode = X86::ADC32rr;
1108  } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) {
1109  // carry is constant, support only 0.
1110  if (*val != 0)
1111  return false;
1112 
1113  Opcode = X86::ADD32rr;
1114  } else
1115  return false;
1116 
1117  MachineInstr &AddInst =
1118  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1119  .addReg(Op0Reg)
1120  .addReg(Op1Reg);
1121 
1122  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
1123  .addReg(X86::EFLAGS);
1124 
1125  if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
1126  !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
1127  return false;
1128 
1129  I.eraseFromParent();
1130  return true;
1131 }
1132 
1133 bool X86InstructionSelector::selectExtract(MachineInstr &I,
1134  MachineRegisterInfo &MRI,
1135  MachineFunction &MF) const {
1136  assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1137  "unexpected instruction");
1138 
1139  const unsigned DstReg = I.getOperand(0).getReg();
1140  const unsigned SrcReg = I.getOperand(1).getReg();
1141  int64_t Index = I.getOperand(2).getImm();
1142 
1143  const LLT DstTy = MRI.getType(DstReg);
1144  const LLT SrcTy = MRI.getType(SrcReg);
1145 
1146  // Meanwile handle vector type only.
1147  if (!DstTy.isVector())
1148  return false;
1149 
1150  if (Index % DstTy.getSizeInBits() != 0)
1151  return false; // Not extract subvector.
1152 
1153  if (Index == 0) {
1154  // Replace by extract subreg copy.
1155  if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
1156  return false;
1157 
1158  I.eraseFromParent();
1159  return true;
1160  }
1161 
1162  bool HasAVX = STI.hasAVX();
1163  bool HasAVX512 = STI.hasAVX512();
1164  bool HasVLX = STI.hasVLX();
1165 
1166  if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
1167  if (HasVLX)
1168  I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
1169  else if (HasAVX)
1170  I.setDesc(TII.get(X86::VEXTRACTF128rr));
1171  else
1172  return false;
1173  } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
1174  if (DstTy.getSizeInBits() == 128)
1175  I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
1176  else if (DstTy.getSizeInBits() == 256)
1177  I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
1178  else
1179  return false;
1180  } else
1181  return false;
1182 
1183  // Convert to X86 VEXTRACT immediate.
1184  Index = Index / DstTy.getSizeInBits();
1185  I.getOperand(2).setImm(Index);
1186 
1187  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1188 }
1189 
1190 bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
1191  MachineInstr &I,
1192  MachineRegisterInfo &MRI,
1193  MachineFunction &MF) const {
1194  const LLT DstTy = MRI.getType(DstReg);
1195  const LLT SrcTy = MRI.getType(SrcReg);
1196  unsigned SubIdx = X86::NoSubRegister;
1197 
1198  if (!DstTy.isVector() || !SrcTy.isVector())
1199  return false;
1200 
1201  assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
1202  "Incorrect Src/Dst register size");
1203 
1204  if (DstTy.getSizeInBits() == 128)
1205  SubIdx = X86::sub_xmm;
1206  else if (DstTy.getSizeInBits() == 256)
1207  SubIdx = X86::sub_ymm;
1208  else
1209  return false;
1210 
1211  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1212  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1213 
1214  SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1215 
1216  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1217  !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1218  LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
1219  return false;
1220  }
1221 
1222  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
1223  .addReg(SrcReg, 0, SubIdx);
1224 
1225  return true;
1226 }
1227 
1228 bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
1229  MachineInstr &I,
1230  MachineRegisterInfo &MRI,
1231  MachineFunction &MF) const {
1232  const LLT DstTy = MRI.getType(DstReg);
1233  const LLT SrcTy = MRI.getType(SrcReg);
1234  unsigned SubIdx = X86::NoSubRegister;
1235 
1236  // TODO: support scalar types
1237  if (!DstTy.isVector() || !SrcTy.isVector())
1238  return false;
1239 
1240  assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1241  "Incorrect Src/Dst register size");
1242 
1243  if (SrcTy.getSizeInBits() == 128)
1244  SubIdx = X86::sub_xmm;
1245  else if (SrcTy.getSizeInBits() == 256)
1246  SubIdx = X86::sub_ymm;
1247  else
1248  return false;
1249 
1250  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1251  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1252 
1253  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1254  !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1255  LLVM_DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1256  return false;
1257  }
1258 
1259  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1260  .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1261  .addReg(SrcReg);
1262 
1263  return true;
1264 }
1265 
1266 bool X86InstructionSelector::selectInsert(MachineInstr &I,
1267  MachineRegisterInfo &MRI,
1268  MachineFunction &MF) const {
1269  assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
1270 
1271  const unsigned DstReg = I.getOperand(0).getReg();
1272  const unsigned SrcReg = I.getOperand(1).getReg();
1273  const unsigned InsertReg = I.getOperand(2).getReg();
1274  int64_t Index = I.getOperand(3).getImm();
1275 
1276  const LLT DstTy = MRI.getType(DstReg);
1277  const LLT InsertRegTy = MRI.getType(InsertReg);
1278 
1279  // Meanwile handle vector type only.
1280  if (!DstTy.isVector())
1281  return false;
1282 
1283  if (Index % InsertRegTy.getSizeInBits() != 0)
1284  return false; // Not insert subvector.
1285 
1286  if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1287  // Replace by subreg copy.
1288  if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1289  return false;
1290 
1291  I.eraseFromParent();
1292  return true;
1293  }
1294 
1295  bool HasAVX = STI.hasAVX();
1296  bool HasAVX512 = STI.hasAVX512();
1297  bool HasVLX = STI.hasVLX();
1298 
1299  if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
1300  if (HasVLX)
1301  I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
1302  else if (HasAVX)
1303  I.setDesc(TII.get(X86::VINSERTF128rr));
1304  else
1305  return false;
1306  } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
1307  if (InsertRegTy.getSizeInBits() == 128)
1308  I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
1309  else if (InsertRegTy.getSizeInBits() == 256)
1310  I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
1311  else
1312  return false;
1313  } else
1314  return false;
1315 
1316  // Convert to X86 VINSERT immediate.
1317  Index = Index / InsertRegTy.getSizeInBits();
1318 
1319  I.getOperand(3).setImm(Index);
1320 
1321  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1322 }
1323 
1326  CodeGenCoverage &CoverageInfo) const {
1327  assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1328  "unexpected instruction");
1329 
1330  // Split to extracts.
1331  unsigned NumDefs = I.getNumOperands() - 1;
1332  unsigned SrcReg = I.getOperand(NumDefs).getReg();
1333  unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1334 
1335  for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1336  MachineInstr &ExtrInst =
1337  *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1338  TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1339  .addReg(SrcReg)
1340  .addImm(Idx * DefSize);
1341 
1342  if (!select(ExtrInst, CoverageInfo))
1343  return false;
1344  }
1345 
1346  I.eraseFromParent();
1347  return true;
1348 }
1349 
1352  CodeGenCoverage &CoverageInfo) const {
1353  assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1354  I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1355  "unexpected instruction");
1356 
1357  // Split to inserts.
1358  unsigned DstReg = I.getOperand(0).getReg();
1359  unsigned SrcReg0 = I.getOperand(1).getReg();
1360 
1361  const LLT DstTy = MRI.getType(DstReg);
1362  const LLT SrcTy = MRI.getType(SrcReg0);
1363  unsigned SrcSize = SrcTy.getSizeInBits();
1364 
1365  const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1366 
1367  // For the first src use insertSubReg.
1368  unsigned DefReg = MRI.createGenericVirtualRegister(DstTy);
1369  MRI.setRegBank(DefReg, RegBank);
1370  if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1371  return false;
1372 
1373  for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
1374  unsigned Tmp = MRI.createGenericVirtualRegister(DstTy);
1375  MRI.setRegBank(Tmp, RegBank);
1376 
1377  MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1378  TII.get(TargetOpcode::G_INSERT), Tmp)
1379  .addReg(DefReg)
1380  .addReg(I.getOperand(Idx).getReg())
1381  .addImm((Idx - 1) * SrcSize);
1382 
1383  DefReg = Tmp;
1384 
1385  if (!select(InsertInst, CoverageInfo))
1386  return false;
1387  }
1388 
1389  MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1390  TII.get(TargetOpcode::COPY), DstReg)
1391  .addReg(DefReg);
1392 
1393  if (!select(CopyInst, CoverageInfo))
1394  return false;
1395 
1396  I.eraseFromParent();
1397  return true;
1398 }
1399 
1400 bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1401  MachineRegisterInfo &MRI,
1402  MachineFunction &MF) const {
1403  assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
1404 
1405  const unsigned CondReg = I.getOperand(0).getReg();
1406  MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1407 
1408  MachineInstr &TestInst =
1409  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1410  .addReg(CondReg)
1411  .addImm(1);
1412  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
1413  .addMBB(DestMBB);
1414 
1415  constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1416 
1417  I.eraseFromParent();
1418  return true;
1419 }
1420 
1421 bool X86InstructionSelector::materializeFP(MachineInstr &I,
1422  MachineRegisterInfo &MRI,
1423  MachineFunction &MF) const {
1424  assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1425  "unexpected instruction");
1426 
1427  // Can't handle alternate code models yet.
1428  CodeModel::Model CM = TM.getCodeModel();
1429  if (CM != CodeModel::Small && CM != CodeModel::Large)
1430  return false;
1431 
1432  const unsigned DstReg = I.getOperand(0).getReg();
1433  const LLT DstTy = MRI.getType(DstReg);
1434  const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1435  unsigned Align = DstTy.getSizeInBits();
1436  const DebugLoc &DbgLoc = I.getDebugLoc();
1437 
1438  unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
1439 
1440  // Create the load from the constant pool.
1441  const ConstantFP *CFP = I.getOperand(1).getFPImm();
1442  unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
1443  MachineInstr *LoadInst = nullptr;
1444  unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1445 
1446  if (CM == CodeModel::Large && STI.is64Bit()) {
1447  // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1448  // they cannot be folded into immediate fields.
1449 
1450  unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1451  BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1452  .addConstantPoolIndex(CPI, 0, OpFlag);
1453 
1455  MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1457 
1458  LoadInst =
1459  addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1460  AddrReg)
1461  .addMemOperand(MMO);
1462 
1463  } else if (CM == CodeModel::Small || !STI.is64Bit()) {
1464  // Handle the case when globals fit in our immediate field.
1465  // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1466 
1467  // x86-32 PIC requires a PIC base register for constant pools.
1468  unsigned PICBase = 0;
1469  if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
1470  // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1471  // In DAGISEL the code that initialize it generated by the CGBR pass.
1472  return false; // TODO support the mode.
1473  } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
1474  PICBase = X86::RIP;
1475 
1476  LoadInst = addConstantPoolReference(
1477  BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1478  OpFlag);
1479  } else
1480  return false;
1481 
1482  constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
1483  I.eraseFromParent();
1484  return true;
1485 }
1486 
1487 bool X86InstructionSelector::selectImplicitDefOrPHI(
1488  MachineInstr &I, MachineRegisterInfo &MRI) const {
1489  assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1490  I.getOpcode() == TargetOpcode::G_PHI) &&
1491  "unexpected instruction");
1492 
1493  unsigned DstReg = I.getOperand(0).getReg();
1494 
1495  if (!MRI.getRegClassOrNull(DstReg)) {
1496  const LLT DstTy = MRI.getType(DstReg);
1497  const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1498 
1499  if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1500  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1501  << " operand\n");
1502  return false;
1503  }
1504  }
1505 
1506  if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1507  I.setDesc(TII.get(X86::IMPLICIT_DEF));
1508  else
1509  I.setDesc(TII.get(X86::PHI));
1510 
1511  return true;
1512 }
1513 
1514 // Currently GlobalIsel TableGen generates patterns for shift imm and shift 1,
1515 // but with shiftCount i8. In G_LSHR/G_ASHR/G_SHL like LLVM-IR both arguments
1516 // has the same type, so for now only shift i8 can use auto generated
1517 // TableGen patterns.
1518 bool X86InstructionSelector::selectShift(MachineInstr &I,
1519  MachineRegisterInfo &MRI,
1520  MachineFunction &MF) const {
1521 
1522  assert((I.getOpcode() == TargetOpcode::G_SHL ||
1523  I.getOpcode() == TargetOpcode::G_ASHR ||
1524  I.getOpcode() == TargetOpcode::G_LSHR) &&
1525  "unexpected instruction");
1526 
1527  unsigned DstReg = I.getOperand(0).getReg();
1528  const LLT DstTy = MRI.getType(DstReg);
1529  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1530 
1531  const static struct ShiftEntry {
1532  unsigned SizeInBits;
1533  unsigned CReg;
1534  unsigned OpLSHR;
1535  unsigned OpASHR;
1536  unsigned OpSHL;
1537  } OpTable[] = {
1538  {8, X86::CL, X86::SHR8rCL, X86::SAR8rCL, X86::SHL8rCL}, // i8
1539  {16, X86::CX, X86::SHR16rCL, X86::SAR16rCL, X86::SHL16rCL}, // i16
1540  {32, X86::ECX, X86::SHR32rCL, X86::SAR32rCL, X86::SHL32rCL}, // i32
1541  {64, X86::RCX, X86::SHR64rCL, X86::SAR64rCL, X86::SHL64rCL} // i64
1542  };
1543 
1544  if (DstRB.getID() != X86::GPRRegBankID)
1545  return false;
1546 
1547  auto ShiftEntryIt = std::find_if(
1548  std::begin(OpTable), std::end(OpTable), [DstTy](const ShiftEntry &El) {
1549  return El.SizeInBits == DstTy.getSizeInBits();
1550  });
1551  if (ShiftEntryIt == std::end(OpTable))
1552  return false;
1553 
1554  unsigned CReg = ShiftEntryIt->CReg;
1555  unsigned Opcode = 0;
1556  switch (I.getOpcode()) {
1557  case TargetOpcode::G_SHL:
1558  Opcode = ShiftEntryIt->OpSHL;
1559  break;
1560  case TargetOpcode::G_ASHR:
1561  Opcode = ShiftEntryIt->OpASHR;
1562  break;
1563  case TargetOpcode::G_LSHR:
1564  Opcode = ShiftEntryIt->OpLSHR;
1565  break;
1566  default:
1567  return false;
1568  }
1569 
1570  unsigned Op0Reg = I.getOperand(1).getReg();
1571  unsigned Op1Reg = I.getOperand(2).getReg();
1572 
1573  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1574  ShiftEntryIt->CReg)
1575  .addReg(Op1Reg);
1576 
1577  // The shift instruction uses X86::CL. If we defined a super-register
1578  // of X86::CL, emit a subreg KILL to precisely describe what we're doing here.
1579  if (CReg != X86::CL)
1581  X86::CL)
1582  .addReg(CReg, RegState::Kill);
1583 
1584  MachineInstr &ShiftInst =
1585  *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1586  .addReg(Op0Reg);
1587 
1588  constrainSelectedInstRegOperands(ShiftInst, TII, TRI, RBI);
1589  I.eraseFromParent();
1590  return true;
1591 }
1592 
1593 bool X86InstructionSelector::selectDivRem(MachineInstr &I,
1594  MachineRegisterInfo &MRI,
1595  MachineFunction &MF) const {
1596  // The implementation of this function is taken from X86FastISel.
1597  assert((I.getOpcode() == TargetOpcode::G_SDIV ||
1598  I.getOpcode() == TargetOpcode::G_SREM ||
1599  I.getOpcode() == TargetOpcode::G_UDIV ||
1600  I.getOpcode() == TargetOpcode::G_UREM) &&
1601  "unexpected instruction");
1602 
1603  const unsigned DstReg = I.getOperand(0).getReg();
1604  const unsigned Op1Reg = I.getOperand(1).getReg();
1605  const unsigned Op2Reg = I.getOperand(2).getReg();
1606 
1607  const LLT RegTy = MRI.getType(DstReg);
1608  assert(RegTy == MRI.getType(Op1Reg) && RegTy == MRI.getType(Op2Reg) &&
1609  "Arguments and return value types must match");
1610 
1611  const RegisterBank &RegRB = *RBI.getRegBank(DstReg, MRI, TRI);
1612  if (RegRB.getID() != X86::GPRRegBankID)
1613  return false;
1614 
1615  const static unsigned NumTypes = 4; // i8, i16, i32, i64
1616  const static unsigned NumOps = 4; // SDiv, SRem, UDiv, URem
1617  const static bool S = true; // IsSigned
1618  const static bool U = false; // !IsSigned
1619  const static unsigned Copy = TargetOpcode::COPY;
1620  // For the X86 IDIV instruction, in most cases the dividend
1621  // (numerator) must be in a specific register pair highreg:lowreg,
1622  // producing the quotient in lowreg and the remainder in highreg.
1623  // For most data types, to set up the instruction, the dividend is
1624  // copied into lowreg, and lowreg is sign-extended into highreg. The
1625  // exception is i8, where the dividend is defined as a single register rather
1626  // than a register pair, and we therefore directly sign-extend the dividend
1627  // into lowreg, instead of copying, and ignore the highreg.
1628  const static struct DivRemEntry {
1629  // The following portion depends only on the data type.
1630  unsigned SizeInBits;
1631  unsigned LowInReg; // low part of the register pair
1632  unsigned HighInReg; // high part of the register pair
1633  // The following portion depends on both the data type and the operation.
1634  struct DivRemResult {
1635  unsigned OpDivRem; // The specific DIV/IDIV opcode to use.
1636  unsigned OpSignExtend; // Opcode for sign-extending lowreg into
1637  // highreg, or copying a zero into highreg.
1638  unsigned OpCopy; // Opcode for copying dividend into lowreg, or
1639  // zero/sign-extending into lowreg for i8.
1640  unsigned DivRemResultReg; // Register containing the desired result.
1641  bool IsOpSigned; // Whether to use signed or unsigned form.
1642  } ResultTable[NumOps];
1643  } OpTable[NumTypes] = {
1644  {8,
1645  X86::AX,
1646  0,
1647  {
1648  {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S}, // SDiv
1649  {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S}, // SRem
1650  {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL, U}, // UDiv
1651  {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH, U}, // URem
1652  }}, // i8
1653  {16,
1654  X86::AX,
1655  X86::DX,
1656  {
1657  {X86::IDIV16r, X86::CWD, Copy, X86::AX, S}, // SDiv
1658  {X86::IDIV16r, X86::CWD, Copy, X86::DX, S}, // SRem
1659  {X86::DIV16r, X86::MOV32r0, Copy, X86::AX, U}, // UDiv
1660  {X86::DIV16r, X86::MOV32r0, Copy, X86::DX, U}, // URem
1661  }}, // i16
1662  {32,
1663  X86::EAX,
1664  X86::EDX,
1665  {
1666  {X86::IDIV32r, X86::CDQ, Copy, X86::EAX, S}, // SDiv
1667  {X86::IDIV32r, X86::CDQ, Copy, X86::EDX, S}, // SRem
1668  {X86::DIV32r, X86::MOV32r0, Copy, X86::EAX, U}, // UDiv
1669  {X86::DIV32r, X86::MOV32r0, Copy, X86::EDX, U}, // URem
1670  }}, // i32
1671  {64,
1672  X86::RAX,
1673  X86::RDX,
1674  {
1675  {X86::IDIV64r, X86::CQO, Copy, X86::RAX, S}, // SDiv
1676  {X86::IDIV64r, X86::CQO, Copy, X86::RDX, S}, // SRem
1677  {X86::DIV64r, X86::MOV32r0, Copy, X86::RAX, U}, // UDiv
1678  {X86::DIV64r, X86::MOV32r0, Copy, X86::RDX, U}, // URem
1679  }}, // i64
1680  };
1681 
1682  auto OpEntryIt = std::find_if(std::begin(OpTable), std::end(OpTable),
1683  [RegTy](const DivRemEntry &El) {
1684  return El.SizeInBits == RegTy.getSizeInBits();
1685  });
1686  if (OpEntryIt == std::end(OpTable))
1687  return false;
1688 
1689  unsigned OpIndex;
1690  switch (I.getOpcode()) {
1691  default:
1692  llvm_unreachable("Unexpected div/rem opcode");
1693  case TargetOpcode::G_SDIV:
1694  OpIndex = 0;
1695  break;
1696  case TargetOpcode::G_SREM:
1697  OpIndex = 1;
1698  break;
1699  case TargetOpcode::G_UDIV:
1700  OpIndex = 2;
1701  break;
1702  case TargetOpcode::G_UREM:
1703  OpIndex = 3;
1704  break;
1705  }
1706 
1707  const DivRemEntry &TypeEntry = *OpEntryIt;
1708  const DivRemEntry::DivRemResult &OpEntry = TypeEntry.ResultTable[OpIndex];
1709 
1710  const TargetRegisterClass *RegRC = getRegClass(RegTy, RegRB);
1711  if (!RBI.constrainGenericRegister(Op1Reg, *RegRC, MRI) ||
1712  !RBI.constrainGenericRegister(Op2Reg, *RegRC, MRI) ||
1713  !RBI.constrainGenericRegister(DstReg, *RegRC, MRI)) {
1714  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1715  << " operand\n");
1716  return false;
1717  }
1718 
1719  // Move op1 into low-order input register.
1720  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpEntry.OpCopy),
1721  TypeEntry.LowInReg)
1722  .addReg(Op1Reg);
1723  // Zero-extend or sign-extend into high-order input register.
1724  if (OpEntry.OpSignExtend) {
1725  if (OpEntry.IsOpSigned)
1726  BuildMI(*I.getParent(), I, I.getDebugLoc(),
1727  TII.get(OpEntry.OpSignExtend));
1728  else {
1729  unsigned Zero32 = MRI.createVirtualRegister(&X86::GR32RegClass);
1730  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::MOV32r0),
1731  Zero32);
1732 
1733  // Copy the zero into the appropriate sub/super/identical physical
1734  // register. Unfortunately the operations needed are not uniform enough
1735  // to fit neatly into the table above.
1736  if (RegTy.getSizeInBits() == 16) {
1737  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy),
1738  TypeEntry.HighInReg)
1739  .addReg(Zero32, 0, X86::sub_16bit);
1740  } else if (RegTy.getSizeInBits() == 32) {
1741  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy),
1742  TypeEntry.HighInReg)
1743  .addReg(Zero32);
1744  } else if (RegTy.getSizeInBits() == 64) {
1745  BuildMI(*I.getParent(), I, I.getDebugLoc(),
1746  TII.get(TargetOpcode::SUBREG_TO_REG), TypeEntry.HighInReg)
1747  .addImm(0)
1748  .addReg(Zero32)
1749  .addImm(X86::sub_32bit);
1750  }
1751  }
1752  }
1753  // Generate the DIV/IDIV instruction.
1754  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpEntry.OpDivRem))
1755  .addReg(Op2Reg);
1756  // For i8 remainder, we can't reference ah directly, as we'll end
1757  // up with bogus copies like %r9b = COPY %ah. Reference ax
1758  // instead to prevent ah references in a rex instruction.
1759  //
1760  // The current assumption of the fast register allocator is that isel
1761  // won't generate explicit references to the GR8_NOREX registers. If
1762  // the allocator and/or the backend get enhanced to be more robust in
1763  // that regard, this can be, and should be, removed.
1764  if ((I.getOpcode() == Instruction::SRem ||
1765  I.getOpcode() == Instruction::URem) &&
1766  OpEntry.DivRemResultReg == X86::AH && STI.is64Bit()) {
1767  unsigned SourceSuperReg = MRI.createVirtualRegister(&X86::GR16RegClass);
1768  unsigned ResultSuperReg = MRI.createVirtualRegister(&X86::GR16RegClass);
1769  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy), SourceSuperReg)
1770  .addReg(X86::AX);
1771 
1772  // Shift AX right by 8 bits instead of using AH.
1773  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::SHR16ri),
1774  ResultSuperReg)
1775  .addReg(SourceSuperReg)
1776  .addImm(8);
1777 
1778  // Now reference the 8-bit subreg of the result.
1779  BuildMI(*I.getParent(), I, I.getDebugLoc(),
1780  TII.get(TargetOpcode::SUBREG_TO_REG))
1781  .addDef(DstReg)
1782  .addImm(0)
1783  .addReg(ResultSuperReg)
1784  .addImm(X86::sub_8bit);
1785  } else {
1786  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1787  DstReg)
1788  .addReg(OpEntry.DivRemResultReg);
1789  }
1790  I.eraseFromParent();
1791  return true;
1792 }
1793 
1794 bool X86InstructionSelector::selectIntrinsicWSideEffects(
1795  MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const {
1796 
1797  assert(I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS &&
1798  "unexpected instruction");
1799 
1800  if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1801  return false;
1802 
1803  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TRAP));
1804 
1805  I.eraseFromParent();
1806  return true;
1807 }
1808 
1811  X86Subtarget &Subtarget,
1812  X86RegisterBankInfo &RBI) {
1813  return new X86InstructionSelector(TM, Subtarget, RBI);
1814 }
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:259
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:632
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
MachineBasicBlock * getMBB() const
Atomic ordering constants.
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
static const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, unsigned GlobalBaseReg, unsigned char OpFlags)
addConstantPoolReference - This function is used to add a reference to the base of a constant value s...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
unsigned getReg() const
getReg - Returns the register number.
enum llvm::X86AddressMode::@489 BaseType
unsigned Reg
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
const GlobalValue * GV
An instruction for reading from memory.
Definition: Instructions.h:168
void setRegBank(unsigned Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static const TargetRegisterClass * getRegClassFromGRPhysReg(unsigned Reg)
return AArch64::GPR64RegClass contains(Reg)
#define DEBUG_TYPE
bool isVector() const
A description of a memory reference used in the backend.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
const HexagonInstrInfo * TII
const ConstantFP * getFPImm() const
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:412
This class provides the information for the target register banks.
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
Definition: X86InstrInfo.h:113
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
static StringRef getName(Value *V)
static int getRegClass(RegisterKind Is, unsigned RegWidth)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
Definition: X86InstrInfo.h:130
static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC, const TargetRegisterClass *SrcRC)
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
std::pair< CondCode, bool > getX86ConditionCode(CmpInst::Predicate Predicate)
Return a pair of condition code for the given predicate and whether the instruction operands should b...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:149
unsigned const MachineRegisterInfo * MRI
#define GET_GLOBALISEL_PREDICATES_INIT
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size FIXME: The defaults need to be removed once all of the backends/clients are updat...
Definition: DataLayout.cpp:629
const GlobalValue * getGlobal() const
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:642
int64_t addOffset(int64_t LHS, int64_t RHS)
void substPhysReg(unsigned Reg, const TargetRegisterInfo &)
substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...
void setImm(int64_t immVal)
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:760
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1208
static void X86SelectAddress(const MachineInstr &I, const MachineRegisterInfo &MRI, X86AddressMode &AM)
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
unsigned getSETFromCond(CondCode CC, bool HasMemoryOperand=false)
Return a set opcode for the given condition and whether it has a memory operand.
bool isCopy() const
bool isImplicitDef() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
This file declares the targeting of the RegisterBankInfo class for X86.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:309
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:534
MachineOperand class - Representation of each machine instruction operand.
Intrinsic::ID getIntrinsicID() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:27
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) 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:88
InstructionSelector * createX86InstructionSelector(const X86TargetMachine &TM, X86Subtarget &, X86RegisterBankInfo &)
This class implements the register bank concept.
Definition: RegisterBank.h:29
int64_t getImm() const
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
Definition: X86Subtarget.h:535
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:941
union llvm::X86AddressMode::@490 Base
Optional< int64_t > getConstantVRegVal(unsigned VReg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:185
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
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.
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
Definition: X86BaseInfo.h:102
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – t...
static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
#define I(x, y, z)
Definition: MD5.cpp:58
void setSubReg(unsigned subReg)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
#define GET_GLOBALISEL_TEMPORARIES_INIT
const TargetRegisterClass * getRegClassOrNull(unsigned Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet...
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:31
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
Definition: X86BaseInfo.h:88
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
X86AddressMode - This struct holds a generalized full x86 address mode.
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
#define LLVM_DEBUG(X)
Definition: Debug.h:123
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
const ConstantInt * getCImm() const
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:48
unsigned getPredicate() const