LLVM 22.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"
38#include "llvm/IR/DataLayout.h"
39#include "llvm/IR/InstrTypes.h"
40#include "llvm/IR/IntrinsicsX86.h"
42#include "llvm/Support/Debug.h"
46#include <cassert>
47#include <cstdint>
48#include <tuple>
49
50#define DEBUG_TYPE "X86-isel"
51
52using namespace llvm;
53
54namespace {
55
56#define GET_GLOBALISEL_PREDICATE_BITSET
57#include "X86GenGlobalISel.inc"
58#undef GET_GLOBALISEL_PREDICATE_BITSET
59
60class X86InstructionSelector : public InstructionSelector {
61public:
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
68private:
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 // TODO: remove once p0<->i32/i64 matching is available
77 unsigned getPtrLoadStoreOp(const LLT &Ty, const RegisterBank &RB,
78 unsigned Opc) const;
79
81 MachineFunction &MF) const;
82 bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
83 MachineFunction &MF) const;
84 bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
85 MachineFunction &MF) const;
86 bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
87 MachineFunction &MF) const;
88 bool selectTruncOrPtrToInt(MachineInstr &I, MachineRegisterInfo &MRI,
89 MachineFunction &MF) const;
90 bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
91 MachineFunction &MF) const;
92 bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
93 MachineFunction &MF) const;
94 bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
95 MachineFunction &MF) const;
96 bool selectFCmp(MachineInstr &I, MachineRegisterInfo &MRI,
97 MachineFunction &MF) const;
98 bool selectUAddSub(MachineInstr &I, MachineRegisterInfo &MRI,
99 MachineFunction &MF) const;
103 MachineFunction &MF);
105 MachineFunction &MF);
106 bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
107 MachineFunction &MF) const;
108 bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
109 MachineFunction &MF) const;
110 bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
111 MachineFunction &MF) const;
112 bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
113 const Register DstReg,
114 const TargetRegisterClass *DstRC,
115 const Register SrcReg,
116 const TargetRegisterClass *SrcRC) const;
117 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
118 MachineFunction &MF) const;
119 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
120 bool selectMulDivRem(MachineInstr &I, MachineRegisterInfo &MRI,
121 MachineFunction &MF) const;
122 bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI,
123 MachineFunction &MF) const;
124
125 ComplexRendererFns selectAddr(MachineOperand &Root) const;
126
127 // emit insert subreg instruction and insert it before MachineInstr &I
128 bool emitInsertSubreg(Register DstReg, Register SrcReg, MachineInstr &I,
130 // emit extract subreg instruction and insert it before MachineInstr &I
131 bool emitExtractSubreg(Register DstReg, Register SrcReg, MachineInstr &I,
133
134 const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
136 MachineRegisterInfo &MRI) const;
137
138 const X86TargetMachine &TM;
139 const X86Subtarget &STI;
140 const X86InstrInfo &TII;
141 const X86RegisterInfo &TRI;
142 const X86RegisterBankInfo &RBI;
143
144#define GET_GLOBALISEL_PREDICATES_DECL
145#include "X86GenGlobalISel.inc"
146#undef GET_GLOBALISEL_PREDICATES_DECL
147
148#define GET_GLOBALISEL_TEMPORARIES_DECL
149#include "X86GenGlobalISel.inc"
150#undef GET_GLOBALISEL_TEMPORARIES_DECL
151};
152
153} // end anonymous namespace
154
155#define GET_GLOBALISEL_IMPL
156#include "X86GenGlobalISel.inc"
157#undef GET_GLOBALISEL_IMPL
158
159X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
160 const X86Subtarget &STI,
161 const X86RegisterBankInfo &RBI)
162 : TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()),
163 RBI(RBI),
165#include "X86GenGlobalISel.inc"
168#include "X86GenGlobalISel.inc"
170{
171}
172
173// FIXME: This should be target-independent, inferred from the types declared
174// for each class in the bank.
176X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
177 if (RB.getID() == X86::GPRRegBankID) {
178 if (Ty.getSizeInBits() <= 8)
179 return &X86::GR8RegClass;
180 if (Ty.getSizeInBits() == 16)
181 return &X86::GR16RegClass;
182 if (Ty.getSizeInBits() == 32)
183 return &X86::GR32RegClass;
184 if (Ty.getSizeInBits() == 64)
185 return &X86::GR64RegClass;
186 }
187 if (RB.getID() == X86::VECRRegBankID) {
188 if (Ty.getSizeInBits() == 16)
189 return STI.hasAVX512() ? &X86::FR16XRegClass : &X86::FR16RegClass;
190 if (Ty.getSizeInBits() == 32)
191 return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
192 if (Ty.getSizeInBits() == 64)
193 return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
194 if (Ty.getSizeInBits() == 128)
195 return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
196 if (Ty.getSizeInBits() == 256)
197 return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
198 if (Ty.getSizeInBits() == 512)
199 return &X86::VR512RegClass;
200 }
201
202 if (RB.getID() == X86::PSRRegBankID) {
203 if (Ty.getSizeInBits() == 80)
204 return &X86::RFP80RegClass;
205 if (Ty.getSizeInBits() == 64)
206 return &X86::RFP64RegClass;
207 if (Ty.getSizeInBits() == 32)
208 return &X86::RFP32RegClass;
209 }
210
211 llvm_unreachable("Unknown RegBank!");
212}
213
215X86InstructionSelector::getRegClass(LLT Ty, Register Reg,
216 MachineRegisterInfo &MRI) const {
217 const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
218 return getRegClass(Ty, RegBank);
219}
220
221static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
222 unsigned SubIdx = X86::NoSubRegister;
223 if (RC == &X86::GR32RegClass) {
224 SubIdx = X86::sub_32bit;
225 } else if (RC == &X86::GR16RegClass) {
226 SubIdx = X86::sub_16bit;
227 } else if (RC == &X86::GR8RegClass) {
228 SubIdx = X86::sub_8bit;
229 }
230
231 return SubIdx;
232}
233
235 assert(Reg.isPhysical());
236 if (X86::GR64RegClass.contains(Reg))
237 return &X86::GR64RegClass;
238 if (X86::GR32RegClass.contains(Reg))
239 return &X86::GR32RegClass;
240 if (X86::GR16RegClass.contains(Reg))
241 return &X86::GR16RegClass;
242 if (X86::GR8RegClass.contains(Reg))
243 return &X86::GR8RegClass;
244
245 llvm_unreachable("Unknown RegClass for PhysReg!");
246}
247
248// FIXME: We need some sort of API in RBI/TRI to allow generic code to
249// constrain operands of simple instructions given a TargetRegisterClass
250// and LLT
251bool X86InstructionSelector::selectDebugInstr(MachineInstr &I,
252 MachineRegisterInfo &MRI) const {
253 for (MachineOperand &MO : I.operands()) {
254 if (!MO.isReg())
255 continue;
256 Register Reg = MO.getReg();
257 if (!Reg)
258 continue;
259 if (Reg.isPhysical())
260 continue;
261 LLT Ty = MRI.getType(Reg);
262 const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
263 const TargetRegisterClass *RC =
264 dyn_cast_if_present<const TargetRegisterClass *>(RegClassOrBank);
265 if (!RC) {
266 const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
267 RC = getRegClass(Ty, RB);
268 if (!RC) {
270 dbgs() << "Warning: DBG_VALUE operand has unexpected size/bank\n");
271 break;
272 }
273 }
274 RBI.constrainGenericRegister(Reg, *RC, MRI);
275 }
276
277 return true;
278}
279
280// Set X86 Opcode and constrain DestReg.
281bool X86InstructionSelector::selectCopy(MachineInstr &I,
282 MachineRegisterInfo &MRI) const {
283 Register DstReg = I.getOperand(0).getReg();
284 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
285 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
286
287 Register SrcReg = I.getOperand(1).getReg();
288 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
289 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
290
291 if (DstReg.isPhysical()) {
292 assert(I.isCopy() && "Generic operators do not allow physical registers");
293
294 if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
295 DstRegBank.getID() == X86::GPRRegBankID) {
296
297 const TargetRegisterClass *SrcRC =
298 getRegClass(MRI.getType(SrcReg), SrcRegBank);
299 const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
300
301 if (SrcRC != DstRC) {
302 // This case can be generated by ABI lowering, performe anyext
303 Register ExtSrc = MRI.createVirtualRegister(DstRC);
304 BuildMI(*I.getParent(), I, I.getDebugLoc(),
305 TII.get(TargetOpcode::SUBREG_TO_REG))
306 .addDef(ExtSrc)
307 .addImm(0)
308 .addReg(SrcReg)
309 .addImm(getSubRegIndex(SrcRC));
310
311 I.getOperand(1).setReg(ExtSrc);
312 }
313 }
314
315 return true;
316 }
317
318 assert((!SrcReg.isPhysical() || I.isCopy()) &&
319 "No phys reg on generic operators");
320 assert((DstSize == SrcSize ||
321 // Copies are a mean to setup initial types, the number of
322 // bits may not exactly match.
323 (SrcReg.isPhysical() &&
324 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
325 "Copy with different width?!");
326
327 const TargetRegisterClass *DstRC =
328 getRegClass(MRI.getType(DstReg), DstRegBank);
329
330 if (SrcRegBank.getID() == X86::GPRRegBankID &&
331 DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
332 SrcReg.isPhysical()) {
333 // Change the physical register to performe truncate.
334
335 const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
336
337 if (DstRC != SrcRC) {
338 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
339 I.getOperand(1).substPhysReg(SrcReg, TRI);
340 }
341 }
342
343 // No need to constrain SrcReg. It will get constrained when
344 // we hit another of its use or its defs.
345 // Copies do not have constraints.
346 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
347 if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
348 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
349 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
350 << " operand\n");
351 return false;
352 }
353 }
354 I.setDesc(TII.get(X86::COPY));
355 return true;
356}
357
358bool X86InstructionSelector::select(MachineInstr &I) {
359 assert(I.getParent() && "Instruction should be in a basic block!");
360 assert(I.getParent()->getParent() && "Instruction should be in a function!");
361
362 MachineBasicBlock &MBB = *I.getParent();
365
366 unsigned Opcode = I.getOpcode();
367 if (!isPreISelGenericOpcode(Opcode) && !I.isPreISelOpcode()) {
368 // Certain non-generic instructions also need some special handling.
369
370 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
371 return false;
372
373 if (I.isCopy())
374 return selectCopy(I, MRI);
375
376 if (I.isDebugInstr())
377 return selectDebugInstr(I, MRI);
378
379 return true;
380 }
381
382 assert(I.getNumOperands() == I.getNumExplicitOperands() &&
383 "Generic instruction has unexpected implicit operands\n");
384
385 if (selectImpl(I, *CoverageInfo))
386 return true;
387
388 LLVM_DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
389
390 // TODO: This should be implemented by tblgen.
391 switch (I.getOpcode()) {
392 default:
393 return false;
394 case TargetOpcode::G_STORE:
395 case TargetOpcode::G_LOAD:
396 return selectLoadStoreOp(I, MRI, MF);
397 case TargetOpcode::G_PTR_ADD:
398 case TargetOpcode::G_FRAME_INDEX:
399 return selectFrameIndexOrGep(I, MRI, MF);
400 case TargetOpcode::G_GLOBAL_VALUE:
401 return selectGlobalValue(I, MRI, MF);
402 case TargetOpcode::G_CONSTANT:
403 return selectConstant(I, MRI, MF);
404 case TargetOpcode::G_FCONSTANT:
405 return materializeFP(I, MRI, MF);
406 case TargetOpcode::G_PTRTOINT:
407 case TargetOpcode::G_TRUNC:
408 return selectTruncOrPtrToInt(I, MRI, MF);
409 case TargetOpcode::G_INTTOPTR:
410 return selectCopy(I, MRI);
411 case TargetOpcode::G_ZEXT:
412 return selectZext(I, MRI, MF);
413 case TargetOpcode::G_ANYEXT:
414 return selectAnyext(I, MRI, MF);
415 case TargetOpcode::G_ICMP:
416 return selectCmp(I, MRI, MF);
417 case TargetOpcode::G_FCMP:
418 return selectFCmp(I, MRI, MF);
419 case TargetOpcode::G_UADDE:
420 case TargetOpcode::G_UADDO:
421 case TargetOpcode::G_USUBE:
422 case TargetOpcode::G_USUBO:
423 return selectUAddSub(I, MRI, MF);
424 case TargetOpcode::G_UNMERGE_VALUES:
425 return selectUnmergeValues(I, MRI, MF);
426 case TargetOpcode::G_MERGE_VALUES:
427 case TargetOpcode::G_CONCAT_VECTORS:
428 return selectMergeValues(I, MRI, MF);
429 case TargetOpcode::G_EXTRACT:
430 return selectExtract(I, MRI, MF);
431 case TargetOpcode::G_INSERT:
432 return selectInsert(I, MRI, MF);
433 case TargetOpcode::G_BRCOND:
434 return selectCondBranch(I, MRI, MF);
435 case TargetOpcode::G_IMPLICIT_DEF:
436 case TargetOpcode::G_PHI:
437 return selectImplicitDefOrPHI(I, MRI);
438 case TargetOpcode::G_MUL:
439 case TargetOpcode::G_SMULH:
440 case TargetOpcode::G_UMULH:
441 case TargetOpcode::G_SDIV:
442 case TargetOpcode::G_UDIV:
443 case TargetOpcode::G_SREM:
444 case TargetOpcode::G_UREM:
445 return selectMulDivRem(I, MRI, MF);
446 case TargetOpcode::G_SELECT:
447 return selectSelect(I, MRI, MF);
448 }
449
450 return false;
451}
452
453unsigned X86InstructionSelector::getPtrLoadStoreOp(const LLT &Ty,
454 const RegisterBank &RB,
455 unsigned Opc) const {
456 assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
457 "Only G_STORE and G_LOAD are expected for selection");
458 if (Ty.isPointer() && X86::GPRRegBankID == RB.getID()) {
459 bool IsLoad = (Opc == TargetOpcode::G_LOAD);
460 switch (Ty.getSizeInBits()) {
461 default:
462 break;
463 case 32:
464 return IsLoad ? X86::MOV32rm : X86::MOV32mr;
465 case 64:
466 return IsLoad ? X86::MOV64rm : X86::MOV64mr;
467 }
468 }
469 return Opc;
470}
471
472unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
473 const RegisterBank &RB,
474 unsigned Opc,
475 Align Alignment) const {
476 bool Isload = (Opc == TargetOpcode::G_LOAD);
477 bool HasAVX = STI.hasAVX();
478 bool HasAVX512 = STI.hasAVX512();
479 bool HasVLX = STI.hasVLX();
480
481 if (Ty == LLT::scalar(8)) {
482 if (X86::GPRRegBankID == RB.getID())
483 return Isload ? X86::MOV8rm : X86::MOV8mr;
484 } else if (Ty == LLT::scalar(16)) {
485 if (X86::GPRRegBankID == RB.getID())
486 return Isload ? X86::MOV16rm : X86::MOV16mr;
487 } else if (Ty == LLT::scalar(32)) {
488 if (X86::GPRRegBankID == RB.getID())
489 return Isload ? X86::MOV32rm : X86::MOV32mr;
490 if (X86::VECRRegBankID == RB.getID())
491 return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
492 HasAVX ? X86::VMOVSSrm_alt :
493 X86::MOVSSrm_alt)
494 : (HasAVX512 ? X86::VMOVSSZmr :
495 HasAVX ? X86::VMOVSSmr :
496 X86::MOVSSmr);
497 if (X86::PSRRegBankID == RB.getID())
498 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
499 } else if (Ty == LLT::scalar(64)) {
500 if (X86::GPRRegBankID == RB.getID())
501 return Isload ? X86::MOV64rm : X86::MOV64mr;
502 if (X86::VECRRegBankID == RB.getID())
503 return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
504 HasAVX ? X86::VMOVSDrm_alt :
505 X86::MOVSDrm_alt)
506 : (HasAVX512 ? X86::VMOVSDZmr :
507 HasAVX ? X86::VMOVSDmr :
508 X86::MOVSDmr);
509 if (X86::PSRRegBankID == RB.getID())
510 return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
511 } else if (Ty == LLT::scalar(80)) {
512 return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
513 } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
514 if (Alignment >= Align(16))
515 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
516 : HasAVX512
517 ? X86::VMOVAPSZ128rm_NOVLX
518 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
519 : (HasVLX ? X86::VMOVAPSZ128mr
520 : HasAVX512
521 ? X86::VMOVAPSZ128mr_NOVLX
522 : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
523 else
524 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
525 : HasAVX512
526 ? X86::VMOVUPSZ128rm_NOVLX
527 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
528 : (HasVLX ? X86::VMOVUPSZ128mr
529 : HasAVX512
530 ? X86::VMOVUPSZ128mr_NOVLX
531 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
532 } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
533 if (Alignment >= Align(32))
534 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
535 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
536 : X86::VMOVAPSYrm)
537 : (HasVLX ? X86::VMOVAPSZ256mr
538 : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
539 : X86::VMOVAPSYmr);
540 else
541 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
542 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
543 : X86::VMOVUPSYrm)
544 : (HasVLX ? X86::VMOVUPSZ256mr
545 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
546 : X86::VMOVUPSYmr);
547 } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
548 if (Alignment >= Align(64))
549 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
550 else
551 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
552 }
553 return Opc;
554}
555
556// Fill in an address from the given instruction.
559 const X86Subtarget &STI, X86AddressMode &AM) {
560 assert(I.getOperand(0).isReg() && "unsupported operand.");
561 assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
562 "unsupported type.");
563
564 switch (I.getOpcode()) {
565 default:
566 break;
567 case TargetOpcode::G_FRAME_INDEX:
568 AM.Base.FrameIndex = I.getOperand(1).getIndex();
570 return true;
571 case TargetOpcode::G_PTR_ADD: {
572 if (auto COff = getIConstantVRegSExtVal(I.getOperand(2).getReg(), MRI)) {
573 int64_t Imm = *COff;
574 if (isInt<32>(Imm)) { // Check for displacement overflow.
575 AM.Disp = static_cast<int32_t>(Imm);
576 AM.Base.Reg = I.getOperand(1).getReg();
577 return true;
578 }
579 }
580 break;
581 }
582 case TargetOpcode::G_GLOBAL_VALUE: {
583 auto GV = I.getOperand(1).getGlobal();
584 if (GV->isThreadLocal()) {
585 return false; // TODO: we don't support TLS yet.
586 }
587 // Can't handle alternate code models yet.
588 if (TM.getCodeModel() != CodeModel::Small)
589 return false;
590 AM.GV = GV;
592
593 // TODO: The ABI requires an extra load. not supported yet.
595 return false;
596
597 // TODO: This reference is relative to the pic base. not supported yet.
599 return false;
600
601 if (STI.isPICStyleRIPRel()) {
602 // Use rip-relative addressing.
603 assert(AM.Base.Reg == 0 && AM.IndexReg == 0 &&
604 "RIP-relative addresses can't have additional register operands");
605 AM.Base.Reg = X86::RIP;
606 }
607 return true;
608 }
609 case TargetOpcode::G_CONSTANT_POOL: {
610 // TODO: Need a separate move for Large model
611 if (TM.getCodeModel() == CodeModel::Large)
612 return false;
613
614 AM.GVOpFlags = STI.classifyLocalReference(nullptr);
615 if (AM.GVOpFlags == X86II::MO_GOTOFF)
616 AM.Base.Reg = STI.getInstrInfo()->getGlobalBaseReg(I.getMF());
617 else if (STI.is64Bit())
618 AM.Base.Reg = X86::RIP;
619 AM.CP = true;
620 AM.Disp = I.getOperand(1).getIndex();
621 return true;
622 }
623 }
624 // Default behavior.
625 AM.Base.Reg = I.getOperand(0).getReg();
626 return true;
627}
628
629bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
631 MachineFunction &MF) const {
632 unsigned Opc = I.getOpcode();
633
634 assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
635 "Only G_STORE and G_LOAD are expected for selection");
636
637 const Register DefReg = I.getOperand(0).getReg();
638 LLT Ty = MRI.getType(DefReg);
639 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
640
641 assert(I.hasOneMemOperand());
642 auto &MemOp = **I.memoperands_begin();
643 if (MemOp.isAtomic()) {
644 // Note: for unordered operations, we rely on the fact the appropriate MMO
645 // is already on the instruction we're mutating, and thus we don't need to
646 // make any changes. So long as we select an opcode which is capable of
647 // loading or storing the appropriate size atomically, the rest of the
648 // backend is required to respect the MMO state.
649 if (!MemOp.isUnordered()) {
650 LLVM_DEBUG(dbgs() << "Atomic ordering not supported yet\n");
651 return false;
652 }
653 if (MemOp.getAlign() < Ty.getSizeInBits() / 8) {
654 LLVM_DEBUG(dbgs() << "Unaligned atomics not supported yet\n");
655 return false;
656 }
657 }
658
659 unsigned NewOpc = getPtrLoadStoreOp(Ty, RB, Opc);
660 if (NewOpc == Opc)
661 return false;
662
663 I.setDesc(TII.get(NewOpc));
664 MachineInstrBuilder MIB(MF, I);
665 MachineInstr *Ptr = MRI.getVRegDef(I.getOperand(1).getReg());
666
668 if (!X86SelectAddress(*Ptr, TM, MRI, STI, AM))
669 return false;
670
671 if (Opc == TargetOpcode::G_LOAD) {
672 I.removeOperand(1);
673 addFullAddress(MIB, AM);
674 } else {
675 // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
676 I.removeOperand(1);
677 I.removeOperand(0);
678 addFullAddress(MIB, AM).addUse(DefReg);
679 }
680 bool Constrained = constrainSelectedInstRegOperands(I, TII, TRI, RBI);
681 I.addImplicitDefUseOperands(MF);
682 return Constrained;
683}
684
685static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
686 if (Ty == LLT::pointer(0, 64))
687 return X86::LEA64r;
688 else if (Ty == LLT::pointer(0, 32))
689 return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
690 else
691 llvm_unreachable("Can't get LEA opcode. Unsupported type.");
692}
693
694bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
696 MachineFunction &MF) const {
697 unsigned Opc = I.getOpcode();
698
699 assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_PTR_ADD) &&
700 "unexpected instruction");
701
702 const Register DefReg = I.getOperand(0).getReg();
703 LLT Ty = MRI.getType(DefReg);
704
705 // Use LEA to calculate frame index and GEP
706 unsigned NewOpc = getLeaOP(Ty, STI);
707 I.setDesc(TII.get(NewOpc));
708 MachineInstrBuilder MIB(MF, I);
709
710 if (Opc == TargetOpcode::G_FRAME_INDEX) {
711 addOffset(MIB, 0);
712 } else {
713 MachineOperand &InxOp = I.getOperand(2);
714 I.addOperand(InxOp); // set IndexReg
715 InxOp.ChangeToImmediate(1); // set Scale
716 MIB.addImm(0).addReg(0);
717 }
718
720}
721
722bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
724 MachineFunction &MF) const {
725 assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
726 "unexpected instruction");
727
729 if (!X86SelectAddress(I, TM, MRI, STI, AM))
730 return false;
731
732 const Register DefReg = I.getOperand(0).getReg();
733 LLT Ty = MRI.getType(DefReg);
734 unsigned NewOpc = getLeaOP(Ty, STI);
735
736 I.setDesc(TII.get(NewOpc));
737 MachineInstrBuilder MIB(MF, I);
738
739 I.removeOperand(1);
740 addFullAddress(MIB, AM);
741
743}
744
745bool X86InstructionSelector::selectConstant(MachineInstr &I,
747 MachineFunction &MF) const {
748 assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
749 "unexpected instruction");
750
751 const Register DefReg = I.getOperand(0).getReg();
752 LLT Ty = MRI.getType(DefReg);
753
754 if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
755 return false;
756
757 uint64_t Val = 0;
758 if (I.getOperand(1).isCImm()) {
759 Val = I.getOperand(1).getCImm()->getZExtValue();
760 I.getOperand(1).ChangeToImmediate(Val);
761 } else if (I.getOperand(1).isImm()) {
762 Val = I.getOperand(1).getImm();
763 } else
764 llvm_unreachable("Unsupported operand type.");
765
766 unsigned NewOpc;
767 switch (Ty.getSizeInBits()) {
768 case 8:
769 NewOpc = X86::MOV8ri;
770 break;
771 case 16:
772 NewOpc = X86::MOV16ri;
773 break;
774 case 32:
775 NewOpc = X86::MOV32ri;
776 break;
777 case 64:
778 // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
779 if (isInt<32>(Val))
780 NewOpc = X86::MOV64ri32;
781 else
782 NewOpc = X86::MOV64ri;
783 break;
784 default:
785 llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
786 }
787
788 I.setDesc(TII.get(NewOpc));
790}
791
792// Helper function for selectTruncOrPtrToInt and selectAnyext.
793// Returns true if DstRC lives on a floating register class and
794// SrcRC lives on a 128-bit vector class.
795static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC,
796 const TargetRegisterClass *SrcRC) {
797 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
798 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
799 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
800}
801
802bool X86InstructionSelector::selectTurnIntoCOPY(
804 const TargetRegisterClass *DstRC, const Register SrcReg,
805 const TargetRegisterClass *SrcRC) const {
806
807 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
808 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
809 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
810 << " operand\n");
811 return false;
812 }
813 I.setDesc(TII.get(X86::COPY));
814 return true;
815}
816
817bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
819 MachineFunction &MF) const {
820 assert((I.getOpcode() == TargetOpcode::G_TRUNC ||
821 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
822 "unexpected instruction");
823
824 const Register DstReg = I.getOperand(0).getReg();
825 const Register SrcReg = I.getOperand(1).getReg();
826
827 const LLT DstTy = MRI.getType(DstReg);
828 const LLT SrcTy = MRI.getType(SrcReg);
829
830 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
831 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
832
833 if (DstRB.getID() != SrcRB.getID()) {
834 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode())
835 << " input/output on different banks\n");
836 return false;
837 }
838
839 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
840 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
841
842 if (!DstRC || !SrcRC)
843 return false;
844
845 // If that's truncation of the value that lives on the vector class and goes
846 // into the floating class, just replace it with copy, as we are able to
847 // select it as a regular move.
848 if (canTurnIntoCOPY(DstRC, SrcRC))
849 return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
850
851 if (DstRB.getID() != X86::GPRRegBankID)
852 return false;
853
854 unsigned SubIdx;
855 if (DstRC == SrcRC) {
856 // Nothing to be done
857 SubIdx = X86::NoSubRegister;
858 } else if (DstRC == &X86::GR32RegClass) {
859 SubIdx = X86::sub_32bit;
860 } else if (DstRC == &X86::GR16RegClass) {
861 SubIdx = X86::sub_16bit;
862 } else if (DstRC == &X86::GR8RegClass) {
863 SubIdx = X86::sub_8bit;
864 } else {
865 return false;
866 }
867
868 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
869
870 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
871 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
872 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
873 << "\n");
874 return false;
875 }
876
877 I.getOperand(1).setSubReg(SubIdx);
878
879 I.setDesc(TII.get(X86::COPY));
880 return true;
881}
882
883bool X86InstructionSelector::selectZext(MachineInstr &I,
885 MachineFunction &MF) const {
886 assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
887
888 const Register DstReg = I.getOperand(0).getReg();
889 const Register SrcReg = I.getOperand(1).getReg();
890
891 const LLT DstTy = MRI.getType(DstReg);
892 const LLT SrcTy = MRI.getType(SrcReg);
893
894 assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(16)) &&
895 "8=>16 Zext is handled by tablegen");
896 assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(32)) &&
897 "8=>32 Zext is handled by tablegen");
898 assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(32)) &&
899 "16=>32 Zext is handled by tablegen");
900 assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(64)) &&
901 "8=>64 Zext is handled by tablegen");
902 assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(64)) &&
903 "16=>64 Zext is handled by tablegen");
904 assert(!(SrcTy == LLT::scalar(32) && DstTy == LLT::scalar(64)) &&
905 "32=>64 Zext is handled by tablegen");
906
907 if (SrcTy != LLT::scalar(1))
908 return false;
909
910 unsigned AndOpc;
911 if (DstTy == LLT::scalar(8))
912 AndOpc = X86::AND8ri;
913 else if (DstTy == LLT::scalar(16))
914 AndOpc = X86::AND16ri;
915 else if (DstTy == LLT::scalar(32))
916 AndOpc = X86::AND32ri;
917 else if (DstTy == LLT::scalar(64))
918 AndOpc = X86::AND64ri32;
919 else
920 return false;
921
922 Register DefReg = SrcReg;
923 if (DstTy != LLT::scalar(8)) {
924 Register ImpDefReg =
925 MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
926 BuildMI(*I.getParent(), I, I.getDebugLoc(),
927 TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
928
929 DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
930 BuildMI(*I.getParent(), I, I.getDebugLoc(),
931 TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
932 .addReg(ImpDefReg)
933 .addReg(SrcReg)
934 .addImm(X86::sub_8bit);
935 }
936
937 MachineInstr &AndInst =
938 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
939 .addReg(DefReg)
940 .addImm(1);
941
943
944 I.eraseFromParent();
945 return true;
946}
947
948bool X86InstructionSelector::selectAnyext(MachineInstr &I,
950 MachineFunction &MF) const {
951 assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
952
953 const Register DstReg = I.getOperand(0).getReg();
954 const Register SrcReg = I.getOperand(1).getReg();
955
956 const LLT DstTy = MRI.getType(DstReg);
957 const LLT SrcTy = MRI.getType(SrcReg);
958
959 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
960 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
961
962 assert(DstRB.getID() == SrcRB.getID() &&
963 "G_ANYEXT input/output on different banks\n");
964
965 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
966 "G_ANYEXT incorrect operand size");
967
968 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
969 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
970
971 // If that's ANY_EXT of the value that lives on the floating class and goes
972 // into the vector class, just replace it with copy, as we are able to select
973 // it as a regular move.
974 if (canTurnIntoCOPY(SrcRC, DstRC))
975 return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC);
976
977 if (DstRB.getID() != X86::GPRRegBankID)
978 return false;
979
980 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
981 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
982 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
983 << " operand\n");
984 return false;
985 }
986
987 if (SrcRC == DstRC) {
988 I.setDesc(TII.get(X86::COPY));
989 return true;
990 }
991
992 BuildMI(*I.getParent(), I, I.getDebugLoc(),
993 TII.get(TargetOpcode::SUBREG_TO_REG))
994 .addDef(DstReg)
995 .addImm(0)
996 .addReg(SrcReg)
997 .addImm(getSubRegIndex(SrcRC));
998
999 I.eraseFromParent();
1000 return true;
1001}
1002
1003bool X86InstructionSelector::selectCmp(MachineInstr &I,
1005 MachineFunction &MF) const {
1006 assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
1007
1008 X86::CondCode CC;
1009 bool SwapArgs;
1010 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
1011 (CmpInst::Predicate)I.getOperand(1).getPredicate());
1012
1013 Register LHS = I.getOperand(2).getReg();
1014 Register RHS = I.getOperand(3).getReg();
1015
1016 if (SwapArgs)
1017 std::swap(LHS, RHS);
1018
1019 unsigned OpCmp;
1020 LLT Ty = MRI.getType(LHS);
1021
1022 switch (Ty.getSizeInBits()) {
1023 default:
1024 return false;
1025 case 8:
1026 OpCmp = X86::CMP8rr;
1027 break;
1028 case 16:
1029 OpCmp = X86::CMP16rr;
1030 break;
1031 case 32:
1032 OpCmp = X86::CMP32rr;
1033 break;
1034 case 64:
1035 OpCmp = X86::CMP64rr;
1036 break;
1037 }
1038
1040 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
1041 .addReg(LHS)
1042 .addReg(RHS);
1043
1044 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1045 TII.get(X86::SETCCr), I.getOperand(0).getReg()).addImm(CC);
1046
1049
1050 I.eraseFromParent();
1051 return true;
1052}
1053
1054bool X86InstructionSelector::selectFCmp(MachineInstr &I,
1056 MachineFunction &MF) const {
1057 assert((I.getOpcode() == TargetOpcode::G_FCMP) && "unexpected instruction");
1058
1059 Register LhsReg = I.getOperand(2).getReg();
1060 Register RhsReg = I.getOperand(3).getReg();
1062 (CmpInst::Predicate)I.getOperand(1).getPredicate();
1063
1064 // FCMP_OEQ and FCMP_UNE cannot be checked with a single instruction.
1065 static const uint16_t SETFOpcTable[2][3] = {
1066 {X86::COND_E, X86::COND_NP, X86::AND8rr},
1067 {X86::COND_NE, X86::COND_P, X86::OR8rr}};
1068 const uint16_t *SETFOpc = nullptr;
1069 switch (Predicate) {
1070 default:
1071 break;
1072 case CmpInst::FCMP_OEQ:
1073 SETFOpc = &SETFOpcTable[0][0];
1074 break;
1075 case CmpInst::FCMP_UNE:
1076 SETFOpc = &SETFOpcTable[1][0];
1077 break;
1078 }
1079
1080 assert((LhsReg.isVirtual() && RhsReg.isVirtual()) &&
1081 "Both arguments of FCMP need to be virtual!");
1082 auto *LhsBank = RBI.getRegBank(LhsReg, MRI, TRI);
1083 [[maybe_unused]] auto *RhsBank = RBI.getRegBank(RhsReg, MRI, TRI);
1084 assert((LhsBank == RhsBank) &&
1085 "Both banks assigned to FCMP arguments need to be same!");
1086
1087 // Compute the opcode for the CMP instruction.
1088 unsigned OpCmp;
1089 LLT Ty = MRI.getType(LhsReg);
1090 switch (Ty.getSizeInBits()) {
1091 default:
1092 return false;
1093 case 32:
1094 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr32
1095 : X86::UCOMISSrr;
1096 break;
1097 case 64:
1098 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr64
1099 : X86::UCOMISDrr;
1100 break;
1101 case 80:
1102 OpCmp = X86::UCOM_FpIr80;
1103 break;
1104 }
1105
1106 Register ResultReg = I.getOperand(0).getReg();
1107 RBI.constrainGenericRegister(
1108 ResultReg,
1109 *getRegClass(LLT::scalar(8), *RBI.getRegBank(ResultReg, MRI, TRI)), MRI);
1110 if (SETFOpc) {
1112 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
1113 .addReg(LhsReg)
1114 .addReg(RhsReg);
1115
1116 Register FlagReg1 = MRI.createVirtualRegister(&X86::GR8RegClass);
1117 Register FlagReg2 = MRI.createVirtualRegister(&X86::GR8RegClass);
1118 MachineInstr &Set1 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1119 TII.get(X86::SETCCr), FlagReg1).addImm(SETFOpc[0]);
1120 MachineInstr &Set2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1121 TII.get(X86::SETCCr), FlagReg2).addImm(SETFOpc[1]);
1122 MachineInstr &Set3 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1123 TII.get(SETFOpc[2]), ResultReg)
1124 .addReg(FlagReg1)
1125 .addReg(FlagReg2);
1130
1131 I.eraseFromParent();
1132 return true;
1133 }
1134
1135 X86::CondCode CC;
1136 bool SwapArgs;
1137 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(Predicate);
1138 assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
1139
1140 if (SwapArgs)
1141 std::swap(LhsReg, RhsReg);
1142
1143 // Emit a compare of LHS/RHS.
1145 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
1146 .addReg(LhsReg)
1147 .addReg(RhsReg);
1148
1149 MachineInstr &Set =
1150 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::SETCCr), ResultReg).addImm(CC);
1153 I.eraseFromParent();
1154 return true;
1155}
1156
1157bool X86InstructionSelector::selectUAddSub(MachineInstr &I,
1159 MachineFunction &MF) const {
1160 assert((I.getOpcode() == TargetOpcode::G_UADDE ||
1161 I.getOpcode() == TargetOpcode::G_UADDO ||
1162 I.getOpcode() == TargetOpcode::G_USUBE ||
1163 I.getOpcode() == TargetOpcode::G_USUBO) &&
1164 "unexpected instruction");
1165
1166 const Register DstReg = I.getOperand(0).getReg();
1167 const Register CarryOutReg = I.getOperand(1).getReg();
1168 const Register Op0Reg = I.getOperand(2).getReg();
1169 const Register Op1Reg = I.getOperand(3).getReg();
1170 bool IsSub = I.getOpcode() == TargetOpcode::G_USUBE ||
1171 I.getOpcode() == TargetOpcode::G_USUBO;
1172 bool HasCarryIn = I.getOpcode() == TargetOpcode::G_UADDE ||
1173 I.getOpcode() == TargetOpcode::G_USUBE;
1174
1175 const LLT DstTy = MRI.getType(DstReg);
1176 assert(DstTy.isScalar() && "selectUAddSub only supported for scalar types");
1177
1178 // TODO: Handle immediate argument variants?
1179 unsigned OpADC, OpADD, OpSBB, OpSUB;
1180 switch (DstTy.getSizeInBits()) {
1181 case 8:
1182 OpADC = X86::ADC8rr;
1183 OpADD = X86::ADD8rr;
1184 OpSBB = X86::SBB8rr;
1185 OpSUB = X86::SUB8rr;
1186 break;
1187 case 16:
1188 OpADC = X86::ADC16rr;
1189 OpADD = X86::ADD16rr;
1190 OpSBB = X86::SBB16rr;
1191 OpSUB = X86::SUB16rr;
1192 break;
1193 case 32:
1194 OpADC = X86::ADC32rr;
1195 OpADD = X86::ADD32rr;
1196 OpSBB = X86::SBB32rr;
1197 OpSUB = X86::SUB32rr;
1198 break;
1199 case 64:
1200 OpADC = X86::ADC64rr;
1201 OpADD = X86::ADD64rr;
1202 OpSBB = X86::SBB64rr;
1203 OpSUB = X86::SUB64rr;
1204 break;
1205 default:
1206 llvm_unreachable("selectUAddSub unsupported type.");
1207 }
1208
1209 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1210 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
1211
1212 unsigned Opcode = IsSub ? OpSUB : OpADD;
1213
1214 // G_UADDE/G_USUBE - find CarryIn def instruction.
1215 if (HasCarryIn) {
1216 Register CarryInReg = I.getOperand(4).getReg();
1217 MachineInstr *Def = MRI.getVRegDef(CarryInReg);
1218 while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
1219 CarryInReg = Def->getOperand(1).getReg();
1220 Def = MRI.getVRegDef(CarryInReg);
1221 }
1222
1223 // TODO - handle more CF generating instructions
1224 if (Def->getOpcode() == TargetOpcode::G_UADDE ||
1225 Def->getOpcode() == TargetOpcode::G_UADDO ||
1226 Def->getOpcode() == TargetOpcode::G_USUBE ||
1227 Def->getOpcode() == TargetOpcode::G_USUBO) {
1228 // carry set by prev ADD/SUB.
1229 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY),
1230 X86::EFLAGS)
1231 .addReg(CarryInReg);
1232
1233 if (!RBI.constrainGenericRegister(CarryInReg, *DstRC, MRI))
1234 return false;
1235
1236 Opcode = IsSub ? OpSBB : OpADC;
1237 } else if (auto val = getIConstantVRegVal(CarryInReg, MRI)) {
1238 // carry is constant, support only 0.
1239 if (*val != 0)
1240 return false;
1241
1242 Opcode = IsSub ? OpSUB : OpADD;
1243 } else
1244 return false;
1245 }
1246
1247 MachineInstr &Inst =
1248 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1249 .addReg(Op0Reg)
1250 .addReg(Op1Reg);
1251
1252 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
1253 .addReg(X86::EFLAGS);
1254
1255 if (!constrainSelectedInstRegOperands(Inst, TII, TRI, RBI) ||
1256 !RBI.constrainGenericRegister(CarryOutReg, *DstRC, MRI))
1257 return false;
1258
1259 I.eraseFromParent();
1260 return true;
1261}
1262
1263bool X86InstructionSelector::selectExtract(MachineInstr &I,
1265 MachineFunction &MF) const {
1266 assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1267 "unexpected instruction");
1268
1269 const Register DstReg = I.getOperand(0).getReg();
1270 const Register SrcReg = I.getOperand(1).getReg();
1271 int64_t Index = I.getOperand(2).getImm();
1272
1273 const LLT DstTy = MRI.getType(DstReg);
1274 const LLT SrcTy = MRI.getType(SrcReg);
1275
1276 // Meanwile handle vector type only.
1277 if (!DstTy.isVector())
1278 return false;
1279
1280 if (Index % DstTy.getSizeInBits() != 0)
1281 return false; // Not extract subvector.
1282
1283 if (Index == 0) {
1284 // Replace by extract subreg copy.
1285 if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
1286 return false;
1287
1288 I.eraseFromParent();
1289 return true;
1290 }
1291
1292 bool HasAVX = STI.hasAVX();
1293 bool HasAVX512 = STI.hasAVX512();
1294 bool HasVLX = STI.hasVLX();
1295
1296 if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
1297 if (HasVLX)
1298 I.setDesc(TII.get(X86::VEXTRACTF32X4Z256rri));
1299 else if (HasAVX)
1300 I.setDesc(TII.get(X86::VEXTRACTF128rri));
1301 else
1302 return false;
1303 } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
1304 if (DstTy.getSizeInBits() == 128)
1305 I.setDesc(TII.get(X86::VEXTRACTF32X4Zrri));
1306 else if (DstTy.getSizeInBits() == 256)
1307 I.setDesc(TII.get(X86::VEXTRACTF64X4Zrri));
1308 else
1309 return false;
1310 } else
1311 return false;
1312
1313 // Convert to X86 VEXTRACT immediate.
1314 Index = Index / DstTy.getSizeInBits();
1315 I.getOperand(2).setImm(Index);
1316
1318}
1319
1320bool X86InstructionSelector::emitExtractSubreg(Register DstReg, Register SrcReg,
1321 MachineInstr &I,
1323 MachineFunction &MF) const {
1324 const LLT DstTy = MRI.getType(DstReg);
1325 const LLT SrcTy = MRI.getType(SrcReg);
1326 unsigned SubIdx = X86::NoSubRegister;
1327
1328 if (!DstTy.isVector() || !SrcTy.isVector())
1329 return false;
1330
1331 assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
1332 "Incorrect Src/Dst register size");
1333
1334 if (DstTy.getSizeInBits() == 128)
1335 SubIdx = X86::sub_xmm;
1336 else if (DstTy.getSizeInBits() == 256)
1337 SubIdx = X86::sub_ymm;
1338 else
1339 return false;
1340
1341 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1342 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1343
1344 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1345
1346 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1347 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1348 LLVM_DEBUG(dbgs() << "Failed to constrain EXTRACT_SUBREG\n");
1349 return false;
1350 }
1351
1352 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
1353 .addReg(SrcReg, 0, SubIdx);
1354
1355 return true;
1356}
1357
1358bool X86InstructionSelector::emitInsertSubreg(Register DstReg, Register SrcReg,
1359 MachineInstr &I,
1361 MachineFunction &MF) const {
1362 const LLT DstTy = MRI.getType(DstReg);
1363 const LLT SrcTy = MRI.getType(SrcReg);
1364 unsigned SubIdx = X86::NoSubRegister;
1365
1366 // TODO: support scalar types
1367 if (!DstTy.isVector() || !SrcTy.isVector())
1368 return false;
1369
1370 assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1371 "Incorrect Src/Dst register size");
1372
1373 if (SrcTy.getSizeInBits() == 128)
1374 SubIdx = X86::sub_xmm;
1375 else if (SrcTy.getSizeInBits() == 256)
1376 SubIdx = X86::sub_ymm;
1377 else
1378 return false;
1379
1380 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1381 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1382
1383 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1384 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1385 LLVM_DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1386 return false;
1387 }
1388
1389 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1390 .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1391 .addReg(SrcReg);
1392
1393 return true;
1394}
1395
1396bool X86InstructionSelector::selectInsert(MachineInstr &I,
1398 MachineFunction &MF) const {
1399 assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
1400
1401 const Register DstReg = I.getOperand(0).getReg();
1402 const Register SrcReg = I.getOperand(1).getReg();
1403 const Register InsertReg = I.getOperand(2).getReg();
1404 int64_t Index = I.getOperand(3).getImm();
1405
1406 const LLT DstTy = MRI.getType(DstReg);
1407 const LLT InsertRegTy = MRI.getType(InsertReg);
1408
1409 // Meanwile handle vector type only.
1410 if (!DstTy.isVector())
1411 return false;
1412
1413 if (Index % InsertRegTy.getSizeInBits() != 0)
1414 return false; // Not insert subvector.
1415
1416 if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1417 // Replace by subreg copy.
1418 if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1419 return false;
1420
1421 I.eraseFromParent();
1422 return true;
1423 }
1424
1425 bool HasAVX = STI.hasAVX();
1426 bool HasAVX512 = STI.hasAVX512();
1427 bool HasVLX = STI.hasVLX();
1428
1429 if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
1430 if (HasVLX)
1431 I.setDesc(TII.get(X86::VINSERTF32X4Z256rri));
1432 else if (HasAVX)
1433 I.setDesc(TII.get(X86::VINSERTF128rri));
1434 else
1435 return false;
1436 } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
1437 if (InsertRegTy.getSizeInBits() == 128)
1438 I.setDesc(TII.get(X86::VINSERTF32X4Zrri));
1439 else if (InsertRegTy.getSizeInBits() == 256)
1440 I.setDesc(TII.get(X86::VINSERTF64X4Zrri));
1441 else
1442 return false;
1443 } else
1444 return false;
1445
1446 // Convert to X86 VINSERT immediate.
1447 Index = Index / InsertRegTy.getSizeInBits();
1448
1449 I.getOperand(3).setImm(Index);
1450
1452}
1453
1454bool X86InstructionSelector::selectUnmergeValues(
1456 assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1457 "unexpected instruction");
1458
1459 // Split to extracts.
1460 unsigned NumDefs = I.getNumOperands() - 1;
1461 Register SrcReg = I.getOperand(NumDefs).getReg();
1462 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1463
1464 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1465 MachineInstr &ExtrInst =
1466 *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1467 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1468 .addReg(SrcReg)
1469 .addImm(Idx * DefSize);
1470
1471 if (!select(ExtrInst))
1472 return false;
1473 }
1474
1475 I.eraseFromParent();
1476 return true;
1477}
1478
1479bool X86InstructionSelector::selectMergeValues(
1481 assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1482 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1483 "unexpected instruction");
1484
1485 // Split to inserts.
1486 Register DstReg = I.getOperand(0).getReg();
1487 Register SrcReg0 = I.getOperand(1).getReg();
1488
1489 const LLT DstTy = MRI.getType(DstReg);
1490 const LLT SrcTy = MRI.getType(SrcReg0);
1491 unsigned SrcSize = SrcTy.getSizeInBits();
1492
1493 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1494
1495 // For the first src use insertSubReg.
1496 Register DefReg = MRI.createGenericVirtualRegister(DstTy);
1497 MRI.setRegBank(DefReg, RegBank);
1498 if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1499 return false;
1500
1501 for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
1502 Register Tmp = MRI.createGenericVirtualRegister(DstTy);
1503 MRI.setRegBank(Tmp, RegBank);
1504
1505 MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1506 TII.get(TargetOpcode::G_INSERT), Tmp)
1507 .addReg(DefReg)
1508 .addReg(I.getOperand(Idx).getReg())
1509 .addImm((Idx - 1) * SrcSize);
1510
1511 DefReg = Tmp;
1512
1513 if (!select(InsertInst))
1514 return false;
1515 }
1516
1517 MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1518 TII.get(TargetOpcode::COPY), DstReg)
1519 .addReg(DefReg);
1520
1521 if (!select(CopyInst))
1522 return false;
1523
1524 I.eraseFromParent();
1525 return true;
1526}
1527
1528bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1530 MachineFunction &MF) const {
1531 assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
1532
1533 const Register CondReg = I.getOperand(0).getReg();
1534 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1535
1536 MachineInstr &TestInst =
1537 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1538 .addReg(CondReg)
1539 .addImm(1);
1540 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JCC_1))
1541 .addMBB(DestMBB).addImm(X86::COND_NE);
1542
1543 constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1544
1545 I.eraseFromParent();
1546 return true;
1547}
1548
1549bool X86InstructionSelector::materializeFP(MachineInstr &I,
1551 MachineFunction &MF) const {
1552 assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1553 "unexpected instruction");
1554
1555 // Can't handle alternate code models yet.
1556 CodeModel::Model CM = TM.getCodeModel();
1557 if (CM != CodeModel::Small && CM != CodeModel::Large)
1558 return false;
1559
1560 const Register DstReg = I.getOperand(0).getReg();
1561 const LLT DstTy = MRI.getType(DstReg);
1562 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1563 // Create the load from the constant pool.
1564 const ConstantFP *CFP = I.getOperand(1).getFPImm();
1565 const auto &DL = MF.getDataLayout();
1566 Align Alignment = DL.getPrefTypeAlign(CFP->getType());
1567 const DebugLoc &DbgLoc = I.getDebugLoc();
1568
1569 unsigned Opc =
1570 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1571
1572 unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Alignment);
1573 MachineInstr *LoadInst = nullptr;
1574 unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1575
1576 if (CM == CodeModel::Large && STI.is64Bit()) {
1577 // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1578 // they cannot be folded into immediate fields.
1579
1580 Register AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1581 BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1582 .addConstantPoolIndex(CPI, 0, OpFlag);
1583
1586 LLT::pointer(0, DL.getPointerSizeInBits()), Alignment);
1587
1588 LoadInst =
1589 addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1590 AddrReg)
1591 .addMemOperand(MMO);
1592
1593 } else if (CM == CodeModel::Small || !STI.is64Bit()) {
1594 // Handle the case when globals fit in our immediate field.
1595 // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1596
1597 // x86-32 PIC requires a PIC base register for constant pools.
1598 unsigned PICBase = 0;
1599 if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
1600 // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1601 // In DAGISEL the code that initialize it generated by the CGBR pass.
1602 return false; // TODO support the mode.
1603 } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
1604 PICBase = X86::RIP;
1605
1607 BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1608 OpFlag);
1609 } else
1610 return false;
1611
1613 I.eraseFromParent();
1614 return true;
1615}
1616
1617bool X86InstructionSelector::selectImplicitDefOrPHI(
1619 assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1620 I.getOpcode() == TargetOpcode::G_PHI) &&
1621 "unexpected instruction");
1622
1623 Register DstReg = I.getOperand(0).getReg();
1624
1625 if (!MRI.getRegClassOrNull(DstReg)) {
1626 const LLT DstTy = MRI.getType(DstReg);
1627 const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1628
1629 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1630 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1631 << " operand\n");
1632 return false;
1633 }
1634 }
1635
1636 if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1637 I.setDesc(TII.get(X86::IMPLICIT_DEF));
1638 else
1639 I.setDesc(TII.get(X86::PHI));
1640
1641 return true;
1642}
1643
1644bool X86InstructionSelector::selectMulDivRem(MachineInstr &I,
1646 MachineFunction &MF) const {
1647 // The implementation of this function is adapted from X86FastISel.
1648 assert((I.getOpcode() == TargetOpcode::G_MUL ||
1649 I.getOpcode() == TargetOpcode::G_SMULH ||
1650 I.getOpcode() == TargetOpcode::G_UMULH ||
1651 I.getOpcode() == TargetOpcode::G_SDIV ||
1652 I.getOpcode() == TargetOpcode::G_SREM ||
1653 I.getOpcode() == TargetOpcode::G_UDIV ||
1654 I.getOpcode() == TargetOpcode::G_UREM) &&
1655 "unexpected instruction");
1656
1657 const Register DstReg = I.getOperand(0).getReg();
1658 const Register Op1Reg = I.getOperand(1).getReg();
1659 const Register Op2Reg = I.getOperand(2).getReg();
1660
1661 const LLT RegTy = MRI.getType(DstReg);
1662 assert(RegTy == MRI.getType(Op1Reg) && RegTy == MRI.getType(Op2Reg) &&
1663 "Arguments and return value types must match");
1664
1665 const RegisterBank *RegRB = RBI.getRegBank(DstReg, MRI, TRI);
1666 if (!RegRB || RegRB->getID() != X86::GPRRegBankID)
1667 return false;
1668
1669 const static unsigned NumTypes = 4; // i8, i16, i32, i64
1670 const static unsigned NumOps = 7; // SDiv/SRem/UDiv/URem/Mul/SMulH/UMulh
1671 const static bool S = true; // IsSigned
1672 const static bool U = false; // !IsSigned
1673 const static unsigned Copy = TargetOpcode::COPY;
1674
1675 // For the X86 IDIV instruction, in most cases the dividend
1676 // (numerator) must be in a specific register pair highreg:lowreg,
1677 // producing the quotient in lowreg and the remainder in highreg.
1678 // For most data types, to set up the instruction, the dividend is
1679 // copied into lowreg, and lowreg is sign-extended into highreg. The
1680 // exception is i8, where the dividend is defined as a single register rather
1681 // than a register pair, and we therefore directly sign-extend the dividend
1682 // into lowreg, instead of copying, and ignore the highreg.
1683 const static struct MulDivRemEntry {
1684 // The following portion depends only on the data type.
1685 unsigned SizeInBits;
1686 unsigned LowInReg; // low part of the register pair
1687 unsigned HighInReg; // high part of the register pair
1688 // The following portion depends on both the data type and the operation.
1689 struct MulDivRemResult {
1690 unsigned OpMulDivRem; // The specific MUL/DIV opcode to use.
1691 unsigned OpSignExtend; // Opcode for sign-extending lowreg into
1692 // highreg, or copying a zero into highreg.
1693 unsigned OpCopy; // Opcode for copying dividend into lowreg, or
1694 // zero/sign-extending into lowreg for i8.
1695 unsigned ResultReg; // Register containing the desired result.
1696 bool IsOpSigned; // Whether to use signed or unsigned form.
1697 } ResultTable[NumOps];
1698 } OpTable[NumTypes] = {
1699 {8,
1700 X86::AX,
1701 0,
1702 {
1703 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S}, // SDiv
1704 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S}, // SRem
1705 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL, U}, // UDiv
1706 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH, U}, // URem
1707 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S}, // Mul
1708 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S}, // SMulH
1709 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH, U}, // UMulH
1710 }}, // i8
1711 {16,
1712 X86::AX,
1713 X86::DX,
1714 {
1715 {X86::IDIV16r, X86::CWD, Copy, X86::AX, S}, // SDiv
1716 {X86::IDIV16r, X86::CWD, Copy, X86::DX, S}, // SRem
1717 {X86::DIV16r, X86::MOV32r0, Copy, X86::AX, U}, // UDiv
1718 {X86::DIV16r, X86::MOV32r0, Copy, X86::DX, U}, // URem
1719 {X86::IMUL16r, X86::MOV32r0, Copy, X86::AX, S}, // Mul
1720 {X86::IMUL16r, X86::MOV32r0, Copy, X86::DX, S}, // SMulH
1721 {X86::MUL16r, X86::MOV32r0, Copy, X86::DX, U}, // UMulH
1722 }}, // i16
1723 {32,
1724 X86::EAX,
1725 X86::EDX,
1726 {
1727 {X86::IDIV32r, X86::CDQ, Copy, X86::EAX, S}, // SDiv
1728 {X86::IDIV32r, X86::CDQ, Copy, X86::EDX, S}, // SRem
1729 {X86::DIV32r, X86::MOV32r0, Copy, X86::EAX, U}, // UDiv
1730 {X86::DIV32r, X86::MOV32r0, Copy, X86::EDX, U}, // URem
1731 {X86::IMUL32r, X86::MOV32r0, Copy, X86::EAX, S}, // Mul
1732 {X86::IMUL32r, X86::MOV32r0, Copy, X86::EDX, S}, // SMulH
1733 {X86::MUL32r, X86::MOV32r0, Copy, X86::EDX, U}, // UMulH
1734 }}, // i32
1735 {64,
1736 X86::RAX,
1737 X86::RDX,
1738 {
1739 {X86::IDIV64r, X86::CQO, Copy, X86::RAX, S}, // SDiv
1740 {X86::IDIV64r, X86::CQO, Copy, X86::RDX, S}, // SRem
1741 {X86::DIV64r, X86::MOV32r0, Copy, X86::RAX, U}, // UDiv
1742 {X86::DIV64r, X86::MOV32r0, Copy, X86::RDX, U}, // URem
1743 {X86::IMUL64r, X86::MOV32r0, Copy, X86::RAX, S}, // Mul
1744 {X86::IMUL64r, X86::MOV32r0, Copy, X86::RDX, S}, // SMulH
1745 {X86::MUL64r, X86::MOV32r0, Copy, X86::RDX, U}, // UMulH
1746 }}, // i64
1747 };
1748
1749 auto OpEntryIt = llvm::find_if(OpTable, [RegTy](const MulDivRemEntry &El) {
1750 return El.SizeInBits == RegTy.getSizeInBits();
1751 });
1752 if (OpEntryIt == std::end(OpTable))
1753 return false;
1754
1755 unsigned OpIndex;
1756 switch (I.getOpcode()) {
1757 default:
1758 llvm_unreachable("Unexpected mul/div/rem opcode");
1759 case TargetOpcode::G_SDIV:
1760 OpIndex = 0;
1761 break;
1762 case TargetOpcode::G_SREM:
1763 OpIndex = 1;
1764 break;
1765 case TargetOpcode::G_UDIV:
1766 OpIndex = 2;
1767 break;
1768 case TargetOpcode::G_UREM:
1769 OpIndex = 3;
1770 break;
1771 case TargetOpcode::G_MUL:
1772 OpIndex = 4;
1773 break;
1774 case TargetOpcode::G_SMULH:
1775 OpIndex = 5;
1776 break;
1777 case TargetOpcode::G_UMULH:
1778 OpIndex = 6;
1779 break;
1780 }
1781
1782 const MulDivRemEntry &TypeEntry = *OpEntryIt;
1783 const MulDivRemEntry::MulDivRemResult &OpEntry =
1784 TypeEntry.ResultTable[OpIndex];
1785
1786 const TargetRegisterClass *RegRC = getRegClass(RegTy, *RegRB);
1787 if (!RBI.constrainGenericRegister(Op1Reg, *RegRC, MRI) ||
1788 !RBI.constrainGenericRegister(Op2Reg, *RegRC, MRI) ||
1789 !RBI.constrainGenericRegister(DstReg, *RegRC, MRI)) {
1790 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1791 << " operand\n");
1792 return false;
1793 }
1794
1795 // Move op1 into low-order input register.
1796 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpEntry.OpCopy),
1797 TypeEntry.LowInReg)
1798 .addReg(Op1Reg);
1799
1800 // Zero-extend or sign-extend into high-order input register.
1801 if (OpEntry.OpSignExtend) {
1802 if (OpEntry.IsOpSigned)
1803 BuildMI(*I.getParent(), I, I.getDebugLoc(),
1804 TII.get(OpEntry.OpSignExtend));
1805 else {
1806 Register Zero32 = MRI.createVirtualRegister(&X86::GR32RegClass);
1807 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::MOV32r0),
1808 Zero32);
1809
1810 // Copy the zero into the appropriate sub/super/identical physical
1811 // register. Unfortunately the operations needed are not uniform enough
1812 // to fit neatly into the table above.
1813 if (RegTy.getSizeInBits() == 16) {
1814 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy),
1815 TypeEntry.HighInReg)
1816 .addReg(Zero32, 0, X86::sub_16bit);
1817 } else if (RegTy.getSizeInBits() == 32) {
1818 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy),
1819 TypeEntry.HighInReg)
1820 .addReg(Zero32);
1821 } else if (RegTy.getSizeInBits() == 64) {
1822 BuildMI(*I.getParent(), I, I.getDebugLoc(),
1823 TII.get(TargetOpcode::SUBREG_TO_REG), TypeEntry.HighInReg)
1824 .addImm(0)
1825 .addReg(Zero32)
1826 .addImm(X86::sub_32bit);
1827 }
1828 }
1829 }
1830
1831 // Generate the DIV/IDIV/MUL/IMUL instruction.
1832 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpEntry.OpMulDivRem))
1833 .addReg(Op2Reg);
1834
1835 // For i8 remainder, we can't reference ah directly, as we'll end
1836 // up with bogus copies like %r9b = COPY %ah. Reference ax
1837 // instead to prevent ah references in a rex instruction.
1838 //
1839 // The current assumption of the fast register allocator is that isel
1840 // won't generate explicit references to the GR8_NOREX registers. If
1841 // the allocator and/or the backend get enhanced to be more robust in
1842 // that regard, this can be, and should be, removed.
1843 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1844 Register SourceSuperReg = MRI.createVirtualRegister(&X86::GR16RegClass);
1845 Register ResultSuperReg = MRI.createVirtualRegister(&X86::GR16RegClass);
1846 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy), SourceSuperReg)
1847 .addReg(X86::AX);
1848
1849 // Shift AX right by 8 bits instead of using AH.
1850 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::SHR16ri),
1851 ResultSuperReg)
1852 .addReg(SourceSuperReg)
1853 .addImm(8);
1854
1855 // Now reference the 8-bit subreg of the result.
1856 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1857 DstReg)
1858 .addReg(ResultSuperReg, 0, X86::sub_8bit);
1859 } else {
1860 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1861 DstReg)
1862 .addReg(OpEntry.ResultReg);
1863 }
1864 I.eraseFromParent();
1865
1866 return true;
1867}
1868
1869bool X86InstructionSelector::selectSelect(MachineInstr &I,
1871 MachineFunction &MF) const {
1872 GSelect &Sel = cast<GSelect>(I);
1873 Register DstReg = Sel.getReg(0);
1874 BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(X86::TEST32rr))
1875 .addReg(Sel.getCondReg())
1876 .addReg(Sel.getCondReg());
1877
1878 unsigned OpCmp;
1879 LLT Ty = MRI.getType(DstReg);
1880 switch (Ty.getSizeInBits()) {
1881 default:
1882 return false;
1883 case 8:
1884 OpCmp = X86::CMOV_GR8;
1885 break;
1886 case 16:
1887 OpCmp = STI.canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1888 break;
1889 case 32:
1890 OpCmp = STI.canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1891 break;
1892 case 64:
1893 assert(STI.is64Bit() && STI.canUseCMOV());
1894 OpCmp = X86::CMOV64rr;
1895 break;
1896 }
1897 BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(OpCmp), DstReg)
1898 .addReg(Sel.getTrueReg())
1899 .addReg(Sel.getFalseReg())
1901
1902 const TargetRegisterClass *DstRC = getRegClass(Ty, DstReg, MRI);
1903 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1904 LLVM_DEBUG(dbgs() << "Failed to constrain CMOV\n");
1905 return false;
1906 }
1907
1908 Sel.eraseFromParent();
1909 return true;
1910}
1911
1913X86InstructionSelector::selectAddr(MachineOperand &Root) const {
1914 MachineInstr *MI = Root.getParent();
1915 MachineIRBuilder MIRBuilder(*MI);
1916
1917 MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
1918 MachineInstr *Ptr = MRI.getVRegDef(Root.getReg());
1919 X86AddressMode AM;
1920 X86SelectAddress(*Ptr, TM, MRI, STI, AM);
1921
1922 if (AM.IndexReg)
1923 return std::nullopt;
1924
1925 return {// Base
1926 {[=](MachineInstrBuilder &MIB) {
1928 MIB.addUse(AM.Base.Reg);
1929 else {
1931 "Unknown type of address base");
1932 MIB.addFrameIndex(AM.Base.FrameIndex);
1933 }
1934 },
1935 // Scale
1936 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.Scale); },
1937 // Index
1938 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
1939 // Disp
1940 [=](MachineInstrBuilder &MIB) {
1941 if (AM.GV)
1942 MIB.addGlobalAddress(AM.GV, AM.Disp, AM.GVOpFlags);
1943 else if (AM.CP)
1944 MIB.addConstantPoolIndex(AM.Disp, 0, AM.GVOpFlags);
1945 else
1946 MIB.addImm(AM.Disp);
1947 },
1948 // Segment
1949 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
1950}
1951
1954 const X86Subtarget &Subtarget,
1955 const X86RegisterBankInfo &RBI) {
1956 return new X86InstructionSelector(TM, Subtarget, RBI);
1957}
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define DEBUG_TYPE
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Implement a low-level type suitable for MachineInstr level instruction selection.
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
static StringRef getName(Value *V)
unsigned OpIndex
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
#define LLVM_DEBUG(...)
Definition: Debug.h:119
static bool X86SelectAddress(MachineInstr &I, const X86TargetMachine &TM, const MachineRegisterInfo &MRI, const X86Subtarget &STI, X86AddressMode &AM)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC, const TargetRegisterClass *SrcRC)
static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI)
static const TargetRegisterClass * getRegClassFromGRPhysReg(Register Reg)
Value * RHS
Value * LHS
This file declares the targeting of the RegisterBankInfo class for X86.
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:666
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:678
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition: InstrTypes.h:681
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Definition: InstrTypes.h:694
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:277
A debug info location.
Definition: DebugLoc.h:124
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
Represents a G_SELECT.
Register getCondReg() const
Register getFalseReg() const
Register getTrueReg() const
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
virtual bool select(MachineInstr &I)=0
Select the (possibly generic) instruction I to only use target-specific opcodes.
constexpr bool isScalar() const
Definition: LowLevelType.h:147
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:43
constexpr bool isVector() const
Definition: LowLevelType.h:149
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelType.h:58
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:191
constexpr bool isPointer() const
Definition: LowLevelType.h:150
An instruction for reading from memory.
Definition: Instructions.h:180
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, 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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
Helper class to build MachineInstr.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
Definition: MachineInstr.h:72
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:359
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:511
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements the register bank concept.
Definition: RegisterBank.h:29
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:46
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:74
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:78
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
Register getGlobalBaseReg(MachineFunction *MF) const
getGlobalBaseReg - Return a virtual register initialized with the the global base register value.
This class provides the information for the target register banks.
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
Definition: X86Subtarget.h:173
const X86InstrInfo * getInstrInfo() const override
Definition: X86Subtarget.h:122
unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const
bool isPICStyleRIPRel() const
Definition: X86Subtarget.h:334
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Reg
All possible values of the reg field in the ModR/M byte.
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
Definition: X86BaseInfo.h:381
@ 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:371
@ LAST_VALID_COND
Definition: X86BaseInfo.h:94
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...
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
Definition: TypePool.h:27
NodeAddr< DefNode * > Def
Definition: RDFGraph.h:384
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
Definition: X86InstrInfo.h:121
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
Definition: X86InstrInfo.h:139
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
Definition: Utils.cpp:294
LLVM_ABI 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:155
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
static const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, Register GlobalBaseReg, unsigned char OpFlags)
addConstantPoolReference - This function is used to add a reference to the base of a constant value s...
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
LLVM_ABI std::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:314
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
static const MachineInstrBuilder & addOffset(const MachineInstrBuilder &MIB, int Offset)
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:1777
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, Register Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – th...
InstructionSelector * createX86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &, const X86RegisterBankInfo &)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
X86AddressMode - This struct holds a generalized full x86 address mode.
enum llvm::X86AddressMode::@679 BaseType
const GlobalValue * GV
union llvm::X86AddressMode::BaseUnion Base