blob: 1f34e13048c73f8fe4508ef914624b1ba7cdc102 [file] [log] [blame]
Igor Bregerf7359d82017-02-22 12:25:09 +00001//===- X86InstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the targeting of the InstructionSelector class for
11/// X86.
12/// \todo This should be generated by TableGen.
13//===----------------------------------------------------------------------===//
14
Igor Bregera8ba5722017-03-23 15:25:57 +000015#include "X86InstrBuilder.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000016#include "X86InstrInfo.h"
17#include "X86RegisterBankInfo.h"
18#include "X86RegisterInfo.h"
19#include "X86Subtarget.h"
20#include "X86TargetMachine.h"
Igor Breger3b97ea32017-04-12 12:54:54 +000021#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
Igor Breger28f290f2017-05-17 12:48:08 +000022#include "llvm/CodeGen/GlobalISel/Utils.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000023#include "llvm/CodeGen/MachineBasicBlock.h"
Igor Breger21200ed2017-09-17 08:08:13 +000024#include "llvm/CodeGen/MachineConstantPool.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000025#include "llvm/CodeGen/MachineFunction.h"
26#include "llvm/CodeGen/MachineInstr.h"
27#include "llvm/CodeGen/MachineInstrBuilder.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000028#include "llvm/CodeGen/MachineOperand.h"
Igor Bregerf7359d82017-02-22 12:25:09 +000029#include "llvm/CodeGen/MachineRegisterInfo.h"
30#include "llvm/IR/Type.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/raw_ostream.h"
33
34#define DEBUG_TYPE "X86-isel"
35
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000036#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
37
Igor Bregerf7359d82017-02-22 12:25:09 +000038using namespace llvm;
39
Daniel Sanders0b5293f2017-04-06 09:49:34 +000040namespace {
41
Daniel Sanderse7b0d662017-04-21 15:59:56 +000042#define GET_GLOBALISEL_PREDICATE_BITSET
43#include "X86GenGlobalISel.inc"
44#undef GET_GLOBALISEL_PREDICATE_BITSET
45
Daniel Sanders0b5293f2017-04-06 09:49:34 +000046class X86InstructionSelector : public InstructionSelector {
47public:
Daniel Sanderse7b0d662017-04-21 15:59:56 +000048 X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
Daniel Sanders0b5293f2017-04-06 09:49:34 +000049 const X86RegisterBankInfo &RBI);
50
51 bool select(MachineInstr &I) const override;
52
53private:
54 /// tblgen-erated 'select' implementation, used as the initial selector for
55 /// the patterns that don't require complex C++.
56 bool selectImpl(MachineInstr &I) const;
57
Hiroshi Inouebb703e82017-07-02 03:24:54 +000058 // TODO: remove after supported by Tablegen-erated instruction selection.
Igor Breger21200ed2017-09-17 08:08:13 +000059 unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
Daniel Sanders0b5293f2017-04-06 09:49:34 +000060 uint64_t Alignment) const;
61
Daniel Sanders0b5293f2017-04-06 09:49:34 +000062 bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
63 MachineFunction &MF) const;
Igor Breger810c6252017-05-08 09:40:43 +000064 bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
65 MachineFunction &MF) const;
Igor Breger717bd362017-07-02 08:58:29 +000066 bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
67 MachineFunction &MF) const;
Igor Breger3b97ea32017-04-12 12:54:54 +000068 bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
69 MachineFunction &MF) const;
Igor Breger4fdf1e42017-04-19 11:34:59 +000070 bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
71 MachineFunction &MF) const;
Igor Bregerfda31e62017-05-10 06:52:58 +000072 bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
73 MachineFunction &MF) const;
Igor Breger1f143642017-09-11 09:41:13 +000074 bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
75 MachineFunction &MF) const;
Igor Bregerc7b59772017-05-11 07:17:40 +000076 bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
77 MachineFunction &MF) const;
Igor Breger28f290f2017-05-17 12:48:08 +000078 bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
79 MachineFunction &MF) const;
Igor Breger1dcd5e82017-06-20 09:15:10 +000080 bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
Igor Bregerb186a692017-07-02 08:15:49 +000081 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
82 MachineFunction &MF) const;
Igor Breger0cddd342017-06-29 12:08:28 +000083 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
84 MachineFunction &MF) const;
Igor Breger1c29be72017-06-22 09:43:35 +000085 bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
86 MachineFunction &MF) const;
Igor Bregerf5035d62017-06-25 11:42:17 +000087 bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
88 MachineFunction &MF) const;
Igor Breger685889c2017-08-21 10:51:54 +000089 bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
90 MachineFunction &MF) const;
Igor Breger21200ed2017-09-17 08:08:13 +000091 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
92 MachineFunction &MF) const;
Igor Breger2661ae42017-09-04 09:06:45 +000093 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
Igor Breger1c29be72017-06-22 09:43:35 +000094
95 // emit insert subreg instruction and insert it before MachineInstr &I
96 bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
97 MachineRegisterInfo &MRI, MachineFunction &MF) const;
Igor Bregerf5035d62017-06-25 11:42:17 +000098 // emit extract subreg instruction and insert it before MachineInstr &I
99 bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
100 MachineRegisterInfo &MRI, MachineFunction &MF) const;
Igor Breger1dcd5e82017-06-20 09:15:10 +0000101
102 const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
103 const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
104 MachineRegisterInfo &MRI) const;
Igor Breger28f290f2017-05-17 12:48:08 +0000105
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000106 const X86TargetMachine &TM;
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000107 const X86Subtarget &STI;
108 const X86InstrInfo &TII;
109 const X86RegisterInfo &TRI;
110 const X86RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000111
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000112#define GET_GLOBALISEL_PREDICATES_DECL
113#include "X86GenGlobalISel.inc"
114#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000115
116#define GET_GLOBALISEL_TEMPORARIES_DECL
117#include "X86GenGlobalISel.inc"
118#undef GET_GLOBALISEL_TEMPORARIES_DECL
119};
120
121} // end anonymous namespace
122
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000123#define GET_GLOBALISEL_IMPL
Igor Bregerf7359d82017-02-22 12:25:09 +0000124#include "X86GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000125#undef GET_GLOBALISEL_IMPL
Igor Bregerf7359d82017-02-22 12:25:09 +0000126
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000127X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
128 const X86Subtarget &STI,
Igor Bregerf7359d82017-02-22 12:25:09 +0000129 const X86RegisterBankInfo &RBI)
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000130 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000131 TRI(*STI.getRegisterInfo()), RBI(RBI),
132#define GET_GLOBALISEL_PREDICATES_INIT
133#include "X86GenGlobalISel.inc"
134#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000135#define GET_GLOBALISEL_TEMPORARIES_INIT
136#include "X86GenGlobalISel.inc"
137#undef GET_GLOBALISEL_TEMPORARIES_INIT
138{
139}
Igor Bregerf7359d82017-02-22 12:25:09 +0000140
141// FIXME: This should be target-independent, inferred from the types declared
142// for each class in the bank.
Igor Breger1dcd5e82017-06-20 09:15:10 +0000143const TargetRegisterClass *
144X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000145 if (RB.getID() == X86::GPRRegBankID) {
Igor Breger4fdf1e42017-04-19 11:34:59 +0000146 if (Ty.getSizeInBits() <= 8)
147 return &X86::GR8RegClass;
148 if (Ty.getSizeInBits() == 16)
149 return &X86::GR16RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000150 if (Ty.getSizeInBits() == 32)
Igor Bregerf7359d82017-02-22 12:25:09 +0000151 return &X86::GR32RegClass;
152 if (Ty.getSizeInBits() == 64)
153 return &X86::GR64RegClass;
154 }
Igor Breger321cf3c2017-03-03 08:06:46 +0000155 if (RB.getID() == X86::VECRRegBankID) {
156 if (Ty.getSizeInBits() == 32)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000157 return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000158 if (Ty.getSizeInBits() == 64)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000159 return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000160 if (Ty.getSizeInBits() == 128)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000161 return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000162 if (Ty.getSizeInBits() == 256)
Igor Breger1dcd5e82017-06-20 09:15:10 +0000163 return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
Igor Breger321cf3c2017-03-03 08:06:46 +0000164 if (Ty.getSizeInBits() == 512)
165 return &X86::VR512RegClass;
166 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000167
168 llvm_unreachable("Unknown RegBank!");
169}
170
Igor Breger1dcd5e82017-06-20 09:15:10 +0000171const TargetRegisterClass *
172X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg,
173 MachineRegisterInfo &MRI) const {
174 const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
175 return getRegClass(Ty, RegBank);
176}
177
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000178static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
Igor Bregerb3a860a2017-08-20 07:14:40 +0000179 unsigned SubIdx = X86::NoSubRegister;
180 if (RC == &X86::GR32RegClass) {
181 SubIdx = X86::sub_32bit;
182 } else if (RC == &X86::GR16RegClass) {
183 SubIdx = X86::sub_16bit;
184 } else if (RC == &X86::GR8RegClass) {
185 SubIdx = X86::sub_8bit;
186 }
187
188 return SubIdx;
189}
190
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000191static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) {
Igor Bregerb3a860a2017-08-20 07:14:40 +0000192 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
193 if (X86::GR64RegClass.contains(Reg))
194 return &X86::GR64RegClass;
195 if (X86::GR32RegClass.contains(Reg))
196 return &X86::GR32RegClass;
197 if (X86::GR16RegClass.contains(Reg))
198 return &X86::GR16RegClass;
199 if (X86::GR8RegClass.contains(Reg))
200 return &X86::GR8RegClass;
201
202 llvm_unreachable("Unknown RegClass for PhysReg!");
203}
204
Igor Bregerf7359d82017-02-22 12:25:09 +0000205// Set X86 Opcode and constrain DestReg.
Igor Breger1dcd5e82017-06-20 09:15:10 +0000206bool X86InstructionSelector::selectCopy(MachineInstr &I,
207 MachineRegisterInfo &MRI) const {
Igor Bregerf7359d82017-02-22 12:25:09 +0000208
209 unsigned DstReg = I.getOperand(0).getReg();
Igor Bregerb3a860a2017-08-20 07:14:40 +0000210 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
211 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
Igor Bregerf7359d82017-02-22 12:25:09 +0000212
Igor Bregerf7359d82017-02-22 12:25:09 +0000213 unsigned SrcReg = I.getOperand(1).getReg();
214 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Igor Bregerb3a860a2017-08-20 07:14:40 +0000215 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
216
217 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
218 assert(I.isCopy() && "Generic operators do not allow physical registers");
219
220 if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
221 DstRegBank.getID() == X86::GPRRegBankID) {
222
223 const TargetRegisterClass *SrcRC =
224 getRegClass(MRI.getType(SrcReg), SrcRegBank);
225 const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
226
227 if (SrcRC != DstRC) {
228 // This case can be generated by ABI lowering, performe anyext
229 unsigned ExtSrc = MRI.createVirtualRegister(DstRC);
230 BuildMI(*I.getParent(), I, I.getDebugLoc(),
231 TII.get(TargetOpcode::SUBREG_TO_REG))
232 .addDef(ExtSrc)
233 .addImm(0)
234 .addReg(SrcReg)
235 .addImm(getSubRegIndex(SrcRC));
236
237 I.getOperand(1).setReg(ExtSrc);
238 }
239 }
240
241 return true;
242 }
Igor Breger360d0f22017-04-27 08:02:03 +0000243
Igor Bregerf7359d82017-02-22 12:25:09 +0000244 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
245 "No phys reg on generic operators");
246 assert((DstSize == SrcSize ||
247 // Copies are a mean to setup initial types, the number of
248 // bits may not exactly match.
249 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
250 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
251 "Copy with different width?!");
252
Igor Bregerb3a860a2017-08-20 07:14:40 +0000253 const TargetRegisterClass *DstRC =
254 getRegClass(MRI.getType(DstReg), DstRegBank);
Igor Bregerf7359d82017-02-22 12:25:09 +0000255
Igor Bregerb3a860a2017-08-20 07:14:40 +0000256 if (SrcRegBank.getID() == X86::GPRRegBankID &&
257 DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
258 TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
259 // Change the physical register to performe truncate.
Igor Breger360d0f22017-04-27 08:02:03 +0000260
Igor Bregerb3a860a2017-08-20 07:14:40 +0000261 const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
Igor Breger360d0f22017-04-27 08:02:03 +0000262
Igor Bregerb3a860a2017-08-20 07:14:40 +0000263 if (DstRC != SrcRC) {
264 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
Igor Breger360d0f22017-04-27 08:02:03 +0000265 I.getOperand(1).substPhysReg(SrcReg, TRI);
266 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000267 }
268
269 // No need to constrain SrcReg. It will get constrained when
270 // we hit another of its use or its defs.
271 // Copies do not have constraints.
Igor Breger8a924be2017-03-23 12:13:29 +0000272 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
Igor Bregerb3a860a2017-08-20 07:14:40 +0000273 if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
274 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Igor Breger8a924be2017-03-23 12:13:29 +0000275 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
276 << " operand\n");
277 return false;
278 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000279 }
280 I.setDesc(TII.get(X86::COPY));
281 return true;
282}
283
284bool X86InstructionSelector::select(MachineInstr &I) const {
285 assert(I.getParent() && "Instruction should be in a basic block!");
286 assert(I.getParent()->getParent() && "Instruction should be in a function!");
287
288 MachineBasicBlock &MBB = *I.getParent();
289 MachineFunction &MF = *MBB.getParent();
290 MachineRegisterInfo &MRI = MF.getRegInfo();
291
292 unsigned Opcode = I.getOpcode();
293 if (!isPreISelGenericOpcode(Opcode)) {
294 // Certain non-generic instructions also need some special handling.
295
Igor Breger03c22082017-08-21 09:17:28 +0000296 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
297 return false;
Igor Breger03c22082017-08-21 09:17:28 +0000298
Igor Bregerf7359d82017-02-22 12:25:09 +0000299 if (I.isCopy())
Igor Breger1dcd5e82017-06-20 09:15:10 +0000300 return selectCopy(I, MRI);
Igor Bregerf7359d82017-02-22 12:25:09 +0000301
Igor Bregerf7359d82017-02-22 12:25:09 +0000302 return true;
303 }
304
Benjamin Kramer5a7e0f82017-02-22 12:59:47 +0000305 assert(I.getNumOperands() == I.getNumExplicitOperands() &&
306 "Generic instruction has unexpected implicit operands\n");
Igor Bregerf7359d82017-02-22 12:25:09 +0000307
Igor Breger2452ef02017-05-01 07:06:08 +0000308 if (selectImpl(I))
Igor Bregerfda31e62017-05-10 06:52:58 +0000309 return true;
Igor Breger2452ef02017-05-01 07:06:08 +0000310
311 DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
312
313 // TODO: This should be implemented by tblgen.
Igor Bregera8ba5722017-03-23 15:25:57 +0000314 if (selectLoadStoreOp(I, MRI, MF))
Igor Breger321cf3c2017-03-03 08:06:46 +0000315 return true;
Igor Breger810c6252017-05-08 09:40:43 +0000316 if (selectFrameIndexOrGep(I, MRI, MF))
Igor Breger531a2032017-03-26 08:11:12 +0000317 return true;
Igor Breger717bd362017-07-02 08:58:29 +0000318 if (selectGlobalValue(I, MRI, MF))
319 return true;
Igor Breger3b97ea32017-04-12 12:54:54 +0000320 if (selectConstant(I, MRI, MF))
321 return true;
Igor Breger4fdf1e42017-04-19 11:34:59 +0000322 if (selectTrunc(I, MRI, MF))
323 return true;
Igor Bregerfda31e62017-05-10 06:52:58 +0000324 if (selectZext(I, MRI, MF))
325 return true;
Igor Breger1f143642017-09-11 09:41:13 +0000326 if (selectAnyext(I, MRI, MF))
327 return true;
Igor Bregerc7b59772017-05-11 07:17:40 +0000328 if (selectCmp(I, MRI, MF))
329 return true;
Igor Breger28f290f2017-05-17 12:48:08 +0000330 if (selectUadde(I, MRI, MF))
331 return true;
Igor Bregerb186a692017-07-02 08:15:49 +0000332 if (selectUnmergeValues(I, MRI, MF))
333 return true;
Igor Breger0cddd342017-06-29 12:08:28 +0000334 if (selectMergeValues(I, MRI, MF))
335 return true;
Igor Bregerf5035d62017-06-25 11:42:17 +0000336 if (selectExtract(I, MRI, MF))
337 return true;
Igor Breger1c29be72017-06-22 09:43:35 +0000338 if (selectInsert(I, MRI, MF))
339 return true;
Igor Breger685889c2017-08-21 10:51:54 +0000340 if (selectCondBranch(I, MRI, MF))
341 return true;
Igor Breger21200ed2017-09-17 08:08:13 +0000342 if (materializeFP(I, MRI, MF))
343 return true;
Igor Breger2661ae42017-09-04 09:06:45 +0000344 if (selectImplicitDefOrPHI(I, MRI))
Igor Breger47be5fb2017-08-24 07:06:27 +0000345 return true;
Igor Breger321cf3c2017-03-03 08:06:46 +0000346
Igor Breger2452ef02017-05-01 07:06:08 +0000347 return false;
Igor Bregerf7359d82017-02-22 12:25:09 +0000348}
Igor Breger321cf3c2017-03-03 08:06:46 +0000349
Igor Breger21200ed2017-09-17 08:08:13 +0000350unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
351 const RegisterBank &RB,
Igor Bregera8ba5722017-03-23 15:25:57 +0000352 unsigned Opc,
353 uint64_t Alignment) const {
354 bool Isload = (Opc == TargetOpcode::G_LOAD);
355 bool HasAVX = STI.hasAVX();
356 bool HasAVX512 = STI.hasAVX512();
357 bool HasVLX = STI.hasVLX();
358
359 if (Ty == LLT::scalar(8)) {
360 if (X86::GPRRegBankID == RB.getID())
361 return Isload ? X86::MOV8rm : X86::MOV8mr;
362 } else if (Ty == LLT::scalar(16)) {
363 if (X86::GPRRegBankID == RB.getID())
364 return Isload ? X86::MOV16rm : X86::MOV16mr;
Igor Bregera9edb882017-05-01 06:08:32 +0000365 } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
Igor Bregera8ba5722017-03-23 15:25:57 +0000366 if (X86::GPRRegBankID == RB.getID())
367 return Isload ? X86::MOV32rm : X86::MOV32mr;
368 if (X86::VECRRegBankID == RB.getID())
369 return Isload ? (HasAVX512 ? X86::VMOVSSZrm
370 : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
371 : (HasAVX512 ? X86::VMOVSSZmr
372 : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
Igor Bregera9edb882017-05-01 06:08:32 +0000373 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Igor Bregera8ba5722017-03-23 15:25:57 +0000374 if (X86::GPRRegBankID == RB.getID())
375 return Isload ? X86::MOV64rm : X86::MOV64mr;
376 if (X86::VECRRegBankID == RB.getID())
377 return Isload ? (HasAVX512 ? X86::VMOVSDZrm
378 : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm)
379 : (HasAVX512 ? X86::VMOVSDZmr
380 : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr);
381 } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
382 if (Alignment >= 16)
383 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
384 : HasAVX512
385 ? X86::VMOVAPSZ128rm_NOVLX
386 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
387 : (HasVLX ? X86::VMOVAPSZ128mr
388 : HasAVX512
389 ? X86::VMOVAPSZ128mr_NOVLX
390 : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
391 else
392 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
393 : HasAVX512
394 ? X86::VMOVUPSZ128rm_NOVLX
395 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
396 : (HasVLX ? X86::VMOVUPSZ128mr
397 : HasAVX512
398 ? X86::VMOVUPSZ128mr_NOVLX
399 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
Igor Breger617be6e2017-05-23 08:23:51 +0000400 } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
401 if (Alignment >= 32)
402 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
403 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
404 : X86::VMOVAPSYrm)
405 : (HasVLX ? X86::VMOVAPSZ256mr
406 : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
407 : X86::VMOVAPSYmr);
408 else
409 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
410 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
411 : X86::VMOVUPSYrm)
412 : (HasVLX ? X86::VMOVUPSZ256mr
413 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
414 : X86::VMOVUPSYmr);
415 } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
416 if (Alignment >= 64)
417 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
418 else
419 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
Igor Bregera8ba5722017-03-23 15:25:57 +0000420 }
421 return Opc;
422}
423
Igor Bregerbd2deda2017-06-19 13:12:57 +0000424// Fill in an address from the given instruction.
Benjamin Kramer49a49fe2017-08-20 13:03:48 +0000425static void X86SelectAddress(const MachineInstr &I,
426 const MachineRegisterInfo &MRI,
427 X86AddressMode &AM) {
Igor Bregerbd2deda2017-06-19 13:12:57 +0000428
429 assert(I.getOperand(0).isReg() && "unsupported opperand.");
430 assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
431 "unsupported type.");
432
433 if (I.getOpcode() == TargetOpcode::G_GEP) {
434 if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) {
435 int64_t Imm = *COff;
436 if (isInt<32>(Imm)) { // Check for displacement overflow.
437 AM.Disp = static_cast<int32_t>(Imm);
438 AM.Base.Reg = I.getOperand(1).getReg();
439 return;
440 }
441 }
442 } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) {
443 AM.Base.FrameIndex = I.getOperand(1).getIndex();
444 AM.BaseType = X86AddressMode::FrameIndexBase;
445 return;
446 }
447
448 // Default behavior.
449 AM.Base.Reg = I.getOperand(0).getReg();
450 return;
451}
452
Igor Bregera8ba5722017-03-23 15:25:57 +0000453bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
454 MachineRegisterInfo &MRI,
455 MachineFunction &MF) const {
456
457 unsigned Opc = I.getOpcode();
458
459 if (Opc != TargetOpcode::G_STORE && Opc != TargetOpcode::G_LOAD)
460 return false;
461
462 const unsigned DefReg = I.getOperand(0).getReg();
463 LLT Ty = MRI.getType(DefReg);
464 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
465
466 auto &MemOp = **I.memoperands_begin();
Igor Bregerbd2deda2017-06-19 13:12:57 +0000467 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
468 DEBUG(dbgs() << "Atomic load/store not supported yet\n");
469 return false;
470 }
471
Igor Bregera8ba5722017-03-23 15:25:57 +0000472 unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
473 if (NewOpc == Opc)
474 return false;
475
Igor Bregerbd2deda2017-06-19 13:12:57 +0000476 X86AddressMode AM;
477 X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM);
478
Igor Bregera8ba5722017-03-23 15:25:57 +0000479 I.setDesc(TII.get(NewOpc));
480 MachineInstrBuilder MIB(MF, I);
Igor Bregerbd2deda2017-06-19 13:12:57 +0000481 if (Opc == TargetOpcode::G_LOAD) {
482 I.RemoveOperand(1);
483 addFullAddress(MIB, AM);
484 } else {
Igor Bregera8ba5722017-03-23 15:25:57 +0000485 // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
Igor Bregerbd2deda2017-06-19 13:12:57 +0000486 I.RemoveOperand(1);
Igor Bregera8ba5722017-03-23 15:25:57 +0000487 I.RemoveOperand(0);
Igor Bregerbd2deda2017-06-19 13:12:57 +0000488 addFullAddress(MIB, AM).addUse(DefReg);
Igor Bregera8ba5722017-03-23 15:25:57 +0000489 }
490 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
491}
492
Igor Breger717bd362017-07-02 08:58:29 +0000493static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
494 if (Ty == LLT::pointer(0, 64))
495 return X86::LEA64r;
496 else if (Ty == LLT::pointer(0, 32))
497 return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
498 else
499 llvm_unreachable("Can't get LEA opcode. Unsupported type.");
500}
501
Igor Breger810c6252017-05-08 09:40:43 +0000502bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
503 MachineRegisterInfo &MRI,
504 MachineFunction &MF) const {
505 unsigned Opc = I.getOpcode();
506
507 if (Opc != TargetOpcode::G_FRAME_INDEX && Opc != TargetOpcode::G_GEP)
Igor Breger531a2032017-03-26 08:11:12 +0000508 return false;
509
510 const unsigned DefReg = I.getOperand(0).getReg();
511 LLT Ty = MRI.getType(DefReg);
512
Igor Breger810c6252017-05-08 09:40:43 +0000513 // Use LEA to calculate frame index and GEP
Igor Breger717bd362017-07-02 08:58:29 +0000514 unsigned NewOpc = getLeaOP(Ty, STI);
Igor Breger531a2032017-03-26 08:11:12 +0000515 I.setDesc(TII.get(NewOpc));
516 MachineInstrBuilder MIB(MF, I);
Igor Breger810c6252017-05-08 09:40:43 +0000517
518 if (Opc == TargetOpcode::G_FRAME_INDEX) {
519 addOffset(MIB, 0);
520 } else {
521 MachineOperand &InxOp = I.getOperand(2);
522 I.addOperand(InxOp); // set IndexReg
523 InxOp.ChangeToImmediate(1); // set Scale
524 MIB.addImm(0).addReg(0);
525 }
Igor Breger531a2032017-03-26 08:11:12 +0000526
527 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
528}
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000529
Igor Breger717bd362017-07-02 08:58:29 +0000530bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
531 MachineRegisterInfo &MRI,
532 MachineFunction &MF) const {
533 unsigned Opc = I.getOpcode();
534
535 if (Opc != TargetOpcode::G_GLOBAL_VALUE)
536 return false;
537
538 auto GV = I.getOperand(1).getGlobal();
539 if (GV->isThreadLocal()) {
540 return false; // TODO: we don't support TLS yet.
541 }
542
543 // Can't handle alternate code models yet.
544 if (TM.getCodeModel() != CodeModel::Small)
545 return 0;
546
547 X86AddressMode AM;
548 AM.GV = GV;
549 AM.GVOpFlags = STI.classifyGlobalReference(GV);
550
551 // TODO: The ABI requires an extra load. not supported yet.
552 if (isGlobalStubReference(AM.GVOpFlags))
553 return false;
554
555 // TODO: This reference is relative to the pic base. not supported yet.
556 if (isGlobalRelativeToPICBase(AM.GVOpFlags))
557 return false;
558
559 if (STI.isPICStyleRIPRel()) {
560 // Use rip-relative addressing.
561 assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
562 AM.Base.Reg = X86::RIP;
563 }
564
565 const unsigned DefReg = I.getOperand(0).getReg();
566 LLT Ty = MRI.getType(DefReg);
567 unsigned NewOpc = getLeaOP(Ty, STI);
568
569 I.setDesc(TII.get(NewOpc));
570 MachineInstrBuilder MIB(MF, I);
571
572 I.RemoveOperand(1);
573 addFullAddress(MIB, AM);
574
575 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
576}
577
Igor Breger3b97ea32017-04-12 12:54:54 +0000578bool X86InstructionSelector::selectConstant(MachineInstr &I,
579 MachineRegisterInfo &MRI,
580 MachineFunction &MF) const {
581 if (I.getOpcode() != TargetOpcode::G_CONSTANT)
582 return false;
583
584 const unsigned DefReg = I.getOperand(0).getReg();
585 LLT Ty = MRI.getType(DefReg);
586
Igor Breger5c787ab2017-07-03 11:06:54 +0000587 if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
588 return false;
Igor Breger3b97ea32017-04-12 12:54:54 +0000589
590 uint64_t Val = 0;
591 if (I.getOperand(1).isCImm()) {
592 Val = I.getOperand(1).getCImm()->getZExtValue();
593 I.getOperand(1).ChangeToImmediate(Val);
594 } else if (I.getOperand(1).isImm()) {
595 Val = I.getOperand(1).getImm();
596 } else
597 llvm_unreachable("Unsupported operand type.");
598
599 unsigned NewOpc;
600 switch (Ty.getSizeInBits()) {
601 case 8:
602 NewOpc = X86::MOV8ri;
603 break;
604 case 16:
605 NewOpc = X86::MOV16ri;
606 break;
607 case 32:
608 NewOpc = X86::MOV32ri;
609 break;
610 case 64: {
611 // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
612 if (isInt<32>(Val))
613 NewOpc = X86::MOV64ri32;
614 else
615 NewOpc = X86::MOV64ri;
616 break;
617 }
618 default:
619 llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
620 }
621
622 I.setDesc(TII.get(NewOpc));
623 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
624}
625
Igor Breger4fdf1e42017-04-19 11:34:59 +0000626bool X86InstructionSelector::selectTrunc(MachineInstr &I,
627 MachineRegisterInfo &MRI,
628 MachineFunction &MF) const {
629 if (I.getOpcode() != TargetOpcode::G_TRUNC)
630 return false;
631
632 const unsigned DstReg = I.getOperand(0).getReg();
633 const unsigned SrcReg = I.getOperand(1).getReg();
634
635 const LLT DstTy = MRI.getType(DstReg);
636 const LLT SrcTy = MRI.getType(SrcReg);
637
638 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
639 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
640
641 if (DstRB.getID() != SrcRB.getID()) {
642 DEBUG(dbgs() << "G_TRUNC input/output on different banks\n");
643 return false;
644 }
645
646 if (DstRB.getID() != X86::GPRRegBankID)
647 return false;
648
Igor Breger1dcd5e82017-06-20 09:15:10 +0000649 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
Igor Breger4fdf1e42017-04-19 11:34:59 +0000650 if (!DstRC)
651 return false;
652
Igor Breger1dcd5e82017-06-20 09:15:10 +0000653 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
Igor Breger4fdf1e42017-04-19 11:34:59 +0000654 if (!SrcRC)
655 return false;
656
Igor Breger014fc562017-05-21 11:13:56 +0000657 unsigned SubIdx;
658 if (DstRC == SrcRC) {
659 // Nothing to be done
660 SubIdx = X86::NoSubRegister;
661 } else if (DstRC == &X86::GR32RegClass) {
662 SubIdx = X86::sub_32bit;
663 } else if (DstRC == &X86::GR16RegClass) {
664 SubIdx = X86::sub_16bit;
665 } else if (DstRC == &X86::GR8RegClass) {
666 SubIdx = X86::sub_8bit;
667 } else {
668 return false;
669 }
670
671 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
672
Igor Breger4fdf1e42017-04-19 11:34:59 +0000673 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
674 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
675 DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
676 return false;
677 }
678
Igor Breger014fc562017-05-21 11:13:56 +0000679 I.getOperand(1).setSubReg(SubIdx);
Igor Breger4fdf1e42017-04-19 11:34:59 +0000680
681 I.setDesc(TII.get(X86::COPY));
682 return true;
683}
684
Igor Bregerfda31e62017-05-10 06:52:58 +0000685bool X86InstructionSelector::selectZext(MachineInstr &I,
686 MachineRegisterInfo &MRI,
687 MachineFunction &MF) const {
688 if (I.getOpcode() != TargetOpcode::G_ZEXT)
689 return false;
690
691 const unsigned DstReg = I.getOperand(0).getReg();
692 const unsigned SrcReg = I.getOperand(1).getReg();
693
694 const LLT DstTy = MRI.getType(DstReg);
695 const LLT SrcTy = MRI.getType(SrcReg);
696
Igor Bregerd48c5e42017-07-10 09:07:34 +0000697 if (SrcTy != LLT::scalar(1))
698 return false;
Igor Bregerfda31e62017-05-10 06:52:58 +0000699
Igor Bregerd48c5e42017-07-10 09:07:34 +0000700 unsigned AndOpc;
701 if (DstTy == LLT::scalar(8))
Igor Breger324d3792017-07-11 08:04:51 +0000702 AndOpc = X86::AND8ri;
Igor Bregerd48c5e42017-07-10 09:07:34 +0000703 else if (DstTy == LLT::scalar(16))
704 AndOpc = X86::AND16ri8;
705 else if (DstTy == LLT::scalar(32))
706 AndOpc = X86::AND32ri8;
707 else if (DstTy == LLT::scalar(64))
708 AndOpc = X86::AND64ri8;
709 else
710 return false;
Igor Bregerfda31e62017-05-10 06:52:58 +0000711
Igor Bregerd48c5e42017-07-10 09:07:34 +0000712 unsigned DefReg = SrcReg;
713 if (DstTy != LLT::scalar(8)) {
714 DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
Igor Bregerfda31e62017-05-10 06:52:58 +0000715 BuildMI(*I.getParent(), I, I.getDebugLoc(),
716 TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
717 .addImm(0)
718 .addReg(SrcReg)
719 .addImm(X86::sub_8bit);
Igor Bregerfda31e62017-05-10 06:52:58 +0000720 }
721
Igor Bregerd48c5e42017-07-10 09:07:34 +0000722 MachineInstr &AndInst =
723 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
724 .addReg(DefReg)
725 .addImm(1);
726
727 constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
728
729 I.eraseFromParent();
730 return true;
Igor Bregerfda31e62017-05-10 06:52:58 +0000731}
732
Igor Breger1f143642017-09-11 09:41:13 +0000733bool X86InstructionSelector::selectAnyext(MachineInstr &I,
734 MachineRegisterInfo &MRI,
735 MachineFunction &MF) const {
736
737 if (I.getOpcode() != TargetOpcode::G_ANYEXT)
738 return false;
739
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
746 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
747 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
748
Igor Breger21200ed2017-09-17 08:08:13 +0000749 assert(DstRB.getID() == SrcRB.getID() &&
750 "G_ANYEXT input/output on different banks\n");
Igor Breger1f143642017-09-11 09:41:13 +0000751
Igor Breger21200ed2017-09-17 08:08:13 +0000752 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
753 "G_ANYEXT incorrect operand size");
Igor Breger1f143642017-09-11 09:41:13 +0000754
755 if (DstRB.getID() != X86::GPRRegBankID)
756 return false;
757
758 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
759 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
760
761 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
762 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
763 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
764 << " operand\n");
765 return false;
766 }
767
768 if (SrcRC == DstRC) {
769 I.setDesc(TII.get(X86::COPY));
770 return true;
771 }
772
773 BuildMI(*I.getParent(), I, I.getDebugLoc(),
774 TII.get(TargetOpcode::SUBREG_TO_REG))
775 .addDef(DstReg)
776 .addImm(0)
777 .addReg(SrcReg)
778 .addImm(getSubRegIndex(SrcRC));
779
780 I.eraseFromParent();
781 return true;
782}
783
Igor Bregerc7b59772017-05-11 07:17:40 +0000784bool X86InstructionSelector::selectCmp(MachineInstr &I,
785 MachineRegisterInfo &MRI,
786 MachineFunction &MF) const {
787 if (I.getOpcode() != TargetOpcode::G_ICMP)
788 return false;
789
790 X86::CondCode CC;
791 bool SwapArgs;
792 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
793 (CmpInst::Predicate)I.getOperand(1).getPredicate());
794 unsigned OpSet = X86::getSETFromCond(CC);
795
796 unsigned LHS = I.getOperand(2).getReg();
797 unsigned RHS = I.getOperand(3).getReg();
798
799 if (SwapArgs)
800 std::swap(LHS, RHS);
801
802 unsigned OpCmp;
803 LLT Ty = MRI.getType(LHS);
804
805 switch (Ty.getSizeInBits()) {
806 default:
807 return false;
808 case 8:
809 OpCmp = X86::CMP8rr;
810 break;
811 case 16:
812 OpCmp = X86::CMP16rr;
813 break;
814 case 32:
815 OpCmp = X86::CMP32rr;
816 break;
817 case 64:
818 OpCmp = X86::CMP64rr;
819 break;
820 }
821
822 MachineInstr &CmpInst =
823 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
824 .addReg(LHS)
825 .addReg(RHS);
826
827 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
828 TII.get(OpSet), I.getOperand(0).getReg());
829
830 constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
831 constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
832
833 I.eraseFromParent();
834 return true;
835}
836
Igor Breger28f290f2017-05-17 12:48:08 +0000837bool X86InstructionSelector::selectUadde(MachineInstr &I,
838 MachineRegisterInfo &MRI,
839 MachineFunction &MF) const {
840 if (I.getOpcode() != TargetOpcode::G_UADDE)
841 return false;
842
843 const unsigned DstReg = I.getOperand(0).getReg();
844 const unsigned CarryOutReg = I.getOperand(1).getReg();
845 const unsigned Op0Reg = I.getOperand(2).getReg();
846 const unsigned Op1Reg = I.getOperand(3).getReg();
847 unsigned CarryInReg = I.getOperand(4).getReg();
848
849 const LLT DstTy = MRI.getType(DstReg);
850
851 if (DstTy != LLT::scalar(32))
852 return false;
853
854 // find CarryIn def instruction.
855 MachineInstr *Def = MRI.getVRegDef(CarryInReg);
856 while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
857 CarryInReg = Def->getOperand(1).getReg();
858 Def = MRI.getVRegDef(CarryInReg);
859 }
860
861 unsigned Opcode;
862 if (Def->getOpcode() == TargetOpcode::G_UADDE) {
863 // carry set by prev ADD.
864
865 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
866 .addReg(CarryInReg);
867
868 if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
869 return false;
870
871 Opcode = X86::ADC32rr;
872 } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) {
873 // carry is constant, support only 0.
874 if (*val != 0)
875 return false;
876
877 Opcode = X86::ADD32rr;
878 } else
879 return false;
880
881 MachineInstr &AddInst =
882 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
883 .addReg(Op0Reg)
884 .addReg(Op1Reg);
885
886 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
887 .addReg(X86::EFLAGS);
888
889 if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
890 !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
891 return false;
892
893 I.eraseFromParent();
894 return true;
895}
896
Igor Bregerf5035d62017-06-25 11:42:17 +0000897bool X86InstructionSelector::selectExtract(MachineInstr &I,
898 MachineRegisterInfo &MRI,
899 MachineFunction &MF) const {
900
901 if (I.getOpcode() != TargetOpcode::G_EXTRACT)
902 return false;
903
904 const unsigned DstReg = I.getOperand(0).getReg();
905 const unsigned SrcReg = I.getOperand(1).getReg();
906 int64_t Index = I.getOperand(2).getImm();
907
908 const LLT DstTy = MRI.getType(DstReg);
909 const LLT SrcTy = MRI.getType(SrcReg);
910
911 // Meanwile handle vector type only.
912 if (!DstTy.isVector())
913 return false;
914
915 if (Index % DstTy.getSizeInBits() != 0)
916 return false; // Not extract subvector.
917
918 if (Index == 0) {
919 // Replace by extract subreg copy.
920 if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
921 return false;
922
923 I.eraseFromParent();
924 return true;
925 }
926
927 bool HasAVX = STI.hasAVX();
928 bool HasAVX512 = STI.hasAVX512();
929 bool HasVLX = STI.hasVLX();
930
931 if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
932 if (HasVLX)
933 I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
934 else if (HasAVX)
935 I.setDesc(TII.get(X86::VEXTRACTF128rr));
936 else
937 return false;
938 } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
939 if (DstTy.getSizeInBits() == 128)
940 I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
941 else if (DstTy.getSizeInBits() == 256)
942 I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
943 else
944 return false;
945 } else
946 return false;
947
948 // Convert to X86 VEXTRACT immediate.
949 Index = Index / DstTy.getSizeInBits();
950 I.getOperand(2).setImm(Index);
951
952 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
953}
954
955bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
956 MachineInstr &I,
957 MachineRegisterInfo &MRI,
958 MachineFunction &MF) const {
959
960 const LLT DstTy = MRI.getType(DstReg);
961 const LLT SrcTy = MRI.getType(SrcReg);
962 unsigned SubIdx = X86::NoSubRegister;
963
964 if (!DstTy.isVector() || !SrcTy.isVector())
965 return false;
966
967 assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
968 "Incorrect Src/Dst register size");
969
970 if (DstTy.getSizeInBits() == 128)
971 SubIdx = X86::sub_xmm;
972 else if (DstTy.getSizeInBits() == 256)
973 SubIdx = X86::sub_ymm;
974 else
975 return false;
976
977 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
978 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
979
980 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
981
982 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
983 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
984 DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
985 return false;
986 }
987
988 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
989 .addReg(SrcReg, 0, SubIdx);
990
991 return true;
992}
993
Igor Breger1c29be72017-06-22 09:43:35 +0000994bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
995 MachineInstr &I,
996 MachineRegisterInfo &MRI,
997 MachineFunction &MF) const {
998
999 const LLT DstTy = MRI.getType(DstReg);
1000 const LLT SrcTy = MRI.getType(SrcReg);
1001 unsigned SubIdx = X86::NoSubRegister;
1002
1003 // TODO: support scalar types
1004 if (!DstTy.isVector() || !SrcTy.isVector())
1005 return false;
1006
1007 assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1008 "Incorrect Src/Dst register size");
1009
1010 if (SrcTy.getSizeInBits() == 128)
1011 SubIdx = X86::sub_xmm;
1012 else if (SrcTy.getSizeInBits() == 256)
1013 SubIdx = X86::sub_ymm;
1014 else
1015 return false;
1016
1017 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1018 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1019
1020 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1021 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1022 DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1023 return false;
1024 }
1025
1026 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1027 .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1028 .addReg(SrcReg);
1029
1030 return true;
1031}
1032
1033bool X86InstructionSelector::selectInsert(MachineInstr &I,
1034 MachineRegisterInfo &MRI,
1035 MachineFunction &MF) const {
1036
1037 if (I.getOpcode() != TargetOpcode::G_INSERT)
1038 return false;
1039
1040 const unsigned DstReg = I.getOperand(0).getReg();
1041 const unsigned SrcReg = I.getOperand(1).getReg();
1042 const unsigned InsertReg = I.getOperand(2).getReg();
1043 int64_t Index = I.getOperand(3).getImm();
1044
1045 const LLT DstTy = MRI.getType(DstReg);
1046 const LLT InsertRegTy = MRI.getType(InsertReg);
1047
1048 // Meanwile handle vector type only.
1049 if (!DstTy.isVector())
1050 return false;
1051
1052 if (Index % InsertRegTy.getSizeInBits() != 0)
1053 return false; // Not insert subvector.
1054
1055 if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1056 // Replace by subreg copy.
1057 if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1058 return false;
1059
1060 I.eraseFromParent();
1061 return true;
1062 }
1063
1064 bool HasAVX = STI.hasAVX();
1065 bool HasAVX512 = STI.hasAVX512();
1066 bool HasVLX = STI.hasVLX();
1067
1068 if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
1069 if (HasVLX)
1070 I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
1071 else if (HasAVX)
1072 I.setDesc(TII.get(X86::VINSERTF128rr));
1073 else
1074 return false;
1075 } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
1076 if (InsertRegTy.getSizeInBits() == 128)
1077 I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
1078 else if (InsertRegTy.getSizeInBits() == 256)
1079 I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
1080 else
1081 return false;
1082 } else
1083 return false;
1084
1085 // Convert to X86 VINSERT immediate.
1086 Index = Index / InsertRegTy.getSizeInBits();
1087
1088 I.getOperand(3).setImm(Index);
1089
1090 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1091}
1092
Igor Bregerb186a692017-07-02 08:15:49 +00001093bool X86InstructionSelector::selectUnmergeValues(MachineInstr &I,
1094 MachineRegisterInfo &MRI,
1095 MachineFunction &MF) const {
1096 if (I.getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
1097 return false;
1098
1099 // Split to extracts.
1100 unsigned NumDefs = I.getNumOperands() - 1;
1101 unsigned SrcReg = I.getOperand(NumDefs).getReg();
1102 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1103
1104 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1105
1106 MachineInstr &ExtrInst =
1107 *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1108 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1109 .addReg(SrcReg)
1110 .addImm(Idx * DefSize);
1111
1112 if (!select(ExtrInst))
1113 return false;
1114 }
1115
1116 I.eraseFromParent();
1117 return true;
1118}
1119
Igor Breger0cddd342017-06-29 12:08:28 +00001120bool X86InstructionSelector::selectMergeValues(MachineInstr &I,
1121 MachineRegisterInfo &MRI,
1122 MachineFunction &MF) const {
1123 if (I.getOpcode() != TargetOpcode::G_MERGE_VALUES)
1124 return false;
1125
1126 // Split to inserts.
1127 unsigned DstReg = I.getOperand(0).getReg();
1128 unsigned SrcReg0 = I.getOperand(1).getReg();
1129
1130 const LLT DstTy = MRI.getType(DstReg);
1131 const LLT SrcTy = MRI.getType(SrcReg0);
1132 unsigned SrcSize = SrcTy.getSizeInBits();
1133
1134 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1135
1136 // For the first src use insertSubReg.
1137 unsigned DefReg = MRI.createGenericVirtualRegister(DstTy);
1138 MRI.setRegBank(DefReg, RegBank);
1139 if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1140 return false;
1141
1142 for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
1143
1144 unsigned Tmp = MRI.createGenericVirtualRegister(DstTy);
1145 MRI.setRegBank(Tmp, RegBank);
1146
1147 MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1148 TII.get(TargetOpcode::G_INSERT), Tmp)
1149 .addReg(DefReg)
1150 .addReg(I.getOperand(Idx).getReg())
1151 .addImm((Idx - 1) * SrcSize);
1152
1153 DefReg = Tmp;
1154
1155 if (!select(InsertInst))
1156 return false;
1157 }
1158
1159 MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1160 TII.get(TargetOpcode::COPY), DstReg)
1161 .addReg(DefReg);
1162
1163 if (!select(CopyInst))
1164 return false;
1165
1166 I.eraseFromParent();
1167 return true;
1168}
Igor Breger685889c2017-08-21 10:51:54 +00001169
1170bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1171 MachineRegisterInfo &MRI,
1172 MachineFunction &MF) const {
1173 if (I.getOpcode() != TargetOpcode::G_BRCOND)
1174 return false;
1175
1176 const unsigned CondReg = I.getOperand(0).getReg();
1177 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1178
1179 MachineInstr &TestInst =
1180 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1181 .addReg(CondReg)
1182 .addImm(1);
1183 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
1184 .addMBB(DestMBB);
1185
1186 constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1187
1188 I.eraseFromParent();
1189 return true;
1190}
1191
Igor Breger21200ed2017-09-17 08:08:13 +00001192bool X86InstructionSelector::materializeFP(MachineInstr &I,
1193 MachineRegisterInfo &MRI,
1194 MachineFunction &MF) const {
1195 if (I.getOpcode() != TargetOpcode::G_FCONSTANT)
1196 return false;
1197
1198 // Can't handle alternate code models yet.
1199 CodeModel::Model CM = TM.getCodeModel();
1200 if (CM != CodeModel::Small && CM != CodeModel::Large)
1201 return false;
1202
1203 const unsigned DstReg = I.getOperand(0).getReg();
1204 const LLT DstTy = MRI.getType(DstReg);
1205 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1206 unsigned Align = DstTy.getSizeInBits();
1207 const DebugLoc &DbgLoc = I.getDebugLoc();
1208
1209 unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
1210
1211 // Create the load from the constant pool.
1212 const ConstantFP *CFP = I.getOperand(1).getFPImm();
1213 unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
1214 MachineInstr *LoadInst = nullptr;
1215 unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1216
1217 if (CM == CodeModel::Large && STI.is64Bit()) {
1218 // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1219 // they cannot be folded into immediate fields.
1220
1221 unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1222 BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1223 .addConstantPoolIndex(CPI, 0, OpFlag);
1224
1225 MachineMemOperand *MMO = MF.getMachineMemOperand(
1226 MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1227 MF.getDataLayout().getPointerSize(), Align);
1228
1229 LoadInst =
1230 addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1231 AddrReg)
1232 .addMemOperand(MMO);
1233
1234 } else if(CM == CodeModel::Small || !STI.is64Bit()){
1235 // Handle the case when globals fit in our immediate field.
1236 // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1237
1238 // x86-32 PIC requires a PIC base register for constant pools.
1239 unsigned PICBase = 0;
1240 if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
1241 // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1242 // In DAGISEL the code that initialize it generated by the CGBR pass.
1243 return false; // TODO support the mode.
1244 }
1245 else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
1246 PICBase = X86::RIP;
1247
1248 LoadInst = addConstantPoolReference(
1249 BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1250 OpFlag);
1251 } else
1252 return false;
1253
1254 constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
1255 I.eraseFromParent();
1256 return true;
1257}
1258
Igor Breger2661ae42017-09-04 09:06:45 +00001259bool X86InstructionSelector::selectImplicitDefOrPHI(
1260 MachineInstr &I, MachineRegisterInfo &MRI) const {
Igor Breger47be5fb2017-08-24 07:06:27 +00001261
Igor Breger2661ae42017-09-04 09:06:45 +00001262 if (I.getOpcode() != TargetOpcode::G_IMPLICIT_DEF &&
1263 I.getOpcode() != TargetOpcode::G_PHI)
Igor Breger47be5fb2017-08-24 07:06:27 +00001264 return false;
1265
1266 unsigned DstReg = I.getOperand(0).getReg();
1267
1268 if (!MRI.getRegClassOrNull(DstReg)) {
1269 const LLT DstTy = MRI.getType(DstReg);
1270 const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1271
1272 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1273 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1274 << " operand\n");
1275 return false;
1276 }
1277 }
1278
Igor Breger2661ae42017-09-04 09:06:45 +00001279 if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1280 I.setDesc(TII.get(X86::IMPLICIT_DEF));
1281 else
1282 I.setDesc(TII.get(X86::PHI));
1283
Igor Breger47be5fb2017-08-24 07:06:27 +00001284 return true;
1285}
1286
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001287InstructionSelector *
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001288llvm::createX86InstructionSelector(const X86TargetMachine &TM,
1289 X86Subtarget &Subtarget,
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001290 X86RegisterBankInfo &RBI) {
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001291 return new X86InstructionSelector(TM, Subtarget, RBI);
Daniel Sanders0b5293f2017-04-06 09:49:34 +00001292}