blob: 41f4eb9563afda3aff93677536e6e10e34be1a89 [file] [log] [blame]
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001//===- AArch64InstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for
10/// AArch64.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000014#include "AArch64InstrInfo.h"
Tim Northovere9600d82017-02-08 17:57:27 +000015#include "AArch64MachineFunctionInfo.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000016#include "AArch64RegisterBankInfo.h"
17#include "AArch64RegisterInfo.h"
18#include "AArch64Subtarget.h"
Tim Northoverbdf16242016-10-10 21:50:00 +000019#include "AArch64TargetMachine.h"
Tim Northover9ac0eba2016-11-08 00:45:29 +000020#include "MCTargetDesc/AArch64AddressingModes.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000021#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
David Blaikie62651302017-10-26 23:39:54 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Amara Emerson1e8c1642018-07-31 00:09:02 +000023#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Aditya Nandakumar75ad9cc2017-04-19 20:48:50 +000024#include "llvm/CodeGen/GlobalISel/Utils.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000025#include "llvm/CodeGen/MachineBasicBlock.h"
Amara Emerson1abe05c2019-02-21 20:20:16 +000026#include "llvm/CodeGen/MachineConstantPool.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000027#include "llvm/CodeGen/MachineFunction.h"
28#include "llvm/CodeGen/MachineInstr.h"
29#include "llvm/CodeGen/MachineInstrBuilder.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000030#include "llvm/CodeGen/MachineOperand.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000031#include "llvm/CodeGen/MachineRegisterInfo.h"
32#include "llvm/IR/Type.h"
33#include "llvm/Support/Debug.h"
34#include "llvm/Support/raw_ostream.h"
35
36#define DEBUG_TYPE "aarch64-isel"
37
38using 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 "AArch64GenGlobalISel.inc"
44#undef GET_GLOBALISEL_PREDICATE_BITSET
45
Daniel Sanders0b5293f2017-04-06 09:49:34 +000046class AArch64InstructionSelector : public InstructionSelector {
47public:
48 AArch64InstructionSelector(const AArch64TargetMachine &TM,
49 const AArch64Subtarget &STI,
50 const AArch64RegisterBankInfo &RBI);
51
Daniel Sandersf76f3152017-11-16 00:46:35 +000052 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000053 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000054
55private:
56 /// tblgen-erated 'select' implementation, used as the initial selector for
57 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000058 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000059
60 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF,
61 MachineRegisterInfo &MRI) const;
62 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
63 MachineRegisterInfo &MRI) const;
64
65 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
66 MachineRegisterInfo &MRI) const;
67
Amara Emerson5ec14602018-12-10 18:44:58 +000068 // Helper to generate an equivalent of scalar_to_vector into a new register,
69 // returned via 'Dst'.
Amara Emerson8acb0d92019-03-04 19:16:00 +000070 MachineInstr *emitScalarToVector(unsigned EltSize,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +000071 const TargetRegisterClass *DstRC,
72 unsigned Scalar,
73 MachineIRBuilder &MIRBuilder) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000074 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson8cb186c2018-12-20 01:11:04 +000075 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette245047d2019-01-24 22:00:41 +000076 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000077
Amara Emerson1abe05c2019-02-21 20:20:16 +000078 void collectShuffleMaskIndices(MachineInstr &I, MachineRegisterInfo &MRI,
79 SmallVectorImpl<int> &Idxs) const;
80 bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
81
82 unsigned emitConstantPoolEntry(Constant *CPVal, MachineFunction &MF) const;
83 MachineInstr *emitLoadFromConstantPool(Constant *CPVal,
84 MachineIRBuilder &MIRBuilder) const;
Amara Emerson8acb0d92019-03-04 19:16:00 +000085 MachineInstr *emitVectorConcat(unsigned Op1, unsigned Op2,
86 MachineIRBuilder &MIRBuilder) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +000087
Daniel Sanders1e4569f2017-10-20 20:55:29 +000088 ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000089
Daniel Sanders1e4569f2017-10-20 20:55:29 +000090 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root,
91 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +000092
Daniel Sanders1e4569f2017-10-20 20:55:29 +000093 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000094 return selectAddrModeUnscaled(Root, 1);
95 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000096 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +000097 return selectAddrModeUnscaled(Root, 2);
98 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +000099 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000100 return selectAddrModeUnscaled(Root, 4);
101 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000102 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000103 return selectAddrModeUnscaled(Root, 8);
104 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000105 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000106 return selectAddrModeUnscaled(Root, 16);
107 }
108
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000109 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root,
110 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000111 template <int Width>
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000112 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000113 return selectAddrModeIndexed(Root, Width / 8);
114 }
115
Volkan Kelesf7f25682018-01-16 18:44:05 +0000116 void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const;
117
Amara Emerson1e8c1642018-07-31 00:09:02 +0000118 // Materialize a GlobalValue or BlockAddress using a movz+movk sequence.
119 void materializeLargeCMVal(MachineInstr &I, const Value *V,
120 unsigned char OpFlags) const;
121
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000122 const AArch64TargetMachine &TM;
123 const AArch64Subtarget &STI;
124 const AArch64InstrInfo &TII;
125 const AArch64RegisterInfo &TRI;
126 const AArch64RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000127
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000128#define GET_GLOBALISEL_PREDICATES_DECL
129#include "AArch64GenGlobalISel.inc"
130#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000131
132// We declare the temporaries used by selectImpl() in the class to minimize the
133// cost of constructing placeholder values.
134#define GET_GLOBALISEL_TEMPORARIES_DECL
135#include "AArch64GenGlobalISel.inc"
136#undef GET_GLOBALISEL_TEMPORARIES_DECL
137};
138
139} // end anonymous namespace
140
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000141#define GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000142#include "AArch64GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000143#undef GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000144
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000145AArch64InstructionSelector::AArch64InstructionSelector(
Tim Northoverbdf16242016-10-10 21:50:00 +0000146 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
147 const AArch64RegisterBankInfo &RBI)
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000148 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000149 TRI(*STI.getRegisterInfo()), RBI(RBI),
150#define GET_GLOBALISEL_PREDICATES_INIT
151#include "AArch64GenGlobalISel.inc"
152#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000153#define GET_GLOBALISEL_TEMPORARIES_INIT
154#include "AArch64GenGlobalISel.inc"
155#undef GET_GLOBALISEL_TEMPORARIES_INIT
156{
157}
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000158
Tim Northoverfb8d9892016-10-12 22:49:15 +0000159// FIXME: This should be target-independent, inferred from the types declared
160// for each class in the bank.
161static const TargetRegisterClass *
162getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
Amara Emerson3838ed02018-02-02 18:03:30 +0000163 const RegisterBankInfo &RBI,
164 bool GetAllRegSet = false) {
Tim Northoverfb8d9892016-10-12 22:49:15 +0000165 if (RB.getID() == AArch64::GPRRegBankID) {
166 if (Ty.getSizeInBits() <= 32)
Amara Emerson3838ed02018-02-02 18:03:30 +0000167 return GetAllRegSet ? &AArch64::GPR32allRegClass
168 : &AArch64::GPR32RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000169 if (Ty.getSizeInBits() == 64)
Amara Emerson3838ed02018-02-02 18:03:30 +0000170 return GetAllRegSet ? &AArch64::GPR64allRegClass
171 : &AArch64::GPR64RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000172 return nullptr;
173 }
174
175 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson3838ed02018-02-02 18:03:30 +0000176 if (Ty.getSizeInBits() <= 16)
177 return &AArch64::FPR16RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000178 if (Ty.getSizeInBits() == 32)
179 return &AArch64::FPR32RegClass;
180 if (Ty.getSizeInBits() == 64)
181 return &AArch64::FPR64RegClass;
182 if (Ty.getSizeInBits() == 128)
183 return &AArch64::FPR128RegClass;
184 return nullptr;
185 }
186
187 return nullptr;
188}
189
Jessica Paquette245047d2019-01-24 22:00:41 +0000190/// Given a register bank, and size in bits, return the smallest register class
191/// that can represent that combination.
Benjamin Kramer711950c2019-02-11 15:16:21 +0000192static const TargetRegisterClass *
193getMinClassForRegBank(const RegisterBank &RB, unsigned SizeInBits,
194 bool GetAllRegSet = false) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000195 unsigned RegBankID = RB.getID();
196
197 if (RegBankID == AArch64::GPRRegBankID) {
198 if (SizeInBits <= 32)
199 return GetAllRegSet ? &AArch64::GPR32allRegClass
200 : &AArch64::GPR32RegClass;
201 if (SizeInBits == 64)
202 return GetAllRegSet ? &AArch64::GPR64allRegClass
203 : &AArch64::GPR64RegClass;
204 }
205
206 if (RegBankID == AArch64::FPRRegBankID) {
207 switch (SizeInBits) {
208 default:
209 return nullptr;
210 case 8:
211 return &AArch64::FPR8RegClass;
212 case 16:
213 return &AArch64::FPR16RegClass;
214 case 32:
215 return &AArch64::FPR32RegClass;
216 case 64:
217 return &AArch64::FPR64RegClass;
218 case 128:
219 return &AArch64::FPR128RegClass;
220 }
221 }
222
223 return nullptr;
224}
225
226/// Returns the correct subregister to use for a given register class.
227static bool getSubRegForClass(const TargetRegisterClass *RC,
228 const TargetRegisterInfo &TRI, unsigned &SubReg) {
229 switch (TRI.getRegSizeInBits(*RC)) {
230 case 8:
231 SubReg = AArch64::bsub;
232 break;
233 case 16:
234 SubReg = AArch64::hsub;
235 break;
236 case 32:
237 if (RC == &AArch64::GPR32RegClass)
238 SubReg = AArch64::sub_32;
239 else
240 SubReg = AArch64::ssub;
241 break;
242 case 64:
243 SubReg = AArch64::dsub;
244 break;
245 default:
246 LLVM_DEBUG(
247 dbgs() << "Couldn't find appropriate subregister for register class.");
248 return false;
249 }
250
251 return true;
252}
253
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000254/// Check whether \p I is a currently unsupported binary operation:
255/// - it has an unsized type
256/// - an operand is not a vreg
257/// - all operands are not in the same bank
258/// These are checks that should someday live in the verifier, but right now,
259/// these are mostly limitations of the aarch64 selector.
260static bool unsupportedBinOp(const MachineInstr &I,
261 const AArch64RegisterBankInfo &RBI,
262 const MachineRegisterInfo &MRI,
263 const AArch64RegisterInfo &TRI) {
Tim Northover0f140c72016-09-09 11:46:34 +0000264 LLT Ty = MRI.getType(I.getOperand(0).getReg());
Tim Northover32a078a2016-09-15 10:09:59 +0000265 if (!Ty.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000266 LLVM_DEBUG(dbgs() << "Generic binop register should be typed\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000267 return true;
268 }
269
270 const RegisterBank *PrevOpBank = nullptr;
271 for (auto &MO : I.operands()) {
272 // FIXME: Support non-register operands.
273 if (!MO.isReg()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000274 LLVM_DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000275 return true;
276 }
277
278 // FIXME: Can generic operations have physical registers operands? If
279 // so, this will need to be taught about that, and we'll need to get the
280 // bank out of the minimal class for the register.
281 // Either way, this needs to be documented (and possibly verified).
282 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000283 LLVM_DEBUG(dbgs() << "Generic inst has physical register operand\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000284 return true;
285 }
286
287 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI);
288 if (!OpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000289 LLVM_DEBUG(dbgs() << "Generic register has no bank or class\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000290 return true;
291 }
292
293 if (PrevOpBank && OpBank != PrevOpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000294 LLVM_DEBUG(dbgs() << "Generic inst operands have different banks\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000295 return true;
296 }
297 PrevOpBank = OpBank;
298 }
299 return false;
300}
301
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000302/// Select the AArch64 opcode for the basic binary operation \p GenericOpc
Ahmed Bougachacfb384d2017-01-23 21:10:05 +0000303/// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000304/// and of size \p OpSize.
305/// \returns \p GenericOpc if the combination is unsupported.
306static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
307 unsigned OpSize) {
308 switch (RegBankID) {
309 case AArch64::GPRRegBankID:
Ahmed Bougacha05a5f7d2017-01-25 02:41:38 +0000310 if (OpSize == 32) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000311 switch (GenericOpc) {
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000312 case TargetOpcode::G_SHL:
313 return AArch64::LSLVWr;
314 case TargetOpcode::G_LSHR:
315 return AArch64::LSRVWr;
316 case TargetOpcode::G_ASHR:
317 return AArch64::ASRVWr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000318 default:
319 return GenericOpc;
320 }
Tim Northover55782222016-10-18 20:03:48 +0000321 } else if (OpSize == 64) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000322 switch (GenericOpc) {
Tim Northover2fda4b02016-10-10 21:49:49 +0000323 case TargetOpcode::G_GEP:
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000324 return AArch64::ADDXrr;
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000325 case TargetOpcode::G_SHL:
326 return AArch64::LSLVXr;
327 case TargetOpcode::G_LSHR:
328 return AArch64::LSRVXr;
329 case TargetOpcode::G_ASHR:
330 return AArch64::ASRVXr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000331 default:
332 return GenericOpc;
333 }
334 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000335 break;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000336 case AArch64::FPRRegBankID:
337 switch (OpSize) {
338 case 32:
339 switch (GenericOpc) {
340 case TargetOpcode::G_FADD:
341 return AArch64::FADDSrr;
342 case TargetOpcode::G_FSUB:
343 return AArch64::FSUBSrr;
344 case TargetOpcode::G_FMUL:
345 return AArch64::FMULSrr;
346 case TargetOpcode::G_FDIV:
347 return AArch64::FDIVSrr;
348 default:
349 return GenericOpc;
350 }
351 case 64:
352 switch (GenericOpc) {
353 case TargetOpcode::G_FADD:
354 return AArch64::FADDDrr;
355 case TargetOpcode::G_FSUB:
356 return AArch64::FSUBDrr;
357 case TargetOpcode::G_FMUL:
358 return AArch64::FMULDrr;
359 case TargetOpcode::G_FDIV:
360 return AArch64::FDIVDrr;
Quentin Colombet0e531272016-10-11 00:21:11 +0000361 case TargetOpcode::G_OR:
362 return AArch64::ORRv8i8;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000363 default:
364 return GenericOpc;
365 }
366 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000367 break;
368 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000369 return GenericOpc;
370}
371
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000372/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
373/// appropriate for the (value) register bank \p RegBankID and of memory access
374/// size \p OpSize. This returns the variant with the base+unsigned-immediate
375/// addressing mode (e.g., LDRXui).
376/// \returns \p GenericOpc if the combination is unsupported.
377static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
378 unsigned OpSize) {
379 const bool isStore = GenericOpc == TargetOpcode::G_STORE;
380 switch (RegBankID) {
381 case AArch64::GPRRegBankID:
382 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000383 case 8:
384 return isStore ? AArch64::STRBBui : AArch64::LDRBBui;
385 case 16:
386 return isStore ? AArch64::STRHHui : AArch64::LDRHHui;
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000387 case 32:
388 return isStore ? AArch64::STRWui : AArch64::LDRWui;
389 case 64:
390 return isStore ? AArch64::STRXui : AArch64::LDRXui;
391 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000392 break;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000393 case AArch64::FPRRegBankID:
394 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000395 case 8:
396 return isStore ? AArch64::STRBui : AArch64::LDRBui;
397 case 16:
398 return isStore ? AArch64::STRHui : AArch64::LDRHui;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000399 case 32:
400 return isStore ? AArch64::STRSui : AArch64::LDRSui;
401 case 64:
402 return isStore ? AArch64::STRDui : AArch64::LDRDui;
403 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000404 break;
405 }
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000406 return GenericOpc;
407}
408
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000409#ifndef NDEBUG
Jessica Paquette245047d2019-01-24 22:00:41 +0000410/// Helper function that verifies that we have a valid copy at the end of
411/// selectCopy. Verifies that the source and dest have the expected sizes and
412/// then returns true.
413static bool isValidCopy(const MachineInstr &I, const RegisterBank &DstBank,
414 const MachineRegisterInfo &MRI,
415 const TargetRegisterInfo &TRI,
416 const RegisterBankInfo &RBI) {
417 const unsigned DstReg = I.getOperand(0).getReg();
418 const unsigned SrcReg = I.getOperand(1).getReg();
419 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
420 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Amara Emersondb211892018-02-20 05:11:57 +0000421
Jessica Paquette245047d2019-01-24 22:00:41 +0000422 // Make sure the size of the source and dest line up.
423 assert(
424 (DstSize == SrcSize ||
425 // Copies are a mean to setup initial types, the number of
426 // bits may not exactly match.
427 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && DstSize <= SrcSize) ||
428 // Copies are a mean to copy bits around, as long as we are
429 // on the same register class, that's fine. Otherwise, that
430 // means we need some SUBREG_TO_REG or AND & co.
431 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) &&
432 "Copy with different width?!");
433
434 // Check the size of the destination.
435 assert((DstSize <= 64 || DstBank.getID() == AArch64::FPRRegBankID) &&
436 "GPRs cannot get more than 64-bit width values");
437
438 return true;
439}
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000440#endif
Jessica Paquette245047d2019-01-24 22:00:41 +0000441
442/// Helper function for selectCopy. Inserts a subregister copy from
443/// \p *From to \p *To, linking it up to \p I.
444///
445/// e.g, given I = "Dst = COPY SrcReg", we'll transform that into
446///
447/// CopyReg (From class) = COPY SrcReg
448/// SubRegCopy (To class) = COPY CopyReg:SubReg
449/// Dst = COPY SubRegCopy
450static bool selectSubregisterCopy(MachineInstr &I, const TargetInstrInfo &TII,
451 MachineRegisterInfo &MRI,
452 const RegisterBankInfo &RBI, unsigned SrcReg,
453 const TargetRegisterClass *From,
454 const TargetRegisterClass *To,
455 unsigned SubReg) {
456 unsigned CopyReg = MRI.createVirtualRegister(From);
457 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::COPY), CopyReg)
458 .addUse(SrcReg);
459 unsigned SubRegCopy = MRI.createVirtualRegister(To);
460 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
461 SubRegCopy)
462 .addUse(CopyReg, 0, SubReg);
Amara Emersondb211892018-02-20 05:11:57 +0000463 MachineOperand &RegOp = I.getOperand(1);
464 RegOp.setReg(SubRegCopy);
Jessica Paquette245047d2019-01-24 22:00:41 +0000465
466 // It's possible that the destination register won't be constrained. Make
467 // sure that happens.
468 if (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()))
469 RBI.constrainGenericRegister(I.getOperand(0).getReg(), *To, MRI);
470
Amara Emersondb211892018-02-20 05:11:57 +0000471 return true;
472}
473
Quentin Colombetcb629a82016-10-12 03:57:49 +0000474static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
475 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
476 const RegisterBankInfo &RBI) {
477
478 unsigned DstReg = I.getOperand(0).getReg();
Amara Emersondb211892018-02-20 05:11:57 +0000479 unsigned SrcReg = I.getOperand(1).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +0000480 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
481 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
482 const TargetRegisterClass *DstRC = getMinClassForRegBank(
483 DstRegBank, RBI.getSizeInBits(DstReg, MRI, TRI), true);
484 if (!DstRC) {
485 LLVM_DEBUG(dbgs() << "Unexpected dest size "
486 << RBI.getSizeInBits(DstReg, MRI, TRI) << '\n');
Amara Emerson3838ed02018-02-02 18:03:30 +0000487 return false;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000488 }
489
Jessica Paquette245047d2019-01-24 22:00:41 +0000490 // A couple helpers below, for making sure that the copy we produce is valid.
491
492 // Set to true if we insert a SUBREG_TO_REG. If we do this, then we don't want
493 // to verify that the src and dst are the same size, since that's handled by
494 // the SUBREG_TO_REG.
495 bool KnownValid = false;
496
497 // Returns true, or asserts if something we don't expect happens. Instead of
498 // returning true, we return isValidCopy() to ensure that we verify the
499 // result.
Jessica Paquette76c40f82019-01-24 22:51:31 +0000500 auto CheckCopy = [&]() {
Jessica Paquette245047d2019-01-24 22:00:41 +0000501 // If we have a bitcast or something, we can't have physical registers.
502 assert(
Simon Pilgrimdea61742019-01-25 11:38:40 +0000503 (I.isCopy() ||
504 (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()) &&
505 !TargetRegisterInfo::isPhysicalRegister(I.getOperand(1).getReg()))) &&
506 "No phys reg on generic operator!");
Jessica Paquette245047d2019-01-24 22:00:41 +0000507 assert(KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI));
Jonas Hahnfeld65a401f2019-03-04 08:51:32 +0000508 (void)KnownValid;
Jessica Paquette245047d2019-01-24 22:00:41 +0000509 return true;
510 };
511
512 // Is this a copy? If so, then we may need to insert a subregister copy, or
513 // a SUBREG_TO_REG.
514 if (I.isCopy()) {
515 // Yes. Check if there's anything to fix up.
516 const TargetRegisterClass *SrcRC = getMinClassForRegBank(
517 SrcRegBank, RBI.getSizeInBits(SrcReg, MRI, TRI), true);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000518 if (!SrcRC) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000519 LLVM_DEBUG(dbgs() << "Couldn't determine source register class\n");
520 return false;
Amara Emerson7e9f3482018-02-18 17:10:49 +0000521 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000522
523 // Is this a cross-bank copy?
524 if (DstRegBank.getID() != SrcRegBank.getID()) {
525 // If we're doing a cross-bank copy on different-sized registers, we need
526 // to do a bit more work.
527 unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
528 unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
529
530 if (SrcSize > DstSize) {
531 // We're doing a cross-bank copy into a smaller register. We need a
532 // subregister copy. First, get a register class that's on the same bank
533 // as the destination, but the same size as the source.
534 const TargetRegisterClass *SubregRC =
535 getMinClassForRegBank(DstRegBank, SrcSize, true);
536 assert(SubregRC && "Didn't get a register class for subreg?");
537
538 // Get the appropriate subregister for the destination.
539 unsigned SubReg = 0;
540 if (!getSubRegForClass(DstRC, TRI, SubReg)) {
541 LLVM_DEBUG(dbgs() << "Couldn't determine subregister for copy.\n");
542 return false;
543 }
544
545 // Now, insert a subregister copy using the new register class.
546 selectSubregisterCopy(I, TII, MRI, RBI, SrcReg, SubregRC, DstRC,
547 SubReg);
548 return CheckCopy();
549 }
550
551 else if (DstRegBank.getID() == AArch64::GPRRegBankID && DstSize == 32 &&
552 SrcSize == 16) {
553 // Special case for FPR16 to GPR32.
554 // FIXME: This can probably be generalized like the above case.
555 unsigned PromoteReg =
556 MRI.createVirtualRegister(&AArch64::FPR32RegClass);
557 BuildMI(*I.getParent(), I, I.getDebugLoc(),
558 TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
559 .addImm(0)
560 .addUse(SrcReg)
561 .addImm(AArch64::hsub);
562 MachineOperand &RegOp = I.getOperand(1);
563 RegOp.setReg(PromoteReg);
564
565 // Promise that the copy is implicitly validated by the SUBREG_TO_REG.
566 KnownValid = true;
567 }
Amara Emerson7e9f3482018-02-18 17:10:49 +0000568 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000569
570 // If the destination is a physical register, then there's nothing to
571 // change, so we're done.
572 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
573 return CheckCopy();
Amara Emerson7e9f3482018-02-18 17:10:49 +0000574 }
575
Jessica Paquette245047d2019-01-24 22:00:41 +0000576 // No need to constrain SrcReg. It will get constrained when we hit another
577 // of its use or its defs. Copies do not have constraints.
578 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000579 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
580 << " operand\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000581 return false;
582 }
583 I.setDesc(TII.get(AArch64::COPY));
Jessica Paquette245047d2019-01-24 22:00:41 +0000584 return CheckCopy();
Quentin Colombetcb629a82016-10-12 03:57:49 +0000585}
586
Tim Northover69271c62016-10-12 22:49:11 +0000587static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
588 if (!DstTy.isScalar() || !SrcTy.isScalar())
589 return GenericOpc;
590
591 const unsigned DstSize = DstTy.getSizeInBits();
592 const unsigned SrcSize = SrcTy.getSizeInBits();
593
594 switch (DstSize) {
595 case 32:
596 switch (SrcSize) {
597 case 32:
598 switch (GenericOpc) {
599 case TargetOpcode::G_SITOFP:
600 return AArch64::SCVTFUWSri;
601 case TargetOpcode::G_UITOFP:
602 return AArch64::UCVTFUWSri;
603 case TargetOpcode::G_FPTOSI:
604 return AArch64::FCVTZSUWSr;
605 case TargetOpcode::G_FPTOUI:
606 return AArch64::FCVTZUUWSr;
607 default:
608 return GenericOpc;
609 }
610 case 64:
611 switch (GenericOpc) {
612 case TargetOpcode::G_SITOFP:
613 return AArch64::SCVTFUXSri;
614 case TargetOpcode::G_UITOFP:
615 return AArch64::UCVTFUXSri;
616 case TargetOpcode::G_FPTOSI:
617 return AArch64::FCVTZSUWDr;
618 case TargetOpcode::G_FPTOUI:
619 return AArch64::FCVTZUUWDr;
620 default:
621 return GenericOpc;
622 }
623 default:
624 return GenericOpc;
625 }
626 case 64:
627 switch (SrcSize) {
628 case 32:
629 switch (GenericOpc) {
630 case TargetOpcode::G_SITOFP:
631 return AArch64::SCVTFUWDri;
632 case TargetOpcode::G_UITOFP:
633 return AArch64::UCVTFUWDri;
634 case TargetOpcode::G_FPTOSI:
635 return AArch64::FCVTZSUXSr;
636 case TargetOpcode::G_FPTOUI:
637 return AArch64::FCVTZUUXSr;
638 default:
639 return GenericOpc;
640 }
641 case 64:
642 switch (GenericOpc) {
643 case TargetOpcode::G_SITOFP:
644 return AArch64::SCVTFUXDri;
645 case TargetOpcode::G_UITOFP:
646 return AArch64::UCVTFUXDri;
647 case TargetOpcode::G_FPTOSI:
648 return AArch64::FCVTZSUXDr;
649 case TargetOpcode::G_FPTOUI:
650 return AArch64::FCVTZUUXDr;
651 default:
652 return GenericOpc;
653 }
654 default:
655 return GenericOpc;
656 }
657 default:
658 return GenericOpc;
659 };
660 return GenericOpc;
661}
662
Tim Northover6c02ad52016-10-12 22:49:04 +0000663static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
664 switch (P) {
665 default:
666 llvm_unreachable("Unknown condition code!");
667 case CmpInst::ICMP_NE:
668 return AArch64CC::NE;
669 case CmpInst::ICMP_EQ:
670 return AArch64CC::EQ;
671 case CmpInst::ICMP_SGT:
672 return AArch64CC::GT;
673 case CmpInst::ICMP_SGE:
674 return AArch64CC::GE;
675 case CmpInst::ICMP_SLT:
676 return AArch64CC::LT;
677 case CmpInst::ICMP_SLE:
678 return AArch64CC::LE;
679 case CmpInst::ICMP_UGT:
680 return AArch64CC::HI;
681 case CmpInst::ICMP_UGE:
682 return AArch64CC::HS;
683 case CmpInst::ICMP_ULT:
684 return AArch64CC::LO;
685 case CmpInst::ICMP_ULE:
686 return AArch64CC::LS;
687 }
688}
689
Tim Northover7dd378d2016-10-12 22:49:07 +0000690static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
691 AArch64CC::CondCode &CondCode,
692 AArch64CC::CondCode &CondCode2) {
693 CondCode2 = AArch64CC::AL;
694 switch (P) {
695 default:
696 llvm_unreachable("Unknown FP condition!");
697 case CmpInst::FCMP_OEQ:
698 CondCode = AArch64CC::EQ;
699 break;
700 case CmpInst::FCMP_OGT:
701 CondCode = AArch64CC::GT;
702 break;
703 case CmpInst::FCMP_OGE:
704 CondCode = AArch64CC::GE;
705 break;
706 case CmpInst::FCMP_OLT:
707 CondCode = AArch64CC::MI;
708 break;
709 case CmpInst::FCMP_OLE:
710 CondCode = AArch64CC::LS;
711 break;
712 case CmpInst::FCMP_ONE:
713 CondCode = AArch64CC::MI;
714 CondCode2 = AArch64CC::GT;
715 break;
716 case CmpInst::FCMP_ORD:
717 CondCode = AArch64CC::VC;
718 break;
719 case CmpInst::FCMP_UNO:
720 CondCode = AArch64CC::VS;
721 break;
722 case CmpInst::FCMP_UEQ:
723 CondCode = AArch64CC::EQ;
724 CondCode2 = AArch64CC::VS;
725 break;
726 case CmpInst::FCMP_UGT:
727 CondCode = AArch64CC::HI;
728 break;
729 case CmpInst::FCMP_UGE:
730 CondCode = AArch64CC::PL;
731 break;
732 case CmpInst::FCMP_ULT:
733 CondCode = AArch64CC::LT;
734 break;
735 case CmpInst::FCMP_ULE:
736 CondCode = AArch64CC::LE;
737 break;
738 case CmpInst::FCMP_UNE:
739 CondCode = AArch64CC::NE;
740 break;
741 }
742}
743
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000744bool AArch64InstructionSelector::selectCompareBranch(
745 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
746
747 const unsigned CondReg = I.getOperand(0).getReg();
748 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
749 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
Aditya Nandakumar02c602e2017-07-31 17:00:16 +0000750 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC)
751 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg());
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000752 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
753 return false;
754
755 unsigned LHS = CCMI->getOperand(2).getReg();
756 unsigned RHS = CCMI->getOperand(3).getReg();
757 if (!getConstantVRegVal(RHS, MRI))
758 std::swap(RHS, LHS);
759
760 const auto RHSImm = getConstantVRegVal(RHS, MRI);
761 if (!RHSImm || *RHSImm != 0)
762 return false;
763
764 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
765 if (RB.getID() != AArch64::GPRRegBankID)
766 return false;
767
768 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
769 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
770 return false;
771
772 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
773 unsigned CBOpc = 0;
774 if (CmpWidth <= 32)
775 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
776 else if (CmpWidth == 64)
777 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
778 else
779 return false;
780
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +0000781 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
782 .addUse(LHS)
783 .addMBB(DestMBB)
784 .constrainAllUses(TII, TRI, RBI);
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000785
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000786 I.eraseFromParent();
787 return true;
788}
789
Tim Northovere9600d82017-02-08 17:57:27 +0000790bool AArch64InstructionSelector::selectVaStartAAPCS(
791 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
792 return false;
793}
794
795bool AArch64InstructionSelector::selectVaStartDarwin(
796 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
797 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
798 unsigned ListReg = I.getOperand(0).getReg();
799
800 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
801
802 auto MIB =
803 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri))
804 .addDef(ArgsAddrReg)
805 .addFrameIndex(FuncInfo->getVarArgsStackIndex())
806 .addImm(0)
807 .addImm(0);
808
809 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
810
811 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui))
812 .addUse(ArgsAddrReg)
813 .addUse(ListReg)
814 .addImm(0)
815 .addMemOperand(*I.memoperands_begin());
816
817 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
818 I.eraseFromParent();
819 return true;
820}
821
Amara Emerson1e8c1642018-07-31 00:09:02 +0000822void AArch64InstructionSelector::materializeLargeCMVal(
823 MachineInstr &I, const Value *V, unsigned char OpFlags) const {
824 MachineBasicBlock &MBB = *I.getParent();
825 MachineFunction &MF = *MBB.getParent();
826 MachineRegisterInfo &MRI = MF.getRegInfo();
827 MachineIRBuilder MIB(I);
828
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000829 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, {&AArch64::GPR64RegClass}, {});
Amara Emerson1e8c1642018-07-31 00:09:02 +0000830 MovZ->addOperand(MF, I.getOperand(1));
831 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 |
832 AArch64II::MO_NC);
833 MovZ->addOperand(MF, MachineOperand::CreateImm(0));
834 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI);
835
836 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, unsigned Offset,
837 unsigned ForceDstReg) {
838 unsigned DstReg = ForceDstReg
839 ? ForceDstReg
840 : MRI.createVirtualRegister(&AArch64::GPR64RegClass);
841 auto MovI = MIB.buildInstr(AArch64::MOVKXi).addDef(DstReg).addUse(SrcReg);
842 if (auto *GV = dyn_cast<GlobalValue>(V)) {
843 MovI->addOperand(MF, MachineOperand::CreateGA(
844 GV, MovZ->getOperand(1).getOffset(), Flags));
845 } else {
846 MovI->addOperand(
847 MF, MachineOperand::CreateBA(cast<BlockAddress>(V),
848 MovZ->getOperand(1).getOffset(), Flags));
849 }
850 MovI->addOperand(MF, MachineOperand::CreateImm(Offset));
851 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI);
852 return DstReg;
853 };
Aditya Nandakumarfef76192019-02-05 22:14:40 +0000854 unsigned DstReg = BuildMovK(MovZ.getReg(0),
Amara Emerson1e8c1642018-07-31 00:09:02 +0000855 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0);
856 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0);
857 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg());
858 return;
859}
860
Daniel Sandersf76f3152017-11-16 00:46:35 +0000861bool AArch64InstructionSelector::select(MachineInstr &I,
862 CodeGenCoverage &CoverageInfo) const {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000863 assert(I.getParent() && "Instruction should be in a basic block!");
864 assert(I.getParent()->getParent() && "Instruction should be in a function!");
865
866 MachineBasicBlock &MBB = *I.getParent();
867 MachineFunction &MF = *MBB.getParent();
868 MachineRegisterInfo &MRI = MF.getRegInfo();
869
Tim Northovercdf23f12016-10-31 18:30:59 +0000870 unsigned Opcode = I.getOpcode();
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000871 // G_PHI requires same handling as PHI
872 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
Tim Northovercdf23f12016-10-31 18:30:59 +0000873 // Certain non-generic instructions also need some special handling.
874
875 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
876 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000877
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000878 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
Tim Northover7d88da62016-11-08 00:34:06 +0000879 const unsigned DefReg = I.getOperand(0).getReg();
880 const LLT DefTy = MRI.getType(DefReg);
881
882 const TargetRegisterClass *DefRC = nullptr;
883 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
884 DefRC = TRI.getRegClass(DefReg);
885 } else {
886 const RegClassOrRegBank &RegClassOrBank =
887 MRI.getRegClassOrRegBank(DefReg);
888
889 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
890 if (!DefRC) {
891 if (!DefTy.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000892 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000893 return false;
894 }
895 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
896 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
897 if (!DefRC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000898 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
Tim Northover7d88da62016-11-08 00:34:06 +0000899 return false;
900 }
901 }
902 }
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000903 I.setDesc(TII.get(TargetOpcode::PHI));
Tim Northover7d88da62016-11-08 00:34:06 +0000904
905 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
906 }
907
908 if (I.isCopy())
Tim Northovercdf23f12016-10-31 18:30:59 +0000909 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000910
911 return true;
Tim Northovercdf23f12016-10-31 18:30:59 +0000912 }
913
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000914
915 if (I.getNumOperands() != I.getNumExplicitOperands()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000916 LLVM_DEBUG(
917 dbgs() << "Generic instruction has unexpected implicit operands\n");
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000918 return false;
919 }
920
Daniel Sandersf76f3152017-11-16 00:46:35 +0000921 if (selectImpl(I, CoverageInfo))
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000922 return true;
923
Tim Northover32a078a2016-09-15 10:09:59 +0000924 LLT Ty =
925 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000926
Tim Northover69271c62016-10-12 22:49:11 +0000927 switch (Opcode) {
Tim Northover5e3dbf32016-10-12 22:49:01 +0000928 case TargetOpcode::G_BRCOND: {
929 if (Ty.getSizeInBits() > 32) {
930 // We shouldn't need this on AArch64, but it would be implemented as an
931 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
932 // bit being tested is < 32.
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000933 LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
934 << ", expected at most 32-bits");
Tim Northover5e3dbf32016-10-12 22:49:01 +0000935 return false;
936 }
937
938 const unsigned CondReg = I.getOperand(0).getReg();
939 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
940
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000941 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
942 // instructions will not be produced, as they are conditional branch
943 // instructions that do not set flags.
944 bool ProduceNonFlagSettingCondBr =
945 !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening);
946 if (ProduceNonFlagSettingCondBr && selectCompareBranch(I, MF, MRI))
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000947 return true;
948
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000949 if (ProduceNonFlagSettingCondBr) {
950 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
951 .addUse(CondReg)
952 .addImm(/*bit offset=*/0)
953 .addMBB(DestMBB);
Tim Northover5e3dbf32016-10-12 22:49:01 +0000954
Kristof Beylse66bc1f2018-12-18 08:50:02 +0000955 I.eraseFromParent();
956 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
957 } else {
958 auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
959 .addDef(AArch64::WZR)
960 .addUse(CondReg)
961 .addImm(1);
962 constrainSelectedInstRegOperands(*CMP.getInstr(), TII, TRI, RBI);
963 auto Bcc =
964 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::Bcc))
965 .addImm(AArch64CC::EQ)
966 .addMBB(DestMBB);
967
968 I.eraseFromParent();
969 return constrainSelectedInstRegOperands(*Bcc.getInstr(), TII, TRI, RBI);
970 }
Tim Northover5e3dbf32016-10-12 22:49:01 +0000971 }
972
Kristof Beyls65a12c02017-01-30 09:13:18 +0000973 case TargetOpcode::G_BRINDIRECT: {
974 I.setDesc(TII.get(AArch64::BR));
975 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
976 }
977
Tim Northover4494d692016-10-18 19:47:57 +0000978 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +0000979 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +0000980 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
981
982 const LLT s32 = LLT::scalar(32);
983 const LLT s64 = LLT::scalar(64);
984 const LLT p0 = LLT::pointer(0, 64);
985
986 const unsigned DefReg = I.getOperand(0).getReg();
987 const LLT DefTy = MRI.getType(DefReg);
988 const unsigned DefSize = DefTy.getSizeInBits();
989 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
990
991 // FIXME: Redundant check, but even less readable when factored out.
992 if (isFP) {
993 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000994 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
995 << " constant, expected: " << s32 << " or " << s64
996 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +0000997 return false;
998 }
999
1000 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001001 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1002 << " constant on bank: " << RB
1003 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001004 return false;
1005 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00001006
1007 // The case when we have 0.0 is covered by tablegen. Reject it here so we
1008 // can be sure tablegen works correctly and isn't rescued by this code.
1009 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
1010 return false;
Tim Northover4494d692016-10-18 19:47:57 +00001011 } else {
Daniel Sanders05540042017-08-08 10:44:31 +00001012 // s32 and s64 are covered by tablegen.
1013 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001014 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1015 << " constant, expected: " << s32 << ", " << s64
1016 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001017 return false;
1018 }
1019
1020 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001021 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1022 << " constant on bank: " << RB
1023 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001024 return false;
1025 }
1026 }
1027
1028 const unsigned MovOpc =
1029 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
1030
1031 I.setDesc(TII.get(MovOpc));
1032
1033 if (isFP) {
1034 const TargetRegisterClass &GPRRC =
1035 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
1036 const TargetRegisterClass &FPRRC =
1037 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
1038
1039 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
1040 MachineOperand &RegOp = I.getOperand(0);
1041 RegOp.setReg(DefGPRReg);
1042
1043 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1044 TII.get(AArch64::COPY))
1045 .addDef(DefReg)
1046 .addUse(DefGPRReg);
1047
1048 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001049 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +00001050 return false;
1051 }
1052
1053 MachineOperand &ImmOp = I.getOperand(1);
1054 // FIXME: Is going through int64_t always correct?
1055 ImmOp.ChangeToImmediate(
1056 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001057 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +00001058 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
1059 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001060 } else if (I.getOperand(1).isImm()) {
1061 uint64_t Val = I.getOperand(1).getImm();
1062 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +00001063 }
1064
1065 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1066 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +00001067 }
Tim Northover7b6d66c2017-07-20 22:58:38 +00001068 case TargetOpcode::G_EXTRACT: {
1069 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001070 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +00001071 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +00001072 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001073 // Larger extracts are vectors, same-size extracts should be something else
1074 // by now (either split up or simplified to a COPY).
1075 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
1076 return false;
1077
Amara Emersonbc03bae2018-02-18 17:03:02 +00001078 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001079 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
1080 Ty.getSizeInBits() - 1);
1081
Amara Emersonbc03bae2018-02-18 17:03:02 +00001082 if (SrcSize < 64) {
1083 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
1084 "unexpected G_EXTRACT types");
1085 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1086 }
1087
Tim Northover7b6d66c2017-07-20 22:58:38 +00001088 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1089 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
1090 TII.get(AArch64::COPY))
1091 .addDef(I.getOperand(0).getReg())
1092 .addUse(DstReg, 0, AArch64::sub_32);
1093 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
1094 AArch64::GPR32RegClass, MRI);
1095 I.getOperand(0).setReg(DstReg);
1096
1097 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1098 }
1099
1100 case TargetOpcode::G_INSERT: {
1101 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001102 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1103 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001104 // Larger inserts are vectors, same-size ones should be something else by
1105 // now (split up or turned into COPYs).
1106 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
1107 return false;
1108
Amara Emersonbc03bae2018-02-18 17:03:02 +00001109 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001110 unsigned LSB = I.getOperand(3).getImm();
1111 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +00001112 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +00001113 MachineInstrBuilder(MF, I).addImm(Width - 1);
1114
Amara Emersonbc03bae2018-02-18 17:03:02 +00001115 if (DstSize < 64) {
1116 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
1117 "unexpected G_INSERT types");
1118 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1119 }
1120
Tim Northover7b6d66c2017-07-20 22:58:38 +00001121 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1122 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
1123 TII.get(AArch64::SUBREG_TO_REG))
1124 .addDef(SrcReg)
1125 .addImm(0)
1126 .addUse(I.getOperand(2).getReg())
1127 .addImm(AArch64::sub_32);
1128 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
1129 AArch64::GPR32RegClass, MRI);
1130 I.getOperand(2).setReg(SrcReg);
1131
1132 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1133 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001134 case TargetOpcode::G_FRAME_INDEX: {
1135 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +00001136 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001137 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
1138 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001139 return false;
1140 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001141 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001142
1143 // MOs for a #0 shifted immediate.
1144 I.addOperand(MachineOperand::CreateImm(0));
1145 I.addOperand(MachineOperand::CreateImm(0));
1146
1147 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1148 }
Tim Northoverbdf16242016-10-10 21:50:00 +00001149
1150 case TargetOpcode::G_GLOBAL_VALUE: {
1151 auto GV = I.getOperand(1).getGlobal();
1152 if (GV->isThreadLocal()) {
1153 // FIXME: we don't support TLS yet.
1154 return false;
1155 }
1156 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001157 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +00001158 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001159 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001160 } else if (TM.getCodeModel() == CodeModel::Large) {
1161 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +00001162 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001163 I.eraseFromParent();
1164 return true;
David Green9dd1d452018-08-22 11:31:39 +00001165 } else if (TM.getCodeModel() == CodeModel::Tiny) {
1166 I.setDesc(TII.get(AArch64::ADR));
1167 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001168 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +00001169 I.setDesc(TII.get(AArch64::MOVaddr));
1170 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1171 MachineInstrBuilder MIB(MF, I);
1172 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1173 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1174 }
1175 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1176 }
1177
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001178 case TargetOpcode::G_LOAD:
1179 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001180 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001181
Tim Northover5ae83502016-09-15 09:20:34 +00001182 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001183 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1184 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001185 return false;
1186 }
1187
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001188 auto &MemOp = **I.memoperands_begin();
1189 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001190 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001191 return false;
1192 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001193 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001194
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001195 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001196#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001197 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001198 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001199 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1200 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001201 assert(MRI.getType(PtrReg).isPointer() &&
1202 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001203#endif
1204
1205 const unsigned ValReg = I.getOperand(0).getReg();
1206 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1207
1208 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001209 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001210 if (NewOpc == I.getOpcode())
1211 return false;
1212
1213 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001214
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001215 uint64_t Offset = 0;
1216 auto *PtrMI = MRI.getVRegDef(PtrReg);
1217
1218 // Try to fold a GEP into our unsigned immediate addressing mode.
1219 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1220 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1221 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001222 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001223 const unsigned Scale = Log2_32(Size);
1224 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1225 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1226 I.getOperand(1).setReg(Ptr2Reg);
1227 PtrMI = MRI.getVRegDef(Ptr2Reg);
1228 Offset = Imm / Size;
1229 }
1230 }
1231 }
1232
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001233 // If we haven't folded anything into our addressing mode yet, try to fold
1234 // a frame index into the base+offset.
1235 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1236 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1237
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001238 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001239
1240 // If we're storing a 0, use WZR/XZR.
1241 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1242 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1243 if (I.getOpcode() == AArch64::STRWui)
1244 I.getOperand(0).setReg(AArch64::WZR);
1245 else if (I.getOpcode() == AArch64::STRXui)
1246 I.getOperand(0).setReg(AArch64::XZR);
1247 }
1248 }
1249
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001250 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1251 }
1252
Tim Northover9dd78f82017-02-08 21:22:25 +00001253 case TargetOpcode::G_SMULH:
1254 case TargetOpcode::G_UMULH: {
1255 // Reject the various things we don't support yet.
1256 if (unsupportedBinOp(I, RBI, MRI, TRI))
1257 return false;
1258
1259 const unsigned DefReg = I.getOperand(0).getReg();
1260 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1261
1262 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001263 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001264 return false;
1265 }
1266
1267 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001268 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1269 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001270 return false;
1271 }
1272
1273 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1274 : AArch64::UMULHrr;
1275 I.setDesc(TII.get(NewOpc));
1276
1277 // Now that we selected an opcode, we need to constrain the register
1278 // operands to use appropriate classes.
1279 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1280 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001281 case TargetOpcode::G_FADD:
1282 case TargetOpcode::G_FSUB:
1283 case TargetOpcode::G_FMUL:
1284 case TargetOpcode::G_FDIV:
1285
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001286 case TargetOpcode::G_OR:
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001287 case TargetOpcode::G_SHL:
1288 case TargetOpcode::G_LSHR:
1289 case TargetOpcode::G_ASHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001290 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001291 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001292 if (unsupportedBinOp(I, RBI, MRI, TRI))
1293 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001294
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001295 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001296
1297 const unsigned DefReg = I.getOperand(0).getReg();
1298 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1299
1300 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1301 if (NewOpc == I.getOpcode())
1302 return false;
1303
1304 I.setDesc(TII.get(NewOpc));
1305 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001306
1307 // Now that we selected an opcode, we need to constrain the register
1308 // operands to use appropriate classes.
1309 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1310 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001311
Tim Northover398c5f52017-02-14 20:56:29 +00001312 case TargetOpcode::G_PTR_MASK: {
1313 uint64_t Align = I.getOperand(2).getImm();
1314 if (Align >= 64 || Align == 0)
1315 return false;
1316
1317 uint64_t Mask = ~((1ULL << Align) - 1);
1318 I.setDesc(TII.get(AArch64::ANDXri));
1319 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1320
1321 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1322 }
Tim Northover037af52c2016-10-31 18:31:09 +00001323 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001324 case TargetOpcode::G_TRUNC: {
1325 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1326 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1327
1328 const unsigned DstReg = I.getOperand(0).getReg();
1329 const unsigned SrcReg = I.getOperand(1).getReg();
1330
1331 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1332 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1333
1334 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001335 LLVM_DEBUG(
1336 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001337 return false;
1338 }
1339
1340 if (DstRB.getID() == AArch64::GPRRegBankID) {
1341 const TargetRegisterClass *DstRC =
1342 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1343 if (!DstRC)
1344 return false;
1345
1346 const TargetRegisterClass *SrcRC =
1347 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1348 if (!SrcRC)
1349 return false;
1350
1351 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1352 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001353 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001354 return false;
1355 }
1356
1357 if (DstRC == SrcRC) {
1358 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001359 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1360 SrcTy == LLT::scalar(64)) {
1361 llvm_unreachable("TableGen can import this case");
1362 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001363 } else if (DstRC == &AArch64::GPR32RegClass &&
1364 SrcRC == &AArch64::GPR64RegClass) {
1365 I.getOperand(1).setSubReg(AArch64::sub_32);
1366 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001367 LLVM_DEBUG(
1368 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001369 return false;
1370 }
1371
1372 I.setDesc(TII.get(TargetOpcode::COPY));
1373 return true;
1374 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1375 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1376 I.setDesc(TII.get(AArch64::XTNv4i16));
1377 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1378 return true;
1379 }
1380 }
1381
1382 return false;
1383 }
1384
Tim Northover3d38b3a2016-10-11 20:50:21 +00001385 case TargetOpcode::G_ANYEXT: {
1386 const unsigned DstReg = I.getOperand(0).getReg();
1387 const unsigned SrcReg = I.getOperand(1).getReg();
1388
Quentin Colombetcb629a82016-10-12 03:57:49 +00001389 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1390 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001391 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1392 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001393 return false;
1394 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001395
Quentin Colombetcb629a82016-10-12 03:57:49 +00001396 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1397 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001398 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1399 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001400 return false;
1401 }
1402
1403 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1404
1405 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001406 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001407 return false;
1408 }
1409
Quentin Colombetcb629a82016-10-12 03:57:49 +00001410 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001411 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1412 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001413 return false;
1414 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001415 // At this point G_ANYEXT is just like a plain COPY, but we need
1416 // to explicitly form the 64-bit value if any.
1417 if (DstSize > 32) {
1418 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1419 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1420 .addDef(ExtSrc)
1421 .addImm(0)
1422 .addUse(SrcReg)
1423 .addImm(AArch64::sub_32);
1424 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001425 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001426 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001427 }
1428
1429 case TargetOpcode::G_ZEXT:
1430 case TargetOpcode::G_SEXT: {
1431 unsigned Opcode = I.getOpcode();
1432 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1433 SrcTy = MRI.getType(I.getOperand(1).getReg());
1434 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1435 const unsigned DefReg = I.getOperand(0).getReg();
1436 const unsigned SrcReg = I.getOperand(1).getReg();
1437 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1438
1439 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001440 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1441 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001442 return false;
1443 }
1444
1445 MachineInstr *ExtI;
1446 if (DstTy == LLT::scalar(64)) {
1447 // FIXME: Can we avoid manually doing this?
1448 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001449 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1450 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001451 return false;
1452 }
1453
1454 const unsigned SrcXReg =
1455 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1456 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1457 .addDef(SrcXReg)
1458 .addImm(0)
1459 .addUse(SrcReg)
1460 .addImm(AArch64::sub_32);
1461
1462 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1463 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1464 .addDef(DefReg)
1465 .addUse(SrcXReg)
1466 .addImm(0)
1467 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001468 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001469 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1470 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1471 .addDef(DefReg)
1472 .addUse(SrcReg)
1473 .addImm(0)
1474 .addImm(SrcTy.getSizeInBits() - 1);
1475 } else {
1476 return false;
1477 }
1478
1479 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1480
1481 I.eraseFromParent();
1482 return true;
1483 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001484
Tim Northover69271c62016-10-12 22:49:11 +00001485 case TargetOpcode::G_SITOFP:
1486 case TargetOpcode::G_UITOFP:
1487 case TargetOpcode::G_FPTOSI:
1488 case TargetOpcode::G_FPTOUI: {
1489 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1490 SrcTy = MRI.getType(I.getOperand(1).getReg());
1491 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1492 if (NewOpc == Opcode)
1493 return false;
1494
1495 I.setDesc(TII.get(NewOpc));
1496 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1497
1498 return true;
1499 }
1500
1501
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001502 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001503 // The importer is currently unable to import pointer types since they
1504 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001505 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001506
Daniel Sandersedd07842017-08-17 09:26:14 +00001507 case TargetOpcode::G_BITCAST:
1508 // Imported SelectionDAG rules can handle every bitcast except those that
1509 // bitcast from a type to the same type. Ideally, these shouldn't occur
1510 // but we might not run an optimizer that deletes them.
1511 if (MRI.getType(I.getOperand(0).getReg()) ==
1512 MRI.getType(I.getOperand(1).getReg()))
1513 return selectCopy(I, TII, MRI, TRI, RBI);
1514 return false;
1515
Tim Northover9ac0eba2016-11-08 00:45:29 +00001516 case TargetOpcode::G_SELECT: {
1517 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001518 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1519 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001520 return false;
1521 }
1522
1523 const unsigned CondReg = I.getOperand(1).getReg();
1524 const unsigned TReg = I.getOperand(2).getReg();
1525 const unsigned FReg = I.getOperand(3).getReg();
1526
1527 unsigned CSelOpc = 0;
1528
1529 if (Ty == LLT::scalar(32)) {
1530 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001531 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001532 CSelOpc = AArch64::CSELXr;
1533 } else {
1534 return false;
1535 }
1536
1537 MachineInstr &TstMI =
1538 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1539 .addDef(AArch64::WZR)
1540 .addUse(CondReg)
1541 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1542
1543 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1544 .addDef(I.getOperand(0).getReg())
1545 .addUse(TReg)
1546 .addUse(FReg)
1547 .addImm(AArch64CC::NE);
1548
1549 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1550 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1551
1552 I.eraseFromParent();
1553 return true;
1554 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001555 case TargetOpcode::G_ICMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001556 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001557 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1558 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001559 return false;
1560 }
1561
1562 unsigned CmpOpc = 0;
1563 unsigned ZReg = 0;
1564
1565 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1566 if (CmpTy == LLT::scalar(32)) {
1567 CmpOpc = AArch64::SUBSWrr;
1568 ZReg = AArch64::WZR;
1569 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1570 CmpOpc = AArch64::SUBSXrr;
1571 ZReg = AArch64::XZR;
1572 } else {
1573 return false;
1574 }
1575
Kristof Beyls22524402017-01-05 10:16:08 +00001576 // CSINC increments the result by one when the condition code is false.
1577 // Therefore, we have to invert the predicate to get an increment by 1 when
1578 // the predicate is true.
1579 const AArch64CC::CondCode invCC =
1580 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1581 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001582
1583 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1584 .addDef(ZReg)
1585 .addUse(I.getOperand(2).getReg())
1586 .addUse(I.getOperand(3).getReg());
1587
1588 MachineInstr &CSetMI =
1589 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1590 .addDef(I.getOperand(0).getReg())
1591 .addUse(AArch64::WZR)
1592 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001593 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001594
1595 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1596 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1597
1598 I.eraseFromParent();
1599 return true;
1600 }
1601
Tim Northover7dd378d2016-10-12 22:49:07 +00001602 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001603 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001604 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1605 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001606 return false;
1607 }
1608
1609 unsigned CmpOpc = 0;
1610 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1611 if (CmpTy == LLT::scalar(32)) {
1612 CmpOpc = AArch64::FCMPSrr;
1613 } else if (CmpTy == LLT::scalar(64)) {
1614 CmpOpc = AArch64::FCMPDrr;
1615 } else {
1616 return false;
1617 }
1618
1619 // FIXME: regbank
1620
1621 AArch64CC::CondCode CC1, CC2;
1622 changeFCMPPredToAArch64CC(
1623 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1624
1625 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1626 .addUse(I.getOperand(2).getReg())
1627 .addUse(I.getOperand(3).getReg());
1628
1629 const unsigned DefReg = I.getOperand(0).getReg();
1630 unsigned Def1Reg = DefReg;
1631 if (CC2 != AArch64CC::AL)
1632 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1633
1634 MachineInstr &CSetMI =
1635 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1636 .addDef(Def1Reg)
1637 .addUse(AArch64::WZR)
1638 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001639 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001640
1641 if (CC2 != AArch64CC::AL) {
1642 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1643 MachineInstr &CSet2MI =
1644 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1645 .addDef(Def2Reg)
1646 .addUse(AArch64::WZR)
1647 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001648 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001649 MachineInstr &OrMI =
1650 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1651 .addDef(DefReg)
1652 .addUse(Def1Reg)
1653 .addUse(Def2Reg);
1654 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1655 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1656 }
1657
1658 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1659 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1660
1661 I.eraseFromParent();
1662 return true;
1663 }
Tim Northovere9600d82017-02-08 17:57:27 +00001664 case TargetOpcode::G_VASTART:
1665 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1666 : selectVaStartAAPCS(I, MF, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001667 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1668 if (!I.getOperand(0).isIntrinsicID())
1669 return false;
1670 if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
1671 return false;
1672 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::BRK))
1673 .addImm(1);
1674 I.eraseFromParent();
1675 return true;
Amara Emerson1e8c1642018-07-31 00:09:02 +00001676 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001677 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001678 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1679 const unsigned DstReg = I.getOperand(0).getReg();
1680 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1681 const TargetRegisterClass *DstRC =
1682 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1683 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001684 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001685 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001686 case TargetOpcode::G_BLOCK_ADDR: {
1687 if (TM.getCodeModel() == CodeModel::Large) {
1688 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1689 I.eraseFromParent();
1690 return true;
1691 } else {
1692 I.setDesc(TII.get(AArch64::MOVaddrBA));
1693 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1694 I.getOperand(0).getReg())
1695 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1696 /* Offset */ 0, AArch64II::MO_PAGE)
1697 .addBlockAddress(
1698 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1699 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1700 I.eraseFromParent();
1701 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1702 }
1703 }
Amara Emerson5ec14602018-12-10 18:44:58 +00001704 case TargetOpcode::G_BUILD_VECTOR:
1705 return selectBuildVector(I, MRI);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001706 case TargetOpcode::G_MERGE_VALUES:
1707 return selectMergeValues(I, MRI);
Jessica Paquette245047d2019-01-24 22:00:41 +00001708 case TargetOpcode::G_UNMERGE_VALUES:
1709 return selectUnmergeValues(I, MRI);
Amara Emerson1abe05c2019-02-21 20:20:16 +00001710 case TargetOpcode::G_SHUFFLE_VECTOR:
1711 return selectShuffleVector(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001712 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001713
1714 return false;
1715}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001716
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001717MachineInstr *AArch64InstructionSelector::emitScalarToVector(
Amara Emerson8acb0d92019-03-04 19:16:00 +00001718 unsigned EltSize, const TargetRegisterClass *DstRC, unsigned Scalar,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001719 MachineIRBuilder &MIRBuilder) const {
1720 auto Undef = MIRBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF, {DstRC}, {});
Amara Emerson5ec14602018-12-10 18:44:58 +00001721
1722 auto BuildFn = [&](unsigned SubregIndex) {
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001723 auto Ins =
1724 MIRBuilder
1725 .buildInstr(TargetOpcode::INSERT_SUBREG, {DstRC}, {Undef, Scalar})
1726 .addImm(SubregIndex);
1727 constrainSelectedInstRegOperands(*Undef, TII, TRI, RBI);
1728 constrainSelectedInstRegOperands(*Ins, TII, TRI, RBI);
1729 return &*Ins;
Amara Emerson5ec14602018-12-10 18:44:58 +00001730 };
1731
Amara Emerson8acb0d92019-03-04 19:16:00 +00001732 switch (EltSize) {
Jessica Paquette245047d2019-01-24 22:00:41 +00001733 case 16:
1734 return BuildFn(AArch64::hsub);
Amara Emerson5ec14602018-12-10 18:44:58 +00001735 case 32:
1736 return BuildFn(AArch64::ssub);
1737 case 64:
1738 return BuildFn(AArch64::dsub);
1739 default:
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00001740 return nullptr;
Amara Emerson5ec14602018-12-10 18:44:58 +00001741 }
1742}
1743
Amara Emerson8cb186c2018-12-20 01:11:04 +00001744bool AArch64InstructionSelector::selectMergeValues(
1745 MachineInstr &I, MachineRegisterInfo &MRI) const {
1746 assert(I.getOpcode() == TargetOpcode::G_MERGE_VALUES && "unexpected opcode");
1747 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1748 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1749 assert(!DstTy.isVector() && !SrcTy.isVector() && "invalid merge operation");
1750
1751 // At the moment we only support merging two s32s into an s64.
1752 if (I.getNumOperands() != 3)
1753 return false;
1754 if (DstTy.getSizeInBits() != 64 || SrcTy.getSizeInBits() != 32)
1755 return false;
1756 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
1757 if (RB.getID() != AArch64::GPRRegBankID)
1758 return false;
1759
1760 auto *DstRC = &AArch64::GPR64RegClass;
1761 unsigned SubToRegDef = MRI.createVirtualRegister(DstRC);
1762 MachineInstr &SubRegMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1763 TII.get(TargetOpcode::SUBREG_TO_REG))
1764 .addDef(SubToRegDef)
1765 .addImm(0)
1766 .addUse(I.getOperand(1).getReg())
1767 .addImm(AArch64::sub_32);
1768 unsigned SubToRegDef2 = MRI.createVirtualRegister(DstRC);
1769 // Need to anyext the second scalar before we can use bfm
1770 MachineInstr &SubRegMI2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1771 TII.get(TargetOpcode::SUBREG_TO_REG))
1772 .addDef(SubToRegDef2)
1773 .addImm(0)
1774 .addUse(I.getOperand(2).getReg())
1775 .addImm(AArch64::sub_32);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001776 MachineInstr &BFM =
1777 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::BFMXri))
Amara Emerson321bfb22018-12-20 03:27:42 +00001778 .addDef(I.getOperand(0).getReg())
Amara Emerson8cb186c2018-12-20 01:11:04 +00001779 .addUse(SubToRegDef)
1780 .addUse(SubToRegDef2)
1781 .addImm(32)
1782 .addImm(31);
1783 constrainSelectedInstRegOperands(SubRegMI, TII, TRI, RBI);
1784 constrainSelectedInstRegOperands(SubRegMI2, TII, TRI, RBI);
1785 constrainSelectedInstRegOperands(BFM, TII, TRI, RBI);
1786 I.eraseFromParent();
1787 return true;
1788}
1789
Jessica Paquette245047d2019-01-24 22:00:41 +00001790bool AArch64InstructionSelector::selectUnmergeValues(
1791 MachineInstr &I, MachineRegisterInfo &MRI) const {
1792 assert(I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
1793 "unexpected opcode");
1794
1795 // TODO: Handle unmerging into GPRs and from scalars to scalars.
1796 if (RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI)->getID() !=
1797 AArch64::FPRRegBankID ||
1798 RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI)->getID() !=
1799 AArch64::FPRRegBankID) {
1800 LLVM_DEBUG(dbgs() << "Unmerging vector-to-gpr and scalar-to-scalar "
1801 "currently unsupported.\n");
1802 return false;
1803 }
1804
1805 // The last operand is the vector source register, and every other operand is
1806 // a register to unpack into.
1807 unsigned NumElts = I.getNumOperands() - 1;
1808 unsigned SrcReg = I.getOperand(NumElts).getReg();
1809 const LLT NarrowTy = MRI.getType(I.getOperand(0).getReg());
1810 const LLT WideTy = MRI.getType(SrcReg);
Benjamin Kramer653020d2019-01-24 23:45:07 +00001811 (void)WideTy;
Jessica Paquette245047d2019-01-24 22:00:41 +00001812 assert(WideTy.isVector() && "can only unmerge from vector types!");
1813 assert(WideTy.getSizeInBits() > NarrowTy.getSizeInBits() &&
1814 "source register size too small!");
1815
Jessica Paquette1f9bc282019-01-25 21:28:27 +00001816 // TODO: Handle unmerging into vectors.
Jessica Paquette245047d2019-01-24 22:00:41 +00001817 if (!NarrowTy.isScalar()) {
1818 LLVM_DEBUG(dbgs() << "Vector-to-vector unmerges not supported yet.\n");
1819 return false;
1820 }
1821
1822 // Choose a lane copy opcode and subregister based off of the size of the
1823 // vector's elements.
1824 unsigned CopyOpc = 0;
1825 unsigned ExtractSubReg = 0;
Jessica Paquette00d58472019-03-05 15:47:00 +00001826 switch (NarrowTy.getSizeInBits()) {
1827 case 16:
1828 CopyOpc = AArch64::CPYi16;
1829 ExtractSubReg = AArch64::hsub;
1830 break;
1831 case 32:
1832 CopyOpc = AArch64::CPYi32;
1833 ExtractSubReg = AArch64::ssub;
1834 break;
1835 case 64:
1836 CopyOpc = AArch64::CPYi64;
1837 ExtractSubReg = AArch64::dsub;
1838 break;
1839 default:
1840 // Unknown size, bail out.
1841 LLVM_DEBUG(dbgs() << "NarrowTy had unsupported size.\n");
Jessica Paquette245047d2019-01-24 22:00:41 +00001842 return false;
Jessica Paquette00d58472019-03-05 15:47:00 +00001843 }
Jessica Paquette245047d2019-01-24 22:00:41 +00001844
1845 // Set up for the lane copies.
1846 MachineBasicBlock &MBB = *I.getParent();
1847
1848 // Stores the registers we'll be copying from.
1849 SmallVector<unsigned, 4> InsertRegs;
1850
1851 // We'll use the first register twice, so we only need NumElts-1 registers.
1852 unsigned NumInsertRegs = NumElts - 1;
1853
1854 // If our elements fit into exactly 128 bits, then we can copy from the source
1855 // directly. Otherwise, we need to do a bit of setup with some subregister
1856 // inserts.
1857 if (NarrowTy.getSizeInBits() * NumElts == 128) {
1858 InsertRegs = SmallVector<unsigned, 4>(NumInsertRegs, SrcReg);
1859 } else {
1860 // No. We have to perform subregister inserts. For each insert, create an
1861 // implicit def and a subregister insert, and save the register we create.
1862 for (unsigned Idx = 0; Idx < NumInsertRegs; ++Idx) {
1863 unsigned ImpDefReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
1864 MachineInstr &ImpDefMI =
1865 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
1866 ImpDefReg);
1867
1868 // Now, create the subregister insert from SrcReg.
1869 unsigned InsertReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
1870 MachineInstr &InsMI =
1871 *BuildMI(MBB, I, I.getDebugLoc(),
1872 TII.get(TargetOpcode::INSERT_SUBREG), InsertReg)
1873 .addUse(ImpDefReg)
1874 .addUse(SrcReg)
1875 .addImm(AArch64::dsub);
1876
1877 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
1878 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
1879
1880 // Save the register so that we can copy from it after.
1881 InsertRegs.push_back(InsertReg);
1882 }
1883 }
1884
1885 // Now that we've created any necessary subregister inserts, we can
1886 // create the copies.
1887 //
1888 // Perform the first copy separately as a subregister copy.
1889 unsigned CopyTo = I.getOperand(0).getReg();
1890 MachineInstr &FirstCopy =
1891 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), CopyTo)
1892 .addUse(InsertRegs[0], 0, ExtractSubReg);
1893 constrainSelectedInstRegOperands(FirstCopy, TII, TRI, RBI);
1894
1895 // Now, perform the remaining copies as vector lane copies.
1896 unsigned LaneIdx = 1;
1897 for (unsigned InsReg : InsertRegs) {
1898 unsigned CopyTo = I.getOperand(LaneIdx).getReg();
1899 MachineInstr &CopyInst =
1900 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CopyOpc), CopyTo)
1901 .addUse(InsReg)
1902 .addImm(LaneIdx);
1903 constrainSelectedInstRegOperands(CopyInst, TII, TRI, RBI);
1904 ++LaneIdx;
1905 }
1906
1907 // Separately constrain the first copy's destination. Because of the
1908 // limitation in constrainOperandRegClass, we can't guarantee that this will
1909 // actually be constrained. So, do it ourselves using the second operand.
1910 const TargetRegisterClass *RC =
1911 MRI.getRegClassOrNull(I.getOperand(1).getReg());
1912 if (!RC) {
1913 LLVM_DEBUG(dbgs() << "Couldn't constrain copy destination.\n");
1914 return false;
1915 }
1916
1917 RBI.constrainGenericRegister(CopyTo, *RC, MRI);
1918 I.eraseFromParent();
1919 return true;
1920}
1921
Amara Emerson1abe05c2019-02-21 20:20:16 +00001922void AArch64InstructionSelector::collectShuffleMaskIndices(
1923 MachineInstr &I, MachineRegisterInfo &MRI,
1924 SmallVectorImpl<int> &Idxs) const {
1925 MachineInstr *MaskDef = MRI.getVRegDef(I.getOperand(3).getReg());
1926 assert(
1927 MaskDef->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&
1928 "G_SHUFFLE_VECTOR should have a constant mask operand as G_BUILD_VECTOR");
1929 // Find the constant indices.
1930 for (unsigned i = 1, e = MaskDef->getNumOperands(); i < e; ++i) {
1931 MachineInstr *ScalarDef = MRI.getVRegDef(MaskDef->getOperand(i).getReg());
1932 assert(ScalarDef && "Could not find vreg def of shufflevec index op");
1933 // Look through copies.
1934 while (ScalarDef->getOpcode() == TargetOpcode::COPY) {
1935 ScalarDef = MRI.getVRegDef(ScalarDef->getOperand(1).getReg());
1936 assert(ScalarDef && "Could not find def of copy operand");
1937 }
1938 assert(ScalarDef->getOpcode() == TargetOpcode::G_CONSTANT);
1939 Idxs.push_back(ScalarDef->getOperand(1).getCImm()->getSExtValue());
1940 }
1941}
1942
1943unsigned
1944AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
1945 MachineFunction &MF) const {
1946 Type *CPTy = CPVal->getType()->getPointerTo();
1947 unsigned Align = MF.getDataLayout().getPrefTypeAlignment(CPTy);
1948 if (Align == 0)
1949 Align = MF.getDataLayout().getTypeAllocSize(CPTy);
1950
1951 MachineConstantPool *MCP = MF.getConstantPool();
1952 return MCP->getConstantPoolIndex(CPVal, Align);
1953}
1954
1955MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
1956 Constant *CPVal, MachineIRBuilder &MIRBuilder) const {
1957 unsigned CPIdx = emitConstantPoolEntry(CPVal, MIRBuilder.getMF());
1958
1959 auto Adrp =
1960 MIRBuilder.buildInstr(AArch64::ADRP, {&AArch64::GPR64RegClass}, {})
1961 .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE);
Amara Emerson8acb0d92019-03-04 19:16:00 +00001962
1963 MachineInstr *LoadMI = nullptr;
1964 switch (MIRBuilder.getDataLayout().getTypeStoreSize(CPVal->getType())) {
1965 case 16:
1966 LoadMI =
1967 &*MIRBuilder
1968 .buildInstr(AArch64::LDRQui, {&AArch64::FPR128RegClass}, {Adrp})
1969 .addConstantPoolIndex(CPIdx, 0,
1970 AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1971 break;
1972 case 8:
1973 LoadMI = &*MIRBuilder
1974 .buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp})
1975 .addConstantPoolIndex(
1976 CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1977 break;
1978 default:
1979 LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
1980 << *CPVal->getType());
1981 return nullptr;
1982 }
Amara Emerson1abe05c2019-02-21 20:20:16 +00001983 constrainSelectedInstRegOperands(*Adrp, TII, TRI, RBI);
Amara Emerson8acb0d92019-03-04 19:16:00 +00001984 constrainSelectedInstRegOperands(*LoadMI, TII, TRI, RBI);
1985 return LoadMI;
1986}
1987
1988/// Return an <Opcode, SubregIndex> pair to do an vector elt insert of a given
1989/// size and RB.
1990static std::pair<unsigned, unsigned>
1991getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
1992 unsigned Opc, SubregIdx;
1993 if (RB.getID() == AArch64::GPRRegBankID) {
1994 if (EltSize == 32) {
1995 Opc = AArch64::INSvi32gpr;
1996 SubregIdx = AArch64::ssub;
1997 } else if (EltSize == 64) {
1998 Opc = AArch64::INSvi64gpr;
1999 SubregIdx = AArch64::dsub;
2000 } else {
2001 llvm_unreachable("invalid elt size!");
2002 }
2003 } else {
2004 if (EltSize == 8) {
2005 Opc = AArch64::INSvi8lane;
2006 SubregIdx = AArch64::bsub;
2007 } else if (EltSize == 16) {
2008 Opc = AArch64::INSvi16lane;
2009 SubregIdx = AArch64::hsub;
2010 } else if (EltSize == 32) {
2011 Opc = AArch64::INSvi32lane;
2012 SubregIdx = AArch64::ssub;
2013 } else if (EltSize == 64) {
2014 Opc = AArch64::INSvi64lane;
2015 SubregIdx = AArch64::dsub;
2016 } else {
2017 llvm_unreachable("invalid elt size!");
2018 }
2019 }
2020 return std::make_pair(Opc, SubregIdx);
2021}
2022
2023MachineInstr *AArch64InstructionSelector::emitVectorConcat(
2024 unsigned Op1, unsigned Op2, MachineIRBuilder &MIRBuilder) const {
2025 // We implement a vector concat by:
2026 // 1. Use scalar_to_vector to insert the lower vector into the larger dest
2027 // 2. Insert the upper vector into the destination's upper element
2028 // TODO: some of this code is common with G_BUILD_VECTOR handling.
2029 MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
2030
2031 const LLT Op1Ty = MRI.getType(Op1);
2032 const LLT Op2Ty = MRI.getType(Op2);
2033
2034 if (Op1Ty != Op2Ty) {
2035 LLVM_DEBUG(dbgs() << "Could not do vector concat of differing vector tys");
2036 return nullptr;
2037 }
2038 assert(Op1Ty.isVector() && "Expected a vector for vector concat");
2039
2040 if (Op1Ty.getSizeInBits() >= 128) {
2041 LLVM_DEBUG(dbgs() << "Vector concat not supported for full size vectors");
2042 return nullptr;
2043 }
2044
2045 // At the moment we just support 64 bit vector concats.
2046 if (Op1Ty.getSizeInBits() != 64) {
2047 LLVM_DEBUG(dbgs() << "Vector concat supported for 64b vectors");
2048 return nullptr;
2049 }
2050
2051 const LLT ScalarTy = LLT::scalar(Op1Ty.getSizeInBits());
2052 const RegisterBank &FPRBank = *RBI.getRegBank(Op1, MRI, TRI);
2053 const TargetRegisterClass *DstRC =
2054 getMinClassForRegBank(FPRBank, Op1Ty.getSizeInBits() * 2);
2055
2056 MachineInstr *WidenedOp1 =
2057 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op1, MIRBuilder);
2058 MachineInstr *WidenedOp2 =
2059 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op2, MIRBuilder);
2060 if (!WidenedOp1 || !WidenedOp2) {
2061 LLVM_DEBUG(dbgs() << "Could not emit a vector from scalar value");
2062 return nullptr;
2063 }
2064
2065 // Now do the insert of the upper element.
2066 unsigned InsertOpc, InsSubRegIdx;
2067 std::tie(InsertOpc, InsSubRegIdx) =
2068 getInsertVecEltOpInfo(FPRBank, ScalarTy.getSizeInBits());
2069
2070 auto InsElt =
2071 MIRBuilder
2072 .buildInstr(InsertOpc, {DstRC}, {WidenedOp1->getOperand(0).getReg()})
2073 .addImm(1) /* Lane index */
2074 .addUse(WidenedOp2->getOperand(0).getReg())
2075 .addImm(0);
2076
2077 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2078 return &*InsElt;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002079}
2080
2081bool AArch64InstructionSelector::selectShuffleVector(
2082 MachineInstr &I, MachineRegisterInfo &MRI) const {
2083 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2084 unsigned Src1Reg = I.getOperand(1).getReg();
2085 const LLT Src1Ty = MRI.getType(Src1Reg);
2086 unsigned Src2Reg = I.getOperand(2).getReg();
2087 const LLT Src2Ty = MRI.getType(Src2Reg);
2088
2089 MachineBasicBlock &MBB = *I.getParent();
2090 MachineFunction &MF = *MBB.getParent();
2091 LLVMContext &Ctx = MF.getFunction().getContext();
2092
2093 // G_SHUFFLE_VECTOR doesn't really have a strictly enforced constant mask
2094 // operand, it comes in as a normal vector value which we have to analyze to
2095 // find the mask indices.
2096 SmallVector<int, 8> Mask;
2097 collectShuffleMaskIndices(I, MRI, Mask);
2098 assert(!Mask.empty() && "Expected to find mask indices");
2099
2100 // G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
2101 // it's originated from a <1 x T> type. Those should have been lowered into
2102 // G_BUILD_VECTOR earlier.
2103 if (!Src1Ty.isVector() || !Src2Ty.isVector()) {
2104 LLVM_DEBUG(dbgs() << "Could not select a \"scalar\" G_SHUFFLE_VECTOR\n");
2105 return false;
2106 }
2107
2108 unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
2109
2110 SmallVector<Constant *, 64> CstIdxs;
2111 for (int Val : Mask) {
2112 for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
2113 unsigned Offset = Byte + Val * BytesPerElt;
2114 CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));
2115 }
2116 }
2117
Amara Emerson8acb0d92019-03-04 19:16:00 +00002118 MachineIRBuilder MIRBuilder(I);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002119
2120 // Use a constant pool to load the index vector for TBL.
2121 Constant *CPVal = ConstantVector::get(CstIdxs);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002122 MachineInstr *IndexLoad = emitLoadFromConstantPool(CPVal, MIRBuilder);
2123 if (!IndexLoad) {
2124 LLVM_DEBUG(dbgs() << "Could not load from a constant pool");
2125 return false;
2126 }
2127
Amara Emerson8acb0d92019-03-04 19:16:00 +00002128 if (DstTy.getSizeInBits() != 128) {
2129 assert(DstTy.getSizeInBits() == 64 && "Unexpected shuffle result ty");
2130 // This case can be done with TBL1.
2131 MachineInstr *Concat = emitVectorConcat(Src1Reg, Src2Reg, MIRBuilder);
2132 if (!Concat) {
2133 LLVM_DEBUG(dbgs() << "Could not do vector concat for tbl1");
2134 return false;
2135 }
2136
2137 // The constant pool load will be 64 bits, so need to convert to FPR128 reg.
2138 IndexLoad =
2139 emitScalarToVector(64, &AArch64::FPR128RegClass,
2140 IndexLoad->getOperand(0).getReg(), MIRBuilder);
2141
2142 auto TBL1 = MIRBuilder.buildInstr(
2143 AArch64::TBLv16i8One, {&AArch64::FPR128RegClass},
2144 {Concat->getOperand(0).getReg(), IndexLoad->getOperand(0).getReg()});
2145 constrainSelectedInstRegOperands(*TBL1, TII, TRI, RBI);
2146
2147 auto Copy = BuildMI(*I.getParent(), I, I.getDebugLoc(),
2148 TII.get(TargetOpcode::COPY), I.getOperand(0).getReg())
2149 .addUse(TBL1->getOperand(0).getReg(), 0, AArch64::dsub);
2150 RBI.constrainGenericRegister(Copy.getReg(0), AArch64::FPR64RegClass, MRI);
2151 I.eraseFromParent();
2152 return true;
2153 }
2154
Amara Emerson1abe05c2019-02-21 20:20:16 +00002155 // For TBL2 we need to emit a REG_SEQUENCE to tie together two consecutive
2156 // Q registers for regalloc.
2157 auto RegSeq = MIRBuilder
2158 .buildInstr(TargetOpcode::REG_SEQUENCE,
2159 {&AArch64::QQRegClass}, {Src1Reg})
2160 .addImm(AArch64::qsub0)
2161 .addUse(Src2Reg)
2162 .addImm(AArch64::qsub1);
2163
2164 auto TBL2 =
2165 MIRBuilder.buildInstr(AArch64::TBLv16i8Two, {I.getOperand(0).getReg()},
2166 {RegSeq, IndexLoad->getOperand(0).getReg()});
2167 constrainSelectedInstRegOperands(*RegSeq, TII, TRI, RBI);
2168 constrainSelectedInstRegOperands(*TBL2, TII, TRI, RBI);
2169 I.eraseFromParent();
2170 return true;
2171}
2172
Amara Emerson5ec14602018-12-10 18:44:58 +00002173bool AArch64InstructionSelector::selectBuildVector(
2174 MachineInstr &I, MachineRegisterInfo &MRI) const {
2175 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
2176 // Until we port more of the optimized selections, for now just use a vector
2177 // insert sequence.
2178 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2179 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
2180 unsigned EltSize = EltTy.getSizeInBits();
Jessica Paquette245047d2019-01-24 22:00:41 +00002181 if (EltSize < 16 || EltSize > 64)
Amara Emerson5ec14602018-12-10 18:44:58 +00002182 return false; // Don't support all element types yet.
2183 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
2184 unsigned Opc;
2185 unsigned SubregIdx;
Amara Emerson8acb0d92019-03-04 19:16:00 +00002186
2187 std::tie(Opc, SubregIdx) = getInsertVecEltOpInfo(RB, EltSize);
Amara Emerson5ec14602018-12-10 18:44:58 +00002188
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002189 MachineIRBuilder MIRBuilder(I);
Jessica Paquette245047d2019-01-24 22:00:41 +00002190
2191 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002192 MachineInstr *ScalarToVec =
Amara Emerson8acb0d92019-03-04 19:16:00 +00002193 emitScalarToVector(DstTy.getElementType().getSizeInBits(), DstRC,
2194 I.getOperand(1).getReg(), MIRBuilder);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002195 if (!ScalarToVec)
Jessica Paquette245047d2019-01-24 22:00:41 +00002196 return false;
2197
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002198 unsigned DstVec = ScalarToVec->getOperand(0).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +00002199 unsigned DstSize = DstTy.getSizeInBits();
2200
2201 // Keep track of the last MI we inserted. Later on, we might be able to save
2202 // a copy using it.
2203 MachineInstr *PrevMI = nullptr;
2204 for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
Jessica Paquette245047d2019-01-24 22:00:41 +00002205 // Note that if we don't do a subregister copy, we end up making one more
2206 // of these than we need.
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002207 unsigned InsDef = MRI.createVirtualRegister(DstRC);
Amara Emerson5ec14602018-12-10 18:44:58 +00002208 unsigned LaneIdx = i - 1;
2209 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002210 auto ImpDef =
2211 MIRBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF, {DstRC}, {});
2212 auto InsSub = MIRBuilder
2213 .buildInstr(TargetOpcode::INSERT_SUBREG, {DstRC},
2214 {ImpDef, I.getOperand(i)})
2215 .addImm(SubregIdx);
2216 auto InsElt = MIRBuilder.buildInstr(Opc, {InsDef}, {DstVec})
2217 .addImm(LaneIdx)
2218 .addUse(InsSub.getReg(0))
2219 .addImm(0);
2220 constrainSelectedInstRegOperands(*ImpDef, TII, TRI, RBI);
2221 constrainSelectedInstRegOperands(*InsSub, TII, TRI, RBI);
2222 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
Amara Emerson5ec14602018-12-10 18:44:58 +00002223 DstVec = InsDef;
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002224 PrevMI = &*InsElt;
Amara Emerson5ec14602018-12-10 18:44:58 +00002225 } else {
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002226 auto Ins = MIRBuilder.buildInstr(Opc, {InsDef}, {DstVec})
2227 .addImm(LaneIdx)
2228 .addUse(I.getOperand(i).getReg());
2229 constrainSelectedInstRegOperands(*Ins, TII, TRI, RBI);
Amara Emerson5ec14602018-12-10 18:44:58 +00002230 DstVec = InsDef;
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002231 PrevMI = &*Ins;
Amara Emerson5ec14602018-12-10 18:44:58 +00002232 }
2233 }
Jessica Paquette245047d2019-01-24 22:00:41 +00002234
2235 // If DstTy's size in bits is less than 128, then emit a subregister copy
2236 // from DstVec to the last register we've defined.
2237 if (DstSize < 128) {
2238 unsigned SubReg = 0;
2239
2240 // Helper lambda to decide on a register class and subregister for the
2241 // subregister copy.
2242 auto GetRegInfoForCopy = [&SubReg,
2243 &DstSize]() -> const TargetRegisterClass * {
2244 switch (DstSize) {
2245 default:
2246 LLVM_DEBUG(dbgs() << "Unknown destination size (" << DstSize << ")\n");
2247 return nullptr;
2248 case 32:
2249 SubReg = AArch64::ssub;
2250 return &AArch64::FPR32RegClass;
2251 case 64:
2252 SubReg = AArch64::dsub;
2253 return &AArch64::FPR64RegClass;
2254 }
2255 };
2256
2257 const TargetRegisterClass *RC = GetRegInfoForCopy();
2258 if (!RC)
2259 return false;
2260
2261 unsigned Reg = MRI.createVirtualRegister(RC);
2262 unsigned DstReg = I.getOperand(0).getReg();
2263
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002264 // MIRBuilder doesn't let us create uses with subregs & flags, so use
2265 // BuildMI here instead.
Jessica Paquette245047d2019-01-24 22:00:41 +00002266 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
2267 DstReg)
2268 .addUse(DstVec, 0, SubReg);
2269 MachineOperand &RegOp = I.getOperand(1);
2270 RegOp.setReg(Reg);
2271 RBI.constrainGenericRegister(DstReg, *RC, MRI);
2272 } else {
2273 // We don't need a subregister copy. Save a copy by re-using the
2274 // destination register on the final insert.
2275 assert(PrevMI && "PrevMI was null?");
2276 PrevMI->getOperand(0).setReg(I.getOperand(0).getReg());
2277 constrainSelectedInstRegOperands(*PrevMI, TII, TRI, RBI);
2278 }
2279
Amara Emerson5ec14602018-12-10 18:44:58 +00002280 I.eraseFromParent();
2281 return true;
2282}
2283
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002284/// SelectArithImmed - Select an immediate value that can be represented as
2285/// a 12-bit value shifted left by either 0 or 12. If so, return true with
2286/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002287InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00002288AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002289 MachineInstr &MI = *Root.getParent();
2290 MachineBasicBlock &MBB = *MI.getParent();
2291 MachineFunction &MF = *MBB.getParent();
2292 MachineRegisterInfo &MRI = MF.getRegInfo();
2293
2294 // This function is called from the addsub_shifted_imm ComplexPattern,
2295 // which lists [imm] as the list of opcode it's interested in, however
2296 // we still need to check whether the operand is actually an immediate
2297 // here because the ComplexPattern opcode list is only used in
2298 // root-level opcode matching.
2299 uint64_t Immed;
2300 if (Root.isImm())
2301 Immed = Root.getImm();
2302 else if (Root.isCImm())
2303 Immed = Root.getCImm()->getZExtValue();
2304 else if (Root.isReg()) {
2305 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
2306 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002307 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002308 MachineOperand &Op1 = Def->getOperand(1);
2309 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002310 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00002311 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002312 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002313 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002314
2315 unsigned ShiftAmt;
2316
2317 if (Immed >> 12 == 0) {
2318 ShiftAmt = 0;
2319 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
2320 ShiftAmt = 12;
2321 Immed = Immed >> 12;
2322 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002323 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002324
2325 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002326 return {{
2327 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
2328 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
2329 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002330}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002331
Daniel Sandersea8711b2017-10-16 03:36:29 +00002332/// Select a "register plus unscaled signed 9-bit immediate" address. This
2333/// should only match when there is an offset that is not valid for a scaled
2334/// immediate addressing mode. The "Size" argument is the size in bytes of the
2335/// memory reference, which is needed here to know what is valid for a scaled
2336/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002337InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002338AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
2339 unsigned Size) const {
2340 MachineRegisterInfo &MRI =
2341 Root.getParent()->getParent()->getParent()->getRegInfo();
2342
2343 if (!Root.isReg())
2344 return None;
2345
2346 if (!isBaseWithConstantOffset(Root, MRI))
2347 return None;
2348
2349 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2350 if (!RootDef)
2351 return None;
2352
2353 MachineOperand &OffImm = RootDef->getOperand(2);
2354 if (!OffImm.isReg())
2355 return None;
2356 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
2357 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
2358 return None;
2359 int64_t RHSC;
2360 MachineOperand &RHSOp1 = RHS->getOperand(1);
2361 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
2362 return None;
2363 RHSC = RHSOp1.getCImm()->getSExtValue();
2364
2365 // If the offset is valid as a scaled immediate, don't match here.
2366 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
2367 return None;
2368 if (RHSC >= -256 && RHSC < 256) {
2369 MachineOperand &Base = RootDef->getOperand(1);
2370 return {{
2371 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
2372 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
2373 }};
2374 }
2375 return None;
2376}
2377
2378/// Select a "register plus scaled unsigned 12-bit immediate" address. The
2379/// "Size" argument is the size in bytes of the memory reference, which
2380/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002381InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00002382AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
2383 unsigned Size) const {
2384 MachineRegisterInfo &MRI =
2385 Root.getParent()->getParent()->getParent()->getRegInfo();
2386
2387 if (!Root.isReg())
2388 return None;
2389
2390 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
2391 if (!RootDef)
2392 return None;
2393
2394 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
2395 return {{
2396 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
2397 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2398 }};
2399 }
2400
2401 if (isBaseWithConstantOffset(Root, MRI)) {
2402 MachineOperand &LHS = RootDef->getOperand(1);
2403 MachineOperand &RHS = RootDef->getOperand(2);
2404 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
2405 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
2406 if (LHSDef && RHSDef) {
2407 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
2408 unsigned Scale = Log2_32(Size);
2409 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
2410 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00002411 return {{
2412 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
2413 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2414 }};
2415
Daniel Sandersea8711b2017-10-16 03:36:29 +00002416 return {{
2417 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
2418 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
2419 }};
2420 }
2421 }
2422 }
2423
2424 // Before falling back to our general case, check if the unscaled
2425 // instructions can handle this. If so, that's preferable.
2426 if (selectAddrModeUnscaled(Root, Size).hasValue())
2427 return None;
2428
2429 return {{
2430 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
2431 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
2432 }};
2433}
2434
Volkan Kelesf7f25682018-01-16 18:44:05 +00002435void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
2436 const MachineInstr &MI) const {
2437 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2438 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
2439 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
2440 assert(CstVal && "Expected constant value");
2441 MIB.addImm(CstVal.getValue());
2442}
2443
Daniel Sanders0b5293f2017-04-06 09:49:34 +00002444namespace llvm {
2445InstructionSelector *
2446createAArch64InstructionSelector(const AArch64TargetMachine &TM,
2447 AArch64Subtarget &Subtarget,
2448 AArch64RegisterBankInfo &RBI) {
2449 return new AArch64InstructionSelector(TM, Subtarget, RBI);
2450}
2451}