blob: d538ef1f3518e2410668e3c7f8764d4b97de5a6a [file] [log] [blame]
Eugene Zelenko60433b62017-10-05 00:33:50 +00001//===- X86InstructionSelector.cpp -----------------------------------------===//
Igor Bregerf7359d82017-02-22 12:25:09 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the targeting of the InstructionSelector class for
11/// X86.
12/// \todo This should be generated by TableGen.
13//===----------------------------------------------------------------------===//
14
Eugene Zelenko60433b62017-10-05 00:33:50 +000015#include "MCTargetDesc/X86BaseInfo.h"
Igor Bregera8ba5722017-03-23 15:25:57 +000016#include "X86InstrBuilder.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000017#include "X86InstrInfo.h"
18#include "X86RegisterBankInfo.h"
19#include "X86RegisterInfo.h"
20#include "X86Subtarget.h"
21#include "X86TargetMachine.h"
Igor Breger3b97ea32017-04-12 12:54:54 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000023#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
24#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
Igor Breger28f290f2017-05-17 12:48:08 +000025#include "llvm/CodeGen/GlobalISel/Utils.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000026#include "llvm/CodeGen/MachineBasicBlock.h"
Igor Breger21200ed2017-09-17 08:08:13 +000027#include "llvm/CodeGen/MachineConstantPool.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000028#include "llvm/CodeGen/MachineFunction.h"
29#include "llvm/CodeGen/MachineInstr.h"
30#include "llvm/CodeGen/MachineInstrBuilder.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000031#include "llvm/CodeGen/MachineMemOperand.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000032#include "llvm/CodeGen/MachineOperand.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000033#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000034#include "llvm/CodeGen/TargetOpcodes.h"
35#include "llvm/CodeGen/TargetRegisterInfo.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000036#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/InstrTypes.h"
38#include "llvm/Support/AtomicOrdering.h"
39#include "llvm/Support/CodeGen.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000040#include "llvm/Support/Debug.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000041#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/LowLevelTypeImpl.h"
43#include "llvm/Support/MathExtras.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000044#include "llvm/Support/raw_ostream.h"
Eugene Zelenko60433b62017-10-05 00:33:50 +000045#include <cassert>
46#include <cstdint>
47#include <tuple>
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000048
David Blaikie62651302017-10-26 23:39:54 +000049#define DEBUG_TYPE "X86-isel"
50
Igor Bregerf7359d82017-02-22 12:25:09 +000051using namespace llvm;
52
Daniel Sanders0b5293f2017-04-06 09:49:34 +000053namespace {
54
Daniel Sanderse7b0d662017-04-21 15:59:56 +000055#define GET_GLOBALISEL_PREDICATE_BITSET
56#include "X86GenGlobalISel.inc"
57#undef GET_GLOBALISEL_PREDICATE_BITSET
58
Daniel Sanders0b5293f2017-04-06 09:49:34 +000059class X86InstructionSelector : public InstructionSelector {
60public:
Daniel Sanderse7b0d662017-04-21 15:59:56 +000061 X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
Daniel Sanders0b5293f2017-04-06 09:49:34 +000062 const X86RegisterBankInfo &RBI);
63
Daniel Sandersf76f3152017-11-16 00:46:35 +000064 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000065 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000066
67private:
68 /// tblgen-erated 'select' implementation, used as the initial selector for
69 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000070 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000071
Hiroshi Inouebb703e82017-07-02 03:24:54 +000072 // TODO: remove after supported by Tablegen-erated instruction selection.
Igor Breger21200ed2017-09-17 08:08:13 +000073 unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
Daniel Sanders0b5293f2017-04-06 09:49:34 +000074 uint64_t Alignment) const;
75
Daniel Sanders0b5293f2017-04-06 09:49:34 +000076 bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
77 MachineFunction &MF) const;
Igor Breger810c6252017-05-08 09:40:43 +000078 bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
79 MachineFunction &MF) const;
Igor Breger717bd362017-07-02 08:58:29 +000080 bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
81 MachineFunction &MF) const;
Igor Breger3b97ea32017-04-12 12:54:54 +000082 bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
83 MachineFunction &MF) const;
Igor Breger4fdf1e42017-04-19 11:34:59 +000084 bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
85 MachineFunction &MF) const;
Igor Bregerfda31e62017-05-10 06:52:58 +000086 bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
87 MachineFunction &MF) const;
Igor Breger1f143642017-09-11 09:41:13 +000088 bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
89 MachineFunction &MF) const;
Igor Bregerc7b59772017-05-11 07:17:40 +000090 bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
91 MachineFunction &MF) const;
Igor Breger28f290f2017-05-17 12:48:08 +000092 bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
93 MachineFunction &MF) const;
Igor Breger1dcd5e82017-06-20 09:15:10 +000094 bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
Igor Bregerb186a692017-07-02 08:15:49 +000095 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
Daniel Sandersf76f3152017-11-16 00:46:35 +000096 MachineFunction &MF,
97 CodeGenCoverage &CoverageInfo) const;
Igor Breger0cddd342017-06-29 12:08:28 +000098 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
Daniel Sandersf76f3152017-11-16 00:46:35 +000099 MachineFunction &MF,
100 CodeGenCoverage &CoverageInfo) const;
Igor Breger1c29be72017-06-22 09:43:35 +0000101 bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
102 MachineFunction &MF) const;
Igor Bregerf5035d62017-06-25 11:42:17 +0000103 bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
104 MachineFunction &MF) const;
Igor Breger685889c2017-08-21 10:51:54 +0000105 bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
106 MachineFunction &MF) const;
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000107 bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
108 const unsigned DstReg,
109 const TargetRegisterClass *DstRC,
110 const unsigned SrcReg,
111 const TargetRegisterClass *SrcRC) const;
Igor Breger21200ed2017-09-17 08:08:13 +0000112 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
113 MachineFunction &MF) const;
Igor Breger2661ae42017-09-04 09:06:45 +0000114 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
Igor Breger1c29be72017-06-22 09:43:35 +0000115
116 // emit insert subreg instruction and insert it before MachineInstr &I
117 bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
118 MachineRegisterInfo &MRI, MachineFunction &MF) const;
Igor Bregerf5035d62017-06-25 11:42:17 +0000119 // emit extract subreg instruction and insert it before MachineInstr &I
120 bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
121 MachineRegisterInfo &MRI, MachineFunction &MF) const;
Igor Breger1dcd5e82017-06-20 09:15:10 +0000122
123 const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
124 const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
125 MachineRegisterInfo &MRI) const;
Igor Breger28f290f2017-05-17 12:48:08 +0000126
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000127 const X86TargetMachine &TM;
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000128 const X86Subtarget &STI;
129 const X86InstrInfo &TII;
130 const X86RegisterInfo &TRI;
131 const X86RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000132
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000133#define GET_GLOBALISEL_PREDICATES_DECL
134#include "X86GenGlobalISel.inc"
135#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000136
137#define GET_GLOBALISEL_TEMPORARIES_DECL
138#include "X86GenGlobalISel.inc"
139#undef GET_GLOBALISEL_TEMPORARIES_DECL
140};
141
142} // end anonymous namespace
143
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000144#define GET_GLOBALISEL_IMPL
Igor Bregerf7359d82017-02-22 12:25:09 +0000145#include "X86GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000146#undef GET_GLOBALISEL_IMPL
Igor Bregerf7359d82017-02-22 12:25:09 +0000147
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000148X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
149 const X86Subtarget &STI,
Igor Bregerf7359d82017-02-22 12:25:09 +0000150 const X86RegisterBankInfo &RBI)
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000151 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000152 TRI(*STI.getRegisterInfo()), RBI(RBI),
153#define GET_GLOBALISEL_PREDICATES_INIT
154#include "X86GenGlobalISel.inc"
155#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000156#define GET_GLOBALISEL_TEMPORARIES_INIT
157#include "X86GenGlobalISel.inc"
158#undef GET_GLOBALISEL_TEMPORARIES_INIT
159{
160}
Igor Bregerf7359d82017-02-22 12:25:09 +0000161
162// FIXME: This should be target-independent, inferred from the types declared
163// for each class in the bank.
Igor Breger1dcd5e82017-06-20 09:15:10 +0000164const TargetRegisterClass *
165X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000166 if (RB.getID() == X86::GPRRegBankID) {
Igor Breger4fdf1e42017-04-19 11:34:59 +0000167 if (Ty.getSizeInBits() <= 8)
168 return &X86::GR8RegClass;
169 if (Ty.getSizeInBits() == 16)
170 return &X86::GR16RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000171 if (Ty.getSizeInBits() == 32)
Igor Bregerf7359d82017-02-22 12:25:09 +0000172 return &X86::GR32RegClass;
173 if (Ty.getSizeInBits() == 64)
174 return &X86::GR64RegClass;
175 }
Igor Breger321cf3c2017-03-03 08:06:46 +0000176 if (RB.getID() == X86::VECRRegBankID) {
177 if (Ty.getSizeInBits() == 32)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000178 return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000179 if (Ty.getSizeInBits() == 64)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000180 return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000181 if (Ty.getSizeInBits() == 128)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000182 return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000183 if (Ty.getSizeInBits() == 256)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000184 return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000185 if (Ty.getSizeInBits() == 512)
186 return &X86::VR512RegClass;
187 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000188
189 llvm_unreachable("Unknown RegBank!");
190}
191
Igor Breger1dcd5e82017-06-20 09:15:10 +0000192const TargetRegisterClass *
193X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg,
194 MachineRegisterInfo &MRI) const {
195 const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
196 return getRegClass(Ty, RegBank);
197}
198
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000199static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
Igor Bregerb3a860a2017-08-20 07:14:40 +0000200 unsigned SubIdx = X86::NoSubRegister;
201 if (RC == &X86::GR32RegClass) {
202 SubIdx = X86::sub_32bit;
203 } else if (RC == &X86::GR16RegClass) {
204 SubIdx = X86::sub_16bit;
205 } else if (RC == &X86::GR8RegClass) {
206 SubIdx = X86::sub_8bit;
207 }
208
209 return SubIdx;
210}
211
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000212static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) {
Igor Bregerb3a860a2017-08-20 07:14:40 +0000213 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
214 if (X86::GR64RegClass.contains(Reg))
215 return &X86::GR64RegClass;
216 if (X86::GR32RegClass.contains(Reg))
217 return &X86::GR32RegClass;
218 if (X86::GR16RegClass.contains(Reg))
219 return &X86::GR16RegClass;
220 if (X86::GR8RegClass.contains(Reg))
221 return &X86::GR8RegClass;
222
223 llvm_unreachable("Unknown RegClass for PhysReg!");
224}
225
Igor Bregerf7359d82017-02-22 12:25:09 +0000226// Set X86 Opcode and constrain DestReg.
Igor Breger1dcd5e82017-06-20 09:15:10 +0000227bool X86InstructionSelector::selectCopy(MachineInstr &I,
228 MachineRegisterInfo &MRI) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000229 unsigned DstReg = I.getOperand(0).getReg();
Igor Bregerb3a860a2017-08-20 07:14:40 +0000230 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
231 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
Igor Bregerf7359d82017-02-22 12:25:09 +0000232
Igor Bregerf7359d82017-02-22 12:25:09 +0000233 unsigned SrcReg = I.getOperand(1).getReg();
234 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Igor Bregerb3a860a2017-08-20 07:14:40 +0000235 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
236
237 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
238 assert(I.isCopy() && "Generic operators do not allow physical registers");
239
240 if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
241 DstRegBank.getID() == X86::GPRRegBankID) {
242
243 const TargetRegisterClass *SrcRC =
244 getRegClass(MRI.getType(SrcReg), SrcRegBank);
245 const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
246
247 if (SrcRC != DstRC) {
248 // This case can be generated by ABI lowering, performe anyext
249 unsigned ExtSrc = MRI.createVirtualRegister(DstRC);
250 BuildMI(*I.getParent(), I, I.getDebugLoc(),
251 TII.get(TargetOpcode::SUBREG_TO_REG))
252 .addDef(ExtSrc)
253 .addImm(0)
254 .addReg(SrcReg)
255 .addImm(getSubRegIndex(SrcRC));
256
257 I.getOperand(1).setReg(ExtSrc);
258 }
259 }
260
261 return true;
262 }
Igor Breger360d0f22017-04-27 08:02:03 +0000263
Igor Bregerf7359d82017-02-22 12:25:09 +0000264 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
265 "No phys reg on generic operators");
266 assert((DstSize == SrcSize ||
267 // Copies are a mean to setup initial types, the number of
268 // bits may not exactly match.
269 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
270 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
271 "Copy with different width?!");
272
Igor Bregerb3a860a2017-08-20 07:14:40 +0000273 const TargetRegisterClass *DstRC =
274 getRegClass(MRI.getType(DstReg), DstRegBank);
Igor Bregerf7359d82017-02-22 12:25:09 +0000275
Igor Bregerb3a860a2017-08-20 07:14:40 +0000276 if (SrcRegBank.getID() == X86::GPRRegBankID &&
277 DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
278 TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
279 // Change the physical register to performe truncate.
Igor Breger360d0f22017-04-27 08:02:03 +0000280
Igor Bregerb3a860a2017-08-20 07:14:40 +0000281 const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
Igor Breger360d0f22017-04-27 08:02:03 +0000282
Igor Bregerb3a860a2017-08-20 07:14:40 +0000283 if (DstRC != SrcRC) {
284 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
Igor Breger360d0f22017-04-27 08:02:03 +0000285 I.getOperand(1).substPhysReg(SrcReg, TRI);
286 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000287 }
288
289 // No need to constrain SrcReg. It will get constrained when
290 // we hit another of its use or its defs.
291 // Copies do not have constraints.
Igor Breger8a924be2017-03-23 12:13:29 +0000292 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
Igor Bregerb3a860a2017-08-20 07:14:40 +0000293 if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
294 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Igor Breger8a924be2017-03-23 12:13:29 +0000295 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
296 << " operand\n");
297 return false;
298 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000299 }
300 I.setDesc(TII.get(X86::COPY));
301 return true;
302}
303
Daniel Sandersf76f3152017-11-16 00:46:35 +0000304bool X86InstructionSelector::select(MachineInstr &I,
305 CodeGenCoverage &CoverageInfo) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000306 assert(I.getParent() && "Instruction should be in a basic block!");
307 assert(I.getParent()->getParent() && "Instruction should be in a function!");
308
309 MachineBasicBlock &MBB = *I.getParent();
310 MachineFunction &MF = *MBB.getParent();
311 MachineRegisterInfo &MRI = MF.getRegInfo();
312
313 unsigned Opcode = I.getOpcode();
314 if (!isPreISelGenericOpcode(Opcode)) {
315 // Certain non-generic instructions also need some special handling.
316
Igor Breger03c22082017-08-21 09:17:28 +0000317 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
318 return false;
Igor Breger03c22082017-08-21 09:17:28 +0000319
Igor Bregerf7359d82017-02-22 12:25:09 +0000320 if (I.isCopy())
Igor Breger1dcd5e82017-06-20 09:15:10 +0000321 return selectCopy(I, MRI);
Igor Bregerf7359d82017-02-22 12:25:09 +0000322
Igor Bregerf7359d82017-02-22 12:25:09 +0000323 return true;
324 }
325
Benjamin Kramer5a7e0f82017-02-22 12:59:47 +0000326 assert(I.getNumOperands() == I.getNumExplicitOperands() &&
327 "Generic instruction has unexpected implicit operands\n");
Igor Bregerf7359d82017-02-22 12:25:09 +0000328
Daniel Sandersf76f3152017-11-16 00:46:35 +0000329 if (selectImpl(I, CoverageInfo))
Igor Bregerfda31e62017-05-10 06:52:58 +0000330 return true;
Igor Breger2452ef02017-05-01 07:06:08 +0000331
332 DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
333
334 // TODO: This should be implemented by tblgen.
Igor Breger06335bb2017-09-17 14:02:19 +0000335 switch (I.getOpcode()) {
336 default:
337 return false;
338 case TargetOpcode::G_STORE:
339 case TargetOpcode::G_LOAD:
340 return selectLoadStoreOp(I, MRI, MF);
341 case TargetOpcode::G_GEP:
342 case TargetOpcode::G_FRAME_INDEX:
343 return selectFrameIndexOrGep(I, MRI, MF);
344 case TargetOpcode::G_GLOBAL_VALUE:
345 return selectGlobalValue(I, MRI, MF);
346 case TargetOpcode::G_CONSTANT:
347 return selectConstant(I, MRI, MF);
348 case TargetOpcode::G_FCONSTANT:
349 return materializeFP(I, MRI, MF);
350 case TargetOpcode::G_TRUNC:
351 return selectTrunc(I, MRI, MF);
352 case TargetOpcode::G_ZEXT:
353 return selectZext(I, MRI, MF);
354 case TargetOpcode::G_ANYEXT:
355 return selectAnyext(I, MRI, MF);
356 case TargetOpcode::G_ICMP:
357 return selectCmp(I, MRI, MF);
358 case TargetOpcode::G_UADDE:
359 return selectUadde(I, MRI, MF);
360 case TargetOpcode::G_UNMERGE_VALUES:
Daniel Sandersf76f3152017-11-16 00:46:35 +0000361 return selectUnmergeValues(I, MRI, MF, CoverageInfo);
Igor Breger06335bb2017-09-17 14:02:19 +0000362 case TargetOpcode::G_MERGE_VALUES:
Daniel Sandersf76f3152017-11-16 00:46:35 +0000363 return selectMergeValues(I, MRI, MF, CoverageInfo);
Igor Breger06335bb2017-09-17 14:02:19 +0000364 case TargetOpcode::G_EXTRACT:
365 return selectExtract(I, MRI, MF);
366 case TargetOpcode::G_INSERT:
367 return selectInsert(I, MRI, MF);
368 case TargetOpcode::G_BRCOND:
369 return selectCondBranch(I, MRI, MF);
370 case TargetOpcode::G_IMPLICIT_DEF:
371 case TargetOpcode::G_PHI:
372 return selectImplicitDefOrPHI(I, MRI);
373 }
Igor Breger321cf3c2017-03-03 08:06:46 +0000374
Igor Breger2452ef02017-05-01 07:06:08 +0000375 return false;
Igor Bregerf7359d82017-02-22 12:25:09 +0000376}
Igor Breger321cf3c2017-03-03 08:06:46 +0000377
Igor Breger21200ed2017-09-17 08:08:13 +0000378unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
379 const RegisterBank &RB,
Igor Bregera8ba5722017-03-23 15:25:57 +0000380 unsigned Opc,
381 uint64_t Alignment) const {
382 bool Isload = (Opc == TargetOpcode::G_LOAD);
383 bool HasAVX = STI.hasAVX();
384 bool HasAVX512 = STI.hasAVX512();
385 bool HasVLX = STI.hasVLX();
386
387 if (Ty == LLT::scalar(8)) {
388 if (X86::GPRRegBankID == RB.getID())
389 return Isload ? X86::MOV8rm : X86::MOV8mr;
390 } else if (Ty == LLT::scalar(16)) {
391 if (X86::GPRRegBankID == RB.getID())
392 return Isload ? X86::MOV16rm : X86::MOV16mr;
Igor Bregera9edb882017-05-01 06:08:32 +0000393 } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
Igor Bregera8ba5722017-03-23 15:25:57 +0000394 if (X86::GPRRegBankID == RB.getID())
395 return Isload ? X86::MOV32rm : X86::MOV32mr;
396 if (X86::VECRRegBankID == RB.getID())
397 return Isload ? (HasAVX512 ? X86::VMOVSSZrm
398 : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
399 : (HasAVX512 ? X86::VMOVSSZmr
400 : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
Igor Bregera9edb882017-05-01 06:08:32 +0000401 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Igor Bregera8ba5722017-03-23 15:25:57 +0000402 if (X86::GPRRegBankID == RB.getID())
403 return Isload ? X86::MOV64rm : X86::MOV64mr;
404 if (X86::VECRRegBankID == RB.getID())
405 return Isload ? (HasAVX512 ? X86::VMOVSDZrm
406 : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm)
407 : (HasAVX512 ? X86::VMOVSDZmr
408 : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr);
409 } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
410 if (Alignment >= 16)
411 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
412 : HasAVX512
413 ? X86::VMOVAPSZ128rm_NOVLX
414 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
415 : (HasVLX ? X86::VMOVAPSZ128mr
416 : HasAVX512
417 ? X86::VMOVAPSZ128mr_NOVLX
418 : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
419 else
420 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
421 : HasAVX512
422 ? X86::VMOVUPSZ128rm_NOVLX
423 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
424 : (HasVLX ? X86::VMOVUPSZ128mr
425 : HasAVX512
426 ? X86::VMOVUPSZ128mr_NOVLX
427 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
Igor Breger617be6e2017-05-23 08:23:51 +0000428 } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
429 if (Alignment >= 32)
430 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
431 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
432 : X86::VMOVAPSYrm)
433 : (HasVLX ? X86::VMOVAPSZ256mr
434 : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
435 : X86::VMOVAPSYmr);
436 else
437 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
438 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
439 : X86::VMOVUPSYrm)
440 : (HasVLX ? X86::VMOVUPSZ256mr
441 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
442 : X86::VMOVUPSYmr);
443 } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
444 if (Alignment >= 64)
445 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
446 else
447 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
Igor Bregera8ba5722017-03-23 15:25:57 +0000448 }
449 return Opc;
450}
451
Igor Bregerbd2deda2017-06-19 13:12:57 +0000452// Fill in an address from the given instruction.
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000453static void X86SelectAddress(const MachineInstr &I,
454 const MachineRegisterInfo &MRI,
455 X86AddressMode &AM) {
Igor Bregerbd2deda2017-06-19 13:12:57 +0000456 assert(I.getOperand(0).isReg() && "unsupported opperand.");
457 assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
458 "unsupported type.");
459
460 if (I.getOpcode() == TargetOpcode::G_GEP) {
461 if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) {
462 int64_t Imm = *COff;
463 if (isInt<32>(Imm)) { // Check for displacement overflow.
464 AM.Disp = static_cast<int32_t>(Imm);
465 AM.Base.Reg = I.getOperand(1).getReg();
466 return;
467 }
468 }
469 } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) {
470 AM.Base.FrameIndex = I.getOperand(1).getIndex();
471 AM.BaseType = X86AddressMode::FrameIndexBase;
472 return;
473 }
474
475 // Default behavior.
476 AM.Base.Reg = I.getOperand(0).getReg();
Igor Bregerbd2deda2017-06-19 13:12:57 +0000477}
478
Igor Bregera8ba5722017-03-23 15:25:57 +0000479bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
480 MachineRegisterInfo &MRI,
481 MachineFunction &MF) const {
Igor Bregera8ba5722017-03-23 15:25:57 +0000482 unsigned Opc = I.getOpcode();
483
Igor Breger06335bb2017-09-17 14:02:19 +0000484 assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
485 "unexpected instruction");
Igor Bregera8ba5722017-03-23 15:25:57 +0000486
487 const unsigned DefReg = I.getOperand(0).getReg();
488 LLT Ty = MRI.getType(DefReg);
489 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
490
491 auto &MemOp = **I.memoperands_begin();
Daniel Sanders3c1c4c02017-12-05 05:52:07 +0000492 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
493 DEBUG(dbgs() << "Atomic load/store not supported yet\n");
494 return false;
495 }
496
Igor Bregera8ba5722017-03-23 15:25:57 +0000497 unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
498 if (NewOpc == Opc)
499 return false;
500
Igor Bregerbd2deda2017-06-19 13:12:57 +0000501 X86AddressMode AM;
502 X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM);
503
Igor Bregera8ba5722017-03-23 15:25:57 +0000504 I.setDesc(TII.get(NewOpc));
505 MachineInstrBuilder MIB(MF, I);
Igor Bregerbd2deda2017-06-19 13:12:57 +0000506 if (Opc == TargetOpcode::G_LOAD) {
507 I.RemoveOperand(1);
508 addFullAddress(MIB, AM);
509 } else {
Igor Bregera8ba5722017-03-23 15:25:57 +0000510 // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
Igor Bregerbd2deda2017-06-19 13:12:57 +0000511 I.RemoveOperand(1);
Igor Bregera8ba5722017-03-23 15:25:57 +0000512 I.RemoveOperand(0);
Igor Bregerbd2deda2017-06-19 13:12:57 +0000513 addFullAddress(MIB, AM).addUse(DefReg);
Igor Bregera8ba5722017-03-23 15:25:57 +0000514 }
515 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
516}
517
Igor Breger717bd362017-07-02 08:58:29 +0000518static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
519 if (Ty == LLT::pointer(0, 64))
520 return X86::LEA64r;
521 else if (Ty == LLT::pointer(0, 32))
522 return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
523 else
524 llvm_unreachable("Can't get LEA opcode. Unsupported type.");
525}
526
Igor Breger810c6252017-05-08 09:40:43 +0000527bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
528 MachineRegisterInfo &MRI,
529 MachineFunction &MF) const {
530 unsigned Opc = I.getOpcode();
531
Igor Breger06335bb2017-09-17 14:02:19 +0000532 assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) &&
533 "unexpected instruction");
Igor Breger531a2032017-03-26 08:11:12 +0000534
535 const unsigned DefReg = I.getOperand(0).getReg();
536 LLT Ty = MRI.getType(DefReg);
537
Igor Breger810c6252017-05-08 09:40:43 +0000538 // Use LEA to calculate frame index and GEP
Igor Breger717bd362017-07-02 08:58:29 +0000539 unsigned NewOpc = getLeaOP(Ty, STI);
Igor Breger531a2032017-03-26 08:11:12 +0000540 I.setDesc(TII.get(NewOpc));
541 MachineInstrBuilder MIB(MF, I);
Igor Breger810c6252017-05-08 09:40:43 +0000542
543 if (Opc == TargetOpcode::G_FRAME_INDEX) {
544 addOffset(MIB, 0);
545 } else {
546 MachineOperand &InxOp = I.getOperand(2);
547 I.addOperand(InxOp); // set IndexReg
548 InxOp.ChangeToImmediate(1); // set Scale
549 MIB.addImm(0).addReg(0);
550 }
Igor Breger531a2032017-03-26 08:11:12 +0000551
552 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
553}
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000554
Igor Breger717bd362017-07-02 08:58:29 +0000555bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
556 MachineRegisterInfo &MRI,
557 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000558 assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
559 "unexpected instruction");
Igor Breger717bd362017-07-02 08:58:29 +0000560
561 auto GV = I.getOperand(1).getGlobal();
562 if (GV->isThreadLocal()) {
563 return false; // TODO: we don't support TLS yet.
564 }
565
566 // Can't handle alternate code models yet.
567 if (TM.getCodeModel() != CodeModel::Small)
Eugene Zelenko60433b62017-10-05 00:33:50 +0000568 return false;
Igor Breger717bd362017-07-02 08:58:29 +0000569
570 X86AddressMode AM;
571 AM.GV = GV;
572 AM.GVOpFlags = STI.classifyGlobalReference(GV);
573
574 // TODO: The ABI requires an extra load. not supported yet.
575 if (isGlobalStubReference(AM.GVOpFlags))
576 return false;
577
578 // TODO: This reference is relative to the pic base. not supported yet.
579 if (isGlobalRelativeToPICBase(AM.GVOpFlags))
580 return false;
581
582 if (STI.isPICStyleRIPRel()) {
583 // Use rip-relative addressing.
584 assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
585 AM.Base.Reg = X86::RIP;
586 }
587
588 const unsigned DefReg = I.getOperand(0).getReg();
589 LLT Ty = MRI.getType(DefReg);
590 unsigned NewOpc = getLeaOP(Ty, STI);
591
592 I.setDesc(TII.get(NewOpc));
593 MachineInstrBuilder MIB(MF, I);
594
595 I.RemoveOperand(1);
596 addFullAddress(MIB, AM);
597
598 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
599}
600
Igor Breger3b97ea32017-04-12 12:54:54 +0000601bool X86InstructionSelector::selectConstant(MachineInstr &I,
602 MachineRegisterInfo &MRI,
603 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000604 assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
605 "unexpected instruction");
Igor Breger3b97ea32017-04-12 12:54:54 +0000606
607 const unsigned DefReg = I.getOperand(0).getReg();
608 LLT Ty = MRI.getType(DefReg);
609
Igor Breger5c787ab2017-07-03 11:06:54 +0000610 if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
611 return false;
Igor Breger3b97ea32017-04-12 12:54:54 +0000612
613 uint64_t Val = 0;
614 if (I.getOperand(1).isCImm()) {
615 Val = I.getOperand(1).getCImm()->getZExtValue();
616 I.getOperand(1).ChangeToImmediate(Val);
617 } else if (I.getOperand(1).isImm()) {
618 Val = I.getOperand(1).getImm();
619 } else
620 llvm_unreachable("Unsupported operand type.");
621
622 unsigned NewOpc;
623 switch (Ty.getSizeInBits()) {
624 case 8:
625 NewOpc = X86::MOV8ri;
626 break;
627 case 16:
628 NewOpc = X86::MOV16ri;
629 break;
630 case 32:
631 NewOpc = X86::MOV32ri;
632 break;
Eugene Zelenko60433b62017-10-05 00:33:50 +0000633 case 64:
Igor Breger3b97ea32017-04-12 12:54:54 +0000634 // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
635 if (isInt<32>(Val))
636 NewOpc = X86::MOV64ri32;
637 else
638 NewOpc = X86::MOV64ri;
639 break;
Igor Breger3b97ea32017-04-12 12:54:54 +0000640 default:
641 llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
642 }
643
644 I.setDesc(TII.get(NewOpc));
645 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
646}
647
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000648// Helper function for selectTrunc and selectAnyext.
649// Returns true if DstRC lives on a floating register class and
650// SrcRC lives on a 128-bit vector class.
651static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC,
652 const TargetRegisterClass *SrcRC) {
653 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
654 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
655 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
656}
657
658bool X86InstructionSelector::selectTurnIntoCOPY(
659 MachineInstr &I, MachineRegisterInfo &MRI, const unsigned DstReg,
660 const TargetRegisterClass *DstRC, const unsigned SrcReg,
661 const TargetRegisterClass *SrcRC) const {
662
663 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
664 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
665 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
666 << " operand\n");
667 return false;
668 }
669 I.setDesc(TII.get(X86::COPY));
670 return true;
671}
672
Igor Breger4fdf1e42017-04-19 11:34:59 +0000673bool X86InstructionSelector::selectTrunc(MachineInstr &I,
674 MachineRegisterInfo &MRI,
675 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000676 assert((I.getOpcode() == TargetOpcode::G_TRUNC) && "unexpected instruction");
Igor Breger4fdf1e42017-04-19 11:34:59 +0000677
678 const unsigned DstReg = I.getOperand(0).getReg();
679 const unsigned SrcReg = I.getOperand(1).getReg();
680
681 const LLT DstTy = MRI.getType(DstReg);
682 const LLT SrcTy = MRI.getType(SrcReg);
683
684 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
685 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
686
687 if (DstRB.getID() != SrcRB.getID()) {
688 DEBUG(dbgs() << "G_TRUNC input/output on different banks\n");
689 return false;
690 }
691
Igor Breger1dcd5e82017-06-20 09:15:10 +0000692 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000693 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
694
695 if (!DstRC || !SrcRC)
Igor Breger4fdf1e42017-04-19 11:34:59 +0000696 return false;
697
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000698 // If that's truncation of the value that lives on the vector class and goes
699 // into the floating class, just replace it with copy, as we are able to
700 // select it as a regular move.
701 if (canTurnIntoCOPY(DstRC, SrcRC))
702 return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
703
704 if (DstRB.getID() != X86::GPRRegBankID)
Igor Breger4fdf1e42017-04-19 11:34:59 +0000705 return false;
706
Igor Breger014fc562017-05-21 11:13:56 +0000707 unsigned SubIdx;
708 if (DstRC == SrcRC) {
709 // Nothing to be done
710 SubIdx = X86::NoSubRegister;
711 } else if (DstRC == &X86::GR32RegClass) {
712 SubIdx = X86::sub_32bit;
713 } else if (DstRC == &X86::GR16RegClass) {
714 SubIdx = X86::sub_16bit;
715 } else if (DstRC == &X86::GR8RegClass) {
716 SubIdx = X86::sub_8bit;
717 } else {
718 return false;
719 }
720
721 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
722
Igor Breger4fdf1e42017-04-19 11:34:59 +0000723 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
724 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
725 DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
726 return false;
727 }
728
Igor Breger014fc562017-05-21 11:13:56 +0000729 I.getOperand(1).setSubReg(SubIdx);
Igor Breger4fdf1e42017-04-19 11:34:59 +0000730
731 I.setDesc(TII.get(X86::COPY));
732 return true;
733}
734
Igor Bregerfda31e62017-05-10 06:52:58 +0000735bool X86InstructionSelector::selectZext(MachineInstr &I,
736 MachineRegisterInfo &MRI,
737 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000738 assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
Igor Bregerfda31e62017-05-10 06:52:58 +0000739
740 const unsigned DstReg = I.getOperand(0).getReg();
741 const unsigned SrcReg = I.getOperand(1).getReg();
742
743 const LLT DstTy = MRI.getType(DstReg);
744 const LLT SrcTy = MRI.getType(SrcReg);
745
Igor Bregerd48c5e42017-07-10 09:07:34 +0000746 if (SrcTy != LLT::scalar(1))
747 return false;
Igor Bregerfda31e62017-05-10 06:52:58 +0000748
Igor Bregerd48c5e42017-07-10 09:07:34 +0000749 unsigned AndOpc;
750 if (DstTy == LLT::scalar(8))
Igor Breger324d3792017-07-11 08:04:51 +0000751 AndOpc = X86::AND8ri;
Igor Bregerd48c5e42017-07-10 09:07:34 +0000752 else if (DstTy == LLT::scalar(16))
753 AndOpc = X86::AND16ri8;
754 else if (DstTy == LLT::scalar(32))
755 AndOpc = X86::AND32ri8;
756 else if (DstTy == LLT::scalar(64))
757 AndOpc = X86::AND64ri8;
758 else
759 return false;
Igor Bregerfda31e62017-05-10 06:52:58 +0000760
Igor Bregerd48c5e42017-07-10 09:07:34 +0000761 unsigned DefReg = SrcReg;
762 if (DstTy != LLT::scalar(8)) {
763 DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
Igor Bregerfda31e62017-05-10 06:52:58 +0000764 BuildMI(*I.getParent(), I, I.getDebugLoc(),
765 TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
766 .addImm(0)
767 .addReg(SrcReg)
768 .addImm(X86::sub_8bit);
Igor Bregerfda31e62017-05-10 06:52:58 +0000769 }
770
Igor Bregerd48c5e42017-07-10 09:07:34 +0000771 MachineInstr &AndInst =
772 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
773 .addReg(DefReg)
774 .addImm(1);
775
776 constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
777
778 I.eraseFromParent();
779 return true;
Igor Bregerfda31e62017-05-10 06:52:58 +0000780}
781
Igor Breger1f143642017-09-11 09:41:13 +0000782bool X86InstructionSelector::selectAnyext(MachineInstr &I,
783 MachineRegisterInfo &MRI,
784 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000785 assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
Igor Breger1f143642017-09-11 09:41:13 +0000786
787 const unsigned DstReg = I.getOperand(0).getReg();
788 const unsigned SrcReg = I.getOperand(1).getReg();
789
790 const LLT DstTy = MRI.getType(DstReg);
791 const LLT SrcTy = MRI.getType(SrcReg);
792
793 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
794 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
795
Igor Breger21200ed2017-09-17 08:08:13 +0000796 assert(DstRB.getID() == SrcRB.getID() &&
797 "G_ANYEXT input/output on different banks\n");
Igor Breger1f143642017-09-11 09:41:13 +0000798
Igor Breger21200ed2017-09-17 08:08:13 +0000799 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
800 "G_ANYEXT incorrect operand size");
Igor Breger1f143642017-09-11 09:41:13 +0000801
Igor Breger1f143642017-09-11 09:41:13 +0000802 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
803 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
804
Alexander Ivchenkoda9e81c2018-02-08 22:41:47 +0000805 // If that's ANY_EXT of the value that lives on the floating class and goes
806 // into the vector class, just replace it with copy, as we are able to select
807 // it as a regular move.
808 if (canTurnIntoCOPY(SrcRC, DstRC))
809 return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC);
810
811 if (DstRB.getID() != X86::GPRRegBankID)
812 return false;
813
Igor Breger1f143642017-09-11 09:41:13 +0000814 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
815 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
816 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
817 << " operand\n");
818 return false;
819 }
820
821 if (SrcRC == DstRC) {
822 I.setDesc(TII.get(X86::COPY));
823 return true;
824 }
825
826 BuildMI(*I.getParent(), I, I.getDebugLoc(),
827 TII.get(TargetOpcode::SUBREG_TO_REG))
828 .addDef(DstReg)
829 .addImm(0)
830 .addReg(SrcReg)
831 .addImm(getSubRegIndex(SrcRC));
832
833 I.eraseFromParent();
834 return true;
835}
836
Igor Bregerc7b59772017-05-11 07:17:40 +0000837bool X86InstructionSelector::selectCmp(MachineInstr &I,
838 MachineRegisterInfo &MRI,
839 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000840 assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
Igor Bregerc7b59772017-05-11 07:17:40 +0000841
842 X86::CondCode CC;
843 bool SwapArgs;
844 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
845 (CmpInst::Predicate)I.getOperand(1).getPredicate());
846 unsigned OpSet = X86::getSETFromCond(CC);
847
848 unsigned LHS = I.getOperand(2).getReg();
849 unsigned RHS = I.getOperand(3).getReg();
850
851 if (SwapArgs)
852 std::swap(LHS, RHS);
853
854 unsigned OpCmp;
855 LLT Ty = MRI.getType(LHS);
856
857 switch (Ty.getSizeInBits()) {
858 default:
859 return false;
860 case 8:
861 OpCmp = X86::CMP8rr;
862 break;
863 case 16:
864 OpCmp = X86::CMP16rr;
865 break;
866 case 32:
867 OpCmp = X86::CMP32rr;
868 break;
869 case 64:
870 OpCmp = X86::CMP64rr;
871 break;
872 }
873
874 MachineInstr &CmpInst =
875 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
876 .addReg(LHS)
877 .addReg(RHS);
878
879 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
880 TII.get(OpSet), I.getOperand(0).getReg());
881
882 constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
883 constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
884
885 I.eraseFromParent();
886 return true;
887}
888
Igor Breger28f290f2017-05-17 12:48:08 +0000889bool X86InstructionSelector::selectUadde(MachineInstr &I,
890 MachineRegisterInfo &MRI,
891 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000892 assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction");
Igor Breger28f290f2017-05-17 12:48:08 +0000893
894 const unsigned DstReg = I.getOperand(0).getReg();
895 const unsigned CarryOutReg = I.getOperand(1).getReg();
896 const unsigned Op0Reg = I.getOperand(2).getReg();
897 const unsigned Op1Reg = I.getOperand(3).getReg();
898 unsigned CarryInReg = I.getOperand(4).getReg();
899
900 const LLT DstTy = MRI.getType(DstReg);
901
902 if (DstTy != LLT::scalar(32))
903 return false;
904
905 // find CarryIn def instruction.
906 MachineInstr *Def = MRI.getVRegDef(CarryInReg);
907 while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
908 CarryInReg = Def->getOperand(1).getReg();
909 Def = MRI.getVRegDef(CarryInReg);
910 }
911
912 unsigned Opcode;
913 if (Def->getOpcode() == TargetOpcode::G_UADDE) {
914 // carry set by prev ADD.
915
916 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
917 .addReg(CarryInReg);
918
919 if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
920 return false;
921
922 Opcode = X86::ADC32rr;
923 } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) {
924 // carry is constant, support only 0.
925 if (*val != 0)
926 return false;
927
928 Opcode = X86::ADD32rr;
929 } else
930 return false;
931
932 MachineInstr &AddInst =
933 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
934 .addReg(Op0Reg)
935 .addReg(Op1Reg);
936
937 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
938 .addReg(X86::EFLAGS);
939
940 if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
941 !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
942 return false;
943
944 I.eraseFromParent();
945 return true;
946}
947
Igor Bregerf5035d62017-06-25 11:42:17 +0000948bool X86InstructionSelector::selectExtract(MachineInstr &I,
949 MachineRegisterInfo &MRI,
950 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +0000951 assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
952 "unexpected instruction");
Igor Bregerf5035d62017-06-25 11:42:17 +0000953
954 const unsigned DstReg = I.getOperand(0).getReg();
955 const unsigned SrcReg = I.getOperand(1).getReg();
956 int64_t Index = I.getOperand(2).getImm();
957
958 const LLT DstTy = MRI.getType(DstReg);
959 const LLT SrcTy = MRI.getType(SrcReg);
960
961 // Meanwile handle vector type only.
962 if (!DstTy.isVector())
963 return false;
964
965 if (Index % DstTy.getSizeInBits() != 0)
966 return false; // Not extract subvector.
967
968 if (Index == 0) {
969 // Replace by extract subreg copy.
970 if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
971 return false;
972
973 I.eraseFromParent();
974 return true;
975 }
976
977 bool HasAVX = STI.hasAVX();
978 bool HasAVX512 = STI.hasAVX512();
979 bool HasVLX = STI.hasVLX();
980
981 if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
982 if (HasVLX)
983 I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
984 else if (HasAVX)
985 I.setDesc(TII.get(X86::VEXTRACTF128rr));
986 else
987 return false;
988 } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
989 if (DstTy.getSizeInBits() == 128)
990 I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
991 else if (DstTy.getSizeInBits() == 256)
992 I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
993 else
994 return false;
995 } else
996 return false;
997
998 // Convert to X86 VEXTRACT immediate.
999 Index = Index / DstTy.getSizeInBits();
1000 I.getOperand(2).setImm(Index);
1001
1002 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1003}
1004
1005bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
1006 MachineInstr &I,
1007 MachineRegisterInfo &MRI,
1008 MachineFunction &MF) const {
Igor Bregerf5035d62017-06-25 11:42:17 +00001009 const LLT DstTy = MRI.getType(DstReg);
1010 const LLT SrcTy = MRI.getType(SrcReg);
1011 unsigned SubIdx = X86::NoSubRegister;
1012
1013 if (!DstTy.isVector() || !SrcTy.isVector())
1014 return false;
1015
1016 assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
1017 "Incorrect Src/Dst register size");
1018
1019 if (DstTy.getSizeInBits() == 128)
1020 SubIdx = X86::sub_xmm;
1021 else if (DstTy.getSizeInBits() == 256)
1022 SubIdx = X86::sub_ymm;
1023 else
1024 return false;
1025
1026 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1027 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1028
1029 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1030
1031 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1032 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1033 DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
1034 return false;
1035 }
1036
1037 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
1038 .addReg(SrcReg, 0, SubIdx);
1039
1040 return true;
1041}
1042
Igor Breger1c29be72017-06-22 09:43:35 +00001043bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
1044 MachineInstr &I,
1045 MachineRegisterInfo &MRI,
1046 MachineFunction &MF) const {
Igor Breger1c29be72017-06-22 09:43:35 +00001047 const LLT DstTy = MRI.getType(DstReg);
1048 const LLT SrcTy = MRI.getType(SrcReg);
1049 unsigned SubIdx = X86::NoSubRegister;
1050
1051 // TODO: support scalar types
1052 if (!DstTy.isVector() || !SrcTy.isVector())
1053 return false;
1054
1055 assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1056 "Incorrect Src/Dst register size");
1057
1058 if (SrcTy.getSizeInBits() == 128)
1059 SubIdx = X86::sub_xmm;
1060 else if (SrcTy.getSizeInBits() == 256)
1061 SubIdx = X86::sub_ymm;
1062 else
1063 return false;
1064
1065 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1066 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1067
1068 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1069 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1070 DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1071 return false;
1072 }
1073
1074 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1075 .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1076 .addReg(SrcReg);
1077
1078 return true;
1079}
1080
1081bool X86InstructionSelector::selectInsert(MachineInstr &I,
1082 MachineRegisterInfo &MRI,
1083 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001084 assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
Igor Breger1c29be72017-06-22 09:43:35 +00001085
1086 const unsigned DstReg = I.getOperand(0).getReg();
1087 const unsigned SrcReg = I.getOperand(1).getReg();
1088 const unsigned InsertReg = I.getOperand(2).getReg();
1089 int64_t Index = I.getOperand(3).getImm();
1090
1091 const LLT DstTy = MRI.getType(DstReg);
1092 const LLT InsertRegTy = MRI.getType(InsertReg);
1093
1094 // Meanwile handle vector type only.
1095 if (!DstTy.isVector())
1096 return false;
1097
1098 if (Index % InsertRegTy.getSizeInBits() != 0)
1099 return false; // Not insert subvector.
1100
1101 if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1102 // Replace by subreg copy.
1103 if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1104 return false;
1105
1106 I.eraseFromParent();
1107 return true;
1108 }
1109
1110 bool HasAVX = STI.hasAVX();
1111 bool HasAVX512 = STI.hasAVX512();
1112 bool HasVLX = STI.hasVLX();
1113
1114 if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
1115 if (HasVLX)
1116 I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
1117 else if (HasAVX)
1118 I.setDesc(TII.get(X86::VINSERTF128rr));
1119 else
1120 return false;
1121 } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
1122 if (InsertRegTy.getSizeInBits() == 128)
1123 I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
1124 else if (InsertRegTy.getSizeInBits() == 256)
1125 I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
1126 else
1127 return false;
1128 } else
1129 return false;
1130
1131 // Convert to X86 VINSERT immediate.
1132 Index = Index / InsertRegTy.getSizeInBits();
1133
1134 I.getOperand(3).setImm(Index);
1135
1136 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1137}
1138
Daniel Sandersf76f3152017-11-16 00:46:35 +00001139bool X86InstructionSelector::selectUnmergeValues(
1140 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF,
1141 CodeGenCoverage &CoverageInfo) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001142 assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1143 "unexpected instruction");
Igor Bregerb186a692017-07-02 08:15:49 +00001144
1145 // Split to extracts.
1146 unsigned NumDefs = I.getNumOperands() - 1;
1147 unsigned SrcReg = I.getOperand(NumDefs).getReg();
1148 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1149
1150 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
Igor Bregerb186a692017-07-02 08:15:49 +00001151 MachineInstr &ExtrInst =
1152 *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1153 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1154 .addReg(SrcReg)
1155 .addImm(Idx * DefSize);
1156
Daniel Sandersf76f3152017-11-16 00:46:35 +00001157 if (!select(ExtrInst, CoverageInfo))
Igor Bregerb186a692017-07-02 08:15:49 +00001158 return false;
1159 }
1160
1161 I.eraseFromParent();
1162 return true;
1163}
1164
Daniel Sandersf76f3152017-11-16 00:46:35 +00001165bool X86InstructionSelector::selectMergeValues(
1166 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF,
1167 CodeGenCoverage &CoverageInfo) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001168 assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES) &&
1169 "unexpected instruction");
Igor Breger0cddd342017-06-29 12:08:28 +00001170
1171 // Split to inserts.
1172 unsigned DstReg = I.getOperand(0).getReg();
1173 unsigned SrcReg0 = I.getOperand(1).getReg();
1174
1175 const LLT DstTy = MRI.getType(DstReg);
1176 const LLT SrcTy = MRI.getType(SrcReg0);
1177 unsigned SrcSize = SrcTy.getSizeInBits();
1178
1179 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1180
1181 // For the first src use insertSubReg.
1182 unsigned DefReg = MRI.createGenericVirtualRegister(DstTy);
1183 MRI.setRegBank(DefReg, RegBank);
1184 if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1185 return false;
1186
1187 for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
Igor Breger0cddd342017-06-29 12:08:28 +00001188 unsigned Tmp = MRI.createGenericVirtualRegister(DstTy);
1189 MRI.setRegBank(Tmp, RegBank);
1190
1191 MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1192 TII.get(TargetOpcode::G_INSERT), Tmp)
1193 .addReg(DefReg)
1194 .addReg(I.getOperand(Idx).getReg())
1195 .addImm((Idx - 1) * SrcSize);
1196
1197 DefReg = Tmp;
1198
Daniel Sandersf76f3152017-11-16 00:46:35 +00001199 if (!select(InsertInst, CoverageInfo))
Igor Breger0cddd342017-06-29 12:08:28 +00001200 return false;
1201 }
1202
1203 MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1204 TII.get(TargetOpcode::COPY), DstReg)
1205 .addReg(DefReg);
1206
Daniel Sandersf76f3152017-11-16 00:46:35 +00001207 if (!select(CopyInst, CoverageInfo))
Igor Breger0cddd342017-06-29 12:08:28 +00001208 return false;
1209
1210 I.eraseFromParent();
1211 return true;
1212}
Igor Breger685889c2017-08-21 10:51:54 +00001213
1214bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1215 MachineRegisterInfo &MRI,
1216 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001217 assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
Igor Breger685889c2017-08-21 10:51:54 +00001218
1219 const unsigned CondReg = I.getOperand(0).getReg();
1220 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1221
1222 MachineInstr &TestInst =
1223 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1224 .addReg(CondReg)
1225 .addImm(1);
1226 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
1227 .addMBB(DestMBB);
1228
1229 constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1230
1231 I.eraseFromParent();
1232 return true;
1233}
1234
Igor Breger21200ed2017-09-17 08:08:13 +00001235bool X86InstructionSelector::materializeFP(MachineInstr &I,
1236 MachineRegisterInfo &MRI,
1237 MachineFunction &MF) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001238 assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1239 "unexpected instruction");
Igor Breger21200ed2017-09-17 08:08:13 +00001240
1241 // Can't handle alternate code models yet.
1242 CodeModel::Model CM = TM.getCodeModel();
1243 if (CM != CodeModel::Small && CM != CodeModel::Large)
1244 return false;
1245
1246 const unsigned DstReg = I.getOperand(0).getReg();
1247 const LLT DstTy = MRI.getType(DstReg);
1248 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1249 unsigned Align = DstTy.getSizeInBits();
1250 const DebugLoc &DbgLoc = I.getDebugLoc();
1251
1252 unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
1253
1254 // Create the load from the constant pool.
1255 const ConstantFP *CFP = I.getOperand(1).getFPImm();
1256 unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
1257 MachineInstr *LoadInst = nullptr;
1258 unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1259
1260 if (CM == CodeModel::Large && STI.is64Bit()) {
1261 // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1262 // they cannot be folded into immediate fields.
1263
1264 unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1265 BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1266 .addConstantPoolIndex(CPI, 0, OpFlag);
1267
1268 MachineMemOperand *MMO = MF.getMachineMemOperand(
1269 MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1270 MF.getDataLayout().getPointerSize(), Align);
1271
1272 LoadInst =
1273 addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1274 AddrReg)
1275 .addMemOperand(MMO);
1276
Igor Breger06335bb2017-09-17 14:02:19 +00001277 } else if (CM == CodeModel::Small || !STI.is64Bit()) {
Igor Breger21200ed2017-09-17 08:08:13 +00001278 // Handle the case when globals fit in our immediate field.
1279 // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1280
1281 // x86-32 PIC requires a PIC base register for constant pools.
1282 unsigned PICBase = 0;
1283 if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
1284 // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1285 // In DAGISEL the code that initialize it generated by the CGBR pass.
1286 return false; // TODO support the mode.
Igor Breger06335bb2017-09-17 14:02:19 +00001287 } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
Igor Breger21200ed2017-09-17 08:08:13 +00001288 PICBase = X86::RIP;
1289
1290 LoadInst = addConstantPoolReference(
1291 BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1292 OpFlag);
1293 } else
1294 return false;
1295
1296 constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
1297 I.eraseFromParent();
1298 return true;
1299}
1300
Igor Breger2661ae42017-09-04 09:06:45 +00001301bool X86InstructionSelector::selectImplicitDefOrPHI(
1302 MachineInstr &I, MachineRegisterInfo &MRI) const {
Igor Breger06335bb2017-09-17 14:02:19 +00001303 assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1304 I.getOpcode() == TargetOpcode::G_PHI) &&
1305 "unexpected instruction");
Igor Breger47be5fb2017-08-24 07:06:27 +00001306
1307 unsigned DstReg = I.getOperand(0).getReg();
1308
1309 if (!MRI.getRegClassOrNull(DstReg)) {
1310 const LLT DstTy = MRI.getType(DstReg);
1311 const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1312
1313 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1314 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1315 << " operand\n");
1316 return false;
1317 }
1318 }
1319
Igor Breger2661ae42017-09-04 09:06:45 +00001320 if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1321 I.setDesc(TII.get(X86::IMPLICIT_DEF));
1322 else
1323 I.setDesc(TII.get(X86::PHI));
1324
Igor Breger47be5fb2017-08-24 07:06:27 +00001325 return true;
1326}
1327
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001328InstructionSelector *
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001329llvm::createX86InstructionSelector(const X86TargetMachine &TM,
1330 X86Subtarget &Subtarget,
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001331 X86RegisterBankInfo &RBI) {
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001332 return new X86InstructionSelector(TM, Subtarget, RBI);
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001333}