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