blob: 76bbd9489afc950e0f8822be3dc4f17e6cf8fe76 [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"
Amara Emerson2ff22982019-03-14 22:48:15 +000021#include "llvm/ADT/Optional.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
David Blaikie62651302017-10-26 23:39:54 +000023#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Amara Emerson1e8c1642018-07-31 00:09:02 +000024#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Amara Emerson761ca2e2019-03-19 21:43:05 +000025#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
Aditya Nandakumar75ad9cc2017-04-19 20:48:50 +000026#include "llvm/CodeGen/GlobalISel/Utils.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000027#include "llvm/CodeGen/MachineBasicBlock.h"
Amara Emerson1abe05c2019-02-21 20:20:16 +000028#include "llvm/CodeGen/MachineConstantPool.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000029#include "llvm/CodeGen/MachineFunction.h"
30#include "llvm/CodeGen/MachineInstr.h"
31#include "llvm/CodeGen/MachineInstrBuilder.h"
Daniel Sanders0b5293f2017-04-06 09:49:34 +000032#include "llvm/CodeGen/MachineOperand.h"
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +000033#include "llvm/CodeGen/MachineRegisterInfo.h"
34#include "llvm/IR/Type.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
37
38#define DEBUG_TYPE "aarch64-isel"
39
40using namespace llvm;
41
Daniel Sanders0b5293f2017-04-06 09:49:34 +000042namespace {
43
Daniel Sanderse7b0d662017-04-21 15:59:56 +000044#define GET_GLOBALISEL_PREDICATE_BITSET
45#include "AArch64GenGlobalISel.inc"
46#undef GET_GLOBALISEL_PREDICATE_BITSET
47
Daniel Sanders0b5293f2017-04-06 09:49:34 +000048class AArch64InstructionSelector : public InstructionSelector {
49public:
50 AArch64InstructionSelector(const AArch64TargetMachine &TM,
51 const AArch64Subtarget &STI,
52 const AArch64RegisterBankInfo &RBI);
53
Daniel Sandersf76f3152017-11-16 00:46:35 +000054 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
David Blaikie62651302017-10-26 23:39:54 +000055 static const char *getName() { return DEBUG_TYPE; }
Daniel Sanders0b5293f2017-04-06 09:49:34 +000056
57private:
58 /// tblgen-erated 'select' implementation, used as the initial selector for
59 /// the patterns that don't require complex C++.
Daniel Sandersf76f3152017-11-16 00:46:35 +000060 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +000061
62 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF,
63 MachineRegisterInfo &MRI) const;
64 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
65 MachineRegisterInfo &MRI) const;
66
67 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
68 MachineRegisterInfo &MRI) const;
69
Amara Emerson9bf092d2019-04-09 21:22:43 +000070 bool selectVectorASHR(MachineInstr &I, MachineRegisterInfo &MRI) const;
71 bool selectVectorSHL(MachineInstr &I, MachineRegisterInfo &MRI) const;
72
Amara Emerson5ec14602018-12-10 18:44:58 +000073 // Helper to generate an equivalent of scalar_to_vector into a new register,
74 // returned via 'Dst'.
Amara Emerson8acb0d92019-03-04 19:16:00 +000075 MachineInstr *emitScalarToVector(unsigned EltSize,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +000076 const TargetRegisterClass *DstRC,
77 unsigned Scalar,
78 MachineIRBuilder &MIRBuilder) const;
Jessica Paquette16d67a32019-03-13 23:22:23 +000079
80 /// Emit a lane insert into \p DstReg, or a new vector register if None is
81 /// provided.
82 ///
83 /// The lane inserted into is defined by \p LaneIdx. The vector source
84 /// register is given by \p SrcReg. The register containing the element is
85 /// given by \p EltReg.
86 MachineInstr *emitLaneInsert(Optional<unsigned> DstReg, unsigned SrcReg,
87 unsigned EltReg, unsigned LaneIdx,
88 const RegisterBank &RB,
89 MachineIRBuilder &MIRBuilder) const;
Jessica Paquette5aff1f42019-03-14 18:01:30 +000090 bool selectInsertElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000091 bool selectBuildVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson8cb186c2018-12-20 01:11:04 +000092 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette245047d2019-01-24 22:00:41 +000093 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson5ec14602018-12-10 18:44:58 +000094
Amara Emerson1abe05c2019-02-21 20:20:16 +000095 void collectShuffleMaskIndices(MachineInstr &I, MachineRegisterInfo &MRI,
Amara Emerson2806fd02019-04-12 21:31:21 +000096 SmallVectorImpl<Optional<int>> &Idxs) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +000097 bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette607774c2019-03-11 22:18:01 +000098 bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson2ff22982019-03-14 22:48:15 +000099 bool selectConcatVectors(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emersond61b89b2019-03-14 22:48:18 +0000100 bool selectSplitVectorUnmerge(MachineInstr &I,
101 MachineRegisterInfo &MRI) const;
Jessica Paquette22c62152019-04-02 19:57:26 +0000102 bool selectIntrinsicWithSideEffects(MachineInstr &I,
103 MachineRegisterInfo &MRI) const;
Jessica Paquette7f6fe7c2019-04-29 20:58:17 +0000104 bool selectIntrinsic(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson9bf092d2019-04-09 21:22:43 +0000105 bool selectVectorICmp(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette991cb392019-04-23 20:46:19 +0000106 bool selectIntrinsicTrunc(MachineInstr &I, MachineRegisterInfo &MRI) const;
Jessica Paquette4fe75742019-04-23 23:03:03 +0000107 bool selectIntrinsicRound(MachineInstr &I, MachineRegisterInfo &MRI) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +0000108 unsigned emitConstantPoolEntry(Constant *CPVal, MachineFunction &MF) const;
109 MachineInstr *emitLoadFromConstantPool(Constant *CPVal,
110 MachineIRBuilder &MIRBuilder) const;
Amara Emerson2ff22982019-03-14 22:48:15 +0000111
112 // Emit a vector concat operation.
113 MachineInstr *emitVectorConcat(Optional<unsigned> Dst, unsigned Op1,
114 unsigned Op2,
Amara Emerson8acb0d92019-03-04 19:16:00 +0000115 MachineIRBuilder &MIRBuilder) const;
Amara Emersond61b89b2019-03-14 22:48:18 +0000116 MachineInstr *emitExtractVectorElt(Optional<unsigned> DstReg,
117 const RegisterBank &DstRB, LLT ScalarTy,
118 unsigned VecReg, unsigned LaneIdx,
119 MachineIRBuilder &MIRBuilder) const;
Amara Emerson1abe05c2019-02-21 20:20:16 +0000120
Jessica Paquettea3843fe2019-05-01 22:39:43 +0000121 /// Helper function for selecting G_FCONSTANT. If the G_FCONSTANT can be
122 /// materialized using a FMOV instruction, then update MI and return it.
123 /// Otherwise, do nothing and return a nullptr.
124 MachineInstr *emitFMovForFConstant(MachineInstr &MI,
125 MachineRegisterInfo &MRI) const;
126
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000127 ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000128
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000129 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root,
130 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000131
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000132 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000133 return selectAddrModeUnscaled(Root, 1);
134 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000135 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000136 return selectAddrModeUnscaled(Root, 2);
137 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000138 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000139 return selectAddrModeUnscaled(Root, 4);
140 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000141 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000142 return selectAddrModeUnscaled(Root, 8);
143 }
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000144 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000145 return selectAddrModeUnscaled(Root, 16);
146 }
147
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000148 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root,
149 unsigned Size) const;
Daniel Sandersea8711b2017-10-16 03:36:29 +0000150 template <int Width>
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000151 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000152 return selectAddrModeIndexed(Root, Width / 8);
153 }
154
Volkan Kelesf7f25682018-01-16 18:44:05 +0000155 void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI) const;
156
Amara Emerson1e8c1642018-07-31 00:09:02 +0000157 // Materialize a GlobalValue or BlockAddress using a movz+movk sequence.
158 void materializeLargeCMVal(MachineInstr &I, const Value *V,
159 unsigned char OpFlags) const;
160
Amara Emerson761ca2e2019-03-19 21:43:05 +0000161 // Optimization methods.
162
163 // Helper function to check if a reg def is an MI with a given opcode and
164 // returns it if so.
165 MachineInstr *findMIFromReg(unsigned Reg, unsigned Opc,
166 MachineIRBuilder &MIB) const {
167 auto *Def = MIB.getMRI()->getVRegDef(Reg);
168 if (!Def || Def->getOpcode() != Opc)
169 return nullptr;
170 return Def;
171 }
172
173 bool tryOptVectorShuffle(MachineInstr &I) const;
174 bool tryOptVectorDup(MachineInstr &MI) const;
175
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000176 const AArch64TargetMachine &TM;
177 const AArch64Subtarget &STI;
178 const AArch64InstrInfo &TII;
179 const AArch64RegisterInfo &TRI;
180 const AArch64RegisterBankInfo &RBI;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000181
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000182#define GET_GLOBALISEL_PREDICATES_DECL
183#include "AArch64GenGlobalISel.inc"
184#undef GET_GLOBALISEL_PREDICATES_DECL
Daniel Sanders0b5293f2017-04-06 09:49:34 +0000185
186// We declare the temporaries used by selectImpl() in the class to minimize the
187// cost of constructing placeholder values.
188#define GET_GLOBALISEL_TEMPORARIES_DECL
189#include "AArch64GenGlobalISel.inc"
190#undef GET_GLOBALISEL_TEMPORARIES_DECL
191};
192
193} // end anonymous namespace
194
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000195#define GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000196#include "AArch64GenGlobalISel.inc"
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000197#undef GET_GLOBALISEL_IMPL
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000198
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000199AArch64InstructionSelector::AArch64InstructionSelector(
Tim Northoverbdf16242016-10-10 21:50:00 +0000200 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
201 const AArch64RegisterBankInfo &RBI)
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000202 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
Daniel Sanderse9fdba32017-04-29 17:30:09 +0000203 TRI(*STI.getRegisterInfo()), RBI(RBI),
204#define GET_GLOBALISEL_PREDICATES_INIT
205#include "AArch64GenGlobalISel.inc"
206#undef GET_GLOBALISEL_PREDICATES_INIT
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000207#define GET_GLOBALISEL_TEMPORARIES_INIT
208#include "AArch64GenGlobalISel.inc"
209#undef GET_GLOBALISEL_TEMPORARIES_INIT
210{
211}
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000212
Tim Northoverfb8d9892016-10-12 22:49:15 +0000213// FIXME: This should be target-independent, inferred from the types declared
214// for each class in the bank.
215static const TargetRegisterClass *
216getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
Amara Emerson3838ed02018-02-02 18:03:30 +0000217 const RegisterBankInfo &RBI,
218 bool GetAllRegSet = false) {
Tim Northoverfb8d9892016-10-12 22:49:15 +0000219 if (RB.getID() == AArch64::GPRRegBankID) {
220 if (Ty.getSizeInBits() <= 32)
Amara Emerson3838ed02018-02-02 18:03:30 +0000221 return GetAllRegSet ? &AArch64::GPR32allRegClass
222 : &AArch64::GPR32RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000223 if (Ty.getSizeInBits() == 64)
Amara Emerson3838ed02018-02-02 18:03:30 +0000224 return GetAllRegSet ? &AArch64::GPR64allRegClass
225 : &AArch64::GPR64RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000226 return nullptr;
227 }
228
229 if (RB.getID() == AArch64::FPRRegBankID) {
Amara Emerson3838ed02018-02-02 18:03:30 +0000230 if (Ty.getSizeInBits() <= 16)
231 return &AArch64::FPR16RegClass;
Tim Northoverfb8d9892016-10-12 22:49:15 +0000232 if (Ty.getSizeInBits() == 32)
233 return &AArch64::FPR32RegClass;
234 if (Ty.getSizeInBits() == 64)
235 return &AArch64::FPR64RegClass;
236 if (Ty.getSizeInBits() == 128)
237 return &AArch64::FPR128RegClass;
238 return nullptr;
239 }
240
241 return nullptr;
242}
243
Jessica Paquette245047d2019-01-24 22:00:41 +0000244/// Given a register bank, and size in bits, return the smallest register class
245/// that can represent that combination.
Benjamin Kramer711950c2019-02-11 15:16:21 +0000246static const TargetRegisterClass *
247getMinClassForRegBank(const RegisterBank &RB, unsigned SizeInBits,
248 bool GetAllRegSet = false) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000249 unsigned RegBankID = RB.getID();
250
251 if (RegBankID == AArch64::GPRRegBankID) {
252 if (SizeInBits <= 32)
253 return GetAllRegSet ? &AArch64::GPR32allRegClass
254 : &AArch64::GPR32RegClass;
255 if (SizeInBits == 64)
256 return GetAllRegSet ? &AArch64::GPR64allRegClass
257 : &AArch64::GPR64RegClass;
258 }
259
260 if (RegBankID == AArch64::FPRRegBankID) {
261 switch (SizeInBits) {
262 default:
263 return nullptr;
264 case 8:
265 return &AArch64::FPR8RegClass;
266 case 16:
267 return &AArch64::FPR16RegClass;
268 case 32:
269 return &AArch64::FPR32RegClass;
270 case 64:
271 return &AArch64::FPR64RegClass;
272 case 128:
273 return &AArch64::FPR128RegClass;
274 }
275 }
276
277 return nullptr;
278}
279
280/// Returns the correct subregister to use for a given register class.
281static bool getSubRegForClass(const TargetRegisterClass *RC,
282 const TargetRegisterInfo &TRI, unsigned &SubReg) {
283 switch (TRI.getRegSizeInBits(*RC)) {
284 case 8:
285 SubReg = AArch64::bsub;
286 break;
287 case 16:
288 SubReg = AArch64::hsub;
289 break;
290 case 32:
291 if (RC == &AArch64::GPR32RegClass)
292 SubReg = AArch64::sub_32;
293 else
294 SubReg = AArch64::ssub;
295 break;
296 case 64:
297 SubReg = AArch64::dsub;
298 break;
299 default:
300 LLVM_DEBUG(
301 dbgs() << "Couldn't find appropriate subregister for register class.");
302 return false;
303 }
304
305 return true;
306}
307
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000308/// Check whether \p I is a currently unsupported binary operation:
309/// - it has an unsized type
310/// - an operand is not a vreg
311/// - all operands are not in the same bank
312/// These are checks that should someday live in the verifier, but right now,
313/// these are mostly limitations of the aarch64 selector.
314static bool unsupportedBinOp(const MachineInstr &I,
315 const AArch64RegisterBankInfo &RBI,
316 const MachineRegisterInfo &MRI,
317 const AArch64RegisterInfo &TRI) {
Tim Northover0f140c72016-09-09 11:46:34 +0000318 LLT Ty = MRI.getType(I.getOperand(0).getReg());
Tim Northover32a078a2016-09-15 10:09:59 +0000319 if (!Ty.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000320 LLVM_DEBUG(dbgs() << "Generic binop register should be typed\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000321 return true;
322 }
323
324 const RegisterBank *PrevOpBank = nullptr;
325 for (auto &MO : I.operands()) {
326 // FIXME: Support non-register operands.
327 if (!MO.isReg()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000328 LLVM_DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000329 return true;
330 }
331
332 // FIXME: Can generic operations have physical registers operands? If
333 // so, this will need to be taught about that, and we'll need to get the
334 // bank out of the minimal class for the register.
335 // Either way, this needs to be documented (and possibly verified).
336 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000337 LLVM_DEBUG(dbgs() << "Generic inst has physical register operand\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000338 return true;
339 }
340
341 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI);
342 if (!OpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000343 LLVM_DEBUG(dbgs() << "Generic register has no bank or class\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000344 return true;
345 }
346
347 if (PrevOpBank && OpBank != PrevOpBank) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000348 LLVM_DEBUG(dbgs() << "Generic inst operands have different banks\n");
Ahmed Bougacha59e160a2016-08-16 14:37:40 +0000349 return true;
350 }
351 PrevOpBank = OpBank;
352 }
353 return false;
354}
355
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000356/// Select the AArch64 opcode for the basic binary operation \p GenericOpc
Ahmed Bougachacfb384d2017-01-23 21:10:05 +0000357/// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000358/// and of size \p OpSize.
359/// \returns \p GenericOpc if the combination is unsupported.
360static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
361 unsigned OpSize) {
362 switch (RegBankID) {
363 case AArch64::GPRRegBankID:
Ahmed Bougacha05a5f7d2017-01-25 02:41:38 +0000364 if (OpSize == 32) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000365 switch (GenericOpc) {
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000366 case TargetOpcode::G_SHL:
367 return AArch64::LSLVWr;
368 case TargetOpcode::G_LSHR:
369 return AArch64::LSRVWr;
370 case TargetOpcode::G_ASHR:
371 return AArch64::ASRVWr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000372 default:
373 return GenericOpc;
374 }
Tim Northover55782222016-10-18 20:03:48 +0000375 } else if (OpSize == 64) {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000376 switch (GenericOpc) {
Tim Northover2fda4b02016-10-10 21:49:49 +0000377 case TargetOpcode::G_GEP:
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000378 return AArch64::ADDXrr;
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +0000379 case TargetOpcode::G_SHL:
380 return AArch64::LSLVXr;
381 case TargetOpcode::G_LSHR:
382 return AArch64::LSRVXr;
383 case TargetOpcode::G_ASHR:
384 return AArch64::ASRVXr;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000385 default:
386 return GenericOpc;
387 }
388 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000389 break;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000390 case AArch64::FPRRegBankID:
391 switch (OpSize) {
392 case 32:
393 switch (GenericOpc) {
394 case TargetOpcode::G_FADD:
395 return AArch64::FADDSrr;
396 case TargetOpcode::G_FSUB:
397 return AArch64::FSUBSrr;
398 case TargetOpcode::G_FMUL:
399 return AArch64::FMULSrr;
400 case TargetOpcode::G_FDIV:
401 return AArch64::FDIVSrr;
402 default:
403 return GenericOpc;
404 }
405 case 64:
406 switch (GenericOpc) {
407 case TargetOpcode::G_FADD:
408 return AArch64::FADDDrr;
409 case TargetOpcode::G_FSUB:
410 return AArch64::FSUBDrr;
411 case TargetOpcode::G_FMUL:
412 return AArch64::FMULDrr;
413 case TargetOpcode::G_FDIV:
414 return AArch64::FDIVDrr;
Quentin Colombet0e531272016-10-11 00:21:11 +0000415 case TargetOpcode::G_OR:
416 return AArch64::ORRv8i8;
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +0000417 default:
418 return GenericOpc;
419 }
420 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000421 break;
422 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000423 return GenericOpc;
424}
425
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000426/// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc,
427/// appropriate for the (value) register bank \p RegBankID and of memory access
428/// size \p OpSize. This returns the variant with the base+unsigned-immediate
429/// addressing mode (e.g., LDRXui).
430/// \returns \p GenericOpc if the combination is unsupported.
431static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID,
432 unsigned OpSize) {
433 const bool isStore = GenericOpc == TargetOpcode::G_STORE;
434 switch (RegBankID) {
435 case AArch64::GPRRegBankID:
436 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000437 case 8:
438 return isStore ? AArch64::STRBBui : AArch64::LDRBBui;
439 case 16:
440 return isStore ? AArch64::STRHHui : AArch64::LDRHHui;
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000441 case 32:
442 return isStore ? AArch64::STRWui : AArch64::LDRWui;
443 case 64:
444 return isStore ? AArch64::STRXui : AArch64::LDRXui;
445 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000446 break;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000447 case AArch64::FPRRegBankID:
448 switch (OpSize) {
Tim Northover020d1042016-10-17 18:36:53 +0000449 case 8:
450 return isStore ? AArch64::STRBui : AArch64::LDRBui;
451 case 16:
452 return isStore ? AArch64::STRHui : AArch64::LDRHui;
Quentin Colombetd2623f8e2016-10-11 00:21:14 +0000453 case 32:
454 return isStore ? AArch64::STRSui : AArch64::LDRSui;
455 case 64:
456 return isStore ? AArch64::STRDui : AArch64::LDRDui;
457 }
Simon Pilgrim9e901522017-07-08 19:28:24 +0000458 break;
459 }
Ahmed Bougacha7adfac52016-07-29 16:56:16 +0000460 return GenericOpc;
461}
462
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000463#ifndef NDEBUG
Jessica Paquette245047d2019-01-24 22:00:41 +0000464/// Helper function that verifies that we have a valid copy at the end of
465/// selectCopy. Verifies that the source and dest have the expected sizes and
466/// then returns true.
467static bool isValidCopy(const MachineInstr &I, const RegisterBank &DstBank,
468 const MachineRegisterInfo &MRI,
469 const TargetRegisterInfo &TRI,
470 const RegisterBankInfo &RBI) {
471 const unsigned DstReg = I.getOperand(0).getReg();
472 const unsigned SrcReg = I.getOperand(1).getReg();
473 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
474 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
Amara Emersondb211892018-02-20 05:11:57 +0000475
Jessica Paquette245047d2019-01-24 22:00:41 +0000476 // Make sure the size of the source and dest line up.
477 assert(
478 (DstSize == SrcSize ||
479 // Copies are a mean to setup initial types, the number of
480 // bits may not exactly match.
481 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && DstSize <= SrcSize) ||
482 // Copies are a mean to copy bits around, as long as we are
483 // on the same register class, that's fine. Otherwise, that
484 // means we need some SUBREG_TO_REG or AND & co.
485 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) &&
486 "Copy with different width?!");
487
488 // Check the size of the destination.
489 assert((DstSize <= 64 || DstBank.getID() == AArch64::FPRRegBankID) &&
490 "GPRs cannot get more than 64-bit width values");
491
492 return true;
493}
Benjamin Kramer1411ecf2019-01-24 23:39:47 +0000494#endif
Jessica Paquette245047d2019-01-24 22:00:41 +0000495
496/// Helper function for selectCopy. Inserts a subregister copy from
497/// \p *From to \p *To, linking it up to \p I.
498///
499/// e.g, given I = "Dst = COPY SrcReg", we'll transform that into
500///
501/// CopyReg (From class) = COPY SrcReg
502/// SubRegCopy (To class) = COPY CopyReg:SubReg
503/// Dst = COPY SubRegCopy
Amara Emerson3739a202019-03-15 21:59:50 +0000504static bool selectSubregisterCopy(MachineInstr &I, MachineRegisterInfo &MRI,
Jessica Paquette245047d2019-01-24 22:00:41 +0000505 const RegisterBankInfo &RBI, unsigned SrcReg,
506 const TargetRegisterClass *From,
507 const TargetRegisterClass *To,
508 unsigned SubReg) {
Amara Emerson3739a202019-03-15 21:59:50 +0000509 MachineIRBuilder MIB(I);
510 auto Copy = MIB.buildCopy({From}, {SrcReg});
Amara Emerson86271782019-03-18 19:20:10 +0000511 auto SubRegCopy = MIB.buildInstr(TargetOpcode::COPY, {To}, {})
512 .addReg(Copy.getReg(0), 0, SubReg);
Amara Emersondb211892018-02-20 05:11:57 +0000513 MachineOperand &RegOp = I.getOperand(1);
Amara Emerson3739a202019-03-15 21:59:50 +0000514 RegOp.setReg(SubRegCopy.getReg(0));
Jessica Paquette245047d2019-01-24 22:00:41 +0000515
516 // It's possible that the destination register won't be constrained. Make
517 // sure that happens.
518 if (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()))
519 RBI.constrainGenericRegister(I.getOperand(0).getReg(), *To, MRI);
520
Amara Emersondb211892018-02-20 05:11:57 +0000521 return true;
522}
523
Quentin Colombetcb629a82016-10-12 03:57:49 +0000524static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
525 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
526 const RegisterBankInfo &RBI) {
527
528 unsigned DstReg = I.getOperand(0).getReg();
Amara Emersondb211892018-02-20 05:11:57 +0000529 unsigned SrcReg = I.getOperand(1).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +0000530 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
531 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
532 const TargetRegisterClass *DstRC = getMinClassForRegBank(
533 DstRegBank, RBI.getSizeInBits(DstReg, MRI, TRI), true);
534 if (!DstRC) {
535 LLVM_DEBUG(dbgs() << "Unexpected dest size "
536 << RBI.getSizeInBits(DstReg, MRI, TRI) << '\n');
Amara Emerson3838ed02018-02-02 18:03:30 +0000537 return false;
Quentin Colombetcb629a82016-10-12 03:57:49 +0000538 }
539
Jessica Paquette245047d2019-01-24 22:00:41 +0000540 // A couple helpers below, for making sure that the copy we produce is valid.
541
542 // Set to true if we insert a SUBREG_TO_REG. If we do this, then we don't want
543 // to verify that the src and dst are the same size, since that's handled by
544 // the SUBREG_TO_REG.
545 bool KnownValid = false;
546
547 // Returns true, or asserts if something we don't expect happens. Instead of
548 // returning true, we return isValidCopy() to ensure that we verify the
549 // result.
Jessica Paquette76c40f82019-01-24 22:51:31 +0000550 auto CheckCopy = [&]() {
Jessica Paquette245047d2019-01-24 22:00:41 +0000551 // If we have a bitcast or something, we can't have physical registers.
552 assert(
Simon Pilgrimdea61742019-01-25 11:38:40 +0000553 (I.isCopy() ||
554 (!TargetRegisterInfo::isPhysicalRegister(I.getOperand(0).getReg()) &&
555 !TargetRegisterInfo::isPhysicalRegister(I.getOperand(1).getReg()))) &&
556 "No phys reg on generic operator!");
Jessica Paquette245047d2019-01-24 22:00:41 +0000557 assert(KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI));
Jonas Hahnfeld65a401f2019-03-04 08:51:32 +0000558 (void)KnownValid;
Jessica Paquette245047d2019-01-24 22:00:41 +0000559 return true;
560 };
561
562 // Is this a copy? If so, then we may need to insert a subregister copy, or
563 // a SUBREG_TO_REG.
564 if (I.isCopy()) {
565 // Yes. Check if there's anything to fix up.
566 const TargetRegisterClass *SrcRC = getMinClassForRegBank(
567 SrcRegBank, RBI.getSizeInBits(SrcReg, MRI, TRI), true);
Amara Emerson7e9f3482018-02-18 17:10:49 +0000568 if (!SrcRC) {
Jessica Paquette245047d2019-01-24 22:00:41 +0000569 LLVM_DEBUG(dbgs() << "Couldn't determine source register class\n");
570 return false;
Amara Emerson7e9f3482018-02-18 17:10:49 +0000571 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000572
573 // Is this a cross-bank copy?
574 if (DstRegBank.getID() != SrcRegBank.getID()) {
575 // If we're doing a cross-bank copy on different-sized registers, we need
576 // to do a bit more work.
577 unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
578 unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
579
580 if (SrcSize > DstSize) {
581 // We're doing a cross-bank copy into a smaller register. We need a
582 // subregister copy. First, get a register class that's on the same bank
583 // as the destination, but the same size as the source.
584 const TargetRegisterClass *SubregRC =
585 getMinClassForRegBank(DstRegBank, SrcSize, true);
586 assert(SubregRC && "Didn't get a register class for subreg?");
587
588 // Get the appropriate subregister for the destination.
589 unsigned SubReg = 0;
590 if (!getSubRegForClass(DstRC, TRI, SubReg)) {
591 LLVM_DEBUG(dbgs() << "Couldn't determine subregister for copy.\n");
592 return false;
593 }
594
595 // Now, insert a subregister copy using the new register class.
Amara Emerson3739a202019-03-15 21:59:50 +0000596 selectSubregisterCopy(I, MRI, RBI, SrcReg, SubregRC, DstRC, SubReg);
Jessica Paquette245047d2019-01-24 22:00:41 +0000597 return CheckCopy();
598 }
599
600 else if (DstRegBank.getID() == AArch64::GPRRegBankID && DstSize == 32 &&
601 SrcSize == 16) {
602 // Special case for FPR16 to GPR32.
603 // FIXME: This can probably be generalized like the above case.
604 unsigned PromoteReg =
605 MRI.createVirtualRegister(&AArch64::FPR32RegClass);
606 BuildMI(*I.getParent(), I, I.getDebugLoc(),
607 TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
608 .addImm(0)
609 .addUse(SrcReg)
610 .addImm(AArch64::hsub);
611 MachineOperand &RegOp = I.getOperand(1);
612 RegOp.setReg(PromoteReg);
613
614 // Promise that the copy is implicitly validated by the SUBREG_TO_REG.
615 KnownValid = true;
616 }
Amara Emerson7e9f3482018-02-18 17:10:49 +0000617 }
Jessica Paquette245047d2019-01-24 22:00:41 +0000618
619 // If the destination is a physical register, then there's nothing to
620 // change, so we're done.
621 if (TargetRegisterInfo::isPhysicalRegister(DstReg))
622 return CheckCopy();
Amara Emerson7e9f3482018-02-18 17:10:49 +0000623 }
624
Jessica Paquette245047d2019-01-24 22:00:41 +0000625 // No need to constrain SrcReg. It will get constrained when we hit another
626 // of its use or its defs. Copies do not have constraints.
627 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000628 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
629 << " operand\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +0000630 return false;
631 }
632 I.setDesc(TII.get(AArch64::COPY));
Jessica Paquette245047d2019-01-24 22:00:41 +0000633 return CheckCopy();
Quentin Colombetcb629a82016-10-12 03:57:49 +0000634}
635
Tim Northover69271c62016-10-12 22:49:11 +0000636static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
637 if (!DstTy.isScalar() || !SrcTy.isScalar())
638 return GenericOpc;
639
640 const unsigned DstSize = DstTy.getSizeInBits();
641 const unsigned SrcSize = SrcTy.getSizeInBits();
642
643 switch (DstSize) {
644 case 32:
645 switch (SrcSize) {
646 case 32:
647 switch (GenericOpc) {
648 case TargetOpcode::G_SITOFP:
649 return AArch64::SCVTFUWSri;
650 case TargetOpcode::G_UITOFP:
651 return AArch64::UCVTFUWSri;
652 case TargetOpcode::G_FPTOSI:
653 return AArch64::FCVTZSUWSr;
654 case TargetOpcode::G_FPTOUI:
655 return AArch64::FCVTZUUWSr;
656 default:
657 return GenericOpc;
658 }
659 case 64:
660 switch (GenericOpc) {
661 case TargetOpcode::G_SITOFP:
662 return AArch64::SCVTFUXSri;
663 case TargetOpcode::G_UITOFP:
664 return AArch64::UCVTFUXSri;
665 case TargetOpcode::G_FPTOSI:
666 return AArch64::FCVTZSUWDr;
667 case TargetOpcode::G_FPTOUI:
668 return AArch64::FCVTZUUWDr;
669 default:
670 return GenericOpc;
671 }
672 default:
673 return GenericOpc;
674 }
675 case 64:
676 switch (SrcSize) {
677 case 32:
678 switch (GenericOpc) {
679 case TargetOpcode::G_SITOFP:
680 return AArch64::SCVTFUWDri;
681 case TargetOpcode::G_UITOFP:
682 return AArch64::UCVTFUWDri;
683 case TargetOpcode::G_FPTOSI:
684 return AArch64::FCVTZSUXSr;
685 case TargetOpcode::G_FPTOUI:
686 return AArch64::FCVTZUUXSr;
687 default:
688 return GenericOpc;
689 }
690 case 64:
691 switch (GenericOpc) {
692 case TargetOpcode::G_SITOFP:
693 return AArch64::SCVTFUXDri;
694 case TargetOpcode::G_UITOFP:
695 return AArch64::UCVTFUXDri;
696 case TargetOpcode::G_FPTOSI:
697 return AArch64::FCVTZSUXDr;
698 case TargetOpcode::G_FPTOUI:
699 return AArch64::FCVTZUUXDr;
700 default:
701 return GenericOpc;
702 }
703 default:
704 return GenericOpc;
705 }
706 default:
707 return GenericOpc;
708 };
709 return GenericOpc;
710}
711
Tim Northover6c02ad52016-10-12 22:49:04 +0000712static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
713 switch (P) {
714 default:
715 llvm_unreachable("Unknown condition code!");
716 case CmpInst::ICMP_NE:
717 return AArch64CC::NE;
718 case CmpInst::ICMP_EQ:
719 return AArch64CC::EQ;
720 case CmpInst::ICMP_SGT:
721 return AArch64CC::GT;
722 case CmpInst::ICMP_SGE:
723 return AArch64CC::GE;
724 case CmpInst::ICMP_SLT:
725 return AArch64CC::LT;
726 case CmpInst::ICMP_SLE:
727 return AArch64CC::LE;
728 case CmpInst::ICMP_UGT:
729 return AArch64CC::HI;
730 case CmpInst::ICMP_UGE:
731 return AArch64CC::HS;
732 case CmpInst::ICMP_ULT:
733 return AArch64CC::LO;
734 case CmpInst::ICMP_ULE:
735 return AArch64CC::LS;
736 }
737}
738
Tim Northover7dd378d2016-10-12 22:49:07 +0000739static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
740 AArch64CC::CondCode &CondCode,
741 AArch64CC::CondCode &CondCode2) {
742 CondCode2 = AArch64CC::AL;
743 switch (P) {
744 default:
745 llvm_unreachable("Unknown FP condition!");
746 case CmpInst::FCMP_OEQ:
747 CondCode = AArch64CC::EQ;
748 break;
749 case CmpInst::FCMP_OGT:
750 CondCode = AArch64CC::GT;
751 break;
752 case CmpInst::FCMP_OGE:
753 CondCode = AArch64CC::GE;
754 break;
755 case CmpInst::FCMP_OLT:
756 CondCode = AArch64CC::MI;
757 break;
758 case CmpInst::FCMP_OLE:
759 CondCode = AArch64CC::LS;
760 break;
761 case CmpInst::FCMP_ONE:
762 CondCode = AArch64CC::MI;
763 CondCode2 = AArch64CC::GT;
764 break;
765 case CmpInst::FCMP_ORD:
766 CondCode = AArch64CC::VC;
767 break;
768 case CmpInst::FCMP_UNO:
769 CondCode = AArch64CC::VS;
770 break;
771 case CmpInst::FCMP_UEQ:
772 CondCode = AArch64CC::EQ;
773 CondCode2 = AArch64CC::VS;
774 break;
775 case CmpInst::FCMP_UGT:
776 CondCode = AArch64CC::HI;
777 break;
778 case CmpInst::FCMP_UGE:
779 CondCode = AArch64CC::PL;
780 break;
781 case CmpInst::FCMP_ULT:
782 CondCode = AArch64CC::LT;
783 break;
784 case CmpInst::FCMP_ULE:
785 CondCode = AArch64CC::LE;
786 break;
787 case CmpInst::FCMP_UNE:
788 CondCode = AArch64CC::NE;
789 break;
790 }
791}
792
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000793bool AArch64InstructionSelector::selectCompareBranch(
794 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
795
796 const unsigned CondReg = I.getOperand(0).getReg();
797 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
798 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
Aditya Nandakumar02c602e2017-07-31 17:00:16 +0000799 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC)
800 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg());
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000801 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
802 return false;
803
804 unsigned LHS = CCMI->getOperand(2).getReg();
805 unsigned RHS = CCMI->getOperand(3).getReg();
806 if (!getConstantVRegVal(RHS, MRI))
807 std::swap(RHS, LHS);
808
809 const auto RHSImm = getConstantVRegVal(RHS, MRI);
810 if (!RHSImm || *RHSImm != 0)
811 return false;
812
813 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
814 if (RB.getID() != AArch64::GPRRegBankID)
815 return false;
816
817 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
818 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
819 return false;
820
821 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
822 unsigned CBOpc = 0;
823 if (CmpWidth <= 32)
824 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
825 else if (CmpWidth == 64)
826 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
827 else
828 return false;
829
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +0000830 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
831 .addUse(LHS)
832 .addMBB(DestMBB)
833 .constrainAllUses(TII, TRI, RBI);
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000834
Ahmed Bougacha641cb202017-03-27 16:35:31 +0000835 I.eraseFromParent();
836 return true;
837}
838
Amara Emerson9bf092d2019-04-09 21:22:43 +0000839bool AArch64InstructionSelector::selectVectorSHL(
840 MachineInstr &I, MachineRegisterInfo &MRI) const {
841 assert(I.getOpcode() == TargetOpcode::G_SHL);
842 unsigned DstReg = I.getOperand(0).getReg();
843 const LLT Ty = MRI.getType(DstReg);
844 unsigned Src1Reg = I.getOperand(1).getReg();
845 unsigned Src2Reg = I.getOperand(2).getReg();
846
847 if (!Ty.isVector())
848 return false;
849
850 unsigned Opc = 0;
Amara Emerson9bf092d2019-04-09 21:22:43 +0000851 if (Ty == LLT::vector(4, 32)) {
852 Opc = AArch64::USHLv4i32;
Amara Emerson9bf092d2019-04-09 21:22:43 +0000853 } else if (Ty == LLT::vector(2, 32)) {
854 Opc = AArch64::USHLv2i32;
Amara Emerson9bf092d2019-04-09 21:22:43 +0000855 } else {
856 LLVM_DEBUG(dbgs() << "Unhandled G_SHL type");
857 return false;
858 }
859
860 MachineIRBuilder MIB(I);
861 auto UShl = MIB.buildInstr(Opc, {DstReg}, {Src1Reg, Src2Reg});
862 constrainSelectedInstRegOperands(*UShl, TII, TRI, RBI);
863 I.eraseFromParent();
864 return true;
865}
866
867bool AArch64InstructionSelector::selectVectorASHR(
868 MachineInstr &I, MachineRegisterInfo &MRI) const {
869 assert(I.getOpcode() == TargetOpcode::G_ASHR);
870 unsigned DstReg = I.getOperand(0).getReg();
871 const LLT Ty = MRI.getType(DstReg);
872 unsigned Src1Reg = I.getOperand(1).getReg();
873 unsigned Src2Reg = I.getOperand(2).getReg();
874
875 if (!Ty.isVector())
876 return false;
877
878 // There is not a shift right register instruction, but the shift left
879 // register instruction takes a signed value, where negative numbers specify a
880 // right shift.
881
882 unsigned Opc = 0;
883 unsigned NegOpc = 0;
884 const TargetRegisterClass *RC = nullptr;
885 if (Ty == LLT::vector(4, 32)) {
886 Opc = AArch64::SSHLv4i32;
887 NegOpc = AArch64::NEGv4i32;
888 RC = &AArch64::FPR128RegClass;
889 } else if (Ty == LLT::vector(2, 32)) {
890 Opc = AArch64::SSHLv2i32;
891 NegOpc = AArch64::NEGv2i32;
892 RC = &AArch64::FPR64RegClass;
893 } else {
894 LLVM_DEBUG(dbgs() << "Unhandled G_ASHR type");
895 return false;
896 }
897
898 MachineIRBuilder MIB(I);
899 auto Neg = MIB.buildInstr(NegOpc, {RC}, {Src2Reg});
900 constrainSelectedInstRegOperands(*Neg, TII, TRI, RBI);
901 auto SShl = MIB.buildInstr(Opc, {DstReg}, {Src1Reg, Neg});
902 constrainSelectedInstRegOperands(*SShl, TII, TRI, RBI);
903 I.eraseFromParent();
904 return true;
905}
906
Tim Northovere9600d82017-02-08 17:57:27 +0000907bool AArch64InstructionSelector::selectVaStartAAPCS(
908 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
909 return false;
910}
911
912bool AArch64InstructionSelector::selectVaStartDarwin(
913 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
914 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
915 unsigned ListReg = I.getOperand(0).getReg();
916
917 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
918
919 auto MIB =
920 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri))
921 .addDef(ArgsAddrReg)
922 .addFrameIndex(FuncInfo->getVarArgsStackIndex())
923 .addImm(0)
924 .addImm(0);
925
926 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
927
928 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui))
929 .addUse(ArgsAddrReg)
930 .addUse(ListReg)
931 .addImm(0)
932 .addMemOperand(*I.memoperands_begin());
933
934 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
935 I.eraseFromParent();
936 return true;
937}
938
Amara Emerson1e8c1642018-07-31 00:09:02 +0000939void AArch64InstructionSelector::materializeLargeCMVal(
940 MachineInstr &I, const Value *V, unsigned char OpFlags) const {
941 MachineBasicBlock &MBB = *I.getParent();
942 MachineFunction &MF = *MBB.getParent();
943 MachineRegisterInfo &MRI = MF.getRegInfo();
944 MachineIRBuilder MIB(I);
945
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000946 auto MovZ = MIB.buildInstr(AArch64::MOVZXi, {&AArch64::GPR64RegClass}, {});
Amara Emerson1e8c1642018-07-31 00:09:02 +0000947 MovZ->addOperand(MF, I.getOperand(1));
948 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 |
949 AArch64II::MO_NC);
950 MovZ->addOperand(MF, MachineOperand::CreateImm(0));
951 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI);
952
953 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, unsigned Offset,
954 unsigned ForceDstReg) {
955 unsigned DstReg = ForceDstReg
956 ? ForceDstReg
957 : MRI.createVirtualRegister(&AArch64::GPR64RegClass);
958 auto MovI = MIB.buildInstr(AArch64::MOVKXi).addDef(DstReg).addUse(SrcReg);
959 if (auto *GV = dyn_cast<GlobalValue>(V)) {
960 MovI->addOperand(MF, MachineOperand::CreateGA(
961 GV, MovZ->getOperand(1).getOffset(), Flags));
962 } else {
963 MovI->addOperand(
964 MF, MachineOperand::CreateBA(cast<BlockAddress>(V),
965 MovZ->getOperand(1).getOffset(), Flags));
966 }
967 MovI->addOperand(MF, MachineOperand::CreateImm(Offset));
968 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI);
969 return DstReg;
970 };
Aditya Nandakumarfef76192019-02-05 22:14:40 +0000971 unsigned DstReg = BuildMovK(MovZ.getReg(0),
Amara Emerson1e8c1642018-07-31 00:09:02 +0000972 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0);
973 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0);
974 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg());
975 return;
976}
977
Daniel Sandersf76f3152017-11-16 00:46:35 +0000978bool AArch64InstructionSelector::select(MachineInstr &I,
979 CodeGenCoverage &CoverageInfo) const {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +0000980 assert(I.getParent() && "Instruction should be in a basic block!");
981 assert(I.getParent()->getParent() && "Instruction should be in a function!");
982
983 MachineBasicBlock &MBB = *I.getParent();
984 MachineFunction &MF = *MBB.getParent();
985 MachineRegisterInfo &MRI = MF.getRegInfo();
986
Tim Northovercdf23f12016-10-31 18:30:59 +0000987 unsigned Opcode = I.getOpcode();
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000988 // G_PHI requires same handling as PHI
989 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
Tim Northovercdf23f12016-10-31 18:30:59 +0000990 // Certain non-generic instructions also need some special handling.
991
992 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
993 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +0000994
Aditya Nandakumarefd8a842017-08-23 20:45:48 +0000995 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
Tim Northover7d88da62016-11-08 00:34:06 +0000996 const unsigned DefReg = I.getOperand(0).getReg();
997 const LLT DefTy = MRI.getType(DefReg);
998
999 const TargetRegisterClass *DefRC = nullptr;
1000 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
1001 DefRC = TRI.getRegClass(DefReg);
1002 } else {
1003 const RegClassOrRegBank &RegClassOrBank =
1004 MRI.getRegClassOrRegBank(DefReg);
1005
1006 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
1007 if (!DefRC) {
1008 if (!DefTy.isValid()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001009 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
Tim Northover7d88da62016-11-08 00:34:06 +00001010 return false;
1011 }
1012 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
1013 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
1014 if (!DefRC) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001015 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
Tim Northover7d88da62016-11-08 00:34:06 +00001016 return false;
1017 }
1018 }
1019 }
Aditya Nandakumarefd8a842017-08-23 20:45:48 +00001020 I.setDesc(TII.get(TargetOpcode::PHI));
Tim Northover7d88da62016-11-08 00:34:06 +00001021
1022 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
1023 }
1024
1025 if (I.isCopy())
Tim Northovercdf23f12016-10-31 18:30:59 +00001026 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover7d88da62016-11-08 00:34:06 +00001027
1028 return true;
Tim Northovercdf23f12016-10-31 18:30:59 +00001029 }
1030
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001031
1032 if (I.getNumOperands() != I.getNumExplicitOperands()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001033 LLVM_DEBUG(
1034 dbgs() << "Generic instruction has unexpected implicit operands\n");
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001035 return false;
1036 }
1037
Daniel Sandersf76f3152017-11-16 00:46:35 +00001038 if (selectImpl(I, CoverageInfo))
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001039 return true;
1040
Tim Northover32a078a2016-09-15 10:09:59 +00001041 LLT Ty =
1042 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{};
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001043
Amara Emerson3739a202019-03-15 21:59:50 +00001044 MachineIRBuilder MIB(I);
1045
Tim Northover69271c62016-10-12 22:49:11 +00001046 switch (Opcode) {
Tim Northover5e3dbf32016-10-12 22:49:01 +00001047 case TargetOpcode::G_BRCOND: {
1048 if (Ty.getSizeInBits() > 32) {
1049 // We shouldn't need this on AArch64, but it would be implemented as an
1050 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
1051 // bit being tested is < 32.
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001052 LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
1053 << ", expected at most 32-bits");
Tim Northover5e3dbf32016-10-12 22:49:01 +00001054 return false;
1055 }
1056
1057 const unsigned CondReg = I.getOperand(0).getReg();
1058 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1059
Kristof Beylse66bc1f2018-12-18 08:50:02 +00001060 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
1061 // instructions will not be produced, as they are conditional branch
1062 // instructions that do not set flags.
1063 bool ProduceNonFlagSettingCondBr =
1064 !MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening);
1065 if (ProduceNonFlagSettingCondBr && selectCompareBranch(I, MF, MRI))
Ahmed Bougacha641cb202017-03-27 16:35:31 +00001066 return true;
1067
Kristof Beylse66bc1f2018-12-18 08:50:02 +00001068 if (ProduceNonFlagSettingCondBr) {
1069 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
1070 .addUse(CondReg)
1071 .addImm(/*bit offset=*/0)
1072 .addMBB(DestMBB);
Tim Northover5e3dbf32016-10-12 22:49:01 +00001073
Kristof Beylse66bc1f2018-12-18 08:50:02 +00001074 I.eraseFromParent();
1075 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
1076 } else {
1077 auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1078 .addDef(AArch64::WZR)
1079 .addUse(CondReg)
1080 .addImm(1);
1081 constrainSelectedInstRegOperands(*CMP.getInstr(), TII, TRI, RBI);
1082 auto Bcc =
1083 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::Bcc))
1084 .addImm(AArch64CC::EQ)
1085 .addMBB(DestMBB);
1086
1087 I.eraseFromParent();
1088 return constrainSelectedInstRegOperands(*Bcc.getInstr(), TII, TRI, RBI);
1089 }
Tim Northover5e3dbf32016-10-12 22:49:01 +00001090 }
1091
Kristof Beyls65a12c02017-01-30 09:13:18 +00001092 case TargetOpcode::G_BRINDIRECT: {
1093 I.setDesc(TII.get(AArch64::BR));
1094 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1095 }
1096
Jessica Paquette67ab9eb2019-04-26 18:00:01 +00001097 case TargetOpcode::G_BSWAP: {
1098 // Handle vector types for G_BSWAP directly.
1099 unsigned DstReg = I.getOperand(0).getReg();
1100 LLT DstTy = MRI.getType(DstReg);
1101
1102 // We should only get vector types here; everything else is handled by the
1103 // importer right now.
1104 if (!DstTy.isVector() || DstTy.getSizeInBits() > 128) {
1105 LLVM_DEBUG(dbgs() << "Dst type for G_BSWAP currently unsupported.\n");
1106 return false;
1107 }
1108
1109 // Only handle 4 and 2 element vectors for now.
1110 // TODO: 16-bit elements.
1111 unsigned NumElts = DstTy.getNumElements();
1112 if (NumElts != 4 && NumElts != 2) {
1113 LLVM_DEBUG(dbgs() << "Unsupported number of elements for G_BSWAP.\n");
1114 return false;
1115 }
1116
1117 // Choose the correct opcode for the supported types. Right now, that's
1118 // v2s32, v4s32, and v2s64.
1119 unsigned Opc = 0;
1120 unsigned EltSize = DstTy.getElementType().getSizeInBits();
1121 if (EltSize == 32)
1122 Opc = (DstTy.getNumElements() == 2) ? AArch64::REV32v8i8
1123 : AArch64::REV32v16i8;
1124 else if (EltSize == 64)
1125 Opc = AArch64::REV64v16i8;
1126
1127 // We should always get something by the time we get here...
1128 assert(Opc != 0 && "Didn't get an opcode for G_BSWAP?");
1129
1130 I.setDesc(TII.get(Opc));
1131 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1132 }
1133
Tim Northover4494d692016-10-18 19:47:57 +00001134 case TargetOpcode::G_FCONSTANT:
Tim Northover4edc60d2016-10-10 21:49:42 +00001135 case TargetOpcode::G_CONSTANT: {
Tim Northover4494d692016-10-18 19:47:57 +00001136 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
1137
1138 const LLT s32 = LLT::scalar(32);
1139 const LLT s64 = LLT::scalar(64);
1140 const LLT p0 = LLT::pointer(0, 64);
1141
1142 const unsigned DefReg = I.getOperand(0).getReg();
1143 const LLT DefTy = MRI.getType(DefReg);
1144 const unsigned DefSize = DefTy.getSizeInBits();
1145 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1146
1147 // FIXME: Redundant check, but even less readable when factored out.
1148 if (isFP) {
1149 if (Ty != s32 && Ty != s64) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001150 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1151 << " constant, expected: " << s32 << " or " << s64
1152 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001153 return false;
1154 }
1155
1156 if (RB.getID() != AArch64::FPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001157 LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
1158 << " constant on bank: " << RB
1159 << ", expected: FPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001160 return false;
1161 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00001162
1163 // The case when we have 0.0 is covered by tablegen. Reject it here so we
1164 // can be sure tablegen works correctly and isn't rescued by this code.
1165 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
1166 return false;
Tim Northover4494d692016-10-18 19:47:57 +00001167 } else {
Daniel Sanders05540042017-08-08 10:44:31 +00001168 // s32 and s64 are covered by tablegen.
1169 if (Ty != p0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001170 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1171 << " constant, expected: " << s32 << ", " << s64
1172 << ", or " << p0 << '\n');
Tim Northover4494d692016-10-18 19:47:57 +00001173 return false;
1174 }
1175
1176 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001177 LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
1178 << " constant on bank: " << RB
1179 << ", expected: GPR\n");
Tim Northover4494d692016-10-18 19:47:57 +00001180 return false;
1181 }
1182 }
1183
1184 const unsigned MovOpc =
1185 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
1186
Tim Northover4494d692016-10-18 19:47:57 +00001187 if (isFP) {
Jessica Paquettea3843fe2019-05-01 22:39:43 +00001188 // Either emit a FMOV, or emit a copy to emit a normal mov.
Tim Northover4494d692016-10-18 19:47:57 +00001189 const TargetRegisterClass &GPRRC =
1190 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
1191 const TargetRegisterClass &FPRRC =
1192 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
1193
Jessica Paquettea3843fe2019-05-01 22:39:43 +00001194 // Can we use a FMOV instruction to represent the immediate?
1195 if (emitFMovForFConstant(I, MRI))
1196 return true;
1197
1198 // Nope. Emit a copy and use a normal mov instead.
Tim Northover4494d692016-10-18 19:47:57 +00001199 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
1200 MachineOperand &RegOp = I.getOperand(0);
1201 RegOp.setReg(DefGPRReg);
Amara Emerson3739a202019-03-15 21:59:50 +00001202 MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
1203 MIB.buildCopy({DefReg}, {DefGPRReg});
Tim Northover4494d692016-10-18 19:47:57 +00001204
1205 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001206 LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
Tim Northover4494d692016-10-18 19:47:57 +00001207 return false;
1208 }
1209
1210 MachineOperand &ImmOp = I.getOperand(1);
1211 // FIXME: Is going through int64_t always correct?
1212 ImmOp.ChangeToImmediate(
1213 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001214 } else if (I.getOperand(1).isCImm()) {
Tim Northover9267ac52016-12-05 21:47:07 +00001215 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
1216 I.getOperand(1).ChangeToImmediate(Val);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001217 } else if (I.getOperand(1).isImm()) {
1218 uint64_t Val = I.getOperand(1).getImm();
1219 I.getOperand(1).ChangeToImmediate(Val);
Tim Northover4494d692016-10-18 19:47:57 +00001220 }
1221
Jessica Paquettea3843fe2019-05-01 22:39:43 +00001222 I.setDesc(TII.get(MovOpc));
Tim Northover4494d692016-10-18 19:47:57 +00001223 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1224 return true;
Tim Northover4edc60d2016-10-10 21:49:42 +00001225 }
Tim Northover7b6d66c2017-07-20 22:58:38 +00001226 case TargetOpcode::G_EXTRACT: {
1227 LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001228 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Amara Emerson242efdb2018-02-18 17:28:34 +00001229 (void)DstTy;
Amara Emersonbc03bae2018-02-18 17:03:02 +00001230 unsigned SrcSize = SrcTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001231 // Larger extracts are vectors, same-size extracts should be something else
1232 // by now (either split up or simplified to a COPY).
1233 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32)
1234 return false;
1235
Amara Emersonbc03bae2018-02-18 17:03:02 +00001236 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001237 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() +
1238 Ty.getSizeInBits() - 1);
1239
Amara Emersonbc03bae2018-02-18 17:03:02 +00001240 if (SrcSize < 64) {
1241 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 &&
1242 "unexpected G_EXTRACT types");
1243 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1244 }
1245
Tim Northover7b6d66c2017-07-20 22:58:38 +00001246 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
Amara Emerson3739a202019-03-15 21:59:50 +00001247 MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
Amara Emerson86271782019-03-18 19:20:10 +00001248 MIB.buildInstr(TargetOpcode::COPY, {I.getOperand(0).getReg()}, {})
1249 .addReg(DstReg, 0, AArch64::sub_32);
Tim Northover7b6d66c2017-07-20 22:58:38 +00001250 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
1251 AArch64::GPR32RegClass, MRI);
1252 I.getOperand(0).setReg(DstReg);
1253
1254 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1255 }
1256
1257 case TargetOpcode::G_INSERT: {
1258 LLT SrcTy = MRI.getType(I.getOperand(2).getReg());
Amara Emersonbc03bae2018-02-18 17:03:02 +00001259 LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1260 unsigned DstSize = DstTy.getSizeInBits();
Tim Northover7b6d66c2017-07-20 22:58:38 +00001261 // Larger inserts are vectors, same-size ones should be something else by
1262 // now (split up or turned into COPYs).
1263 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32)
1264 return false;
1265
Amara Emersonbc03bae2018-02-18 17:03:02 +00001266 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri));
Tim Northover7b6d66c2017-07-20 22:58:38 +00001267 unsigned LSB = I.getOperand(3).getImm();
1268 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
Amara Emersonbc03bae2018-02-18 17:03:02 +00001269 I.getOperand(3).setImm((DstSize - LSB) % DstSize);
Tim Northover7b6d66c2017-07-20 22:58:38 +00001270 MachineInstrBuilder(MF, I).addImm(Width - 1);
1271
Amara Emersonbc03bae2018-02-18 17:03:02 +00001272 if (DstSize < 64) {
1273 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 &&
1274 "unexpected G_INSERT types");
1275 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1276 }
1277
Tim Northover7b6d66c2017-07-20 22:58:38 +00001278 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1279 BuildMI(MBB, I.getIterator(), I.getDebugLoc(),
1280 TII.get(AArch64::SUBREG_TO_REG))
1281 .addDef(SrcReg)
1282 .addImm(0)
1283 .addUse(I.getOperand(2).getReg())
1284 .addImm(AArch64::sub_32);
1285 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
1286 AArch64::GPR32RegClass, MRI);
1287 I.getOperand(2).setReg(SrcReg);
1288
1289 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1290 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001291 case TargetOpcode::G_FRAME_INDEX: {
1292 // allocas and G_FRAME_INDEX are only supported in addrspace(0).
Tim Northover5ae83502016-09-15 09:20:34 +00001293 if (Ty != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001294 LLVM_DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty
1295 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001296 return false;
1297 }
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001298 I.setDesc(TII.get(AArch64::ADDXri));
Ahmed Bougacha0306b5e2016-08-16 14:02:42 +00001299
1300 // MOs for a #0 shifted immediate.
1301 I.addOperand(MachineOperand::CreateImm(0));
1302 I.addOperand(MachineOperand::CreateImm(0));
1303
1304 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1305 }
Tim Northoverbdf16242016-10-10 21:50:00 +00001306
1307 case TargetOpcode::G_GLOBAL_VALUE: {
1308 auto GV = I.getOperand(1).getGlobal();
1309 if (GV->isThreadLocal()) {
1310 // FIXME: we don't support TLS yet.
1311 return false;
1312 }
1313 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001314 if (OpFlags & AArch64II::MO_GOT) {
Tim Northoverbdf16242016-10-10 21:50:00 +00001315 I.setDesc(TII.get(AArch64::LOADgot));
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001316 I.getOperand(1).setTargetFlags(OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001317 } else if (TM.getCodeModel() == CodeModel::Large) {
1318 // Materialize the global using movz/movk instructions.
Amara Emerson1e8c1642018-07-31 00:09:02 +00001319 materializeLargeCMVal(I, GV, OpFlags);
Amara Emersond5785772018-01-18 19:21:27 +00001320 I.eraseFromParent();
1321 return true;
David Green9dd1d452018-08-22 11:31:39 +00001322 } else if (TM.getCodeModel() == CodeModel::Tiny) {
1323 I.setDesc(TII.get(AArch64::ADR));
1324 I.getOperand(1).setTargetFlags(OpFlags);
Tim Northoverfe7c59a2016-12-13 18:25:38 +00001325 } else {
Tim Northoverbdf16242016-10-10 21:50:00 +00001326 I.setDesc(TII.get(AArch64::MOVaddr));
1327 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE);
1328 MachineInstrBuilder MIB(MF, I);
1329 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(),
1330 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1331 }
1332 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1333 }
1334
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001335 case TargetOpcode::G_LOAD:
1336 case TargetOpcode::G_STORE: {
Tim Northover0f140c72016-09-09 11:46:34 +00001337 LLT PtrTy = MRI.getType(I.getOperand(1).getReg());
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001338
Tim Northover5ae83502016-09-15 09:20:34 +00001339 if (PtrTy != LLT::pointer(0, 64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001340 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
1341 << ", expected: " << LLT::pointer(0, 64) << '\n');
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001342 return false;
1343 }
1344
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001345 auto &MemOp = **I.memoperands_begin();
1346 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001347 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001348 return false;
1349 }
Daniel Sandersf84bc372018-05-05 20:53:24 +00001350 unsigned MemSizeInBits = MemOp.getSize() * 8;
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00001351
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001352 const unsigned PtrReg = I.getOperand(1).getReg();
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001353#ifndef NDEBUG
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001354 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
Ahmed Bougachaf0b22c42017-03-27 18:14:20 +00001355 // Sanity-check the pointer register.
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001356 assert(PtrRB.getID() == AArch64::GPRRegBankID &&
1357 "Load/Store pointer operand isn't a GPR");
Tim Northover0f140c72016-09-09 11:46:34 +00001358 assert(MRI.getType(PtrReg).isPointer() &&
1359 "Load/Store pointer operand isn't a pointer");
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001360#endif
1361
1362 const unsigned ValReg = I.getOperand(0).getReg();
1363 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
1364
1365 const unsigned NewOpc =
Daniel Sandersf84bc372018-05-05 20:53:24 +00001366 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001367 if (NewOpc == I.getOpcode())
1368 return false;
1369
1370 I.setDesc(TII.get(NewOpc));
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001371
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001372 uint64_t Offset = 0;
1373 auto *PtrMI = MRI.getVRegDef(PtrReg);
1374
1375 // Try to fold a GEP into our unsigned immediate addressing mode.
1376 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) {
1377 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) {
1378 int64_t Imm = *COff;
Daniel Sandersf84bc372018-05-05 20:53:24 +00001379 const unsigned Size = MemSizeInBits / 8;
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001380 const unsigned Scale = Log2_32(Size);
1381 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) {
1382 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg();
1383 I.getOperand(1).setReg(Ptr2Reg);
1384 PtrMI = MRI.getVRegDef(Ptr2Reg);
1385 Offset = Imm / Size;
1386 }
1387 }
1388 }
1389
Ahmed Bougachaf75782f2017-03-27 17:31:56 +00001390 // If we haven't folded anything into our addressing mode yet, try to fold
1391 // a frame index into the base+offset.
1392 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX)
1393 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex());
1394
Ahmed Bougacha8a654082017-03-27 17:31:52 +00001395 I.addOperand(MachineOperand::CreateImm(Offset));
Ahmed Bougacha85a66a62017-03-27 17:31:48 +00001396
1397 // If we're storing a 0, use WZR/XZR.
1398 if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
1399 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
1400 if (I.getOpcode() == AArch64::STRWui)
1401 I.getOperand(0).setReg(AArch64::WZR);
1402 else if (I.getOpcode() == AArch64::STRXui)
1403 I.getOperand(0).setReg(AArch64::XZR);
1404 }
1405 }
1406
Ahmed Bougacha7adfac52016-07-29 16:56:16 +00001407 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1408 }
1409
Tim Northover9dd78f82017-02-08 21:22:25 +00001410 case TargetOpcode::G_SMULH:
1411 case TargetOpcode::G_UMULH: {
1412 // Reject the various things we don't support yet.
1413 if (unsupportedBinOp(I, RBI, MRI, TRI))
1414 return false;
1415
1416 const unsigned DefReg = I.getOperand(0).getReg();
1417 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1418
1419 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001420 LLVM_DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
Tim Northover9dd78f82017-02-08 21:22:25 +00001421 return false;
1422 }
1423
1424 if (Ty != LLT::scalar(64)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001425 LLVM_DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
1426 << ", expected: " << LLT::scalar(64) << '\n');
Tim Northover9dd78f82017-02-08 21:22:25 +00001427 return false;
1428 }
1429
1430 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
1431 : AArch64::UMULHrr;
1432 I.setDesc(TII.get(NewOpc));
1433
1434 // Now that we selected an opcode, we need to constrain the register
1435 // operands to use appropriate classes.
1436 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1437 }
Ahmed Bougacha33e19fe2016-08-18 16:05:11 +00001438 case TargetOpcode::G_FADD:
1439 case TargetOpcode::G_FSUB:
1440 case TargetOpcode::G_FMUL:
1441 case TargetOpcode::G_FDIV:
1442
Ahmed Bougacha2ac5bf92016-08-16 14:02:47 +00001443 case TargetOpcode::G_ASHR:
Amara Emerson9bf092d2019-04-09 21:22:43 +00001444 if (MRI.getType(I.getOperand(0).getReg()).isVector())
1445 return selectVectorASHR(I, MRI);
1446 LLVM_FALLTHROUGH;
1447 case TargetOpcode::G_SHL:
1448 if (Opcode == TargetOpcode::G_SHL &&
1449 MRI.getType(I.getOperand(0).getReg()).isVector())
1450 return selectVectorSHL(I, MRI);
1451 LLVM_FALLTHROUGH;
1452 case TargetOpcode::G_OR:
1453 case TargetOpcode::G_LSHR:
Tim Northover2fda4b02016-10-10 21:49:49 +00001454 case TargetOpcode::G_GEP: {
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001455 // Reject the various things we don't support yet.
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001456 if (unsupportedBinOp(I, RBI, MRI, TRI))
1457 return false;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001458
Ahmed Bougacha59e160a2016-08-16 14:37:40 +00001459 const unsigned OpSize = Ty.getSizeInBits();
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001460
1461 const unsigned DefReg = I.getOperand(0).getReg();
1462 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1463
1464 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize);
1465 if (NewOpc == I.getOpcode())
1466 return false;
1467
1468 I.setDesc(TII.get(NewOpc));
1469 // FIXME: Should the type be always reset in setDesc?
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001470
1471 // Now that we selected an opcode, we need to constrain the register
1472 // operands to use appropriate classes.
1473 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1474 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001475
Jessica Paquette7d6784f2019-03-14 22:54:29 +00001476 case TargetOpcode::G_UADDO: {
1477 // TODO: Support other types.
1478 unsigned OpSize = Ty.getSizeInBits();
1479 if (OpSize != 32 && OpSize != 64) {
1480 LLVM_DEBUG(
1481 dbgs()
1482 << "G_UADDO currently only supported for 32 and 64 b types.\n");
1483 return false;
1484 }
1485
1486 // TODO: Support vectors.
1487 if (Ty.isVector()) {
1488 LLVM_DEBUG(dbgs() << "G_UADDO currently only supported for scalars.\n");
1489 return false;
1490 }
1491
1492 // Add and set the set condition flag.
1493 unsigned AddsOpc = OpSize == 32 ? AArch64::ADDSWrr : AArch64::ADDSXrr;
1494 MachineIRBuilder MIRBuilder(I);
1495 auto AddsMI = MIRBuilder.buildInstr(
1496 AddsOpc, {I.getOperand(0).getReg()},
1497 {I.getOperand(2).getReg(), I.getOperand(3).getReg()});
1498 constrainSelectedInstRegOperands(*AddsMI, TII, TRI, RBI);
1499
1500 // Now, put the overflow result in the register given by the first operand
1501 // to the G_UADDO. CSINC increments the result when the predicate is false,
1502 // so to get the increment when it's true, we need to use the inverse. In
1503 // this case, we want to increment when carry is set.
1504 auto CsetMI = MIRBuilder
1505 .buildInstr(AArch64::CSINCWr, {I.getOperand(1).getReg()},
1506 {AArch64::WZR, AArch64::WZR})
1507 .addImm(getInvertedCondCode(AArch64CC::HS));
1508 constrainSelectedInstRegOperands(*CsetMI, TII, TRI, RBI);
1509 I.eraseFromParent();
1510 return true;
1511 }
1512
Tim Northover398c5f52017-02-14 20:56:29 +00001513 case TargetOpcode::G_PTR_MASK: {
1514 uint64_t Align = I.getOperand(2).getImm();
1515 if (Align >= 64 || Align == 0)
1516 return false;
1517
1518 uint64_t Mask = ~((1ULL << Align) - 1);
1519 I.setDesc(TII.get(AArch64::ANDXri));
1520 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64));
1521
1522 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1523 }
Tim Northover037af52c2016-10-31 18:31:09 +00001524 case TargetOpcode::G_PTRTOINT:
Tim Northoverfb8d9892016-10-12 22:49:15 +00001525 case TargetOpcode::G_TRUNC: {
1526 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1527 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
1528
1529 const unsigned DstReg = I.getOperand(0).getReg();
1530 const unsigned SrcReg = I.getOperand(1).getReg();
1531
1532 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1533 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
1534
1535 if (DstRB.getID() != SrcRB.getID()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001536 LLVM_DEBUG(
1537 dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001538 return false;
1539 }
1540
1541 if (DstRB.getID() == AArch64::GPRRegBankID) {
1542 const TargetRegisterClass *DstRC =
1543 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1544 if (!DstRC)
1545 return false;
1546
1547 const TargetRegisterClass *SrcRC =
1548 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
1549 if (!SrcRC)
1550 return false;
1551
1552 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1553 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001554 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001555 return false;
1556 }
1557
1558 if (DstRC == SrcRC) {
1559 // Nothing to be done
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001560 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&
1561 SrcTy == LLT::scalar(64)) {
1562 llvm_unreachable("TableGen can import this case");
1563 return false;
Tim Northoverfb8d9892016-10-12 22:49:15 +00001564 } else if (DstRC == &AArch64::GPR32RegClass &&
1565 SrcRC == &AArch64::GPR64RegClass) {
1566 I.getOperand(1).setSubReg(AArch64::sub_32);
1567 } else {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001568 LLVM_DEBUG(
1569 dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");
Tim Northoverfb8d9892016-10-12 22:49:15 +00001570 return false;
1571 }
1572
1573 I.setDesc(TII.get(TargetOpcode::COPY));
1574 return true;
1575 } else if (DstRB.getID() == AArch64::FPRRegBankID) {
1576 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) {
1577 I.setDesc(TII.get(AArch64::XTNv4i16));
1578 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1579 return true;
1580 }
1581 }
1582
1583 return false;
1584 }
1585
Tim Northover3d38b3a2016-10-11 20:50:21 +00001586 case TargetOpcode::G_ANYEXT: {
1587 const unsigned DstReg = I.getOperand(0).getReg();
1588 const unsigned SrcReg = I.getOperand(1).getReg();
1589
Quentin Colombetcb629a82016-10-12 03:57:49 +00001590 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI);
1591 if (RBDst.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001592 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst
1593 << ", expected: GPR\n");
Quentin Colombetcb629a82016-10-12 03:57:49 +00001594 return false;
1595 }
Tim Northover3d38b3a2016-10-11 20:50:21 +00001596
Quentin Colombetcb629a82016-10-12 03:57:49 +00001597 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI);
1598 if (RBSrc.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001599 LLVM_DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc
1600 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001601 return false;
1602 }
1603
1604 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
1605
1606 if (DstSize == 0) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001607 LLVM_DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001608 return false;
1609 }
1610
Quentin Colombetcb629a82016-10-12 03:57:49 +00001611 if (DstSize != 64 && DstSize > 32) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001612 LLVM_DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
1613 << ", expected: 32 or 64\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001614 return false;
1615 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001616 // At this point G_ANYEXT is just like a plain COPY, but we need
1617 // to explicitly form the 64-bit value if any.
1618 if (DstSize > 32) {
1619 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass);
1620 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1621 .addDef(ExtSrc)
1622 .addImm(0)
1623 .addUse(SrcReg)
1624 .addImm(AArch64::sub_32);
1625 I.getOperand(1).setReg(ExtSrc);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001626 }
Quentin Colombetcb629a82016-10-12 03:57:49 +00001627 return selectCopy(I, TII, MRI, TRI, RBI);
Tim Northover3d38b3a2016-10-11 20:50:21 +00001628 }
1629
1630 case TargetOpcode::G_ZEXT:
1631 case TargetOpcode::G_SEXT: {
1632 unsigned Opcode = I.getOpcode();
1633 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1634 SrcTy = MRI.getType(I.getOperand(1).getReg());
1635 const bool isSigned = Opcode == TargetOpcode::G_SEXT;
1636 const unsigned DefReg = I.getOperand(0).getReg();
1637 const unsigned SrcReg = I.getOperand(1).getReg();
1638 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
1639
1640 if (RB.getID() != AArch64::GPRRegBankID) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001641 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
1642 << ", expected: GPR\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001643 return false;
1644 }
1645
1646 MachineInstr *ExtI;
1647 if (DstTy == LLT::scalar(64)) {
1648 // FIXME: Can we avoid manually doing this?
1649 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001650 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
1651 << " operand\n");
Tim Northover3d38b3a2016-10-11 20:50:21 +00001652 return false;
1653 }
1654
1655 const unsigned SrcXReg =
1656 MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1657 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
1658 .addDef(SrcXReg)
1659 .addImm(0)
1660 .addUse(SrcReg)
1661 .addImm(AArch64::sub_32);
1662
1663 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
1664 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1665 .addDef(DefReg)
1666 .addUse(SrcXReg)
1667 .addImm(0)
1668 .addImm(SrcTy.getSizeInBits() - 1);
Tim Northovera9105be2016-11-09 22:39:54 +00001669 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) {
Tim Northover3d38b3a2016-10-11 20:50:21 +00001670 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
1671 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
1672 .addDef(DefReg)
1673 .addUse(SrcReg)
1674 .addImm(0)
1675 .addImm(SrcTy.getSizeInBits() - 1);
1676 } else {
1677 return false;
1678 }
1679
1680 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
1681
1682 I.eraseFromParent();
1683 return true;
1684 }
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001685
Tim Northover69271c62016-10-12 22:49:11 +00001686 case TargetOpcode::G_SITOFP:
1687 case TargetOpcode::G_UITOFP:
1688 case TargetOpcode::G_FPTOSI:
1689 case TargetOpcode::G_FPTOUI: {
1690 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
1691 SrcTy = MRI.getType(I.getOperand(1).getReg());
1692 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy);
1693 if (NewOpc == Opcode)
1694 return false;
1695
1696 I.setDesc(TII.get(NewOpc));
1697 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1698
1699 return true;
1700 }
1701
1702
Tim Northoverc1d8c2b2016-10-11 22:29:23 +00001703 case TargetOpcode::G_INTTOPTR:
Daniel Sandersedd07842017-08-17 09:26:14 +00001704 // The importer is currently unable to import pointer types since they
1705 // didn't exist in SelectionDAG.
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00001706 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sanders16e6dd32017-08-15 13:50:09 +00001707
Daniel Sandersedd07842017-08-17 09:26:14 +00001708 case TargetOpcode::G_BITCAST:
1709 // Imported SelectionDAG rules can handle every bitcast except those that
1710 // bitcast from a type to the same type. Ideally, these shouldn't occur
Amara Emersonb9560512019-04-11 20:32:24 +00001711 // but we might not run an optimizer that deletes them. The other exception
1712 // is bitcasts involving pointer types, as SelectionDAG has no knowledge
1713 // of them.
1714 return selectCopy(I, TII, MRI, TRI, RBI);
Daniel Sandersedd07842017-08-17 09:26:14 +00001715
Tim Northover9ac0eba2016-11-08 00:45:29 +00001716 case TargetOpcode::G_SELECT: {
1717 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001718 LLVM_DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
1719 << ", expected: " << LLT::scalar(1) << '\n');
Tim Northover9ac0eba2016-11-08 00:45:29 +00001720 return false;
1721 }
1722
1723 const unsigned CondReg = I.getOperand(1).getReg();
1724 const unsigned TReg = I.getOperand(2).getReg();
1725 const unsigned FReg = I.getOperand(3).getReg();
1726
1727 unsigned CSelOpc = 0;
1728
1729 if (Ty == LLT::scalar(32)) {
1730 CSelOpc = AArch64::CSELWr;
Kristof Beylse9412b42017-01-19 13:32:14 +00001731 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
Tim Northover9ac0eba2016-11-08 00:45:29 +00001732 CSelOpc = AArch64::CSELXr;
1733 } else {
1734 return false;
1735 }
1736
1737 MachineInstr &TstMI =
1738 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
1739 .addDef(AArch64::WZR)
1740 .addUse(CondReg)
1741 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
1742
1743 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
1744 .addDef(I.getOperand(0).getReg())
1745 .addUse(TReg)
1746 .addUse(FReg)
1747 .addImm(AArch64CC::NE);
1748
1749 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
1750 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);
1751
1752 I.eraseFromParent();
1753 return true;
1754 }
Tim Northover6c02ad52016-10-12 22:49:04 +00001755 case TargetOpcode::G_ICMP: {
Amara Emerson9bf092d2019-04-09 21:22:43 +00001756 if (Ty.isVector())
1757 return selectVectorICmp(I, MRI);
1758
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001759 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001760 LLVM_DEBUG(dbgs() << "G_ICMP result has type: " << Ty
1761 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover6c02ad52016-10-12 22:49:04 +00001762 return false;
1763 }
1764
1765 unsigned CmpOpc = 0;
1766 unsigned ZReg = 0;
1767
1768 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1769 if (CmpTy == LLT::scalar(32)) {
1770 CmpOpc = AArch64::SUBSWrr;
1771 ZReg = AArch64::WZR;
1772 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) {
1773 CmpOpc = AArch64::SUBSXrr;
1774 ZReg = AArch64::XZR;
1775 } else {
1776 return false;
1777 }
1778
Kristof Beyls22524402017-01-05 10:16:08 +00001779 // CSINC increments the result by one when the condition code is false.
1780 // Therefore, we have to invert the predicate to get an increment by 1 when
1781 // the predicate is true.
1782 const AArch64CC::CondCode invCC =
1783 changeICMPPredToAArch64CC(CmpInst::getInversePredicate(
1784 (CmpInst::Predicate)I.getOperand(1).getPredicate()));
Tim Northover6c02ad52016-10-12 22:49:04 +00001785
1786 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1787 .addDef(ZReg)
1788 .addUse(I.getOperand(2).getReg())
1789 .addUse(I.getOperand(3).getReg());
1790
1791 MachineInstr &CSetMI =
1792 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1793 .addDef(I.getOperand(0).getReg())
1794 .addUse(AArch64::WZR)
1795 .addUse(AArch64::WZR)
Kristof Beyls22524402017-01-05 10:16:08 +00001796 .addImm(invCC);
Tim Northover6c02ad52016-10-12 22:49:04 +00001797
1798 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1799 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1800
1801 I.eraseFromParent();
1802 return true;
1803 }
1804
Tim Northover7dd378d2016-10-12 22:49:07 +00001805 case TargetOpcode::G_FCMP: {
Aditya Nandakumar02c602e2017-07-31 17:00:16 +00001806 if (Ty != LLT::scalar(32)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001807 LLVM_DEBUG(dbgs() << "G_FCMP result has type: " << Ty
1808 << ", expected: " << LLT::scalar(32) << '\n');
Tim Northover7dd378d2016-10-12 22:49:07 +00001809 return false;
1810 }
1811
1812 unsigned CmpOpc = 0;
1813 LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
1814 if (CmpTy == LLT::scalar(32)) {
1815 CmpOpc = AArch64::FCMPSrr;
1816 } else if (CmpTy == LLT::scalar(64)) {
1817 CmpOpc = AArch64::FCMPDrr;
1818 } else {
1819 return false;
1820 }
1821
1822 // FIXME: regbank
1823
1824 AArch64CC::CondCode CC1, CC2;
1825 changeFCMPPredToAArch64CC(
1826 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
1827
1828 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
1829 .addUse(I.getOperand(2).getReg())
1830 .addUse(I.getOperand(3).getReg());
1831
1832 const unsigned DefReg = I.getOperand(0).getReg();
1833 unsigned Def1Reg = DefReg;
1834 if (CC2 != AArch64CC::AL)
1835 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1836
1837 MachineInstr &CSetMI =
1838 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1839 .addDef(Def1Reg)
1840 .addUse(AArch64::WZR)
1841 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001842 .addImm(getInvertedCondCode(CC1));
Tim Northover7dd378d2016-10-12 22:49:07 +00001843
1844 if (CC2 != AArch64CC::AL) {
1845 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
1846 MachineInstr &CSet2MI =
1847 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
1848 .addDef(Def2Reg)
1849 .addUse(AArch64::WZR)
1850 .addUse(AArch64::WZR)
Tim Northover33a1a0b2017-01-17 23:04:01 +00001851 .addImm(getInvertedCondCode(CC2));
Tim Northover7dd378d2016-10-12 22:49:07 +00001852 MachineInstr &OrMI =
1853 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
1854 .addDef(DefReg)
1855 .addUse(Def1Reg)
1856 .addUse(Def2Reg);
1857 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
1858 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
1859 }
1860
1861 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI);
1862 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI);
1863
1864 I.eraseFromParent();
1865 return true;
1866 }
Tim Northovere9600d82017-02-08 17:57:27 +00001867 case TargetOpcode::G_VASTART:
1868 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI)
1869 : selectVaStartAAPCS(I, MF, MRI);
Jessica Paquette7f6fe7c2019-04-29 20:58:17 +00001870 case TargetOpcode::G_INTRINSIC:
1871 return selectIntrinsic(I, MRI);
Amara Emerson1f5d9942018-04-25 14:43:59 +00001872 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
Jessica Paquette22c62152019-04-02 19:57:26 +00001873 return selectIntrinsicWithSideEffects(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001874 case TargetOpcode::G_IMPLICIT_DEF: {
Justin Bogner4fc69662017-07-12 17:32:32 +00001875 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
Amara Emerson58aea522018-02-02 01:44:43 +00001876 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
1877 const unsigned DstReg = I.getOperand(0).getReg();
1878 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1879 const TargetRegisterClass *DstRC =
1880 getRegClassForTypeOnBank(DstTy, DstRB, RBI);
1881 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Justin Bogner4fc69662017-07-12 17:32:32 +00001882 return true;
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001883 }
Amara Emerson1e8c1642018-07-31 00:09:02 +00001884 case TargetOpcode::G_BLOCK_ADDR: {
1885 if (TM.getCodeModel() == CodeModel::Large) {
1886 materializeLargeCMVal(I, I.getOperand(1).getBlockAddress(), 0);
1887 I.eraseFromParent();
1888 return true;
1889 } else {
1890 I.setDesc(TII.get(AArch64::MOVaddrBA));
1891 auto MovMI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::MOVaddrBA),
1892 I.getOperand(0).getReg())
1893 .addBlockAddress(I.getOperand(1).getBlockAddress(),
1894 /* Offset */ 0, AArch64II::MO_PAGE)
1895 .addBlockAddress(
1896 I.getOperand(1).getBlockAddress(), /* Offset */ 0,
1897 AArch64II::MO_NC | AArch64II::MO_PAGEOFF);
1898 I.eraseFromParent();
1899 return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
1900 }
1901 }
Jessica Paquette991cb392019-04-23 20:46:19 +00001902 case TargetOpcode::G_INTRINSIC_TRUNC:
1903 return selectIntrinsicTrunc(I, MRI);
Jessica Paquette4fe75742019-04-23 23:03:03 +00001904 case TargetOpcode::G_INTRINSIC_ROUND:
1905 return selectIntrinsicRound(I, MRI);
Amara Emerson5ec14602018-12-10 18:44:58 +00001906 case TargetOpcode::G_BUILD_VECTOR:
1907 return selectBuildVector(I, MRI);
Amara Emerson8cb186c2018-12-20 01:11:04 +00001908 case TargetOpcode::G_MERGE_VALUES:
1909 return selectMergeValues(I, MRI);
Jessica Paquette245047d2019-01-24 22:00:41 +00001910 case TargetOpcode::G_UNMERGE_VALUES:
1911 return selectUnmergeValues(I, MRI);
Amara Emerson1abe05c2019-02-21 20:20:16 +00001912 case TargetOpcode::G_SHUFFLE_VECTOR:
1913 return selectShuffleVector(I, MRI);
Jessica Paquette607774c2019-03-11 22:18:01 +00001914 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
1915 return selectExtractElt(I, MRI);
Jessica Paquette5aff1f42019-03-14 18:01:30 +00001916 case TargetOpcode::G_INSERT_VECTOR_ELT:
1917 return selectInsertElt(I, MRI);
Amara Emerson2ff22982019-03-14 22:48:15 +00001918 case TargetOpcode::G_CONCAT_VECTORS:
1919 return selectConcatVectors(I, MRI);
Amara Emerson1e8c1642018-07-31 00:09:02 +00001920 }
Ahmed Bougacha6756a2c2016-07-27 14:31:55 +00001921
1922 return false;
1923}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001924
Jessica Paquette991cb392019-04-23 20:46:19 +00001925bool AArch64InstructionSelector::selectIntrinsicTrunc(
1926 MachineInstr &I, MachineRegisterInfo &MRI) const {
1927 const LLT SrcTy = MRI.getType(I.getOperand(0).getReg());
1928
1929 // Select the correct opcode.
1930 unsigned Opc = 0;
1931 if (!SrcTy.isVector()) {
1932 switch (SrcTy.getSizeInBits()) {
1933 default:
1934 case 16:
1935 Opc = AArch64::FRINTZHr;
1936 break;
1937 case 32:
1938 Opc = AArch64::FRINTZSr;
1939 break;
1940 case 64:
1941 Opc = AArch64::FRINTZDr;
1942 break;
1943 }
1944 } else {
1945 unsigned NumElts = SrcTy.getNumElements();
1946 switch (SrcTy.getElementType().getSizeInBits()) {
1947 default:
1948 break;
1949 case 16:
1950 if (NumElts == 4)
1951 Opc = AArch64::FRINTZv4f16;
1952 else if (NumElts == 8)
1953 Opc = AArch64::FRINTZv8f16;
1954 break;
1955 case 32:
1956 if (NumElts == 2)
1957 Opc = AArch64::FRINTZv2f32;
1958 else if (NumElts == 4)
1959 Opc = AArch64::FRINTZv4f32;
1960 break;
1961 case 64:
1962 if (NumElts == 2)
1963 Opc = AArch64::FRINTZv2f64;
1964 break;
1965 }
1966 }
1967
1968 if (!Opc) {
1969 // Didn't get an opcode above, bail.
1970 LLVM_DEBUG(dbgs() << "Unsupported type for G_INTRINSIC_TRUNC!\n");
1971 return false;
1972 }
1973
1974 // Legalization would have set us up perfectly for this; we just need to
1975 // set the opcode and move on.
1976 I.setDesc(TII.get(Opc));
1977 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1978}
1979
Jessica Paquette4fe75742019-04-23 23:03:03 +00001980bool AArch64InstructionSelector::selectIntrinsicRound(
1981 MachineInstr &I, MachineRegisterInfo &MRI) const {
1982 const LLT SrcTy = MRI.getType(I.getOperand(0).getReg());
1983
1984 // Select the correct opcode.
1985 unsigned Opc = 0;
1986 if (!SrcTy.isVector()) {
1987 switch (SrcTy.getSizeInBits()) {
1988 default:
1989 case 16:
1990 Opc = AArch64::FRINTAHr;
1991 break;
1992 case 32:
1993 Opc = AArch64::FRINTASr;
1994 break;
1995 case 64:
1996 Opc = AArch64::FRINTADr;
1997 break;
1998 }
1999 } else {
2000 unsigned NumElts = SrcTy.getNumElements();
2001 switch (SrcTy.getElementType().getSizeInBits()) {
2002 default:
2003 break;
2004 case 16:
2005 if (NumElts == 4)
2006 Opc = AArch64::FRINTAv4f16;
2007 else if (NumElts == 8)
2008 Opc = AArch64::FRINTAv8f16;
2009 break;
2010 case 32:
2011 if (NumElts == 2)
2012 Opc = AArch64::FRINTAv2f32;
2013 else if (NumElts == 4)
2014 Opc = AArch64::FRINTAv4f32;
2015 break;
2016 case 64:
2017 if (NumElts == 2)
2018 Opc = AArch64::FRINTAv2f64;
2019 break;
2020 }
2021 }
2022
2023 if (!Opc) {
2024 // Didn't get an opcode above, bail.
2025 LLVM_DEBUG(dbgs() << "Unsupported type for G_INTRINSIC_ROUND!\n");
2026 return false;
2027 }
2028
2029 // Legalization would have set us up perfectly for this; we just need to
2030 // set the opcode and move on.
2031 I.setDesc(TII.get(Opc));
2032 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
2033}
2034
Amara Emerson9bf092d2019-04-09 21:22:43 +00002035bool AArch64InstructionSelector::selectVectorICmp(
2036 MachineInstr &I, MachineRegisterInfo &MRI) const {
2037 unsigned DstReg = I.getOperand(0).getReg();
2038 LLT DstTy = MRI.getType(DstReg);
2039 unsigned SrcReg = I.getOperand(2).getReg();
2040 unsigned Src2Reg = I.getOperand(3).getReg();
2041 LLT SrcTy = MRI.getType(SrcReg);
2042
2043 unsigned SrcEltSize = SrcTy.getElementType().getSizeInBits();
2044 unsigned NumElts = DstTy.getNumElements();
2045
2046 // First index is element size, 0 == 8b, 1 == 16b, 2 == 32b, 3 == 64b
2047 // Second index is num elts, 0 == v2, 1 == v4, 2 == v8, 3 == v16
2048 // Third index is cc opcode:
2049 // 0 == eq
2050 // 1 == ugt
2051 // 2 == uge
2052 // 3 == ult
2053 // 4 == ule
2054 // 5 == sgt
2055 // 6 == sge
2056 // 7 == slt
2057 // 8 == sle
2058 // ne is done by negating 'eq' result.
2059
2060 // This table below assumes that for some comparisons the operands will be
2061 // commuted.
2062 // ult op == commute + ugt op
2063 // ule op == commute + uge op
2064 // slt op == commute + sgt op
2065 // sle op == commute + sge op
2066 unsigned PredIdx = 0;
2067 bool SwapOperands = false;
2068 CmpInst::Predicate Pred = (CmpInst::Predicate)I.getOperand(1).getPredicate();
2069 switch (Pred) {
2070 case CmpInst::ICMP_NE:
2071 case CmpInst::ICMP_EQ:
2072 PredIdx = 0;
2073 break;
2074 case CmpInst::ICMP_UGT:
2075 PredIdx = 1;
2076 break;
2077 case CmpInst::ICMP_UGE:
2078 PredIdx = 2;
2079 break;
2080 case CmpInst::ICMP_ULT:
2081 PredIdx = 3;
2082 SwapOperands = true;
2083 break;
2084 case CmpInst::ICMP_ULE:
2085 PredIdx = 4;
2086 SwapOperands = true;
2087 break;
2088 case CmpInst::ICMP_SGT:
2089 PredIdx = 5;
2090 break;
2091 case CmpInst::ICMP_SGE:
2092 PredIdx = 6;
2093 break;
2094 case CmpInst::ICMP_SLT:
2095 PredIdx = 7;
2096 SwapOperands = true;
2097 break;
2098 case CmpInst::ICMP_SLE:
2099 PredIdx = 8;
2100 SwapOperands = true;
2101 break;
2102 default:
2103 llvm_unreachable("Unhandled icmp predicate");
2104 return false;
2105 }
2106
2107 // This table obviously should be tablegen'd when we have our GISel native
2108 // tablegen selector.
2109
2110 static const unsigned OpcTable[4][4][9] = {
2111 {
2112 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2113 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2114 0 /* invalid */},
2115 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2116 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2117 0 /* invalid */},
2118 {AArch64::CMEQv8i8, AArch64::CMHIv8i8, AArch64::CMHSv8i8,
2119 AArch64::CMHIv8i8, AArch64::CMHSv8i8, AArch64::CMGTv8i8,
2120 AArch64::CMGEv8i8, AArch64::CMGTv8i8, AArch64::CMGEv8i8},
2121 {AArch64::CMEQv16i8, AArch64::CMHIv16i8, AArch64::CMHSv16i8,
2122 AArch64::CMHIv16i8, AArch64::CMHSv16i8, AArch64::CMGTv16i8,
2123 AArch64::CMGEv16i8, AArch64::CMGTv16i8, AArch64::CMGEv16i8}
2124 },
2125 {
2126 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2127 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2128 0 /* invalid */},
2129 {AArch64::CMEQv4i16, AArch64::CMHIv4i16, AArch64::CMHSv4i16,
2130 AArch64::CMHIv4i16, AArch64::CMHSv4i16, AArch64::CMGTv4i16,
2131 AArch64::CMGEv4i16, AArch64::CMGTv4i16, AArch64::CMGEv4i16},
2132 {AArch64::CMEQv8i16, AArch64::CMHIv8i16, AArch64::CMHSv8i16,
2133 AArch64::CMHIv8i16, AArch64::CMHSv8i16, AArch64::CMGTv8i16,
2134 AArch64::CMGEv8i16, AArch64::CMGTv8i16, AArch64::CMGEv8i16},
2135 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2136 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2137 0 /* invalid */}
2138 },
2139 {
2140 {AArch64::CMEQv2i32, AArch64::CMHIv2i32, AArch64::CMHSv2i32,
2141 AArch64::CMHIv2i32, AArch64::CMHSv2i32, AArch64::CMGTv2i32,
2142 AArch64::CMGEv2i32, AArch64::CMGTv2i32, AArch64::CMGEv2i32},
2143 {AArch64::CMEQv4i32, AArch64::CMHIv4i32, AArch64::CMHSv4i32,
2144 AArch64::CMHIv4i32, AArch64::CMHSv4i32, AArch64::CMGTv4i32,
2145 AArch64::CMGEv4i32, AArch64::CMGTv4i32, AArch64::CMGEv4i32},
2146 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2147 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2148 0 /* invalid */},
2149 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2150 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2151 0 /* invalid */}
2152 },
2153 {
2154 {AArch64::CMEQv2i64, AArch64::CMHIv2i64, AArch64::CMHSv2i64,
2155 AArch64::CMHIv2i64, AArch64::CMHSv2i64, AArch64::CMGTv2i64,
2156 AArch64::CMGEv2i64, AArch64::CMGTv2i64, AArch64::CMGEv2i64},
2157 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2158 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2159 0 /* invalid */},
2160 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2161 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2162 0 /* invalid */},
2163 {0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2164 0 /* invalid */, 0 /* invalid */, 0 /* invalid */, 0 /* invalid */,
2165 0 /* invalid */}
2166 },
2167 };
2168 unsigned EltIdx = Log2_32(SrcEltSize / 8);
2169 unsigned NumEltsIdx = Log2_32(NumElts / 2);
2170 unsigned Opc = OpcTable[EltIdx][NumEltsIdx][PredIdx];
2171 if (!Opc) {
2172 LLVM_DEBUG(dbgs() << "Could not map G_ICMP to cmp opcode");
2173 return false;
2174 }
2175
2176 const RegisterBank &VecRB = *RBI.getRegBank(SrcReg, MRI, TRI);
2177 const TargetRegisterClass *SrcRC =
2178 getRegClassForTypeOnBank(SrcTy, VecRB, RBI, true);
2179 if (!SrcRC) {
2180 LLVM_DEBUG(dbgs() << "Could not determine source register class.\n");
2181 return false;
2182 }
2183
2184 unsigned NotOpc = Pred == ICmpInst::ICMP_NE ? AArch64::NOTv8i8 : 0;
2185 if (SrcTy.getSizeInBits() == 128)
2186 NotOpc = NotOpc ? AArch64::NOTv16i8 : 0;
2187
2188 if (SwapOperands)
2189 std::swap(SrcReg, Src2Reg);
2190
2191 MachineIRBuilder MIB(I);
2192 auto Cmp = MIB.buildInstr(Opc, {SrcRC}, {SrcReg, Src2Reg});
2193 constrainSelectedInstRegOperands(*Cmp, TII, TRI, RBI);
2194
2195 // Invert if we had a 'ne' cc.
2196 if (NotOpc) {
2197 Cmp = MIB.buildInstr(NotOpc, {DstReg}, {Cmp});
2198 constrainSelectedInstRegOperands(*Cmp, TII, TRI, RBI);
2199 } else {
2200 MIB.buildCopy(DstReg, Cmp.getReg(0));
2201 }
2202 RBI.constrainGenericRegister(DstReg, *SrcRC, MRI);
2203 I.eraseFromParent();
2204 return true;
2205}
2206
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002207MachineInstr *AArch64InstructionSelector::emitScalarToVector(
Amara Emerson8acb0d92019-03-04 19:16:00 +00002208 unsigned EltSize, const TargetRegisterClass *DstRC, unsigned Scalar,
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002209 MachineIRBuilder &MIRBuilder) const {
2210 auto Undef = MIRBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF, {DstRC}, {});
Amara Emerson5ec14602018-12-10 18:44:58 +00002211
2212 auto BuildFn = [&](unsigned SubregIndex) {
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002213 auto Ins =
2214 MIRBuilder
2215 .buildInstr(TargetOpcode::INSERT_SUBREG, {DstRC}, {Undef, Scalar})
2216 .addImm(SubregIndex);
2217 constrainSelectedInstRegOperands(*Undef, TII, TRI, RBI);
2218 constrainSelectedInstRegOperands(*Ins, TII, TRI, RBI);
2219 return &*Ins;
Amara Emerson5ec14602018-12-10 18:44:58 +00002220 };
2221
Amara Emerson8acb0d92019-03-04 19:16:00 +00002222 switch (EltSize) {
Jessica Paquette245047d2019-01-24 22:00:41 +00002223 case 16:
2224 return BuildFn(AArch64::hsub);
Amara Emerson5ec14602018-12-10 18:44:58 +00002225 case 32:
2226 return BuildFn(AArch64::ssub);
2227 case 64:
2228 return BuildFn(AArch64::dsub);
2229 default:
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00002230 return nullptr;
Amara Emerson5ec14602018-12-10 18:44:58 +00002231 }
2232}
2233
Amara Emerson8cb186c2018-12-20 01:11:04 +00002234bool AArch64InstructionSelector::selectMergeValues(
2235 MachineInstr &I, MachineRegisterInfo &MRI) const {
2236 assert(I.getOpcode() == TargetOpcode::G_MERGE_VALUES && "unexpected opcode");
2237 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2238 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
2239 assert(!DstTy.isVector() && !SrcTy.isVector() && "invalid merge operation");
2240
2241 // At the moment we only support merging two s32s into an s64.
2242 if (I.getNumOperands() != 3)
2243 return false;
2244 if (DstTy.getSizeInBits() != 64 || SrcTy.getSizeInBits() != 32)
2245 return false;
2246 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
2247 if (RB.getID() != AArch64::GPRRegBankID)
2248 return false;
2249
2250 auto *DstRC = &AArch64::GPR64RegClass;
2251 unsigned SubToRegDef = MRI.createVirtualRegister(DstRC);
2252 MachineInstr &SubRegMI = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
2253 TII.get(TargetOpcode::SUBREG_TO_REG))
2254 .addDef(SubToRegDef)
2255 .addImm(0)
2256 .addUse(I.getOperand(1).getReg())
2257 .addImm(AArch64::sub_32);
2258 unsigned SubToRegDef2 = MRI.createVirtualRegister(DstRC);
2259 // Need to anyext the second scalar before we can use bfm
2260 MachineInstr &SubRegMI2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
2261 TII.get(TargetOpcode::SUBREG_TO_REG))
2262 .addDef(SubToRegDef2)
2263 .addImm(0)
2264 .addUse(I.getOperand(2).getReg())
2265 .addImm(AArch64::sub_32);
Amara Emerson8cb186c2018-12-20 01:11:04 +00002266 MachineInstr &BFM =
2267 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::BFMXri))
Amara Emerson321bfb22018-12-20 03:27:42 +00002268 .addDef(I.getOperand(0).getReg())
Amara Emerson8cb186c2018-12-20 01:11:04 +00002269 .addUse(SubToRegDef)
2270 .addUse(SubToRegDef2)
2271 .addImm(32)
2272 .addImm(31);
2273 constrainSelectedInstRegOperands(SubRegMI, TII, TRI, RBI);
2274 constrainSelectedInstRegOperands(SubRegMI2, TII, TRI, RBI);
2275 constrainSelectedInstRegOperands(BFM, TII, TRI, RBI);
2276 I.eraseFromParent();
2277 return true;
2278}
2279
Jessica Paquette607774c2019-03-11 22:18:01 +00002280static bool getLaneCopyOpcode(unsigned &CopyOpc, unsigned &ExtractSubReg,
2281 const unsigned EltSize) {
2282 // Choose a lane copy opcode and subregister based off of the size of the
2283 // vector's elements.
2284 switch (EltSize) {
2285 case 16:
2286 CopyOpc = AArch64::CPYi16;
2287 ExtractSubReg = AArch64::hsub;
2288 break;
2289 case 32:
2290 CopyOpc = AArch64::CPYi32;
2291 ExtractSubReg = AArch64::ssub;
2292 break;
2293 case 64:
2294 CopyOpc = AArch64::CPYi64;
2295 ExtractSubReg = AArch64::dsub;
2296 break;
2297 default:
2298 // Unknown size, bail out.
2299 LLVM_DEBUG(dbgs() << "Elt size '" << EltSize << "' unsupported.\n");
2300 return false;
2301 }
2302 return true;
2303}
2304
Amara Emersond61b89b2019-03-14 22:48:18 +00002305MachineInstr *AArch64InstructionSelector::emitExtractVectorElt(
2306 Optional<unsigned> DstReg, const RegisterBank &DstRB, LLT ScalarTy,
2307 unsigned VecReg, unsigned LaneIdx, MachineIRBuilder &MIRBuilder) const {
2308 MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
2309 unsigned CopyOpc = 0;
2310 unsigned ExtractSubReg = 0;
2311 if (!getLaneCopyOpcode(CopyOpc, ExtractSubReg, ScalarTy.getSizeInBits())) {
2312 LLVM_DEBUG(
2313 dbgs() << "Couldn't determine lane copy opcode for instruction.\n");
2314 return nullptr;
2315 }
2316
2317 const TargetRegisterClass *DstRC =
2318 getRegClassForTypeOnBank(ScalarTy, DstRB, RBI, true);
2319 if (!DstRC) {
2320 LLVM_DEBUG(dbgs() << "Could not determine destination register class.\n");
2321 return nullptr;
2322 }
2323
2324 const RegisterBank &VecRB = *RBI.getRegBank(VecReg, MRI, TRI);
2325 const LLT &VecTy = MRI.getType(VecReg);
2326 const TargetRegisterClass *VecRC =
2327 getRegClassForTypeOnBank(VecTy, VecRB, RBI, true);
2328 if (!VecRC) {
2329 LLVM_DEBUG(dbgs() << "Could not determine source register class.\n");
2330 return nullptr;
2331 }
2332
2333 // The register that we're going to copy into.
2334 unsigned InsertReg = VecReg;
2335 if (!DstReg)
2336 DstReg = MRI.createVirtualRegister(DstRC);
2337 // If the lane index is 0, we just use a subregister COPY.
2338 if (LaneIdx == 0) {
Amara Emerson86271782019-03-18 19:20:10 +00002339 auto Copy = MIRBuilder.buildInstr(TargetOpcode::COPY, {*DstReg}, {})
2340 .addReg(VecReg, 0, ExtractSubReg);
Amara Emersond61b89b2019-03-14 22:48:18 +00002341 RBI.constrainGenericRegister(*DstReg, *DstRC, MRI);
Amara Emerson3739a202019-03-15 21:59:50 +00002342 return &*Copy;
Amara Emersond61b89b2019-03-14 22:48:18 +00002343 }
2344
2345 // Lane copies require 128-bit wide registers. If we're dealing with an
2346 // unpacked vector, then we need to move up to that width. Insert an implicit
2347 // def and a subregister insert to get us there.
2348 if (VecTy.getSizeInBits() != 128) {
2349 MachineInstr *ScalarToVector = emitScalarToVector(
2350 VecTy.getSizeInBits(), &AArch64::FPR128RegClass, VecReg, MIRBuilder);
2351 if (!ScalarToVector)
2352 return nullptr;
2353 InsertReg = ScalarToVector->getOperand(0).getReg();
2354 }
2355
2356 MachineInstr *LaneCopyMI =
2357 MIRBuilder.buildInstr(CopyOpc, {*DstReg}, {InsertReg}).addImm(LaneIdx);
2358 constrainSelectedInstRegOperands(*LaneCopyMI, TII, TRI, RBI);
2359
2360 // Make sure that we actually constrain the initial copy.
2361 RBI.constrainGenericRegister(*DstReg, *DstRC, MRI);
2362 return LaneCopyMI;
2363}
2364
Jessica Paquette607774c2019-03-11 22:18:01 +00002365bool AArch64InstructionSelector::selectExtractElt(
2366 MachineInstr &I, MachineRegisterInfo &MRI) const {
2367 assert(I.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT &&
2368 "unexpected opcode!");
2369 unsigned DstReg = I.getOperand(0).getReg();
2370 const LLT NarrowTy = MRI.getType(DstReg);
2371 const unsigned SrcReg = I.getOperand(1).getReg();
2372 const LLT WideTy = MRI.getType(SrcReg);
Amara Emersond61b89b2019-03-14 22:48:18 +00002373 (void)WideTy;
Jessica Paquette607774c2019-03-11 22:18:01 +00002374 assert(WideTy.getSizeInBits() >= NarrowTy.getSizeInBits() &&
2375 "source register size too small!");
2376 assert(NarrowTy.isScalar() && "cannot extract vector into vector!");
2377
2378 // Need the lane index to determine the correct copy opcode.
2379 MachineOperand &LaneIdxOp = I.getOperand(2);
2380 assert(LaneIdxOp.isReg() && "Lane index operand was not a register?");
2381
2382 if (RBI.getRegBank(DstReg, MRI, TRI)->getID() != AArch64::FPRRegBankID) {
2383 LLVM_DEBUG(dbgs() << "Cannot extract into GPR.\n");
2384 return false;
2385 }
2386
Jessica Paquettebb1aced2019-03-13 21:19:29 +00002387 // Find the index to extract from.
Jessica Paquette76f64b62019-04-26 21:53:13 +00002388 auto VRegAndVal = getConstantVRegValWithLookThrough(LaneIdxOp.getReg(), MRI);
2389 if (!VRegAndVal)
Jessica Paquette607774c2019-03-11 22:18:01 +00002390 return false;
Jessica Paquette76f64b62019-04-26 21:53:13 +00002391 unsigned LaneIdx = VRegAndVal->Value;
Jessica Paquette607774c2019-03-11 22:18:01 +00002392
Jessica Paquette607774c2019-03-11 22:18:01 +00002393 MachineIRBuilder MIRBuilder(I);
2394
Amara Emersond61b89b2019-03-14 22:48:18 +00002395 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
2396 MachineInstr *Extract = emitExtractVectorElt(DstReg, DstRB, NarrowTy, SrcReg,
2397 LaneIdx, MIRBuilder);
2398 if (!Extract)
2399 return false;
2400
2401 I.eraseFromParent();
2402 return true;
2403}
2404
2405bool AArch64InstructionSelector::selectSplitVectorUnmerge(
2406 MachineInstr &I, MachineRegisterInfo &MRI) const {
2407 unsigned NumElts = I.getNumOperands() - 1;
2408 unsigned SrcReg = I.getOperand(NumElts).getReg();
2409 const LLT NarrowTy = MRI.getType(I.getOperand(0).getReg());
2410 const LLT SrcTy = MRI.getType(SrcReg);
2411
2412 assert(NarrowTy.isVector() && "Expected an unmerge into vectors");
2413 if (SrcTy.getSizeInBits() > 128) {
2414 LLVM_DEBUG(dbgs() << "Unexpected vector type for vec split unmerge");
2415 return false;
Jessica Paquette607774c2019-03-11 22:18:01 +00002416 }
2417
Amara Emersond61b89b2019-03-14 22:48:18 +00002418 MachineIRBuilder MIB(I);
2419
2420 // We implement a split vector operation by treating the sub-vectors as
2421 // scalars and extracting them.
2422 const RegisterBank &DstRB =
2423 *RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI);
2424 for (unsigned OpIdx = 0; OpIdx < NumElts; ++OpIdx) {
2425 unsigned Dst = I.getOperand(OpIdx).getReg();
2426 MachineInstr *Extract =
2427 emitExtractVectorElt(Dst, DstRB, NarrowTy, SrcReg, OpIdx, MIB);
2428 if (!Extract)
Jessica Paquette607774c2019-03-11 22:18:01 +00002429 return false;
Jessica Paquette607774c2019-03-11 22:18:01 +00002430 }
Jessica Paquette607774c2019-03-11 22:18:01 +00002431 I.eraseFromParent();
2432 return true;
2433}
2434
Jessica Paquette245047d2019-01-24 22:00:41 +00002435bool AArch64InstructionSelector::selectUnmergeValues(
2436 MachineInstr &I, MachineRegisterInfo &MRI) const {
2437 assert(I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
2438 "unexpected opcode");
2439
2440 // TODO: Handle unmerging into GPRs and from scalars to scalars.
2441 if (RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI)->getID() !=
2442 AArch64::FPRRegBankID ||
2443 RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI)->getID() !=
2444 AArch64::FPRRegBankID) {
2445 LLVM_DEBUG(dbgs() << "Unmerging vector-to-gpr and scalar-to-scalar "
2446 "currently unsupported.\n");
2447 return false;
2448 }
2449
2450 // The last operand is the vector source register, and every other operand is
2451 // a register to unpack into.
2452 unsigned NumElts = I.getNumOperands() - 1;
2453 unsigned SrcReg = I.getOperand(NumElts).getReg();
2454 const LLT NarrowTy = MRI.getType(I.getOperand(0).getReg());
2455 const LLT WideTy = MRI.getType(SrcReg);
Benjamin Kramer653020d2019-01-24 23:45:07 +00002456 (void)WideTy;
Jessica Paquette245047d2019-01-24 22:00:41 +00002457 assert(WideTy.isVector() && "can only unmerge from vector types!");
2458 assert(WideTy.getSizeInBits() > NarrowTy.getSizeInBits() &&
2459 "source register size too small!");
2460
Amara Emersond61b89b2019-03-14 22:48:18 +00002461 if (!NarrowTy.isScalar())
2462 return selectSplitVectorUnmerge(I, MRI);
Jessica Paquette245047d2019-01-24 22:00:41 +00002463
Amara Emerson3739a202019-03-15 21:59:50 +00002464 MachineIRBuilder MIB(I);
2465
Jessica Paquette245047d2019-01-24 22:00:41 +00002466 // Choose a lane copy opcode and subregister based off of the size of the
2467 // vector's elements.
2468 unsigned CopyOpc = 0;
2469 unsigned ExtractSubReg = 0;
Jessica Paquette607774c2019-03-11 22:18:01 +00002470 if (!getLaneCopyOpcode(CopyOpc, ExtractSubReg, NarrowTy.getSizeInBits()))
Jessica Paquette245047d2019-01-24 22:00:41 +00002471 return false;
Jessica Paquette245047d2019-01-24 22:00:41 +00002472
2473 // Set up for the lane copies.
2474 MachineBasicBlock &MBB = *I.getParent();
2475
2476 // Stores the registers we'll be copying from.
2477 SmallVector<unsigned, 4> InsertRegs;
2478
2479 // We'll use the first register twice, so we only need NumElts-1 registers.
2480 unsigned NumInsertRegs = NumElts - 1;
2481
2482 // If our elements fit into exactly 128 bits, then we can copy from the source
2483 // directly. Otherwise, we need to do a bit of setup with some subregister
2484 // inserts.
2485 if (NarrowTy.getSizeInBits() * NumElts == 128) {
2486 InsertRegs = SmallVector<unsigned, 4>(NumInsertRegs, SrcReg);
2487 } else {
2488 // No. We have to perform subregister inserts. For each insert, create an
2489 // implicit def and a subregister insert, and save the register we create.
2490 for (unsigned Idx = 0; Idx < NumInsertRegs; ++Idx) {
2491 unsigned ImpDefReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
2492 MachineInstr &ImpDefMI =
2493 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
2494 ImpDefReg);
2495
2496 // Now, create the subregister insert from SrcReg.
2497 unsigned InsertReg = MRI.createVirtualRegister(&AArch64::FPR128RegClass);
2498 MachineInstr &InsMI =
2499 *BuildMI(MBB, I, I.getDebugLoc(),
2500 TII.get(TargetOpcode::INSERT_SUBREG), InsertReg)
2501 .addUse(ImpDefReg)
2502 .addUse(SrcReg)
2503 .addImm(AArch64::dsub);
2504
2505 constrainSelectedInstRegOperands(ImpDefMI, TII, TRI, RBI);
2506 constrainSelectedInstRegOperands(InsMI, TII, TRI, RBI);
2507
2508 // Save the register so that we can copy from it after.
2509 InsertRegs.push_back(InsertReg);
2510 }
2511 }
2512
2513 // Now that we've created any necessary subregister inserts, we can
2514 // create the copies.
2515 //
2516 // Perform the first copy separately as a subregister copy.
2517 unsigned CopyTo = I.getOperand(0).getReg();
Amara Emerson86271782019-03-18 19:20:10 +00002518 auto FirstCopy = MIB.buildInstr(TargetOpcode::COPY, {CopyTo}, {})
2519 .addReg(InsertRegs[0], 0, ExtractSubReg);
Amara Emerson3739a202019-03-15 21:59:50 +00002520 constrainSelectedInstRegOperands(*FirstCopy, TII, TRI, RBI);
Jessica Paquette245047d2019-01-24 22:00:41 +00002521
2522 // Now, perform the remaining copies as vector lane copies.
2523 unsigned LaneIdx = 1;
2524 for (unsigned InsReg : InsertRegs) {
2525 unsigned CopyTo = I.getOperand(LaneIdx).getReg();
2526 MachineInstr &CopyInst =
2527 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CopyOpc), CopyTo)
2528 .addUse(InsReg)
2529 .addImm(LaneIdx);
2530 constrainSelectedInstRegOperands(CopyInst, TII, TRI, RBI);
2531 ++LaneIdx;
2532 }
2533
2534 // Separately constrain the first copy's destination. Because of the
2535 // limitation in constrainOperandRegClass, we can't guarantee that this will
2536 // actually be constrained. So, do it ourselves using the second operand.
2537 const TargetRegisterClass *RC =
2538 MRI.getRegClassOrNull(I.getOperand(1).getReg());
2539 if (!RC) {
2540 LLVM_DEBUG(dbgs() << "Couldn't constrain copy destination.\n");
2541 return false;
2542 }
2543
2544 RBI.constrainGenericRegister(CopyTo, *RC, MRI);
2545 I.eraseFromParent();
2546 return true;
2547}
2548
Amara Emerson2ff22982019-03-14 22:48:15 +00002549bool AArch64InstructionSelector::selectConcatVectors(
2550 MachineInstr &I, MachineRegisterInfo &MRI) const {
2551 assert(I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS &&
2552 "Unexpected opcode");
2553 unsigned Dst = I.getOperand(0).getReg();
2554 unsigned Op1 = I.getOperand(1).getReg();
2555 unsigned Op2 = I.getOperand(2).getReg();
2556 MachineIRBuilder MIRBuilder(I);
2557 MachineInstr *ConcatMI = emitVectorConcat(Dst, Op1, Op2, MIRBuilder);
2558 if (!ConcatMI)
2559 return false;
2560 I.eraseFromParent();
2561 return true;
2562}
2563
Amara Emerson1abe05c2019-02-21 20:20:16 +00002564void AArch64InstructionSelector::collectShuffleMaskIndices(
2565 MachineInstr &I, MachineRegisterInfo &MRI,
Amara Emerson2806fd02019-04-12 21:31:21 +00002566 SmallVectorImpl<Optional<int>> &Idxs) const {
Amara Emerson1abe05c2019-02-21 20:20:16 +00002567 MachineInstr *MaskDef = MRI.getVRegDef(I.getOperand(3).getReg());
2568 assert(
2569 MaskDef->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&
2570 "G_SHUFFLE_VECTOR should have a constant mask operand as G_BUILD_VECTOR");
2571 // Find the constant indices.
2572 for (unsigned i = 1, e = MaskDef->getNumOperands(); i < e; ++i) {
2573 MachineInstr *ScalarDef = MRI.getVRegDef(MaskDef->getOperand(i).getReg());
2574 assert(ScalarDef && "Could not find vreg def of shufflevec index op");
2575 // Look through copies.
2576 while (ScalarDef->getOpcode() == TargetOpcode::COPY) {
2577 ScalarDef = MRI.getVRegDef(ScalarDef->getOperand(1).getReg());
2578 assert(ScalarDef && "Could not find def of copy operand");
2579 }
Amara Emerson2806fd02019-04-12 21:31:21 +00002580 if (ScalarDef->getOpcode() != TargetOpcode::G_CONSTANT) {
2581 // This be an undef if not a constant.
2582 assert(ScalarDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
2583 Idxs.push_back(None);
2584 } else {
2585 Idxs.push_back(ScalarDef->getOperand(1).getCImm()->getSExtValue());
2586 }
Amara Emerson1abe05c2019-02-21 20:20:16 +00002587 }
2588}
2589
2590unsigned
2591AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
2592 MachineFunction &MF) const {
Hans Wennborg5d5ee4a2019-04-26 08:31:00 +00002593 Type *CPTy = CPVal->getType();
Amara Emerson1abe05c2019-02-21 20:20:16 +00002594 unsigned Align = MF.getDataLayout().getPrefTypeAlignment(CPTy);
2595 if (Align == 0)
2596 Align = MF.getDataLayout().getTypeAllocSize(CPTy);
2597
2598 MachineConstantPool *MCP = MF.getConstantPool();
2599 return MCP->getConstantPoolIndex(CPVal, Align);
2600}
2601
2602MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
2603 Constant *CPVal, MachineIRBuilder &MIRBuilder) const {
2604 unsigned CPIdx = emitConstantPoolEntry(CPVal, MIRBuilder.getMF());
2605
2606 auto Adrp =
2607 MIRBuilder.buildInstr(AArch64::ADRP, {&AArch64::GPR64RegClass}, {})
2608 .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002609
2610 MachineInstr *LoadMI = nullptr;
2611 switch (MIRBuilder.getDataLayout().getTypeStoreSize(CPVal->getType())) {
2612 case 16:
2613 LoadMI =
2614 &*MIRBuilder
2615 .buildInstr(AArch64::LDRQui, {&AArch64::FPR128RegClass}, {Adrp})
2616 .addConstantPoolIndex(CPIdx, 0,
2617 AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2618 break;
2619 case 8:
2620 LoadMI = &*MIRBuilder
2621 .buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp})
2622 .addConstantPoolIndex(
2623 CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2624 break;
2625 default:
2626 LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
2627 << *CPVal->getType());
2628 return nullptr;
2629 }
Amara Emerson1abe05c2019-02-21 20:20:16 +00002630 constrainSelectedInstRegOperands(*Adrp, TII, TRI, RBI);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002631 constrainSelectedInstRegOperands(*LoadMI, TII, TRI, RBI);
2632 return LoadMI;
2633}
2634
2635/// Return an <Opcode, SubregIndex> pair to do an vector elt insert of a given
2636/// size and RB.
2637static std::pair<unsigned, unsigned>
2638getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
2639 unsigned Opc, SubregIdx;
2640 if (RB.getID() == AArch64::GPRRegBankID) {
2641 if (EltSize == 32) {
2642 Opc = AArch64::INSvi32gpr;
2643 SubregIdx = AArch64::ssub;
2644 } else if (EltSize == 64) {
2645 Opc = AArch64::INSvi64gpr;
2646 SubregIdx = AArch64::dsub;
2647 } else {
2648 llvm_unreachable("invalid elt size!");
2649 }
2650 } else {
2651 if (EltSize == 8) {
2652 Opc = AArch64::INSvi8lane;
2653 SubregIdx = AArch64::bsub;
2654 } else if (EltSize == 16) {
2655 Opc = AArch64::INSvi16lane;
2656 SubregIdx = AArch64::hsub;
2657 } else if (EltSize == 32) {
2658 Opc = AArch64::INSvi32lane;
2659 SubregIdx = AArch64::ssub;
2660 } else if (EltSize == 64) {
2661 Opc = AArch64::INSvi64lane;
2662 SubregIdx = AArch64::dsub;
2663 } else {
2664 llvm_unreachable("invalid elt size!");
2665 }
2666 }
2667 return std::make_pair(Opc, SubregIdx);
2668}
2669
2670MachineInstr *AArch64InstructionSelector::emitVectorConcat(
Amara Emerson2ff22982019-03-14 22:48:15 +00002671 Optional<unsigned> Dst, unsigned Op1, unsigned Op2,
2672 MachineIRBuilder &MIRBuilder) const {
Amara Emerson8acb0d92019-03-04 19:16:00 +00002673 // We implement a vector concat by:
2674 // 1. Use scalar_to_vector to insert the lower vector into the larger dest
2675 // 2. Insert the upper vector into the destination's upper element
2676 // TODO: some of this code is common with G_BUILD_VECTOR handling.
2677 MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
2678
2679 const LLT Op1Ty = MRI.getType(Op1);
2680 const LLT Op2Ty = MRI.getType(Op2);
2681
2682 if (Op1Ty != Op2Ty) {
2683 LLVM_DEBUG(dbgs() << "Could not do vector concat of differing vector tys");
2684 return nullptr;
2685 }
2686 assert(Op1Ty.isVector() && "Expected a vector for vector concat");
2687
2688 if (Op1Ty.getSizeInBits() >= 128) {
2689 LLVM_DEBUG(dbgs() << "Vector concat not supported for full size vectors");
2690 return nullptr;
2691 }
2692
2693 // At the moment we just support 64 bit vector concats.
2694 if (Op1Ty.getSizeInBits() != 64) {
2695 LLVM_DEBUG(dbgs() << "Vector concat supported for 64b vectors");
2696 return nullptr;
2697 }
2698
2699 const LLT ScalarTy = LLT::scalar(Op1Ty.getSizeInBits());
2700 const RegisterBank &FPRBank = *RBI.getRegBank(Op1, MRI, TRI);
2701 const TargetRegisterClass *DstRC =
2702 getMinClassForRegBank(FPRBank, Op1Ty.getSizeInBits() * 2);
2703
2704 MachineInstr *WidenedOp1 =
2705 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op1, MIRBuilder);
2706 MachineInstr *WidenedOp2 =
2707 emitScalarToVector(ScalarTy.getSizeInBits(), DstRC, Op2, MIRBuilder);
2708 if (!WidenedOp1 || !WidenedOp2) {
2709 LLVM_DEBUG(dbgs() << "Could not emit a vector from scalar value");
2710 return nullptr;
2711 }
2712
2713 // Now do the insert of the upper element.
2714 unsigned InsertOpc, InsSubRegIdx;
2715 std::tie(InsertOpc, InsSubRegIdx) =
2716 getInsertVecEltOpInfo(FPRBank, ScalarTy.getSizeInBits());
2717
Amara Emerson2ff22982019-03-14 22:48:15 +00002718 if (!Dst)
2719 Dst = MRI.createVirtualRegister(DstRC);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002720 auto InsElt =
2721 MIRBuilder
Amara Emerson2ff22982019-03-14 22:48:15 +00002722 .buildInstr(InsertOpc, {*Dst}, {WidenedOp1->getOperand(0).getReg()})
Amara Emerson8acb0d92019-03-04 19:16:00 +00002723 .addImm(1) /* Lane index */
2724 .addUse(WidenedOp2->getOperand(0).getReg())
2725 .addImm(0);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002726 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2727 return &*InsElt;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002728}
2729
Jessica Paquettea3843fe2019-05-01 22:39:43 +00002730MachineInstr *AArch64InstructionSelector::emitFMovForFConstant(
2731 MachineInstr &I, MachineRegisterInfo &MRI) const {
2732 assert(I.getOpcode() == TargetOpcode::G_FCONSTANT &&
2733 "Expected a G_FCONSTANT!");
2734 MachineOperand &ImmOp = I.getOperand(1);
2735 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
2736
2737 // Only handle 32 and 64 bit defs for now.
2738 if (DefSize != 32 && DefSize != 64)
2739 return nullptr;
2740
2741 // Don't handle null values using FMOV.
2742 if (ImmOp.getFPImm()->isNullValue())
2743 return nullptr;
2744
2745 // Get the immediate representation for the FMOV.
2746 const APFloat &ImmValAPF = ImmOp.getFPImm()->getValueAPF();
2747 int Imm = DefSize == 32 ? AArch64_AM::getFP32Imm(ImmValAPF)
2748 : AArch64_AM::getFP64Imm(ImmValAPF);
2749
2750 // If this is -1, it means the immediate can't be represented as the requested
2751 // floating point value. Bail.
2752 if (Imm == -1)
2753 return nullptr;
2754
2755 // Update MI to represent the new FMOV instruction, constrain it, and return.
2756 ImmOp.ChangeToImmediate(Imm);
2757 unsigned MovOpc = DefSize == 32 ? AArch64::FMOVSi : AArch64::FMOVDi;
2758 I.setDesc(TII.get(MovOpc));
2759 constrainSelectedInstRegOperands(I, TII, TRI, RBI);
2760 return &I;
2761}
2762
Amara Emerson761ca2e2019-03-19 21:43:05 +00002763bool AArch64InstructionSelector::tryOptVectorDup(MachineInstr &I) const {
2764 // Try to match a vector splat operation into a dup instruction.
2765 // We're looking for this pattern:
2766 // %scalar:gpr(s64) = COPY $x0
2767 // %undef:fpr(<2 x s64>) = G_IMPLICIT_DEF
2768 // %cst0:gpr(s32) = G_CONSTANT i32 0
2769 // %zerovec:fpr(<2 x s32>) = G_BUILD_VECTOR %cst0(s32), %cst0(s32)
2770 // %ins:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %undef, %scalar(s64), %cst0(s32)
2771 // %splat:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %ins(<2 x s64>), %undef,
2772 // %zerovec(<2 x s32>)
2773 //
2774 // ...into:
2775 // %splat = DUP %scalar
2776 // We use the regbank of the scalar to determine which kind of dup to use.
2777 MachineIRBuilder MIB(I);
2778 MachineRegisterInfo &MRI = *MIB.getMRI();
2779 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
2780 using namespace TargetOpcode;
2781 using namespace MIPatternMatch;
2782
2783 // Begin matching the insert.
2784 auto *InsMI =
2785 findMIFromReg(I.getOperand(1).getReg(), G_INSERT_VECTOR_ELT, MIB);
2786 if (!InsMI)
2787 return false;
2788 // Match the undef vector operand.
2789 auto *UndefMI =
2790 findMIFromReg(InsMI->getOperand(1).getReg(), G_IMPLICIT_DEF, MIB);
2791 if (!UndefMI)
2792 return false;
2793 // Match the scalar being splatted.
2794 unsigned ScalarReg = InsMI->getOperand(2).getReg();
2795 const RegisterBank *ScalarRB = RBI.getRegBank(ScalarReg, MRI, TRI);
2796 // Match the index constant 0.
2797 int64_t Index = 0;
2798 if (!mi_match(InsMI->getOperand(3).getReg(), MRI, m_ICst(Index)) || Index)
2799 return false;
2800
2801 // The shuffle's second operand doesn't matter if the mask is all zero.
2802 auto *ZeroVec = findMIFromReg(I.getOperand(3).getReg(), G_BUILD_VECTOR, MIB);
2803 if (!ZeroVec)
2804 return false;
2805 int64_t Zero = 0;
2806 if (!mi_match(ZeroVec->getOperand(1).getReg(), MRI, m_ICst(Zero)) || Zero)
2807 return false;
2808 for (unsigned i = 1, e = ZeroVec->getNumOperands() - 1; i < e; ++i) {
2809 if (ZeroVec->getOperand(i).getReg() != ZeroVec->getOperand(1).getReg())
2810 return false; // This wasn't an all zeros vector.
2811 }
2812
2813 // We're done, now find out what kind of splat we need.
2814 LLT VecTy = MRI.getType(I.getOperand(0).getReg());
2815 LLT EltTy = VecTy.getElementType();
2816 if (VecTy.getSizeInBits() != 128 || EltTy.getSizeInBits() < 32) {
2817 LLVM_DEBUG(dbgs() << "Could not optimize splat pattern < 128b yet");
2818 return false;
2819 }
2820 bool IsFP = ScalarRB->getID() == AArch64::FPRRegBankID;
2821 static const unsigned OpcTable[2][2] = {
2822 {AArch64::DUPv4i32gpr, AArch64::DUPv2i64gpr},
2823 {AArch64::DUPv4i32lane, AArch64::DUPv2i64lane}};
2824 unsigned Opc = OpcTable[IsFP][EltTy.getSizeInBits() == 64];
2825
2826 // For FP splats, we need to widen the scalar reg via undef too.
2827 if (IsFP) {
2828 MachineInstr *Widen = emitScalarToVector(
2829 EltTy.getSizeInBits(), &AArch64::FPR128RegClass, ScalarReg, MIB);
2830 if (!Widen)
2831 return false;
2832 ScalarReg = Widen->getOperand(0).getReg();
2833 }
2834 auto Dup = MIB.buildInstr(Opc, {I.getOperand(0).getReg()}, {ScalarReg});
2835 if (IsFP)
2836 Dup.addImm(0);
2837 constrainSelectedInstRegOperands(*Dup, TII, TRI, RBI);
2838 I.eraseFromParent();
2839 return true;
2840}
2841
2842bool AArch64InstructionSelector::tryOptVectorShuffle(MachineInstr &I) const {
2843 if (TM.getOptLevel() == CodeGenOpt::None)
2844 return false;
2845 if (tryOptVectorDup(I))
2846 return true;
2847 return false;
2848}
2849
Amara Emerson1abe05c2019-02-21 20:20:16 +00002850bool AArch64InstructionSelector::selectShuffleVector(
2851 MachineInstr &I, MachineRegisterInfo &MRI) const {
Amara Emerson761ca2e2019-03-19 21:43:05 +00002852 if (tryOptVectorShuffle(I))
2853 return true;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002854 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
2855 unsigned Src1Reg = I.getOperand(1).getReg();
2856 const LLT Src1Ty = MRI.getType(Src1Reg);
2857 unsigned Src2Reg = I.getOperand(2).getReg();
2858 const LLT Src2Ty = MRI.getType(Src2Reg);
2859
2860 MachineBasicBlock &MBB = *I.getParent();
2861 MachineFunction &MF = *MBB.getParent();
2862 LLVMContext &Ctx = MF.getFunction().getContext();
2863
2864 // G_SHUFFLE_VECTOR doesn't really have a strictly enforced constant mask
2865 // operand, it comes in as a normal vector value which we have to analyze to
Amara Emerson2806fd02019-04-12 21:31:21 +00002866 // find the mask indices. If the mask element is undef, then
2867 // collectShuffleMaskIndices() will add a None entry for that index into
2868 // the list.
2869 SmallVector<Optional<int>, 8> Mask;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002870 collectShuffleMaskIndices(I, MRI, Mask);
2871 assert(!Mask.empty() && "Expected to find mask indices");
2872
2873 // G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
2874 // it's originated from a <1 x T> type. Those should have been lowered into
2875 // G_BUILD_VECTOR earlier.
2876 if (!Src1Ty.isVector() || !Src2Ty.isVector()) {
2877 LLVM_DEBUG(dbgs() << "Could not select a \"scalar\" G_SHUFFLE_VECTOR\n");
2878 return false;
2879 }
2880
2881 unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
2882
2883 SmallVector<Constant *, 64> CstIdxs;
Amara Emerson2806fd02019-04-12 21:31:21 +00002884 for (auto &MaybeVal : Mask) {
2885 // For now, any undef indexes we'll just assume to be 0. This should be
2886 // optimized in future, e.g. to select DUP etc.
2887 int Val = MaybeVal.hasValue() ? *MaybeVal : 0;
Amara Emerson1abe05c2019-02-21 20:20:16 +00002888 for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
2889 unsigned Offset = Byte + Val * BytesPerElt;
2890 CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));
2891 }
2892 }
2893
Amara Emerson8acb0d92019-03-04 19:16:00 +00002894 MachineIRBuilder MIRBuilder(I);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002895
2896 // Use a constant pool to load the index vector for TBL.
2897 Constant *CPVal = ConstantVector::get(CstIdxs);
Amara Emerson1abe05c2019-02-21 20:20:16 +00002898 MachineInstr *IndexLoad = emitLoadFromConstantPool(CPVal, MIRBuilder);
2899 if (!IndexLoad) {
2900 LLVM_DEBUG(dbgs() << "Could not load from a constant pool");
2901 return false;
2902 }
2903
Amara Emerson8acb0d92019-03-04 19:16:00 +00002904 if (DstTy.getSizeInBits() != 128) {
2905 assert(DstTy.getSizeInBits() == 64 && "Unexpected shuffle result ty");
2906 // This case can be done with TBL1.
Amara Emerson2ff22982019-03-14 22:48:15 +00002907 MachineInstr *Concat = emitVectorConcat(None, Src1Reg, Src2Reg, MIRBuilder);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002908 if (!Concat) {
2909 LLVM_DEBUG(dbgs() << "Could not do vector concat for tbl1");
2910 return false;
2911 }
2912
2913 // The constant pool load will be 64 bits, so need to convert to FPR128 reg.
2914 IndexLoad =
2915 emitScalarToVector(64, &AArch64::FPR128RegClass,
2916 IndexLoad->getOperand(0).getReg(), MIRBuilder);
2917
2918 auto TBL1 = MIRBuilder.buildInstr(
2919 AArch64::TBLv16i8One, {&AArch64::FPR128RegClass},
2920 {Concat->getOperand(0).getReg(), IndexLoad->getOperand(0).getReg()});
2921 constrainSelectedInstRegOperands(*TBL1, TII, TRI, RBI);
2922
Amara Emerson3739a202019-03-15 21:59:50 +00002923 auto Copy =
Amara Emerson86271782019-03-18 19:20:10 +00002924 MIRBuilder
2925 .buildInstr(TargetOpcode::COPY, {I.getOperand(0).getReg()}, {})
2926 .addReg(TBL1.getReg(0), 0, AArch64::dsub);
Amara Emerson8acb0d92019-03-04 19:16:00 +00002927 RBI.constrainGenericRegister(Copy.getReg(0), AArch64::FPR64RegClass, MRI);
2928 I.eraseFromParent();
2929 return true;
2930 }
2931
Amara Emerson1abe05c2019-02-21 20:20:16 +00002932 // For TBL2 we need to emit a REG_SEQUENCE to tie together two consecutive
2933 // Q registers for regalloc.
2934 auto RegSeq = MIRBuilder
2935 .buildInstr(TargetOpcode::REG_SEQUENCE,
2936 {&AArch64::QQRegClass}, {Src1Reg})
2937 .addImm(AArch64::qsub0)
2938 .addUse(Src2Reg)
2939 .addImm(AArch64::qsub1);
2940
2941 auto TBL2 =
2942 MIRBuilder.buildInstr(AArch64::TBLv16i8Two, {I.getOperand(0).getReg()},
2943 {RegSeq, IndexLoad->getOperand(0).getReg()});
2944 constrainSelectedInstRegOperands(*RegSeq, TII, TRI, RBI);
2945 constrainSelectedInstRegOperands(*TBL2, TII, TRI, RBI);
2946 I.eraseFromParent();
2947 return true;
2948}
2949
Jessica Paquette16d67a32019-03-13 23:22:23 +00002950MachineInstr *AArch64InstructionSelector::emitLaneInsert(
2951 Optional<unsigned> DstReg, unsigned SrcReg, unsigned EltReg,
2952 unsigned LaneIdx, const RegisterBank &RB,
2953 MachineIRBuilder &MIRBuilder) const {
2954 MachineInstr *InsElt = nullptr;
2955 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
2956 MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
2957
2958 // Create a register to define with the insert if one wasn't passed in.
2959 if (!DstReg)
2960 DstReg = MRI.createVirtualRegister(DstRC);
2961
2962 unsigned EltSize = MRI.getType(EltReg).getSizeInBits();
2963 unsigned Opc = getInsertVecEltOpInfo(RB, EltSize).first;
2964
2965 if (RB.getID() == AArch64::FPRRegBankID) {
2966 auto InsSub = emitScalarToVector(EltSize, DstRC, EltReg, MIRBuilder);
2967 InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
2968 .addImm(LaneIdx)
2969 .addUse(InsSub->getOperand(0).getReg())
2970 .addImm(0);
2971 } else {
2972 InsElt = MIRBuilder.buildInstr(Opc, {*DstReg}, {SrcReg})
2973 .addImm(LaneIdx)
2974 .addUse(EltReg);
2975 }
2976
2977 constrainSelectedInstRegOperands(*InsElt, TII, TRI, RBI);
2978 return InsElt;
2979}
2980
Jessica Paquette5aff1f42019-03-14 18:01:30 +00002981bool AArch64InstructionSelector::selectInsertElt(
2982 MachineInstr &I, MachineRegisterInfo &MRI) const {
2983 assert(I.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT);
2984
2985 // Get information on the destination.
2986 unsigned DstReg = I.getOperand(0).getReg();
2987 const LLT DstTy = MRI.getType(DstReg);
Jessica Paquetted3ffd472019-03-29 21:39:36 +00002988 unsigned VecSize = DstTy.getSizeInBits();
Jessica Paquette5aff1f42019-03-14 18:01:30 +00002989
2990 // Get information on the element we want to insert into the destination.
2991 unsigned EltReg = I.getOperand(2).getReg();
2992 const LLT EltTy = MRI.getType(EltReg);
2993 unsigned EltSize = EltTy.getSizeInBits();
2994 if (EltSize < 16 || EltSize > 64)
2995 return false; // Don't support all element types yet.
2996
2997 // Find the definition of the index. Bail out if it's not defined by a
2998 // G_CONSTANT.
2999 unsigned IdxReg = I.getOperand(3).getReg();
Jessica Paquette76f64b62019-04-26 21:53:13 +00003000 auto VRegAndVal = getConstantVRegValWithLookThrough(IdxReg, MRI);
3001 if (!VRegAndVal)
Jessica Paquette5aff1f42019-03-14 18:01:30 +00003002 return false;
Jessica Paquette76f64b62019-04-26 21:53:13 +00003003 unsigned LaneIdx = VRegAndVal->Value;
Jessica Paquette5aff1f42019-03-14 18:01:30 +00003004
3005 // Perform the lane insert.
3006 unsigned SrcReg = I.getOperand(1).getReg();
3007 const RegisterBank &EltRB = *RBI.getRegBank(EltReg, MRI, TRI);
3008 MachineIRBuilder MIRBuilder(I);
Jessica Paquetted3ffd472019-03-29 21:39:36 +00003009
3010 if (VecSize < 128) {
3011 // If the vector we're inserting into is smaller than 128 bits, widen it
3012 // to 128 to do the insert.
3013 MachineInstr *ScalarToVec = emitScalarToVector(
3014 VecSize, &AArch64::FPR128RegClass, SrcReg, MIRBuilder);
3015 if (!ScalarToVec)
3016 return false;
3017 SrcReg = ScalarToVec->getOperand(0).getReg();
3018 }
3019
3020 // Create an insert into a new FPR128 register.
3021 // Note that if our vector is already 128 bits, we end up emitting an extra
3022 // register.
3023 MachineInstr *InsMI =
3024 emitLaneInsert(None, SrcReg, EltReg, LaneIdx, EltRB, MIRBuilder);
3025
3026 if (VecSize < 128) {
3027 // If we had to widen to perform the insert, then we have to demote back to
3028 // the original size to get the result we want.
3029 unsigned DemoteVec = InsMI->getOperand(0).getReg();
3030 const TargetRegisterClass *RC =
3031 getMinClassForRegBank(*RBI.getRegBank(DemoteVec, MRI, TRI), VecSize);
3032 if (RC != &AArch64::FPR32RegClass && RC != &AArch64::FPR64RegClass) {
3033 LLVM_DEBUG(dbgs() << "Unsupported register class!\n");
3034 return false;
3035 }
3036 unsigned SubReg = 0;
3037 if (!getSubRegForClass(RC, TRI, SubReg))
3038 return false;
3039 if (SubReg != AArch64::ssub && SubReg != AArch64::dsub) {
3040 LLVM_DEBUG(dbgs() << "Unsupported destination size! (" << VecSize
3041 << "\n");
3042 return false;
3043 }
3044 MIRBuilder.buildInstr(TargetOpcode::COPY, {DstReg}, {})
3045 .addReg(DemoteVec, 0, SubReg);
3046 RBI.constrainGenericRegister(DstReg, *RC, MRI);
3047 } else {
3048 // No widening needed.
3049 InsMI->getOperand(0).setReg(DstReg);
3050 constrainSelectedInstRegOperands(*InsMI, TII, TRI, RBI);
3051 }
3052
Jessica Paquette5aff1f42019-03-14 18:01:30 +00003053 I.eraseFromParent();
3054 return true;
3055}
3056
Amara Emerson5ec14602018-12-10 18:44:58 +00003057bool AArch64InstructionSelector::selectBuildVector(
3058 MachineInstr &I, MachineRegisterInfo &MRI) const {
3059 assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
3060 // Until we port more of the optimized selections, for now just use a vector
3061 // insert sequence.
3062 const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
3063 const LLT EltTy = MRI.getType(I.getOperand(1).getReg());
3064 unsigned EltSize = EltTy.getSizeInBits();
Jessica Paquette245047d2019-01-24 22:00:41 +00003065 if (EltSize < 16 || EltSize > 64)
Amara Emerson5ec14602018-12-10 18:44:58 +00003066 return false; // Don't support all element types yet.
3067 const RegisterBank &RB = *RBI.getRegBank(I.getOperand(1).getReg(), MRI, TRI);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00003068 MachineIRBuilder MIRBuilder(I);
Jessica Paquette245047d2019-01-24 22:00:41 +00003069
3070 const TargetRegisterClass *DstRC = &AArch64::FPR128RegClass;
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00003071 MachineInstr *ScalarToVec =
Amara Emerson8acb0d92019-03-04 19:16:00 +00003072 emitScalarToVector(DstTy.getElementType().getSizeInBits(), DstRC,
3073 I.getOperand(1).getReg(), MIRBuilder);
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00003074 if (!ScalarToVec)
Jessica Paquette245047d2019-01-24 22:00:41 +00003075 return false;
3076
Amara Emerson6bcfa1c2019-02-25 18:52:54 +00003077 unsigned DstVec = ScalarToVec->getOperand(0).getReg();
Jessica Paquette245047d2019-01-24 22:00:41 +00003078 unsigned DstSize = DstTy.getSizeInBits();
3079
3080 // Keep track of the last MI we inserted. Later on, we might be able to save
3081 // a copy using it.
3082 MachineInstr *PrevMI = nullptr;
3083 for (unsigned i = 2, e = DstSize / EltSize + 1; i < e; ++i) {
Jessica Paquette16d67a32019-03-13 23:22:23 +00003084 // Note that if we don't do a subregister copy, we can end up making an
3085 // extra register.
3086 PrevMI = &*emitLaneInsert(None, DstVec, I.getOperand(i).getReg(), i - 1, RB,
3087 MIRBuilder);
3088 DstVec = PrevMI->getOperand(0).getReg();
Amara Emerson5ec14602018-12-10 18:44:58 +00003089 }
Jessica Paquette245047d2019-01-24 22:00:41 +00003090
3091 // If DstTy's size in bits is less than 128, then emit a subregister copy
3092 // from DstVec to the last register we've defined.
3093 if (DstSize < 128) {
Jessica Paquette85ace622019-03-13 23:29:54 +00003094 // Force this to be FPR using the destination vector.
3095 const TargetRegisterClass *RC =
3096 getMinClassForRegBank(*RBI.getRegBank(DstVec, MRI, TRI), DstSize);
Jessica Paquette245047d2019-01-24 22:00:41 +00003097 if (!RC)
3098 return false;
Jessica Paquette85ace622019-03-13 23:29:54 +00003099 if (RC != &AArch64::FPR32RegClass && RC != &AArch64::FPR64RegClass) {
3100 LLVM_DEBUG(dbgs() << "Unsupported register class!\n");
3101 return false;
3102 }
3103
3104 unsigned SubReg = 0;
3105 if (!getSubRegForClass(RC, TRI, SubReg))
3106 return false;
3107 if (SubReg != AArch64::ssub && SubReg != AArch64::dsub) {
3108 LLVM_DEBUG(dbgs() << "Unsupported destination size! (" << DstSize
3109 << "\n");
3110 return false;
3111 }
Jessica Paquette245047d2019-01-24 22:00:41 +00003112
3113 unsigned Reg = MRI.createVirtualRegister(RC);
3114 unsigned DstReg = I.getOperand(0).getReg();
3115
Amara Emerson86271782019-03-18 19:20:10 +00003116 MIRBuilder.buildInstr(TargetOpcode::COPY, {DstReg}, {})
3117 .addReg(DstVec, 0, SubReg);
Jessica Paquette245047d2019-01-24 22:00:41 +00003118 MachineOperand &RegOp = I.getOperand(1);
3119 RegOp.setReg(Reg);
3120 RBI.constrainGenericRegister(DstReg, *RC, MRI);
3121 } else {
3122 // We don't need a subregister copy. Save a copy by re-using the
3123 // destination register on the final insert.
3124 assert(PrevMI && "PrevMI was null?");
3125 PrevMI->getOperand(0).setReg(I.getOperand(0).getReg());
3126 constrainSelectedInstRegOperands(*PrevMI, TII, TRI, RBI);
3127 }
3128
Amara Emerson5ec14602018-12-10 18:44:58 +00003129 I.eraseFromParent();
3130 return true;
3131}
3132
Jessica Paquette7f6fe7c2019-04-29 20:58:17 +00003133/// Helper function to find an intrinsic ID on an a MachineInstr. Returns the
3134/// ID if it exists, and 0 otherwise.
3135static unsigned findIntrinsicID(MachineInstr &I) {
3136 auto IntrinOp = find_if(I.operands(), [&](const MachineOperand &Op) {
3137 return Op.isIntrinsicID();
3138 });
3139 if (IntrinOp == I.operands_end())
3140 return 0;
3141 return IntrinOp->getIntrinsicID();
3142}
3143
Jessica Paquette22c62152019-04-02 19:57:26 +00003144/// Helper function to emit the correct opcode for a llvm.aarch64.stlxr
3145/// intrinsic.
3146static unsigned getStlxrOpcode(unsigned NumBytesToStore) {
3147 switch (NumBytesToStore) {
3148 // TODO: 1, 2, and 4 byte stores.
3149 case 8:
3150 return AArch64::STLXRX;
3151 default:
3152 LLVM_DEBUG(dbgs() << "Unexpected number of bytes to store! ("
3153 << NumBytesToStore << ")\n");
3154 break;
3155 }
3156 return 0;
3157}
3158
3159bool AArch64InstructionSelector::selectIntrinsicWithSideEffects(
3160 MachineInstr &I, MachineRegisterInfo &MRI) const {
3161 // Find the intrinsic ID.
Jessica Paquette7f6fe7c2019-04-29 20:58:17 +00003162 unsigned IntrinID = findIntrinsicID(I);
3163 if (!IntrinID)
Jessica Paquette22c62152019-04-02 19:57:26 +00003164 return false;
Jessica Paquette22c62152019-04-02 19:57:26 +00003165 MachineIRBuilder MIRBuilder(I);
3166
3167 // Select the instruction.
3168 switch (IntrinID) {
3169 default:
3170 return false;
3171 case Intrinsic::trap:
3172 MIRBuilder.buildInstr(AArch64::BRK, {}, {}).addImm(1);
3173 break;
3174 case Intrinsic::aarch64_stlxr:
3175 unsigned StatReg = I.getOperand(0).getReg();
3176 assert(RBI.getSizeInBits(StatReg, MRI, TRI) == 32 &&
3177 "Status register must be 32 bits!");
3178 unsigned SrcReg = I.getOperand(2).getReg();
3179
3180 if (RBI.getSizeInBits(SrcReg, MRI, TRI) != 64) {
3181 LLVM_DEBUG(dbgs() << "Only support 64-bit sources right now.\n");
3182 return false;
3183 }
3184
3185 unsigned PtrReg = I.getOperand(3).getReg();
3186 assert(MRI.getType(PtrReg).isPointer() && "Expected pointer operand");
3187
3188 // Expect only one memory operand.
3189 if (!I.hasOneMemOperand())
3190 return false;
3191
3192 const MachineMemOperand *MemOp = *I.memoperands_begin();
3193 unsigned NumBytesToStore = MemOp->getSize();
3194 unsigned Opc = getStlxrOpcode(NumBytesToStore);
3195 if (!Opc)
3196 return false;
3197
3198 auto StoreMI = MIRBuilder.buildInstr(Opc, {StatReg}, {SrcReg, PtrReg});
3199 constrainSelectedInstRegOperands(*StoreMI, TII, TRI, RBI);
3200 }
3201
3202 I.eraseFromParent();
3203 return true;
3204}
3205
Jessica Paquette7f6fe7c2019-04-29 20:58:17 +00003206bool AArch64InstructionSelector::selectIntrinsic(
3207 MachineInstr &I, MachineRegisterInfo &MRI) const {
3208 unsigned IntrinID = findIntrinsicID(I);
3209 if (!IntrinID)
3210 return false;
3211 MachineIRBuilder MIRBuilder(I);
3212
3213 switch (IntrinID) {
3214 default:
3215 break;
3216 case Intrinsic::aarch64_crypto_sha1h:
3217 unsigned DstReg = I.getOperand(0).getReg();
3218 unsigned SrcReg = I.getOperand(2).getReg();
3219
3220 // FIXME: Should this be an assert?
3221 if (MRI.getType(DstReg).getSizeInBits() != 32 ||
3222 MRI.getType(SrcReg).getSizeInBits() != 32)
3223 return false;
3224
3225 // The operation has to happen on FPRs. Set up some new FPR registers for
3226 // the source and destination if they are on GPRs.
3227 if (RBI.getRegBank(SrcReg, MRI, TRI)->getID() != AArch64::FPRRegBankID) {
3228 SrcReg = MRI.createVirtualRegister(&AArch64::FPR32RegClass);
3229 MIRBuilder.buildCopy({SrcReg}, {I.getOperand(2)});
3230
3231 // Make sure the copy ends up getting constrained properly.
3232 RBI.constrainGenericRegister(I.getOperand(2).getReg(),
3233 AArch64::GPR32RegClass, MRI);
3234 }
3235
3236 if (RBI.getRegBank(DstReg, MRI, TRI)->getID() != AArch64::FPRRegBankID)
3237 DstReg = MRI.createVirtualRegister(&AArch64::FPR32RegClass);
3238
3239 // Actually insert the instruction.
3240 auto SHA1Inst = MIRBuilder.buildInstr(AArch64::SHA1Hrr, {DstReg}, {SrcReg});
3241 constrainSelectedInstRegOperands(*SHA1Inst, TII, TRI, RBI);
3242
3243 // Did we create a new register for the destination?
3244 if (DstReg != I.getOperand(0).getReg()) {
3245 // Yep. Copy the result of the instruction back into the original
3246 // destination.
3247 MIRBuilder.buildCopy({I.getOperand(0)}, {DstReg});
3248 RBI.constrainGenericRegister(I.getOperand(0).getReg(),
3249 AArch64::GPR32RegClass, MRI);
3250 }
3251
3252 I.eraseFromParent();
3253 return true;
3254 }
3255 return false;
3256}
3257
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003258/// SelectArithImmed - Select an immediate value that can be represented as
3259/// a 12-bit value shifted left by either 0 or 12. If so, return true with
3260/// Val set to the 12-bit value and Shift set to the shifter operand.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003261InstructionSelector::ComplexRendererFns
Daniel Sanders2deea182017-04-22 15:11:04 +00003262AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003263 MachineInstr &MI = *Root.getParent();
3264 MachineBasicBlock &MBB = *MI.getParent();
3265 MachineFunction &MF = *MBB.getParent();
3266 MachineRegisterInfo &MRI = MF.getRegInfo();
3267
3268 // This function is called from the addsub_shifted_imm ComplexPattern,
3269 // which lists [imm] as the list of opcode it's interested in, however
3270 // we still need to check whether the operand is actually an immediate
3271 // here because the ComplexPattern opcode list is only used in
3272 // root-level opcode matching.
3273 uint64_t Immed;
3274 if (Root.isImm())
3275 Immed = Root.getImm();
3276 else if (Root.isCImm())
3277 Immed = Root.getCImm()->getZExtValue();
3278 else if (Root.isReg()) {
3279 MachineInstr *Def = MRI.getVRegDef(Root.getReg());
3280 if (Def->getOpcode() != TargetOpcode::G_CONSTANT)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003281 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00003282 MachineOperand &Op1 = Def->getOperand(1);
3283 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64)
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003284 return None;
Daniel Sanders0e642022017-03-16 18:04:50 +00003285 Immed = Op1.getCImm()->getZExtValue();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003286 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003287 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003288
3289 unsigned ShiftAmt;
3290
3291 if (Immed >> 12 == 0) {
3292 ShiftAmt = 0;
3293 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
3294 ShiftAmt = 12;
3295 Immed = Immed >> 12;
3296 } else
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003297 return None;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003298
3299 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003300 return {{
3301 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); },
3302 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); },
3303 }};
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003304}
Daniel Sanders0b5293f2017-04-06 09:49:34 +00003305
Daniel Sandersea8711b2017-10-16 03:36:29 +00003306/// Select a "register plus unscaled signed 9-bit immediate" address. This
3307/// should only match when there is an offset that is not valid for a scaled
3308/// immediate addressing mode. The "Size" argument is the size in bytes of the
3309/// memory reference, which is needed here to know what is valid for a scaled
3310/// immediate.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003311InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00003312AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root,
3313 unsigned Size) const {
3314 MachineRegisterInfo &MRI =
3315 Root.getParent()->getParent()->getParent()->getRegInfo();
3316
3317 if (!Root.isReg())
3318 return None;
3319
3320 if (!isBaseWithConstantOffset(Root, MRI))
3321 return None;
3322
3323 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
3324 if (!RootDef)
3325 return None;
3326
3327 MachineOperand &OffImm = RootDef->getOperand(2);
3328 if (!OffImm.isReg())
3329 return None;
3330 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg());
3331 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT)
3332 return None;
3333 int64_t RHSC;
3334 MachineOperand &RHSOp1 = RHS->getOperand(1);
3335 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64)
3336 return None;
3337 RHSC = RHSOp1.getCImm()->getSExtValue();
3338
3339 // If the offset is valid as a scaled immediate, don't match here.
3340 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size)))
3341 return None;
3342 if (RHSC >= -256 && RHSC < 256) {
3343 MachineOperand &Base = RootDef->getOperand(1);
3344 return {{
3345 [=](MachineInstrBuilder &MIB) { MIB.add(Base); },
3346 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
3347 }};
3348 }
3349 return None;
3350}
3351
3352/// Select a "register plus scaled unsigned 12-bit immediate" address. The
3353/// "Size" argument is the size in bytes of the memory reference, which
3354/// determines the scale.
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003355InstructionSelector::ComplexRendererFns
Daniel Sandersea8711b2017-10-16 03:36:29 +00003356AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
3357 unsigned Size) const {
3358 MachineRegisterInfo &MRI =
3359 Root.getParent()->getParent()->getParent()->getRegInfo();
3360
3361 if (!Root.isReg())
3362 return None;
3363
3364 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg());
3365 if (!RootDef)
3366 return None;
3367
3368 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
3369 return {{
3370 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
3371 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
3372 }};
3373 }
3374
3375 if (isBaseWithConstantOffset(Root, MRI)) {
3376 MachineOperand &LHS = RootDef->getOperand(1);
3377 MachineOperand &RHS = RootDef->getOperand(2);
3378 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg());
3379 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg());
3380 if (LHSDef && RHSDef) {
3381 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue();
3382 unsigned Scale = Log2_32(Size);
3383 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
3384 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
Daniel Sanders01805b62017-10-16 05:39:30 +00003385 return {{
3386 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
3387 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
3388 }};
3389
Daniel Sandersea8711b2017-10-16 03:36:29 +00003390 return {{
3391 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
3392 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); },
3393 }};
3394 }
3395 }
3396 }
3397
3398 // Before falling back to our general case, check if the unscaled
3399 // instructions can handle this. If so, that's preferable.
3400 if (selectAddrModeUnscaled(Root, Size).hasValue())
3401 return None;
3402
3403 return {{
3404 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
3405 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
3406 }};
3407}
3408
Volkan Kelesf7f25682018-01-16 18:44:05 +00003409void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
3410 const MachineInstr &MI) const {
3411 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3412 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
3413 Optional<int64_t> CstVal = getConstantVRegVal(MI.getOperand(0).getReg(), MRI);
3414 assert(CstVal && "Expected constant value");
3415 MIB.addImm(CstVal.getValue());
3416}
3417
Daniel Sanders0b5293f2017-04-06 09:49:34 +00003418namespace llvm {
3419InstructionSelector *
3420createAArch64InstructionSelector(const AArch64TargetMachine &TM,
3421 AArch64Subtarget &Subtarget,
3422 AArch64RegisterBankInfo &RBI) {
3423 return new AArch64InstructionSelector(TM, Subtarget, RBI);
3424}
3425}