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