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
15 #include "MCTargetDesc/X86BaseInfo.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"
22 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
23 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
24 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
25 #include "llvm/CodeGen/GlobalISel/Utils.h"
26 #include "llvm/CodeGen/MachineBasicBlock.h"
27 #include "llvm/CodeGen/MachineConstantPool.h"
28 #include "llvm/CodeGen/MachineFunction.h"
29 #include "llvm/CodeGen/MachineInstr.h"
30 #include "llvm/CodeGen/MachineInstrBuilder.h"
31 #include "llvm/CodeGen/MachineMemOperand.h"
32 #include "llvm/CodeGen/MachineOperand.h"
33 #include "llvm/CodeGen/MachineRegisterInfo.h"
34 #include "llvm/CodeGen/TargetOpcodes.h"
35 #include "llvm/CodeGen/TargetRegisterInfo.h"
36 #include "llvm/IR/DataLayout.h"
37 #include "llvm/IR/InstrTypes.h"
38 #include "llvm/Support/AtomicOrdering.h"
39 #include "llvm/Support/CodeGen.h"
40 #include "llvm/Support/Debug.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include "llvm/Support/LowLevelTypeImpl.h"
43 #include "llvm/Support/MathExtras.h"
44 #include "llvm/Support/raw_ostream.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;
getName()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 selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
93 MachineFunction &MF) const;
94 bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
95 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
96 MachineFunction &MF,
97 CodeGenCoverage &CoverageInfo) const;
98 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
99 MachineFunction &MF,
100 CodeGenCoverage &CoverageInfo) const;
101 bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
102 MachineFunction &MF) const;
103 bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
104 MachineFunction &MF) const;
105 bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
106 MachineFunction &MF) const;
107 bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
108 const unsigned DstReg,
109 const TargetRegisterClass *DstRC,
110 const unsigned SrcReg,
111 const TargetRegisterClass *SrcRC) const;
112 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
113 MachineFunction &MF) const;
114 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
115 bool selectShift(MachineInstr &I, MachineRegisterInfo &MRI,
116 MachineFunction &MF) const;
117 bool selectSDiv(MachineInstr &I, MachineRegisterInfo &MRI,
118 MachineFunction &MF) const;
119
120 // emit insert subreg instruction and insert it before MachineInstr &I
121 bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
122 MachineRegisterInfo &MRI, MachineFunction &MF) const;
123 // emit extract subreg instruction and insert it before MachineInstr &I
124 bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
125 MachineRegisterInfo &MRI, MachineFunction &MF) const;
126
127 const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
128 const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
129 MachineRegisterInfo &MRI) const;
130
131 const X86TargetMachine &TM;
132 const X86Subtarget &STI;
133 const X86InstrInfo &TII;
134 const X86RegisterInfo &TRI;
135 const X86RegisterBankInfo &RBI;
136
137 #define GET_GLOBALISEL_PREDICATES_DECL
138 #include "X86GenGlobalISel.inc"
139 #undef GET_GLOBALISEL_PREDICATES_DECL
140
141 #define GET_GLOBALISEL_TEMPORARIES_DECL
142 #include "X86GenGlobalISel.inc"
143 #undef GET_GLOBALISEL_TEMPORARIES_DECL
144 };
145
146 } // end anonymous namespace
147
148 #define GET_GLOBALISEL_IMPL
149 #include "X86GenGlobalISel.inc"
150 #undef GET_GLOBALISEL_IMPL
151
X86InstructionSelector(const X86TargetMachine & TM,const X86Subtarget & STI,const X86RegisterBankInfo & RBI)152 X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
153 const X86Subtarget &STI,
154 const X86RegisterBankInfo &RBI)
155 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
156 TRI(*STI.getRegisterInfo()), RBI(RBI),
157 #define GET_GLOBALISEL_PREDICATES_INIT
158 #include "X86GenGlobalISel.inc"
159 #undef GET_GLOBALISEL_PREDICATES_INIT
160 #define GET_GLOBALISEL_TEMPORARIES_INIT
161 #include "X86GenGlobalISel.inc"
162 #undef GET_GLOBALISEL_TEMPORARIES_INIT
163 {
164 }
165
166 // FIXME: This should be target-independent, inferred from the types declared
167 // for each class in the bank.
168 const TargetRegisterClass *
getRegClass(LLT Ty,const RegisterBank & RB) const169 X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
170 if (RB.getID() == X86::GPRRegBankID) {
171 if (Ty.getSizeInBits() <= 8)
172 return &X86::GR8RegClass;
173 if (Ty.getSizeInBits() == 16)
174 return &X86::GR16RegClass;
175 if (Ty.getSizeInBits() == 32)
176 return &X86::GR32RegClass;
177 if (Ty.getSizeInBits() == 64)
178 return &X86::GR64RegClass;
179 }
180 if (RB.getID() == X86::VECRRegBankID) {
181 if (Ty.getSizeInBits() == 32)
182 return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
183 if (Ty.getSizeInBits() == 64)
184 return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
185 if (Ty.getSizeInBits() == 128)
186 return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
187 if (Ty.getSizeInBits() == 256)
188 return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
189 if (Ty.getSizeInBits() == 512)
190 return &X86::VR512RegClass;
191 }
192
193 llvm_unreachable("Unknown RegBank!");
194 }
195
196 const TargetRegisterClass *
getRegClass(LLT Ty,unsigned Reg,MachineRegisterInfo & MRI) const197 X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg,
198 MachineRegisterInfo &MRI) const {
199 const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
200 return getRegClass(Ty, RegBank);
201 }
202
getSubRegIndex(const TargetRegisterClass * RC)203 static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
204 unsigned SubIdx = X86::NoSubRegister;
205 if (RC == &X86::GR32RegClass) {
206 SubIdx = X86::sub_32bit;
207 } else if (RC == &X86::GR16RegClass) {
208 SubIdx = X86::sub_16bit;
209 } else if (RC == &X86::GR8RegClass) {
210 SubIdx = X86::sub_8bit;
211 }
212
213 return SubIdx;
214 }
215
getRegClassFromGRPhysReg(unsigned Reg)216 static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) {
217 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
218 if (X86::GR64RegClass.contains(Reg))
219 return &X86::GR64RegClass;
220 if (X86::GR32RegClass.contains(Reg))
221 return &X86::GR32RegClass;
222 if (X86::GR16RegClass.contains(Reg))
223 return &X86::GR16RegClass;
224 if (X86::GR8RegClass.contains(Reg))
225 return &X86::GR8RegClass;
226
227 llvm_unreachable("Unknown RegClass for PhysReg!");
228 }
229
230 // Set X86 Opcode and constrain DestReg.
selectCopy(MachineInstr & I,MachineRegisterInfo & MRI) const231 bool X86InstructionSelector::selectCopy(MachineInstr &I,
232 MachineRegisterInfo &MRI) const {
233 unsigned DstReg = I.getOperand(0).getReg();
234 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
235 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
236
237 unsigned SrcReg = I.getOperand(1).getReg();
238 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
239 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
240
241 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
242 assert(I.isCopy() && "Generic operators do not allow physical registers");
243
244 if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
245 DstRegBank.getID() == X86::GPRRegBankID) {
246
247 const TargetRegisterClass *SrcRC =
248 getRegClass(MRI.getType(SrcReg), SrcRegBank);
249 const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
250
251 if (SrcRC != DstRC) {
252 // This case can be generated by ABI lowering, performe anyext
253 unsigned ExtSrc = MRI.createVirtualRegister(DstRC);
254 BuildMI(*I.getParent(), I, I.getDebugLoc(),
255 TII.get(TargetOpcode::SUBREG_TO_REG))
256 .addDef(ExtSrc)
257 .addImm(0)
258 .addReg(SrcReg)
259 .addImm(getSubRegIndex(SrcRC));
260
261 I.getOperand(1).setReg(ExtSrc);
262 }
263 }
264
265 return true;
266 }
267
268 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
269 "No phys reg on generic operators");
270 assert((DstSize == SrcSize ||
271 // Copies are a mean to setup initial types, the number of
272 // bits may not exactly match.
273 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
274 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
275 "Copy with different width?!");
276
277 const TargetRegisterClass *DstRC =
278 getRegClass(MRI.getType(DstReg), DstRegBank);
279
280 if (SrcRegBank.getID() == X86::GPRRegBankID &&
281 DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
282 TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
283 // Change the physical register to performe truncate.
284
285 const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
286
287 if (DstRC != SrcRC) {
288 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
289 I.getOperand(1).substPhysReg(SrcReg, TRI);
290 }
291 }
292
293 // No need to constrain SrcReg. It will get constrained when
294 // we hit another of its use or its defs.
295 // Copies do not have constraints.
296 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
297 if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
298 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
299 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
300 << " operand\n");
301 return false;
302 }
303 }
304 I.setDesc(TII.get(X86::COPY));
305 return true;
306 }
307
select(MachineInstr & I,CodeGenCoverage & CoverageInfo) const308 bool X86InstructionSelector::select(MachineInstr &I,
309 CodeGenCoverage &CoverageInfo) const {
310 assert(I.getParent() && "Instruction should be in a basic block!");
311 assert(I.getParent()->getParent() && "Instruction should be in a function!");
312
313 MachineBasicBlock &MBB = *I.getParent();
314 MachineFunction &MF = *MBB.getParent();
315 MachineRegisterInfo &MRI = MF.getRegInfo();
316
317 unsigned Opcode = I.getOpcode();
318 if (!isPreISelGenericOpcode(Opcode)) {
319 // Certain non-generic instructions also need some special handling.
320
321 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
322 return false;
323
324 if (I.isCopy())
325 return selectCopy(I, MRI);
326
327 return true;
328 }
329
330 assert(I.getNumOperands() == I.getNumExplicitOperands() &&
331 "Generic instruction has unexpected implicit operands\n");
332
333 if (selectImpl(I, CoverageInfo))
334 return true;
335
336 LLVM_DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
337
338 // TODO: This should be implemented by tblgen.
339 switch (I.getOpcode()) {
340 default:
341 return false;
342 case TargetOpcode::G_STORE:
343 case TargetOpcode::G_LOAD:
344 return selectLoadStoreOp(I, MRI, MF);
345 case TargetOpcode::G_GEP:
346 case TargetOpcode::G_FRAME_INDEX:
347 return selectFrameIndexOrGep(I, MRI, MF);
348 case TargetOpcode::G_GLOBAL_VALUE:
349 return selectGlobalValue(I, MRI, MF);
350 case TargetOpcode::G_CONSTANT:
351 return selectConstant(I, MRI, MF);
352 case TargetOpcode::G_FCONSTANT:
353 return materializeFP(I, MRI, MF);
354 case TargetOpcode::G_PTRTOINT:
355 case TargetOpcode::G_TRUNC:
356 return selectTruncOrPtrToInt(I, MRI, MF);
357 case TargetOpcode::G_INTTOPTR:
358 return selectCopy(I, MRI);
359 case TargetOpcode::G_ZEXT:
360 return selectZext(I, MRI, MF);
361 case TargetOpcode::G_ANYEXT:
362 return selectAnyext(I, MRI, MF);
363 case TargetOpcode::G_ICMP:
364 return selectCmp(I, MRI, MF);
365 case TargetOpcode::G_UADDE:
366 return selectUadde(I, MRI, MF);
367 case TargetOpcode::G_UNMERGE_VALUES:
368 return selectUnmergeValues(I, MRI, MF, CoverageInfo);
369 case TargetOpcode::G_MERGE_VALUES:
370 return selectMergeValues(I, MRI, MF, CoverageInfo);
371 case TargetOpcode::G_EXTRACT:
372 return selectExtract(I, MRI, MF);
373 case TargetOpcode::G_INSERT:
374 return selectInsert(I, MRI, MF);
375 case TargetOpcode::G_BRCOND:
376 return selectCondBranch(I, MRI, MF);
377 case TargetOpcode::G_IMPLICIT_DEF:
378 case TargetOpcode::G_PHI:
379 return selectImplicitDefOrPHI(I, MRI);
380 case TargetOpcode::G_SHL:
381 case TargetOpcode::G_ASHR:
382 case TargetOpcode::G_LSHR:
383 return selectShift(I, MRI, MF);
384 case TargetOpcode::G_SDIV:
385 return selectSDiv(I, MRI, MF);
386 }
387
388 return false;
389 }
390
getLoadStoreOp(const LLT & Ty,const RegisterBank & RB,unsigned Opc,uint64_t Alignment) const391 unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
392 const RegisterBank &RB,
393 unsigned Opc,
394 uint64_t Alignment) const {
395 bool Isload = (Opc == TargetOpcode::G_LOAD);
396 bool HasAVX = STI.hasAVX();
397 bool HasAVX512 = STI.hasAVX512();
398 bool HasVLX = STI.hasVLX();
399
400 if (Ty == LLT::scalar(8)) {
401 if (X86::GPRRegBankID == RB.getID())
402 return Isload ? X86::MOV8rm : X86::MOV8mr;
403 } else if (Ty == LLT::scalar(16)) {
404 if (X86::GPRRegBankID == RB.getID())
405 return Isload ? X86::MOV16rm : X86::MOV16mr;
406 } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
407 if (X86::GPRRegBankID == RB.getID())
408 return Isload ? X86::MOV32rm : X86::MOV32mr;
409 if (X86::VECRRegBankID == RB.getID())
410 return Isload ? (HasAVX512 ? X86::VMOVSSZrm
411 : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
412 : (HasAVX512 ? X86::VMOVSSZmr
413 : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
414 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
415 if (X86::GPRRegBankID == RB.getID())
416 return Isload ? X86::MOV64rm : X86::MOV64mr;
417 if (X86::VECRRegBankID == RB.getID())
418 return Isload ? (HasAVX512 ? X86::VMOVSDZrm
419 : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm)
420 : (HasAVX512 ? X86::VMOVSDZmr
421 : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr);
422 } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
423 if (Alignment >= 16)
424 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
425 : HasAVX512
426 ? X86::VMOVAPSZ128rm_NOVLX
427 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
428 : (HasVLX ? X86::VMOVAPSZ128mr
429 : HasAVX512
430 ? X86::VMOVAPSZ128mr_NOVLX
431 : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
432 else
433 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
434 : HasAVX512
435 ? X86::VMOVUPSZ128rm_NOVLX
436 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
437 : (HasVLX ? X86::VMOVUPSZ128mr
438 : HasAVX512
439 ? X86::VMOVUPSZ128mr_NOVLX
440 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
441 } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
442 if (Alignment >= 32)
443 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
444 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
445 : X86::VMOVAPSYrm)
446 : (HasVLX ? X86::VMOVAPSZ256mr
447 : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
448 : X86::VMOVAPSYmr);
449 else
450 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
451 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
452 : X86::VMOVUPSYrm)
453 : (HasVLX ? X86::VMOVUPSZ256mr
454 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
455 : X86::VMOVUPSYmr);
456 } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
457 if (Alignment >= 64)
458 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
459 else
460 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
461 }
462 return Opc;
463 }
464
465 // Fill in an address from the given instruction.
X86SelectAddress(const MachineInstr & I,const MachineRegisterInfo & MRI,X86AddressMode & AM)466 static void X86SelectAddress(const MachineInstr &I,
467 const MachineRegisterInfo &MRI,
468 X86AddressMode &AM) {
469 assert(I.getOperand(0).isReg() && "unsupported opperand.");
470 assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
471 "unsupported type.");
472
473 if (I.getOpcode() == TargetOpcode::G_GEP) {
474 if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) {
475 int64_t Imm = *COff;
476 if (isInt<32>(Imm)) { // Check for displacement overflow.
477 AM.Disp = static_cast<int32_t>(Imm);
478 AM.Base.Reg = I.getOperand(1).getReg();
479 return;
480 }
481 }
482 } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) {
483 AM.Base.FrameIndex = I.getOperand(1).getIndex();
484 AM.BaseType = X86AddressMode::FrameIndexBase;
485 return;
486 }
487
488 // Default behavior.
489 AM.Base.Reg = I.getOperand(0).getReg();
490 }
491
selectLoadStoreOp(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const492 bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
493 MachineRegisterInfo &MRI,
494 MachineFunction &MF) const {
495 unsigned Opc = I.getOpcode();
496
497 assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
498 "unexpected instruction");
499
500 const unsigned DefReg = I.getOperand(0).getReg();
501 LLT Ty = MRI.getType(DefReg);
502 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
503
504 auto &MemOp = **I.memoperands_begin();
505 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
506 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
507 return false;
508 }
509
510 unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
511 if (NewOpc == Opc)
512 return false;
513
514 X86AddressMode AM;
515 X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM);
516
517 I.setDesc(TII.get(NewOpc));
518 MachineInstrBuilder MIB(MF, I);
519 if (Opc == TargetOpcode::G_LOAD) {
520 I.RemoveOperand(1);
521 addFullAddress(MIB, AM);
522 } else {
523 // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
524 I.RemoveOperand(1);
525 I.RemoveOperand(0);
526 addFullAddress(MIB, AM).addUse(DefReg);
527 }
528 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
529 }
530
getLeaOP(LLT Ty,const X86Subtarget & STI)531 static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
532 if (Ty == LLT::pointer(0, 64))
533 return X86::LEA64r;
534 else if (Ty == LLT::pointer(0, 32))
535 return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
536 else
537 llvm_unreachable("Can't get LEA opcode. Unsupported type.");
538 }
539
selectFrameIndexOrGep(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const540 bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
541 MachineRegisterInfo &MRI,
542 MachineFunction &MF) const {
543 unsigned Opc = I.getOpcode();
544
545 assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) &&
546 "unexpected instruction");
547
548 const unsigned DefReg = I.getOperand(0).getReg();
549 LLT Ty = MRI.getType(DefReg);
550
551 // Use LEA to calculate frame index and GEP
552 unsigned NewOpc = getLeaOP(Ty, STI);
553 I.setDesc(TII.get(NewOpc));
554 MachineInstrBuilder MIB(MF, I);
555
556 if (Opc == TargetOpcode::G_FRAME_INDEX) {
557 addOffset(MIB, 0);
558 } else {
559 MachineOperand &InxOp = I.getOperand(2);
560 I.addOperand(InxOp); // set IndexReg
561 InxOp.ChangeToImmediate(1); // set Scale
562 MIB.addImm(0).addReg(0);
563 }
564
565 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
566 }
567
selectGlobalValue(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const568 bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
569 MachineRegisterInfo &MRI,
570 MachineFunction &MF) const {
571 assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
572 "unexpected instruction");
573
574 auto GV = I.getOperand(1).getGlobal();
575 if (GV->isThreadLocal()) {
576 return false; // TODO: we don't support TLS yet.
577 }
578
579 // Can't handle alternate code models yet.
580 if (TM.getCodeModel() != CodeModel::Small)
581 return false;
582
583 X86AddressMode AM;
584 AM.GV = GV;
585 AM.GVOpFlags = STI.classifyGlobalReference(GV);
586
587 // TODO: The ABI requires an extra load. not supported yet.
588 if (isGlobalStubReference(AM.GVOpFlags))
589 return false;
590
591 // TODO: This reference is relative to the pic base. not supported yet.
592 if (isGlobalRelativeToPICBase(AM.GVOpFlags))
593 return false;
594
595 if (STI.isPICStyleRIPRel()) {
596 // Use rip-relative addressing.
597 assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
598 AM.Base.Reg = X86::RIP;
599 }
600
601 const unsigned DefReg = I.getOperand(0).getReg();
602 LLT Ty = MRI.getType(DefReg);
603 unsigned NewOpc = getLeaOP(Ty, STI);
604
605 I.setDesc(TII.get(NewOpc));
606 MachineInstrBuilder MIB(MF, I);
607
608 I.RemoveOperand(1);
609 addFullAddress(MIB, AM);
610
611 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
612 }
613
selectConstant(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const614 bool X86InstructionSelector::selectConstant(MachineInstr &I,
615 MachineRegisterInfo &MRI,
616 MachineFunction &MF) const {
617 assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
618 "unexpected instruction");
619
620 const unsigned DefReg = I.getOperand(0).getReg();
621 LLT Ty = MRI.getType(DefReg);
622
623 if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
624 return false;
625
626 uint64_t Val = 0;
627 if (I.getOperand(1).isCImm()) {
628 Val = I.getOperand(1).getCImm()->getZExtValue();
629 I.getOperand(1).ChangeToImmediate(Val);
630 } else if (I.getOperand(1).isImm()) {
631 Val = I.getOperand(1).getImm();
632 } else
633 llvm_unreachable("Unsupported operand type.");
634
635 unsigned NewOpc;
636 switch (Ty.getSizeInBits()) {
637 case 8:
638 NewOpc = X86::MOV8ri;
639 break;
640 case 16:
641 NewOpc = X86::MOV16ri;
642 break;
643 case 32:
644 NewOpc = X86::MOV32ri;
645 break;
646 case 64:
647 // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
648 if (isInt<32>(Val))
649 NewOpc = X86::MOV64ri32;
650 else
651 NewOpc = X86::MOV64ri;
652 break;
653 default:
654 llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
655 }
656
657 I.setDesc(TII.get(NewOpc));
658 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
659 }
660
661 // Helper function for selectTruncOrPtrToInt and selectAnyext.
662 // Returns true if DstRC lives on a floating register class and
663 // SrcRC lives on a 128-bit vector class.
canTurnIntoCOPY(const TargetRegisterClass * DstRC,const TargetRegisterClass * SrcRC)664 static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC,
665 const TargetRegisterClass *SrcRC) {
666 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
667 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
668 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
669 }
670
selectTurnIntoCOPY(MachineInstr & I,MachineRegisterInfo & MRI,const unsigned DstReg,const TargetRegisterClass * DstRC,const unsigned SrcReg,const TargetRegisterClass * SrcRC) const671 bool X86InstructionSelector::selectTurnIntoCOPY(
672 MachineInstr &I, MachineRegisterInfo &MRI, const unsigned DstReg,
673 const TargetRegisterClass *DstRC, const unsigned SrcReg,
674 const TargetRegisterClass *SrcRC) const {
675
676 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
677 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
678 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
679 << " operand\n");
680 return false;
681 }
682 I.setDesc(TII.get(X86::COPY));
683 return true;
684 }
685
selectTruncOrPtrToInt(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const686 bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
687 MachineRegisterInfo &MRI,
688 MachineFunction &MF) const {
689 assert((I.getOpcode() == TargetOpcode::G_TRUNC ||
690 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
691 "unexpected instruction");
692
693 const unsigned DstReg = I.getOperand(0).getReg();
694 const unsigned SrcReg = I.getOperand(1).getReg();
695
696 const LLT DstTy = MRI.getType(DstReg);
697 const LLT SrcTy = MRI.getType(SrcReg);
698
699 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
700 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
701
702 if (DstRB.getID() != SrcRB.getID()) {
703 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode())
704 << " input/output on different banks\n");
705 return false;
706 }
707
708 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
709 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
710
711 if (!DstRC || !SrcRC)
712 return false;
713
714 // If that's truncation of the value that lives on the vector class and goes
715 // into the floating class, just replace it with copy, as we are able to
716 // select it as a regular move.
717 if (canTurnIntoCOPY(DstRC, SrcRC))
718 return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
719
720 if (DstRB.getID() != X86::GPRRegBankID)
721 return false;
722
723 unsigned SubIdx;
724 if (DstRC == SrcRC) {
725 // Nothing to be done
726 SubIdx = X86::NoSubRegister;
727 } else if (DstRC == &X86::GR32RegClass) {
728 SubIdx = X86::sub_32bit;
729 } else if (DstRC == &X86::GR16RegClass) {
730 SubIdx = X86::sub_16bit;
731 } else if (DstRC == &X86::GR8RegClass) {
732 SubIdx = X86::sub_8bit;
733 } else {
734 return false;
735 }
736
737 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
738
739 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
740 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
741 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
742 << "\n");
743 return false;
744 }
745
746 I.getOperand(1).setSubReg(SubIdx);
747
748 I.setDesc(TII.get(X86::COPY));
749 return true;
750 }
751
selectZext(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const752 bool X86InstructionSelector::selectZext(MachineInstr &I,
753 MachineRegisterInfo &MRI,
754 MachineFunction &MF) const {
755 assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
756
757 const unsigned DstReg = I.getOperand(0).getReg();
758 const unsigned SrcReg = I.getOperand(1).getReg();
759
760 const LLT DstTy = MRI.getType(DstReg);
761 const LLT SrcTy = MRI.getType(SrcReg);
762
763 assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(32)) &&
764 "8=>32 Zext is handled by tablegen");
765 assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(32)) &&
766 "16=>32 Zext is handled by tablegen");
767
768 const static struct ZextEntry {
769 LLT SrcTy;
770 LLT DstTy;
771 unsigned MovOp;
772 bool NeedSubregToReg;
773 } OpTable[] = {
774 {LLT::scalar(8), LLT::scalar(16), X86::MOVZX16rr8, false}, // i8 => i16
775 {LLT::scalar(8), LLT::scalar(64), X86::MOVZX32rr8, true}, // i8 => i64
776 {LLT::scalar(16), LLT::scalar(64), X86::MOVZX32rr16, true}, // i16 => i64
777 {LLT::scalar(32), LLT::scalar(64), 0, true} // i32 => i64
778 };
779
780 auto ZextEntryIt =
781 std::find_if(std::begin(OpTable), std::end(OpTable),
782 [SrcTy, DstTy](const ZextEntry &El) {
783 return El.DstTy == DstTy && El.SrcTy == SrcTy;
784 });
785
786 // Here we try to select Zext into a MOVZ and/or SUBREG_TO_REG instruction.
787 if (ZextEntryIt != std::end(OpTable)) {
788 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
789 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
790 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
791 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
792
793 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
794 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
795 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
796 << " operand\n");
797 return false;
798 }
799
800 unsigned TransitRegTo = DstReg;
801 unsigned TransitRegFrom = SrcReg;
802 if (ZextEntryIt->MovOp) {
803 // If we select Zext into MOVZ + SUBREG_TO_REG, we need to have
804 // a transit register in between: create it here.
805 if (ZextEntryIt->NeedSubregToReg) {
806 TransitRegFrom = MRI.createVirtualRegister(
807 getRegClass(LLT::scalar(32), DstReg, MRI));
808 TransitRegTo = TransitRegFrom;
809 }
810
811 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ZextEntryIt->MovOp))
812 .addDef(TransitRegTo)
813 .addReg(SrcReg);
814 }
815 if (ZextEntryIt->NeedSubregToReg) {
816 BuildMI(*I.getParent(), I, I.getDebugLoc(),
817 TII.get(TargetOpcode::SUBREG_TO_REG))
818 .addDef(DstReg)
819 .addImm(0)
820 .addReg(TransitRegFrom)
821 .addImm(X86::sub_32bit);
822 }
823 I.eraseFromParent();
824 return true;
825 }
826
827 if (SrcTy != LLT::scalar(1))
828 return false;
829
830 unsigned AndOpc;
831 if (DstTy == LLT::scalar(8))
832 AndOpc = X86::AND8ri;
833 else if (DstTy == LLT::scalar(16))
834 AndOpc = X86::AND16ri8;
835 else if (DstTy == LLT::scalar(32))
836 AndOpc = X86::AND32ri8;
837 else if (DstTy == LLT::scalar(64))
838 AndOpc = X86::AND64ri8;
839 else
840 return false;
841
842 unsigned DefReg = SrcReg;
843 if (DstTy != LLT::scalar(8)) {
844 DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
845 BuildMI(*I.getParent(), I, I.getDebugLoc(),
846 TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
847 .addImm(0)
848 .addReg(SrcReg)
849 .addImm(X86::sub_8bit);
850 }
851
852 MachineInstr &AndInst =
853 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
854 .addReg(DefReg)
855 .addImm(1);
856
857 constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
858
859 I.eraseFromParent();
860 return true;
861 }
862
selectAnyext(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const863 bool X86InstructionSelector::selectAnyext(MachineInstr &I,
864 MachineRegisterInfo &MRI,
865 MachineFunction &MF) const {
866 assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
867
868 const unsigned DstReg = I.getOperand(0).getReg();
869 const unsigned SrcReg = I.getOperand(1).getReg();
870
871 const LLT DstTy = MRI.getType(DstReg);
872 const LLT SrcTy = MRI.getType(SrcReg);
873
874 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
875 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
876
877 assert(DstRB.getID() == SrcRB.getID() &&
878 "G_ANYEXT input/output on different banks\n");
879
880 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
881 "G_ANYEXT incorrect operand size");
882
883 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
884 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
885
886 // If that's ANY_EXT of the value that lives on the floating class and goes
887 // into the vector class, just replace it with copy, as we are able to select
888 // it as a regular move.
889 if (canTurnIntoCOPY(SrcRC, DstRC))
890 return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC);
891
892 if (DstRB.getID() != X86::GPRRegBankID)
893 return false;
894
895 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
896 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
897 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
898 << " operand\n");
899 return false;
900 }
901
902 if (SrcRC == DstRC) {
903 I.setDesc(TII.get(X86::COPY));
904 return true;
905 }
906
907 BuildMI(*I.getParent(), I, I.getDebugLoc(),
908 TII.get(TargetOpcode::SUBREG_TO_REG))
909 .addDef(DstReg)
910 .addImm(0)
911 .addReg(SrcReg)
912 .addImm(getSubRegIndex(SrcRC));
913
914 I.eraseFromParent();
915 return true;
916 }
917
selectCmp(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const918 bool X86InstructionSelector::selectCmp(MachineInstr &I,
919 MachineRegisterInfo &MRI,
920 MachineFunction &MF) const {
921 assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
922
923 X86::CondCode CC;
924 bool SwapArgs;
925 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
926 (CmpInst::Predicate)I.getOperand(1).getPredicate());
927 unsigned OpSet = X86::getSETFromCond(CC);
928
929 unsigned LHS = I.getOperand(2).getReg();
930 unsigned RHS = I.getOperand(3).getReg();
931
932 if (SwapArgs)
933 std::swap(LHS, RHS);
934
935 unsigned OpCmp;
936 LLT Ty = MRI.getType(LHS);
937
938 switch (Ty.getSizeInBits()) {
939 default:
940 return false;
941 case 8:
942 OpCmp = X86::CMP8rr;
943 break;
944 case 16:
945 OpCmp = X86::CMP16rr;
946 break;
947 case 32:
948 OpCmp = X86::CMP32rr;
949 break;
950 case 64:
951 OpCmp = X86::CMP64rr;
952 break;
953 }
954
955 MachineInstr &CmpInst =
956 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
957 .addReg(LHS)
958 .addReg(RHS);
959
960 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
961 TII.get(OpSet), I.getOperand(0).getReg());
962
963 constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
964 constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
965
966 I.eraseFromParent();
967 return true;
968 }
969
selectUadde(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const970 bool X86InstructionSelector::selectUadde(MachineInstr &I,
971 MachineRegisterInfo &MRI,
972 MachineFunction &MF) const {
973 assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction");
974
975 const unsigned DstReg = I.getOperand(0).getReg();
976 const unsigned CarryOutReg = I.getOperand(1).getReg();
977 const unsigned Op0Reg = I.getOperand(2).getReg();
978 const unsigned Op1Reg = I.getOperand(3).getReg();
979 unsigned CarryInReg = I.getOperand(4).getReg();
980
981 const LLT DstTy = MRI.getType(DstReg);
982
983 if (DstTy != LLT::scalar(32))
984 return false;
985
986 // find CarryIn def instruction.
987 MachineInstr *Def = MRI.getVRegDef(CarryInReg);
988 while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
989 CarryInReg = Def->getOperand(1).getReg();
990 Def = MRI.getVRegDef(CarryInReg);
991 }
992
993 unsigned Opcode;
994 if (Def->getOpcode() == TargetOpcode::G_UADDE) {
995 // carry set by prev ADD.
996
997 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
998 .addReg(CarryInReg);
999
1000 if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
1001 return false;
1002
1003 Opcode = X86::ADC32rr;
1004 } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) {
1005 // carry is constant, support only 0.
1006 if (*val != 0)
1007 return false;
1008
1009 Opcode = X86::ADD32rr;
1010 } else
1011 return false;
1012
1013 MachineInstr &AddInst =
1014 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1015 .addReg(Op0Reg)
1016 .addReg(Op1Reg);
1017
1018 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
1019 .addReg(X86::EFLAGS);
1020
1021 if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
1022 !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
1023 return false;
1024
1025 I.eraseFromParent();
1026 return true;
1027 }
1028
selectExtract(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1029 bool X86InstructionSelector::selectExtract(MachineInstr &I,
1030 MachineRegisterInfo &MRI,
1031 MachineFunction &MF) const {
1032 assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1033 "unexpected instruction");
1034
1035 const unsigned DstReg = I.getOperand(0).getReg();
1036 const unsigned SrcReg = I.getOperand(1).getReg();
1037 int64_t Index = I.getOperand(2).getImm();
1038
1039 const LLT DstTy = MRI.getType(DstReg);
1040 const LLT SrcTy = MRI.getType(SrcReg);
1041
1042 // Meanwile handle vector type only.
1043 if (!DstTy.isVector())
1044 return false;
1045
1046 if (Index % DstTy.getSizeInBits() != 0)
1047 return false; // Not extract subvector.
1048
1049 if (Index == 0) {
1050 // Replace by extract subreg copy.
1051 if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
1052 return false;
1053
1054 I.eraseFromParent();
1055 return true;
1056 }
1057
1058 bool HasAVX = STI.hasAVX();
1059 bool HasAVX512 = STI.hasAVX512();
1060 bool HasVLX = STI.hasVLX();
1061
1062 if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
1063 if (HasVLX)
1064 I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
1065 else if (HasAVX)
1066 I.setDesc(TII.get(X86::VEXTRACTF128rr));
1067 else
1068 return false;
1069 } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
1070 if (DstTy.getSizeInBits() == 128)
1071 I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
1072 else if (DstTy.getSizeInBits() == 256)
1073 I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
1074 else
1075 return false;
1076 } else
1077 return false;
1078
1079 // Convert to X86 VEXTRACT immediate.
1080 Index = Index / DstTy.getSizeInBits();
1081 I.getOperand(2).setImm(Index);
1082
1083 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1084 }
1085
emitExtractSubreg(unsigned DstReg,unsigned SrcReg,MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1086 bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
1087 MachineInstr &I,
1088 MachineRegisterInfo &MRI,
1089 MachineFunction &MF) const {
1090 const LLT DstTy = MRI.getType(DstReg);
1091 const LLT SrcTy = MRI.getType(SrcReg);
1092 unsigned SubIdx = X86::NoSubRegister;
1093
1094 if (!DstTy.isVector() || !SrcTy.isVector())
1095 return false;
1096
1097 assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
1098 "Incorrect Src/Dst register size");
1099
1100 if (DstTy.getSizeInBits() == 128)
1101 SubIdx = X86::sub_xmm;
1102 else if (DstTy.getSizeInBits() == 256)
1103 SubIdx = X86::sub_ymm;
1104 else
1105 return false;
1106
1107 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1108 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1109
1110 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1111
1112 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1113 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1114 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
1115 return false;
1116 }
1117
1118 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
1119 .addReg(SrcReg, 0, SubIdx);
1120
1121 return true;
1122 }
1123
emitInsertSubreg(unsigned DstReg,unsigned SrcReg,MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1124 bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
1125 MachineInstr &I,
1126 MachineRegisterInfo &MRI,
1127 MachineFunction &MF) const {
1128 const LLT DstTy = MRI.getType(DstReg);
1129 const LLT SrcTy = MRI.getType(SrcReg);
1130 unsigned SubIdx = X86::NoSubRegister;
1131
1132 // TODO: support scalar types
1133 if (!DstTy.isVector() || !SrcTy.isVector())
1134 return false;
1135
1136 assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1137 "Incorrect Src/Dst register size");
1138
1139 if (SrcTy.getSizeInBits() == 128)
1140 SubIdx = X86::sub_xmm;
1141 else if (SrcTy.getSizeInBits() == 256)
1142 SubIdx = X86::sub_ymm;
1143 else
1144 return false;
1145
1146 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1147 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1148
1149 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1150 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1151 LLVM_DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1152 return false;
1153 }
1154
1155 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1156 .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1157 .addReg(SrcReg);
1158
1159 return true;
1160 }
1161
selectInsert(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1162 bool X86InstructionSelector::selectInsert(MachineInstr &I,
1163 MachineRegisterInfo &MRI,
1164 MachineFunction &MF) const {
1165 assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
1166
1167 const unsigned DstReg = I.getOperand(0).getReg();
1168 const unsigned SrcReg = I.getOperand(1).getReg();
1169 const unsigned InsertReg = I.getOperand(2).getReg();
1170 int64_t Index = I.getOperand(3).getImm();
1171
1172 const LLT DstTy = MRI.getType(DstReg);
1173 const LLT InsertRegTy = MRI.getType(InsertReg);
1174
1175 // Meanwile handle vector type only.
1176 if (!DstTy.isVector())
1177 return false;
1178
1179 if (Index % InsertRegTy.getSizeInBits() != 0)
1180 return false; // Not insert subvector.
1181
1182 if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1183 // Replace by subreg copy.
1184 if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1185 return false;
1186
1187 I.eraseFromParent();
1188 return true;
1189 }
1190
1191 bool HasAVX = STI.hasAVX();
1192 bool HasAVX512 = STI.hasAVX512();
1193 bool HasVLX = STI.hasVLX();
1194
1195 if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
1196 if (HasVLX)
1197 I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
1198 else if (HasAVX)
1199 I.setDesc(TII.get(X86::VINSERTF128rr));
1200 else
1201 return false;
1202 } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
1203 if (InsertRegTy.getSizeInBits() == 128)
1204 I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
1205 else if (InsertRegTy.getSizeInBits() == 256)
1206 I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
1207 else
1208 return false;
1209 } else
1210 return false;
1211
1212 // Convert to X86 VINSERT immediate.
1213 Index = Index / InsertRegTy.getSizeInBits();
1214
1215 I.getOperand(3).setImm(Index);
1216
1217 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1218 }
1219
selectUnmergeValues(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF,CodeGenCoverage & CoverageInfo) const1220 bool X86InstructionSelector::selectUnmergeValues(
1221 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF,
1222 CodeGenCoverage &CoverageInfo) const {
1223 assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1224 "unexpected instruction");
1225
1226 // Split to extracts.
1227 unsigned NumDefs = I.getNumOperands() - 1;
1228 unsigned SrcReg = I.getOperand(NumDefs).getReg();
1229 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1230
1231 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1232 MachineInstr &ExtrInst =
1233 *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1234 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1235 .addReg(SrcReg)
1236 .addImm(Idx * DefSize);
1237
1238 if (!select(ExtrInst, CoverageInfo))
1239 return false;
1240 }
1241
1242 I.eraseFromParent();
1243 return true;
1244 }
1245
selectMergeValues(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF,CodeGenCoverage & CoverageInfo) const1246 bool X86InstructionSelector::selectMergeValues(
1247 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF,
1248 CodeGenCoverage &CoverageInfo) const {
1249 assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES) &&
1250 "unexpected instruction");
1251
1252 // Split to inserts.
1253 unsigned DstReg = I.getOperand(0).getReg();
1254 unsigned SrcReg0 = I.getOperand(1).getReg();
1255
1256 const LLT DstTy = MRI.getType(DstReg);
1257 const LLT SrcTy = MRI.getType(SrcReg0);
1258 unsigned SrcSize = SrcTy.getSizeInBits();
1259
1260 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1261
1262 // For the first src use insertSubReg.
1263 unsigned DefReg = MRI.createGenericVirtualRegister(DstTy);
1264 MRI.setRegBank(DefReg, RegBank);
1265 if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1266 return false;
1267
1268 for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
1269 unsigned Tmp = MRI.createGenericVirtualRegister(DstTy);
1270 MRI.setRegBank(Tmp, RegBank);
1271
1272 MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1273 TII.get(TargetOpcode::G_INSERT), Tmp)
1274 .addReg(DefReg)
1275 .addReg(I.getOperand(Idx).getReg())
1276 .addImm((Idx - 1) * SrcSize);
1277
1278 DefReg = Tmp;
1279
1280 if (!select(InsertInst, CoverageInfo))
1281 return false;
1282 }
1283
1284 MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1285 TII.get(TargetOpcode::COPY), DstReg)
1286 .addReg(DefReg);
1287
1288 if (!select(CopyInst, CoverageInfo))
1289 return false;
1290
1291 I.eraseFromParent();
1292 return true;
1293 }
1294
selectCondBranch(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1295 bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1296 MachineRegisterInfo &MRI,
1297 MachineFunction &MF) const {
1298 assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
1299
1300 const unsigned CondReg = I.getOperand(0).getReg();
1301 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1302
1303 MachineInstr &TestInst =
1304 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1305 .addReg(CondReg)
1306 .addImm(1);
1307 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
1308 .addMBB(DestMBB);
1309
1310 constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1311
1312 I.eraseFromParent();
1313 return true;
1314 }
1315
materializeFP(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1316 bool X86InstructionSelector::materializeFP(MachineInstr &I,
1317 MachineRegisterInfo &MRI,
1318 MachineFunction &MF) const {
1319 assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1320 "unexpected instruction");
1321
1322 // Can't handle alternate code models yet.
1323 CodeModel::Model CM = TM.getCodeModel();
1324 if (CM != CodeModel::Small && CM != CodeModel::Large)
1325 return false;
1326
1327 const unsigned DstReg = I.getOperand(0).getReg();
1328 const LLT DstTy = MRI.getType(DstReg);
1329 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1330 unsigned Align = DstTy.getSizeInBits();
1331 const DebugLoc &DbgLoc = I.getDebugLoc();
1332
1333 unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
1334
1335 // Create the load from the constant pool.
1336 const ConstantFP *CFP = I.getOperand(1).getFPImm();
1337 unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
1338 MachineInstr *LoadInst = nullptr;
1339 unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1340
1341 if (CM == CodeModel::Large && STI.is64Bit()) {
1342 // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1343 // they cannot be folded into immediate fields.
1344
1345 unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1346 BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1347 .addConstantPoolIndex(CPI, 0, OpFlag);
1348
1349 MachineMemOperand *MMO = MF.getMachineMemOperand(
1350 MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1351 MF.getDataLayout().getPointerSize(), Align);
1352
1353 LoadInst =
1354 addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1355 AddrReg)
1356 .addMemOperand(MMO);
1357
1358 } else if (CM == CodeModel::Small || !STI.is64Bit()) {
1359 // Handle the case when globals fit in our immediate field.
1360 // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1361
1362 // x86-32 PIC requires a PIC base register for constant pools.
1363 unsigned PICBase = 0;
1364 if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
1365 // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1366 // In DAGISEL the code that initialize it generated by the CGBR pass.
1367 return false; // TODO support the mode.
1368 } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
1369 PICBase = X86::RIP;
1370
1371 LoadInst = addConstantPoolReference(
1372 BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1373 OpFlag);
1374 } else
1375 return false;
1376
1377 constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
1378 I.eraseFromParent();
1379 return true;
1380 }
1381
selectImplicitDefOrPHI(MachineInstr & I,MachineRegisterInfo & MRI) const1382 bool X86InstructionSelector::selectImplicitDefOrPHI(
1383 MachineInstr &I, MachineRegisterInfo &MRI) const {
1384 assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1385 I.getOpcode() == TargetOpcode::G_PHI) &&
1386 "unexpected instruction");
1387
1388 unsigned DstReg = I.getOperand(0).getReg();
1389
1390 if (!MRI.getRegClassOrNull(DstReg)) {
1391 const LLT DstTy = MRI.getType(DstReg);
1392 const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1393
1394 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1395 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1396 << " operand\n");
1397 return false;
1398 }
1399 }
1400
1401 if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1402 I.setDesc(TII.get(X86::IMPLICIT_DEF));
1403 else
1404 I.setDesc(TII.get(X86::PHI));
1405
1406 return true;
1407 }
1408
1409 // Currently GlobalIsel TableGen generates patterns for shift imm and shift 1,
1410 // but with shiftCount i8. In G_LSHR/G_ASHR/G_SHL like LLVM-IR both arguments
1411 // has the same type, so for now only shift i8 can use auto generated
1412 // TableGen patterns.
selectShift(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1413 bool X86InstructionSelector::selectShift(MachineInstr &I,
1414 MachineRegisterInfo &MRI,
1415 MachineFunction &MF) const {
1416
1417 assert((I.getOpcode() == TargetOpcode::G_SHL ||
1418 I.getOpcode() == TargetOpcode::G_ASHR ||
1419 I.getOpcode() == TargetOpcode::G_LSHR) &&
1420 "unexpected instruction");
1421
1422 unsigned DstReg = I.getOperand(0).getReg();
1423 const LLT DstTy = MRI.getType(DstReg);
1424 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1425
1426 const static struct ShiftEntry {
1427 unsigned SizeInBits;
1428 unsigned CReg;
1429 unsigned OpLSHR;
1430 unsigned OpASHR;
1431 unsigned OpSHL;
1432 } OpTable[] = {
1433 {8, X86::CL, X86::SHR8rCL, X86::SAR8rCL, X86::SHL8rCL}, // i8
1434 {16, X86::CX, X86::SHR16rCL, X86::SAR16rCL, X86::SHL16rCL}, // i16
1435 {32, X86::ECX, X86::SHR32rCL, X86::SAR32rCL, X86::SHL32rCL}, // i32
1436 {64, X86::RCX, X86::SHR64rCL, X86::SAR64rCL, X86::SHL64rCL} // i64
1437 };
1438
1439 if (DstRB.getID() != X86::GPRRegBankID)
1440 return false;
1441
1442 auto ShiftEntryIt = std::find_if(
1443 std::begin(OpTable), std::end(OpTable), [DstTy](const ShiftEntry &El) {
1444 return El.SizeInBits == DstTy.getSizeInBits();
1445 });
1446 if (ShiftEntryIt == std::end(OpTable))
1447 return false;
1448
1449 unsigned CReg = ShiftEntryIt->CReg;
1450 unsigned Opcode = 0;
1451 switch (I.getOpcode()) {
1452 case TargetOpcode::G_SHL:
1453 Opcode = ShiftEntryIt->OpSHL;
1454 break;
1455 case TargetOpcode::G_ASHR:
1456 Opcode = ShiftEntryIt->OpASHR;
1457 break;
1458 case TargetOpcode::G_LSHR:
1459 Opcode = ShiftEntryIt->OpLSHR;
1460 break;
1461 default:
1462 return false;
1463 }
1464
1465 unsigned Op0Reg = I.getOperand(1).getReg();
1466 unsigned Op1Reg = I.getOperand(2).getReg();
1467
1468 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1469 ShiftEntryIt->CReg)
1470 .addReg(Op1Reg);
1471
1472 // The shift instruction uses X86::CL. If we defined a super-register
1473 // of X86::CL, emit a subreg KILL to precisely describe what we're doing here.
1474 if (CReg != X86::CL)
1475 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::KILL),
1476 X86::CL)
1477 .addReg(CReg, RegState::Kill);
1478
1479 MachineInstr &ShiftInst =
1480 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1481 .addReg(Op0Reg);
1482
1483 constrainSelectedInstRegOperands(ShiftInst, TII, TRI, RBI);
1484 I.eraseFromParent();
1485 return true;
1486 }
1487
selectSDiv(MachineInstr & I,MachineRegisterInfo & MRI,MachineFunction & MF) const1488 bool X86InstructionSelector::selectSDiv(MachineInstr &I,
1489 MachineRegisterInfo &MRI,
1490 MachineFunction &MF) const {
1491
1492 assert(I.getOpcode() == TargetOpcode::G_SDIV && "unexpected instruction");
1493
1494 const unsigned DstReg = I.getOperand(0).getReg();
1495 const unsigned DividentReg = I.getOperand(1).getReg();
1496 const unsigned DiviserReg = I.getOperand(2).getReg();
1497
1498 const LLT RegTy = MRI.getType(DstReg);
1499 assert(RegTy == MRI.getType(DividentReg) &&
1500 RegTy == MRI.getType(DiviserReg) &&
1501 "Arguments and return value types must match");
1502
1503 const RegisterBank &RegRB = *RBI.getRegBank(DstReg, MRI, TRI);
1504
1505 // For the X86 IDIV instruction, in most cases the dividend
1506 // (numerator) must be in a specific register pair highreg:lowreg,
1507 // producing the quotient in lowreg and the remainder in highreg.
1508 // For most data types, to set up the instruction, the dividend is
1509 // copied into lowreg, and lowreg is sign-extended into highreg. The
1510 // exception is i8, where the dividend is defined as a single register rather
1511 // than a register pair, and we therefore directly sign-extend the dividend
1512 // into lowreg, instead of copying, and ignore the highreg.
1513 const static struct SDivEntry {
1514 unsigned SizeInBits;
1515 unsigned QuotientReg;
1516 unsigned DividentRegUpper;
1517 unsigned DividentRegLower;
1518 unsigned OpSignExtend;
1519 unsigned OpCopy;
1520 unsigned OpDiv;
1521 } OpTable[] = {
1522 {8, X86::AL, X86::NoRegister, X86::AX, 0, X86::MOVSX16rr8,
1523 X86::IDIV8r}, // i8
1524 {16, X86::AX, X86::DX, X86::AX, X86::CWD, TargetOpcode::COPY,
1525 X86::IDIV16r}, // i16
1526 {32, X86::EAX, X86::EDX, X86::EAX, X86::CDQ, TargetOpcode::COPY,
1527 X86::IDIV32r}, // i32
1528 {64, X86::RAX, X86::RDX, X86::RAX, X86::CQO, TargetOpcode::COPY,
1529 X86::IDIV64r} // i64
1530 };
1531
1532 if (RegRB.getID() != X86::GPRRegBankID)
1533 return false;
1534
1535 auto SDivEntryIt = std::find_if(
1536 std::begin(OpTable), std::end(OpTable), [RegTy](const SDivEntry &El) {
1537 return El.SizeInBits == RegTy.getSizeInBits();
1538 });
1539
1540 if (SDivEntryIt == std::end(OpTable))
1541 return false;
1542
1543 const TargetRegisterClass *RegRC = getRegClass(RegTy, RegRB);
1544 if (!RBI.constrainGenericRegister(DividentReg, *RegRC, MRI) ||
1545 !RBI.constrainGenericRegister(DiviserReg, *RegRC, MRI) ||
1546 !RBI.constrainGenericRegister(DstReg, *RegRC, MRI)) {
1547 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1548 << " operand\n");
1549 return false;
1550 }
1551
1552 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SDivEntryIt->OpCopy),
1553 SDivEntryIt->DividentRegLower)
1554 .addReg(DividentReg);
1555 if (SDivEntryIt->DividentRegUpper != X86::NoRegister)
1556 BuildMI(*I.getParent(), I, I.getDebugLoc(),
1557 TII.get(SDivEntryIt->OpSignExtend));
1558 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SDivEntryIt->OpDiv))
1559 .addReg(DiviserReg);
1560 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1561 DstReg)
1562 .addReg(SDivEntryIt->QuotientReg);
1563
1564 I.eraseFromParent();
1565 return true;
1566 }
1567
1568 InstructionSelector *
createX86InstructionSelector(const X86TargetMachine & TM,X86Subtarget & Subtarget,X86RegisterBankInfo & RBI)1569 llvm::createX86InstructionSelector(const X86TargetMachine &TM,
1570 X86Subtarget &Subtarget,
1571 X86RegisterBankInfo &RBI) {
1572 return new X86InstructionSelector(TM, Subtarget, RBI);
1573 }
1574