LLVM 24.0.0git
AArch64FastISel.cpp
Go to the documentation of this file.
1//===- AArch6464FastISel.cpp - AArch64 FastISel implementation ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the AArch64-specific support for the FastISel class. Some
10// of the target-specific code is generated by tablegen in the file
11// AArch64GenFastISel.inc, which is #included here.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AArch64.h"
18#include "AArch64RegisterInfo.h"
20#include "AArch64Subtarget.h"
23#include "llvm/ADT/APFloat.h"
24#include "llvm/ADT/APInt.h"
25#include "llvm/ADT/DenseMap.h"
41#include "llvm/IR/Argument.h"
42#include "llvm/IR/Attributes.h"
43#include "llvm/IR/BasicBlock.h"
44#include "llvm/IR/CallingConv.h"
45#include "llvm/IR/Constant.h"
46#include "llvm/IR/Constants.h"
47#include "llvm/IR/DataLayout.h"
49#include "llvm/IR/Function.h"
51#include "llvm/IR/GlobalValue.h"
52#include "llvm/IR/InstrTypes.h"
53#include "llvm/IR/Instruction.h"
56#include "llvm/IR/Intrinsics.h"
57#include "llvm/IR/IntrinsicsAArch64.h"
58#include "llvm/IR/Module.h"
59#include "llvm/IR/Operator.h"
60#include "llvm/IR/Type.h"
61#include "llvm/IR/User.h"
62#include "llvm/IR/Value.h"
63#include "llvm/MC/MCInstrDesc.h"
64#include "llvm/MC/MCSymbol.h"
71#include <algorithm>
72#include <cassert>
73#include <cstdint>
74#include <iterator>
75#include <utility>
76
77using namespace llvm;
78
79namespace {
80
81class AArch64FastISel final : public FastISel {
82 class Address {
83 public:
84 enum BaseKind { RegBase, FrameIndexBase };
85
86 private:
87 BaseKind Kind = RegBase;
89 union {
90 unsigned Reg;
91 int FI;
92 } Base;
93 Register OffsetReg;
94 unsigned Shift = 0;
95 int64_t Offset = 0;
96 const GlobalValue *GV = nullptr;
97
98 public:
99 Address() { Base.Reg = 0; }
100
101 void setKind(BaseKind K) { Kind = K; }
102 BaseKind getKind() const { return Kind; }
103 void setExtendType(AArch64_AM::ShiftExtendType E) { ExtType = E; }
104 AArch64_AM::ShiftExtendType getExtendType() const { return ExtType; }
105 bool isRegBase() const { return Kind == RegBase; }
106 bool isFIBase() const { return Kind == FrameIndexBase; }
107
108 void setReg(Register Reg) {
109 assert(isRegBase() && "Invalid base register access!");
110 Base.Reg = Reg.id();
111 }
112
113 Register getReg() const {
114 assert(isRegBase() && "Invalid base register access!");
115 return Base.Reg;
116 }
117
118 void setOffsetReg(Register Reg) { OffsetReg = Reg; }
119
120 Register getOffsetReg() const { return OffsetReg; }
121
122 void setFI(unsigned FI) {
123 assert(isFIBase() && "Invalid base frame index access!");
124 Base.FI = FI;
125 }
126
127 unsigned getFI() const {
128 assert(isFIBase() && "Invalid base frame index access!");
129 return Base.FI;
130 }
131
132 void setOffset(int64_t O) { Offset = O; }
133 int64_t getOffset() { return Offset; }
134 void setShift(unsigned S) { Shift = S; }
135 unsigned getShift() { return Shift; }
136
137 void setGlobalValue(const GlobalValue *G) { GV = G; }
138 const GlobalValue *getGlobalValue() { return GV; }
139 };
140
141 /// Subtarget - Keep a pointer to the AArch64Subtarget around so that we can
142 /// make the right decision when generating code for different targets.
143 const AArch64Subtarget *Subtarget;
144 LLVMContext *Context;
145
146 bool fastLowerArguments() override;
147 bool fastLowerCall(CallLoweringInfo &CLI) override;
148 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;
149
150private:
151 // Selection routines.
152 bool selectAddSub(const Instruction *I);
153 bool selectLogicalOp(const Instruction *I);
154 bool selectLoad(const Instruction *I);
155 bool selectStore(const Instruction *I);
156 bool selectBranch(const Instruction *I);
157 bool selectIndirectBr(const Instruction *I);
158 bool selectCmp(const Instruction *I);
159 bool selectSelect(const Instruction *I);
160 bool selectFPExt(const Instruction *I);
161 bool selectFPTrunc(const Instruction *I);
162 bool selectFPToInt(const Instruction *I, bool Signed);
163 bool selectIntToFP(const Instruction *I, bool Signed);
164 bool selectRem(const Instruction *I, unsigned ISDOpcode);
165 bool selectRet(const Instruction *I);
166 bool selectTrunc(const Instruction *I);
167 bool selectIntExt(const Instruction *I);
168 bool selectMul(const Instruction *I);
169 bool selectShift(const Instruction *I);
170 bool selectBitCast(const Instruction *I);
171 bool selectFRem(const Instruction *I);
172 bool selectSDiv(const Instruction *I);
173 bool selectGetElementPtr(const Instruction *I);
174 bool selectAtomicCmpXchg(const AtomicCmpXchgInst *I);
175
176 // Utility helper routines.
177 bool isTypeLegal(Type *Ty, MVT &VT);
178 bool isTypeSupported(Type *Ty, MVT &VT, bool IsVectorAllowed = false);
179 bool isValueAvailable(const Value *V) const;
180 bool computeAddress(const Value *Obj, Address &Addr, Type *Ty = nullptr);
181 bool computeCallAddress(const Value *V, Address &Addr);
182 bool simplifyAddress(Address &Addr, MVT VT);
183 void addLoadStoreOperands(Address &Addr, const MachineInstrBuilder &MIB,
185 unsigned ScaleFactor, MachineMemOperand *MMO);
186 bool isMemCpySmall(uint64_t Len, MaybeAlign Alignment);
187 bool tryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
188 MaybeAlign Alignment);
189 bool foldXALUIntrinsic(AArch64CC::CondCode &CC, const Instruction *I,
190 const Value *Cond);
191 bool optimizeIntExtLoad(const Instruction *I, MVT RetVT, MVT SrcVT);
192 bool optimizeSelect(const SelectInst *SI);
193 Register getRegForGEPIndex(const Value *Idx);
194
195 // Emit helper routines.
196 Register emitAddSub(bool UseAdd, MVT RetVT, const Value *LHS,
197 const Value *RHS, bool SetFlags = false,
198 bool WantResult = true, bool IsZExt = false);
199 Register emitAddSub_rr(bool UseAdd, MVT RetVT, Register LHSReg,
200 Register RHSReg, bool SetFlags = false,
201 bool WantResult = true);
202 Register emitAddSub_ri(bool UseAdd, MVT RetVT, Register LHSReg, uint64_t Imm,
203 bool SetFlags = false, bool WantResult = true);
204 Register emitAddSub_rs(bool UseAdd, MVT RetVT, Register LHSReg,
205 Register RHSReg, AArch64_AM::ShiftExtendType ShiftType,
206 uint64_t ShiftImm, bool SetFlags = false,
207 bool WantResult = true);
208 Register emitAddSub_rx(bool UseAdd, MVT RetVT, Register LHSReg,
210 uint64_t ShiftImm, bool SetFlags = false,
211 bool WantResult = true);
212
213 // Emit functions.
214 bool emitCompareAndBranch(const CondBrInst *BI);
215 bool emitCmp(const Value *LHS, const Value *RHS, bool IsZExt);
216 bool emitICmp(MVT RetVT, const Value *LHS, const Value *RHS, bool IsZExt);
217 bool emitICmp_ri(MVT RetVT, Register LHSReg, uint64_t Imm);
218 bool emitFCmp(MVT RetVT, const Value *LHS, const Value *RHS);
219 Register emitLoad(MVT VT, MVT ResultVT, Address Addr, bool WantZExt = true,
220 MachineMemOperand *MMO = nullptr);
221 bool emitStore(MVT VT, Register SrcReg, Address Addr,
222 MachineMemOperand *MMO = nullptr);
223 bool emitStoreRelease(MVT VT, Register SrcReg, Register AddrReg,
224 MachineMemOperand *MMO = nullptr);
225 Register emitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT, bool isZExt);
226 Register emiti1Ext(Register SrcReg, MVT DestVT, bool isZExt);
227 Register emitAdd(MVT RetVT, const Value *LHS, const Value *RHS,
228 bool SetFlags = false, bool WantResult = true,
229 bool IsZExt = false);
230 Register emitAdd_ri_(MVT VT, Register Op0, int64_t Imm);
231 Register emitSub(MVT RetVT, const Value *LHS, const Value *RHS,
232 bool SetFlags = false, bool WantResult = true,
233 bool IsZExt = false);
234 Register emitSubs_rr(MVT RetVT, Register LHSReg, Register RHSReg,
235 bool WantResult = true);
236 Register emitSubs_rs(MVT RetVT, Register LHSReg, Register RHSReg,
237 AArch64_AM::ShiftExtendType ShiftType, uint64_t ShiftImm,
238 bool WantResult = true);
239 Register emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS,
240 const Value *RHS);
241 Register emitLogicalOp_ri(unsigned ISDOpc, MVT RetVT, Register LHSReg,
242 uint64_t Imm);
243 Register emitLogicalOp_rs(unsigned ISDOpc, MVT RetVT, Register LHSReg,
244 Register RHSReg, uint64_t ShiftImm);
245 Register emitAnd_ri(MVT RetVT, Register LHSReg, uint64_t Imm);
246 Register emitMul_rr(MVT RetVT, Register Op0, Register Op1);
247 Register emitSMULL_rr(MVT RetVT, Register Op0, Register Op1);
248 Register emitUMULL_rr(MVT RetVT, Register Op0, Register Op1);
249 Register emitLSL_rr(MVT RetVT, Register Op0Reg, Register Op1Reg);
250 Register emitLSL_ri(MVT RetVT, MVT SrcVT, Register Op0Reg, uint64_t Imm,
251 bool IsZExt = true);
252 Register emitLSR_rr(MVT RetVT, Register Op0Reg, Register Op1Reg);
253 Register emitLSR_ri(MVT RetVT, MVT SrcVT, Register Op0Reg, uint64_t Imm,
254 bool IsZExt = true);
255 Register emitASR_rr(MVT RetVT, Register Op0Reg, Register Op1Reg);
256 Register emitASR_ri(MVT RetVT, MVT SrcVT, Register Op0Reg, uint64_t Imm,
257 bool IsZExt = false);
258
259 Register materializeInt(const ConstantInt *CI, MVT VT);
260 Register materializeFP(const ConstantFP *CFP, MVT VT);
261 Register materializeGV(const GlobalValue *GV);
262
263 // Call handling routines.
264private:
265 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const;
266 bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs,
267 SmallVectorImpl<Type *> &OrigTys, unsigned &NumBytes);
268 bool finishCall(CallLoweringInfo &CLI, unsigned NumBytes);
269
270public:
271 // Backend specific FastISel code.
272 Register fastMaterializeAlloca(const AllocaInst *AI) override;
273 Register fastMaterializeConstant(const Constant *C) override;
274 Register fastMaterializeFloatZero(const ConstantFP *CF) override;
275
276 explicit AArch64FastISel(FunctionLoweringInfo &FuncInfo,
277 const TargetLibraryInfo *LibInfo,
278 const LibcallLoweringInfo *libcallLowering)
279 : FastISel(FuncInfo, LibInfo, libcallLowering,
280 /*SkipTargetIndependentISel=*/true) {
281 Subtarget = &FuncInfo.MF->getSubtarget<AArch64Subtarget>();
282 Context = &FuncInfo.Fn->getContext();
283 }
284
285 bool fastSelectInstruction(const Instruction *I) override;
286
287#include "AArch64GenFastISel.inc"
288};
289
290} // end anonymous namespace
291
292/// Check if the sign-/zero-extend will be a noop.
293static bool isIntExtFree(const Instruction *I) {
295 "Unexpected integer extend instruction.");
296 assert(!I->getType()->isVectorTy() && I->getType()->isIntegerTy() &&
297 "Unexpected value type.");
298 bool IsZExt = isa<ZExtInst>(I);
299
300 if (const auto *LI = dyn_cast<LoadInst>(I->getOperand(0)))
301 if (LI->hasOneUse())
302 return true;
303
304 if (const auto *Arg = dyn_cast<Argument>(I->getOperand(0)))
305 if ((IsZExt && Arg->hasZExtAttr()) || (!IsZExt && Arg->hasSExtAttr()))
306 return true;
307
308 return false;
309}
310
311/// Determine the implicit scale factor that is applied by a memory
312/// operation for a given value type.
313static unsigned getImplicitScaleFactor(MVT VT) {
314 switch (VT.SimpleTy) {
315 default:
316 return 0; // invalid
317 case MVT::i1: // fall-through
318 case MVT::i8:
319 return 1;
320 case MVT::i16:
321 return 2;
322 case MVT::i32: // fall-through
323 case MVT::f32:
324 return 4;
325 case MVT::i64: // fall-through
326 case MVT::f64:
327 return 8;
328 }
329}
330
331CCAssignFn *AArch64FastISel::CCAssignFnForCall(CallingConv::ID CC) const {
332 if (CC == CallingConv::GHC)
333 return CC_AArch64_GHC;
334 if (CC == CallingConv::CFGuard_Check)
336 if (Subtarget->isTargetDarwin())
338 if (Subtarget->isTargetWindows())
339 return CC_AArch64_Win64PCS;
340 return CC_AArch64_AAPCS;
341}
342
343Register AArch64FastISel::fastMaterializeAlloca(const AllocaInst *AI) {
344 assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i64 &&
345 "Alloca should always return a pointer.");
346
347 // Don't handle dynamic allocas.
348 auto SI = FuncInfo.StaticAllocaMap.find(AI);
349 if (SI == FuncInfo.StaticAllocaMap.end())
350 return Register();
351
352 if (SI != FuncInfo.StaticAllocaMap.end()) {
353 Register ResultReg = createResultReg(&AArch64::GPR64spRegClass);
354 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADDXri),
355 ResultReg)
356 .addFrameIndex(SI->second)
357 .addImm(0)
358 .addImm(0);
359 return ResultReg;
360 }
361
362 return Register();
363}
364
365Register AArch64FastISel::materializeInt(const ConstantInt *CI, MVT VT) {
366 if (VT > MVT::i64)
367 return Register();
368
369 if (!CI->isZero())
370 return fastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
371
372 // Create a copy from the zero register to materialize a "0" value.
373 const TargetRegisterClass *RC = (VT == MVT::i64) ? &AArch64::GPR64RegClass
374 : &AArch64::GPR32RegClass;
375 unsigned ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
376 Register ResultReg = createResultReg(RC);
377 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
378 ResultReg).addReg(ZeroReg, getKillRegState(true));
379 return ResultReg;
380}
381
382Register AArch64FastISel::materializeFP(const ConstantFP *CFP, MVT VT) {
383 // Positive zero (+0.0) has to be materialized with a fmov from the zero
384 // register, because the immediate version of fmov cannot encode zero.
385 if (CFP->isNullValue())
386 return fastMaterializeFloatZero(CFP);
387
388 if (VT != MVT::f32 && VT != MVT::f64)
389 return Register();
390
391 const APFloat Val = CFP->getValueAPF();
392 bool Is64Bit = (VT == MVT::f64);
393 // This checks to see if we can use FMOV instructions to materialize
394 // a constant, otherwise we have to materialize via the constant pool.
395 int Imm =
396 Is64Bit ? AArch64_AM::getFP64Imm(Val) : AArch64_AM::getFP32Imm(Val);
397 if (Imm != -1) {
398 unsigned Opc = Is64Bit ? AArch64::FMOVDi : AArch64::FMOVSi;
399 return fastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
400 }
401
402 // For the large code model materialize the FP constant in code.
403 if (TM.getCodeModel() == CodeModel::Large) {
404 unsigned Opc1 = Is64Bit ? AArch64::MOVi64imm : AArch64::MOVi32imm;
405 const TargetRegisterClass *RC = Is64Bit ?
406 &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
407
408 Register TmpReg = createResultReg(RC);
409 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc1), TmpReg)
410 .addImm(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
411
412 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
413 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
414 TII.get(TargetOpcode::COPY), ResultReg)
415 .addReg(TmpReg, getKillRegState(true));
416
417 return ResultReg;
418 }
419
420 // Materialize via constant pool. MachineConstantPool wants an explicit
421 // alignment.
422 Align Alignment = DL.getPrefTypeAlign(CFP->getType());
423
424 unsigned CPI = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
425 Register ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
426 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADRP),
428
429 unsigned Opc = Is64Bit ? AArch64::LDRDui : AArch64::LDRSui;
430 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
431 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
432 .addReg(ADRPReg)
434 return ResultReg;
435}
436
437Register AArch64FastISel::materializeGV(const GlobalValue *GV) {
438 // We can't handle thread-local variables quickly yet.
439 if (GV->isThreadLocal())
440 return Register();
441
442 // MachO still uses GOT for large code-model accesses, but ELF requires
443 // movz/movk sequences, which FastISel doesn't handle yet.
444 if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO())
445 return Register();
446
447 if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT())
448 return Register();
449
450 unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
451
452 EVT DestEVT = TLI.getValueType(DL, GV->getType(), true);
453 if (!DestEVT.isSimple())
454 return Register();
455
456 Register ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
457 Register ResultReg;
458
459 if (OpFlags & AArch64II::MO_GOT) {
460 // ADRP + LDRX
461 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADRP),
462 ADRPReg)
463 .addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);
464
465 unsigned LdrOpc;
466 if (Subtarget->isTargetILP32()) {
467 ResultReg = createResultReg(&AArch64::GPR32RegClass);
468 LdrOpc = AArch64::LDRWui;
469 } else {
470 ResultReg = createResultReg(&AArch64::GPR64RegClass);
471 LdrOpc = AArch64::LDRXui;
472 }
473 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(LdrOpc),
474 ResultReg)
475 .addReg(ADRPReg)
477 AArch64II::MO_NC | OpFlags);
478 if (!Subtarget->isTargetILP32())
479 return ResultReg;
480
481 // LDRWui produces a 32-bit register, but pointers in-register are 64-bits
482 // so we must extend the result on ILP32.
483 Register Result64 = createResultReg(&AArch64::GPR64RegClass);
484 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
485 TII.get(TargetOpcode::SUBREG_TO_REG))
486 .addDef(Result64)
487 .addReg(ResultReg, RegState::Kill)
488 .addImm(AArch64::sub_32);
489 return Result64;
490 } else {
491 // ADRP + ADDX
492 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADRP),
493 ADRPReg)
494 .addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);
495
496 if (OpFlags & AArch64II::MO_TAGGED) {
497 // MO_TAGGED on the page indicates a tagged address. Set the tag now.
498 // We do so by creating a MOVK that sets bits 48-63 of the register to
499 // (global address + 0x100000000 - PC) >> 48. This assumes that we're in
500 // the small code model so we can assume a binary size of <= 4GB, which
501 // makes the untagged PC relative offset positive. The binary must also be
502 // loaded into address range [0, 2^48). Both of these properties need to
503 // be ensured at runtime when using tagged addresses.
504 //
505 // TODO: There is duplicate logic in AArch64ExpandPseudoInsts.cpp that
506 // also uses BuildMI for making an ADRP (+ MOVK) + ADD, but the operands
507 // are not exactly 1:1 with FastISel so we cannot easily abstract this
508 // out. At some point, it would be nice to find a way to not have this
509 // duplicate code.
510 Register DstReg = createResultReg(&AArch64::GPR64commonRegClass);
511 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::MOVKXi),
512 DstReg)
513 .addReg(ADRPReg)
514 .addGlobalAddress(GV, /*Offset=*/0x100000000,
516 .addImm(48);
517 ADRPReg = DstReg;
518 }
519
520 ResultReg = createResultReg(&AArch64::GPR64spRegClass);
521 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADDXri),
522 ResultReg)
523 .addReg(ADRPReg)
524 .addGlobalAddress(GV, 0,
526 .addImm(0);
527 }
528 return ResultReg;
529}
530
531Register AArch64FastISel::fastMaterializeConstant(const Constant *C) {
532 EVT CEVT = TLI.getValueType(DL, C->getType(), true);
533
534 // Only handle simple types.
535 if (!CEVT.isSimple())
536 return Register();
537 MVT VT = CEVT.getSimpleVT();
538 // arm64_32 has 32-bit pointers held in 64-bit registers. Because of that,
539 // 'null' pointers need to have a somewhat special treatment.
541 if (C->getType()->isVectorTy())
542 return Register();
543 assert(VT == MVT::i64 && "Expected 64-bit pointers");
544 return materializeInt(ConstantInt::get(Type::getInt64Ty(*Context), 0), VT);
545 }
546
547 if (const auto *CI = dyn_cast<ConstantInt>(C))
548 return materializeInt(CI, VT);
549 else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
550 return materializeFP(CFP, VT);
551 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
552 return materializeGV(GV);
553
554 return Register();
555}
556
557Register AArch64FastISel::fastMaterializeFloatZero(const ConstantFP *CFP) {
558 assert(CFP->isNullValue() &&
559 "Floating-point constant is not a positive zero.");
560 MVT VT;
561 if (!isTypeLegal(CFP->getType(), VT))
562 return Register();
563
564 if (VT != MVT::f32 && VT != MVT::f64)
565 return Register();
566
567 bool Is64Bit = (VT == MVT::f64);
568 unsigned ZReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
569 unsigned Opc = Is64Bit ? AArch64::FMOVXDr : AArch64::FMOVWSr;
570 return fastEmitInst_r(Opc, TLI.getRegClassFor(VT), ZReg);
571}
572
573/// Check if the multiply is by a power-of-2 constant.
574static bool isMulPowOf2(const Value *I) {
575 if (const auto *MI = dyn_cast<MulOperator>(I)) {
576 if (const auto *C = dyn_cast<ConstantInt>(MI->getOperand(0)))
577 if (C->getValue().isPowerOf2())
578 return true;
579 if (const auto *C = dyn_cast<ConstantInt>(MI->getOperand(1)))
580 if (C->getValue().isPowerOf2())
581 return true;
582 }
583 return false;
584}
585
586// Computes the address to get to an object.
587bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
588{
589 const User *U = nullptr;
590 unsigned Opcode = Instruction::UserOp1;
591 if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
592 // Don't walk into other basic blocks unless the object is an alloca from
593 // another block, otherwise it may not have a virtual register assigned.
594 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
595 FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
596 Opcode = I->getOpcode();
597 U = I;
598 }
599 } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
600 Opcode = C->getOpcode();
601 U = C;
602 }
603
604 if (auto *Ty = dyn_cast<PointerType>(Obj->getType()))
605 if (Ty->getAddressSpace() > 255)
606 // Fast instruction selection doesn't support the special
607 // address spaces.
608 return false;
609
610 switch (Opcode) {
611 default:
612 break;
613 case Instruction::BitCast:
614 // Look through bitcasts.
615 return computeAddress(U->getOperand(0), Addr, Ty);
616
617 case Instruction::IntToPtr:
618 // Look past no-op inttoptrs.
619 if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
620 TLI.getPointerTy(DL))
621 return computeAddress(U->getOperand(0), Addr, Ty);
622 break;
623
624 case Instruction::PtrToInt:
625 // Look past no-op ptrtoints.
626 if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
627 return computeAddress(U->getOperand(0), Addr, Ty);
628 break;
629
630 case Instruction::GetElementPtr: {
631 Address SavedAddr = Addr;
632 uint64_t TmpOffset = Addr.getOffset();
633
634 // Iterate through the GEP folding the constants into offsets where
635 // we can.
637 GTI != E; ++GTI) {
638 const Value *Op = GTI.getOperand();
639 if (StructType *STy = GTI.getStructTypeOrNull()) {
640 const StructLayout *SL = DL.getStructLayout(STy);
641 unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
642 TmpOffset += SL->getElementOffset(Idx);
643 } else {
644 uint64_t S = GTI.getSequentialElementStride(DL);
645 while (true) {
646 if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
647 // Constant-offset addressing.
648 TmpOffset += CI->getSExtValue() * S;
649 break;
650 }
651 if (canFoldAddIntoGEP(U, Op)) {
652 // A compatible add with a constant operand. Fold the constant.
653 ConstantInt *CI =
654 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
655 TmpOffset += CI->getSExtValue() * S;
656 // Iterate on the other operand.
657 Op = cast<AddOperator>(Op)->getOperand(0);
658 continue;
659 }
660 // Unsupported
661 goto unsupported_gep;
662 }
663 }
664 }
665
666 // Try to grab the base operand now.
667 Addr.setOffset(TmpOffset);
668 if (computeAddress(U->getOperand(0), Addr, Ty))
669 return true;
670
671 // We failed, restore everything and try the other options.
672 Addr = SavedAddr;
673
674 unsupported_gep:
675 break;
676 }
677 case Instruction::Alloca: {
678 const AllocaInst *AI = cast<AllocaInst>(Obj);
679 auto SI = FuncInfo.StaticAllocaMap.find(AI);
680 if (SI != FuncInfo.StaticAllocaMap.end()) {
681 Addr.setKind(Address::FrameIndexBase);
682 Addr.setFI(SI->second);
683 return true;
684 }
685 break;
686 }
687 case Instruction::Add: {
688 // Adds of constants are common and easy enough.
689 const Value *LHS = U->getOperand(0);
690 const Value *RHS = U->getOperand(1);
691
693 std::swap(LHS, RHS);
694
695 if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
696 Addr.setOffset(Addr.getOffset() + CI->getSExtValue());
697 return computeAddress(LHS, Addr, Ty);
698 }
699
700 Address Backup = Addr;
701 if (computeAddress(LHS, Addr, Ty) && computeAddress(RHS, Addr, Ty))
702 return true;
703 Addr = Backup;
704
705 break;
706 }
707 case Instruction::Sub: {
708 // Subs of constants are common and easy enough.
709 const Value *LHS = U->getOperand(0);
710 const Value *RHS = U->getOperand(1);
711
712 if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
713 Addr.setOffset(Addr.getOffset() - CI->getSExtValue());
714 return computeAddress(LHS, Addr, Ty);
715 }
716 break;
717 }
718 case Instruction::Shl: {
719 if (Addr.getOffsetReg())
720 break;
721
722 const auto *CI = dyn_cast<ConstantInt>(U->getOperand(1));
723 if (!CI)
724 break;
725
726 unsigned Val = CI->getZExtValue();
727 if (Val < 1 || Val > 3)
728 break;
729
730 uint64_t NumBytes = 0;
731 if (Ty && Ty->isSized()) {
732 uint64_t NumBits = DL.getTypeSizeInBits(Ty);
733 NumBytes = NumBits / 8;
734 if (!isPowerOf2_64(NumBits))
735 NumBytes = 0;
736 }
737
738 if (NumBytes != (1ULL << Val))
739 break;
740
741 Addr.setShift(Val);
742 Addr.setExtendType(AArch64_AM::LSL);
743
744 const Value *Src = U->getOperand(0);
745 if (const auto *I = dyn_cast<Instruction>(Src)) {
746 if (FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
747 // Fold the zext or sext when it won't become a noop.
748 if (const auto *ZE = dyn_cast<ZExtInst>(I)) {
749 if (!isIntExtFree(ZE) &&
750 ZE->getOperand(0)->getType()->isIntegerTy(32)) {
751 Addr.setExtendType(AArch64_AM::UXTW);
752 Src = ZE->getOperand(0);
753 }
754 } else if (const auto *SE = dyn_cast<SExtInst>(I)) {
755 if (!isIntExtFree(SE) &&
756 SE->getOperand(0)->getType()->isIntegerTy(32)) {
757 Addr.setExtendType(AArch64_AM::SXTW);
758 Src = SE->getOperand(0);
759 }
760 }
761 }
762 }
763
764 if (const auto *AI = dyn_cast<BinaryOperator>(Src))
765 if (AI->getOpcode() == Instruction::And) {
766 const Value *LHS = AI->getOperand(0);
767 const Value *RHS = AI->getOperand(1);
768
769 if (const auto *C = dyn_cast<ConstantInt>(LHS))
770 if (C->getValue() == 0xffffffff)
771 std::swap(LHS, RHS);
772
773 if (const auto *C = dyn_cast<ConstantInt>(RHS))
774 if (C->getValue() == 0xffffffff) {
775 Addr.setExtendType(AArch64_AM::UXTW);
776 Register Reg = getRegForValue(LHS);
777 if (!Reg)
778 return false;
779 Reg = fastEmitInst_extractsubreg(MVT::i32, Reg, AArch64::sub_32);
780 Addr.setOffsetReg(Reg);
781 return true;
782 }
783 }
784
785 Register Reg = getRegForValue(Src);
786 if (!Reg)
787 return false;
788 Addr.setOffsetReg(Reg);
789 return true;
790 }
791 case Instruction::Mul: {
792 if (Addr.getOffsetReg())
793 break;
794
795 if (!isMulPowOf2(U))
796 break;
797
798 const Value *LHS = U->getOperand(0);
799 const Value *RHS = U->getOperand(1);
800
801 // Canonicalize power-of-2 value to the RHS.
802 if (const auto *C = dyn_cast<ConstantInt>(LHS))
803 if (C->getValue().isPowerOf2())
804 std::swap(LHS, RHS);
805
806 assert(isa<ConstantInt>(RHS) && "Expected an ConstantInt.");
807 const auto *C = cast<ConstantInt>(RHS);
808 unsigned Val = C->getValue().logBase2();
809 if (Val < 1 || Val > 3)
810 break;
811
812 uint64_t NumBytes = 0;
813 if (Ty && Ty->isSized()) {
814 uint64_t NumBits = DL.getTypeSizeInBits(Ty);
815 NumBytes = NumBits / 8;
816 if (!isPowerOf2_64(NumBits))
817 NumBytes = 0;
818 }
819
820 if (NumBytes != (1ULL << Val))
821 break;
822
823 Addr.setShift(Val);
824 Addr.setExtendType(AArch64_AM::LSL);
825
826 const Value *Src = LHS;
827 if (const auto *I = dyn_cast<Instruction>(Src)) {
828 if (FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
829 // Fold the zext or sext when it won't become a noop.
830 if (const auto *ZE = dyn_cast<ZExtInst>(I)) {
831 if (!isIntExtFree(ZE) &&
832 ZE->getOperand(0)->getType()->isIntegerTy(32)) {
833 Addr.setExtendType(AArch64_AM::UXTW);
834 Src = ZE->getOperand(0);
835 }
836 } else if (const auto *SE = dyn_cast<SExtInst>(I)) {
837 if (!isIntExtFree(SE) &&
838 SE->getOperand(0)->getType()->isIntegerTy(32)) {
839 Addr.setExtendType(AArch64_AM::SXTW);
840 Src = SE->getOperand(0);
841 }
842 }
843 }
844 }
845
846 Register Reg = getRegForValue(Src);
847 if (!Reg)
848 return false;
849 Addr.setOffsetReg(Reg);
850 return true;
851 }
852 case Instruction::And: {
853 if (Addr.getOffsetReg())
854 break;
855
856 if (!Ty || DL.getTypeSizeInBits(Ty) != 8)
857 break;
858
859 const Value *LHS = U->getOperand(0);
860 const Value *RHS = U->getOperand(1);
861
862 if (const auto *C = dyn_cast<ConstantInt>(LHS))
863 if (C->getValue() == 0xffffffff)
864 std::swap(LHS, RHS);
865
866 if (const auto *C = dyn_cast<ConstantInt>(RHS))
867 if (C->getValue() == 0xffffffff) {
868 Addr.setShift(0);
869 Addr.setExtendType(AArch64_AM::LSL);
870 Addr.setExtendType(AArch64_AM::UXTW);
871
872 Register Reg = getRegForValue(LHS);
873 if (!Reg)
874 return false;
875 Reg = fastEmitInst_extractsubreg(MVT::i32, Reg, AArch64::sub_32);
876 Addr.setOffsetReg(Reg);
877 return true;
878 }
879 break;
880 }
881 case Instruction::SExt:
882 case Instruction::ZExt: {
883 if (!Addr.getReg() || Addr.getOffsetReg())
884 break;
885
886 const Value *Src = nullptr;
887 // Fold the zext or sext when it won't become a noop.
888 if (const auto *ZE = dyn_cast<ZExtInst>(U)) {
889 if (!isIntExtFree(ZE) && ZE->getOperand(0)->getType()->isIntegerTy(32)) {
890 Addr.setExtendType(AArch64_AM::UXTW);
891 Src = ZE->getOperand(0);
892 }
893 } else if (const auto *SE = dyn_cast<SExtInst>(U)) {
894 if (!isIntExtFree(SE) && SE->getOperand(0)->getType()->isIntegerTy(32)) {
895 Addr.setExtendType(AArch64_AM::SXTW);
896 Src = SE->getOperand(0);
897 }
898 }
899
900 if (!Src)
901 break;
902
903 Addr.setShift(0);
904 Register Reg = getRegForValue(Src);
905 if (!Reg)
906 return false;
907 Addr.setOffsetReg(Reg);
908 return true;
909 }
910 } // end switch
911
912 if (Addr.isRegBase() && !Addr.getReg()) {
913 Register Reg = getRegForValue(Obj);
914 if (!Reg)
915 return false;
916 Addr.setReg(Reg);
917 return true;
918 }
919
920 if (!Addr.getOffsetReg()) {
921 Register Reg = getRegForValue(Obj);
922 if (!Reg)
923 return false;
924 Addr.setOffsetReg(Reg);
925 return true;
926 }
927
928 return false;
929}
930
931bool AArch64FastISel::computeCallAddress(const Value *V, Address &Addr) {
932 const User *U = nullptr;
933 unsigned Opcode = Instruction::UserOp1;
934 bool InMBB = true;
935
936 if (const auto *I = dyn_cast<Instruction>(V)) {
937 Opcode = I->getOpcode();
938 U = I;
939 InMBB = I->getParent() == FuncInfo.MBB->getBasicBlock();
940 } else if (const auto *C = dyn_cast<ConstantExpr>(V)) {
941 Opcode = C->getOpcode();
942 U = C;
943 }
944
945 switch (Opcode) {
946 default: break;
947 case Instruction::BitCast:
948 // Look past bitcasts if its operand is in the same BB.
949 if (InMBB)
950 return computeCallAddress(U->getOperand(0), Addr);
951 break;
952 case Instruction::IntToPtr:
953 // Look past no-op inttoptrs if its operand is in the same BB.
954 if (InMBB &&
955 TLI.getValueType(DL, U->getOperand(0)->getType()) ==
956 TLI.getPointerTy(DL))
957 return computeCallAddress(U->getOperand(0), Addr);
958 break;
959 case Instruction::PtrToInt:
960 // Look past no-op ptrtoints if its operand is in the same BB.
961 if (InMBB && TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
962 return computeCallAddress(U->getOperand(0), Addr);
963 break;
964 }
965
966 if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
967 Addr.setGlobalValue(GV);
968 return true;
969 }
970
971 // If all else fails, try to materialize the value in a register.
972 if (!Addr.getGlobalValue()) {
973 Addr.setReg(getRegForValue(V));
974 return Addr.getReg().isValid();
975 }
976
977 return false;
978}
979
980bool AArch64FastISel::isTypeLegal(Type *Ty, MVT &VT) {
981 EVT evt = TLI.getValueType(DL, Ty, true);
982
983 if (Subtarget->isTargetILP32() && Ty->isPointerTy())
984 return false;
985
986 // Only handle simple types.
987 if (evt == MVT::Other || !evt.isSimple())
988 return false;
989 VT = evt.getSimpleVT();
990
991 // This is a legal type, but it's not something we handle in fast-isel.
992 if (VT == MVT::f128)
993 return false;
994
995 // Handle all other legal types, i.e. a register that will directly hold this
996 // value.
997 return TLI.isTypeLegal(VT);
998}
999
1000/// Determine if the value type is supported by FastISel.
1001///
1002/// FastISel for AArch64 can handle more value types than are legal. This adds
1003/// simple value type such as i1, i8, and i16.
1004bool AArch64FastISel::isTypeSupported(Type *Ty, MVT &VT, bool IsVectorAllowed) {
1005 if (Ty->isVectorTy() && !IsVectorAllowed)
1006 return false;
1007
1008 if (isTypeLegal(Ty, VT))
1009 return true;
1010
1011 // If this is a type than can be sign or zero-extended to a basic operation
1012 // go ahead and accept it now.
1013 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
1014 return true;
1015
1016 return false;
1017}
1018
1019bool AArch64FastISel::isValueAvailable(const Value *V) const {
1020 if (!isa<Instruction>(V))
1021 return true;
1022
1023 const auto *I = cast<Instruction>(V);
1024 return FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB;
1025}
1026
1027bool AArch64FastISel::simplifyAddress(Address &Addr, MVT VT) {
1028 if (Subtarget->isTargetILP32())
1029 return false;
1030
1031 unsigned ScaleFactor = getImplicitScaleFactor(VT);
1032 if (!ScaleFactor)
1033 return false;
1034
1035 bool ImmediateOffsetNeedsLowering = false;
1036 bool RegisterOffsetNeedsLowering = false;
1037 int64_t Offset = Addr.getOffset();
1038 if (((Offset < 0) || (Offset & (ScaleFactor - 1))) && !isInt<9>(Offset))
1039 ImmediateOffsetNeedsLowering = true;
1040 else if (Offset > 0 && !(Offset & (ScaleFactor - 1)) &&
1041 !isUInt<12>(Offset / ScaleFactor))
1042 ImmediateOffsetNeedsLowering = true;
1043
1044 // Cannot encode an offset register and an immediate offset in the same
1045 // instruction. Fold the immediate offset into the load/store instruction and
1046 // emit an additional add to take care of the offset register.
1047 if (!ImmediateOffsetNeedsLowering && Addr.getOffset() && Addr.getOffsetReg())
1048 RegisterOffsetNeedsLowering = true;
1049
1050 // Cannot encode zero register as base.
1051 if (Addr.isRegBase() && Addr.getOffsetReg() && !Addr.getReg())
1052 RegisterOffsetNeedsLowering = true;
1053
1054 // If this is a stack pointer and the offset needs to be simplified then put
1055 // the alloca address into a register, set the base type back to register and
1056 // continue. This should almost never happen.
1057 if ((ImmediateOffsetNeedsLowering || Addr.getOffsetReg()) && Addr.isFIBase())
1058 {
1059 Register ResultReg = createResultReg(&AArch64::GPR64spRegClass);
1060 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADDXri),
1061 ResultReg)
1062 .addFrameIndex(Addr.getFI())
1063 .addImm(0)
1064 .addImm(0);
1065 Addr.setKind(Address::RegBase);
1066 Addr.setReg(ResultReg);
1067 }
1068
1069 if (RegisterOffsetNeedsLowering) {
1070 Register ResultReg;
1071 if (Addr.getReg()) {
1072 if (Addr.getExtendType() == AArch64_AM::SXTW ||
1073 Addr.getExtendType() == AArch64_AM::UXTW )
1074 ResultReg = emitAddSub_rx(/*UseAdd=*/true, MVT::i64, Addr.getReg(),
1075 Addr.getOffsetReg(), Addr.getExtendType(),
1076 Addr.getShift());
1077 else
1078 ResultReg = emitAddSub_rs(/*UseAdd=*/true, MVT::i64, Addr.getReg(),
1079 Addr.getOffsetReg(), AArch64_AM::LSL,
1080 Addr.getShift());
1081 } else {
1082 if (Addr.getExtendType() == AArch64_AM::UXTW)
1083 ResultReg = emitLSL_ri(MVT::i64, MVT::i32, Addr.getOffsetReg(),
1084 Addr.getShift(), /*IsZExt=*/true);
1085 else if (Addr.getExtendType() == AArch64_AM::SXTW)
1086 ResultReg = emitLSL_ri(MVT::i64, MVT::i32, Addr.getOffsetReg(),
1087 Addr.getShift(), /*IsZExt=*/false);
1088 else
1089 ResultReg = emitLSL_ri(MVT::i64, MVT::i64, Addr.getOffsetReg(),
1090 Addr.getShift());
1091 }
1092 if (!ResultReg)
1093 return false;
1094
1095 Addr.setReg(ResultReg);
1096 Addr.setOffsetReg(0);
1097 Addr.setShift(0);
1098 Addr.setExtendType(AArch64_AM::InvalidShiftExtend);
1099 }
1100
1101 // Since the offset is too large for the load/store instruction get the
1102 // reg+offset into a register.
1103 if (ImmediateOffsetNeedsLowering) {
1104 Register ResultReg;
1105 if (Addr.getReg())
1106 // Try to fold the immediate into the add instruction.
1107 ResultReg = emitAdd_ri_(MVT::i64, Addr.getReg(), Offset);
1108 else
1109 ResultReg = fastEmit_i(MVT::i64, MVT::i64, ISD::Constant, Offset);
1110
1111 if (!ResultReg)
1112 return false;
1113 Addr.setReg(ResultReg);
1114 Addr.setOffset(0);
1115 }
1116 return true;
1117}
1118
1119void AArch64FastISel::addLoadStoreOperands(Address &Addr,
1120 const MachineInstrBuilder &MIB,
1122 unsigned ScaleFactor,
1123 MachineMemOperand *MMO) {
1124 int64_t Offset = Addr.getOffset() / ScaleFactor;
1125 // Frame base works a bit differently. Handle it separately.
1126 if (Addr.isFIBase()) {
1127 int FI = Addr.getFI();
1128 // FIXME: We shouldn't be using getObjectSize/getObjectAlignment. The size
1129 // and alignment should be based on the VT.
1130 MMO = FuncInfo.MF->getMachineMemOperand(
1131 MachinePointerInfo::getFixedStack(*FuncInfo.MF, FI, Offset), Flags,
1132 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
1133 // Now add the rest of the operands.
1134 MIB.addFrameIndex(FI).addImm(Offset);
1135 } else {
1136 assert(Addr.isRegBase() && "Unexpected address kind.");
1137 const MCInstrDesc &II = MIB->getDesc();
1138 unsigned Idx = (Flags & MachineMemOperand::MOStore) ? 1 : 0;
1139 Addr.setReg(
1140 constrainOperandRegClass(II, Addr.getReg(), II.getNumDefs()+Idx));
1141 Addr.setOffsetReg(
1142 constrainOperandRegClass(II, Addr.getOffsetReg(), II.getNumDefs()+Idx+1));
1143 if (Addr.getOffsetReg()) {
1144 assert(Addr.getOffset() == 0 && "Unexpected offset");
1145 bool IsSigned = Addr.getExtendType() == AArch64_AM::SXTW ||
1146 Addr.getExtendType() == AArch64_AM::SXTX;
1147 MIB.addReg(Addr.getReg());
1148 MIB.addReg(Addr.getOffsetReg());
1149 MIB.addImm(IsSigned);
1150 MIB.addImm(Addr.getShift() != 0);
1151 } else
1152 MIB.addReg(Addr.getReg()).addImm(Offset);
1153 }
1154
1155 if (MMO)
1156 MIB.addMemOperand(MMO);
1157}
1158
1159Register AArch64FastISel::emitAddSub(bool UseAdd, MVT RetVT, const Value *LHS,
1160 const Value *RHS, bool SetFlags,
1161 bool WantResult, bool IsZExt) {
1163 bool NeedExtend = false;
1164 switch (RetVT.SimpleTy) {
1165 default:
1166 return Register();
1167 case MVT::i1:
1168 NeedExtend = true;
1169 break;
1170 case MVT::i8:
1171 NeedExtend = true;
1172 ExtendType = IsZExt ? AArch64_AM::UXTB : AArch64_AM::SXTB;
1173 break;
1174 case MVT::i16:
1175 NeedExtend = true;
1176 ExtendType = IsZExt ? AArch64_AM::UXTH : AArch64_AM::SXTH;
1177 break;
1178 case MVT::i32: // fall-through
1179 case MVT::i64:
1180 break;
1181 }
1182 MVT SrcVT = RetVT;
1183 RetVT.SimpleTy = std::max(RetVT.SimpleTy, MVT::i32);
1184
1185 // Canonicalize immediates to the RHS first.
1186 if (UseAdd && isa<Constant>(LHS) && !isa<Constant>(RHS))
1187 std::swap(LHS, RHS);
1188
1189 // Canonicalize mul by power of 2 to the RHS.
1190 if (UseAdd && LHS->hasOneUse() && isValueAvailable(LHS))
1191 if (isMulPowOf2(LHS))
1192 std::swap(LHS, RHS);
1193
1194 // Canonicalize shift immediate to the RHS.
1195 if (UseAdd && LHS->hasOneUse() && isValueAvailable(LHS))
1196 if (const auto *SI = dyn_cast<BinaryOperator>(LHS))
1197 if (isa<ConstantInt>(SI->getOperand(1)))
1198 if (SI->getOpcode() == Instruction::Shl ||
1199 SI->getOpcode() == Instruction::LShr ||
1200 SI->getOpcode() == Instruction::AShr )
1201 std::swap(LHS, RHS);
1202
1203 Register LHSReg = getRegForValue(LHS);
1204 if (!LHSReg)
1205 return Register();
1206
1207 if (NeedExtend)
1208 LHSReg = emitIntExt(SrcVT, LHSReg, RetVT, IsZExt);
1209
1210 Register ResultReg;
1211 if (const auto *C = dyn_cast<ConstantInt>(RHS)) {
1212 uint64_t Imm = IsZExt ? C->getZExtValue() : C->getSExtValue();
1213 if (C->isNegative())
1214 ResultReg = emitAddSub_ri(!UseAdd, RetVT, LHSReg, -Imm, SetFlags,
1215 WantResult);
1216 else
1217 ResultReg = emitAddSub_ri(UseAdd, RetVT, LHSReg, Imm, SetFlags,
1218 WantResult);
1219 } else if (const auto *C = dyn_cast<Constant>(RHS))
1220 if (C->isNullValue())
1221 ResultReg = emitAddSub_ri(UseAdd, RetVT, LHSReg, 0, SetFlags, WantResult);
1222
1223 if (ResultReg)
1224 return ResultReg;
1225
1226 // Only extend the RHS within the instruction if there is a valid extend type.
1227 if (ExtendType != AArch64_AM::InvalidShiftExtend && RHS->hasOneUse() &&
1228 isValueAvailable(RHS)) {
1229 Register RHSReg = getRegForValue(RHS);
1230 if (!RHSReg)
1231 return Register();
1232 return emitAddSub_rx(UseAdd, RetVT, LHSReg, RHSReg, ExtendType, 0,
1233 SetFlags, WantResult);
1234 }
1235
1236 // Check if the mul can be folded into the instruction.
1237 if (RHS->hasOneUse() && isValueAvailable(RHS)) {
1238 if (isMulPowOf2(RHS)) {
1239 const Value *MulLHS = cast<MulOperator>(RHS)->getOperand(0);
1240 const Value *MulRHS = cast<MulOperator>(RHS)->getOperand(1);
1241
1242 if (const auto *C = dyn_cast<ConstantInt>(MulLHS))
1243 if (C->getValue().isPowerOf2())
1244 std::swap(MulLHS, MulRHS);
1245
1246 assert(isa<ConstantInt>(MulRHS) && "Expected a ConstantInt.");
1247 uint64_t ShiftVal = cast<ConstantInt>(MulRHS)->getValue().logBase2();
1248 Register RHSReg = getRegForValue(MulLHS);
1249 if (!RHSReg)
1250 return Register();
1251 ResultReg = emitAddSub_rs(UseAdd, RetVT, LHSReg, RHSReg, AArch64_AM::LSL,
1252 ShiftVal, SetFlags, WantResult);
1253 if (ResultReg)
1254 return ResultReg;
1255 }
1256 }
1257
1258 // Check if the shift can be folded into the instruction.
1259 if (RHS->hasOneUse() && isValueAvailable(RHS)) {
1260 if (const auto *SI = dyn_cast<BinaryOperator>(RHS)) {
1261 if (const auto *C = dyn_cast<ConstantInt>(SI->getOperand(1))) {
1263 switch (SI->getOpcode()) {
1264 default: break;
1265 case Instruction::Shl: ShiftType = AArch64_AM::LSL; break;
1266 case Instruction::LShr: ShiftType = AArch64_AM::LSR; break;
1267 case Instruction::AShr: ShiftType = AArch64_AM::ASR; break;
1268 }
1269 uint64_t ShiftVal = C->getZExtValue();
1270 if (ShiftType != AArch64_AM::InvalidShiftExtend) {
1271 Register RHSReg = getRegForValue(SI->getOperand(0));
1272 if (!RHSReg)
1273 return Register();
1274 ResultReg = emitAddSub_rs(UseAdd, RetVT, LHSReg, RHSReg, ShiftType,
1275 ShiftVal, SetFlags, WantResult);
1276 if (ResultReg)
1277 return ResultReg;
1278 }
1279 }
1280 }
1281 }
1282
1283 Register RHSReg = getRegForValue(RHS);
1284 if (!RHSReg)
1285 return Register();
1286
1287 if (NeedExtend)
1288 RHSReg = emitIntExt(SrcVT, RHSReg, RetVT, IsZExt);
1289
1290 return emitAddSub_rr(UseAdd, RetVT, LHSReg, RHSReg, SetFlags, WantResult);
1291}
1292
1293Register AArch64FastISel::emitAddSub_rr(bool UseAdd, MVT RetVT, Register LHSReg,
1294 Register RHSReg, bool SetFlags,
1295 bool WantResult) {
1296 assert(LHSReg && RHSReg && "Invalid register number.");
1297
1298 if (LHSReg == AArch64::SP || LHSReg == AArch64::WSP ||
1299 RHSReg == AArch64::SP || RHSReg == AArch64::WSP)
1300 return Register();
1301
1302 if (RetVT != MVT::i32 && RetVT != MVT::i64)
1303 return Register();
1304
1305 static const unsigned OpcTable[2][2][2] = {
1306 { { AArch64::SUBWrr, AArch64::SUBXrr },
1307 { AArch64::ADDWrr, AArch64::ADDXrr } },
1308 { { AArch64::SUBSWrr, AArch64::SUBSXrr },
1309 { AArch64::ADDSWrr, AArch64::ADDSXrr } }
1310 };
1311 bool Is64Bit = RetVT == MVT::i64;
1312 unsigned Opc = OpcTable[SetFlags][UseAdd][Is64Bit];
1313 const TargetRegisterClass *RC =
1314 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
1315 Register ResultReg;
1316 if (WantResult)
1317 ResultReg = createResultReg(RC);
1318 else
1319 ResultReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
1320
1321 const MCInstrDesc &II = TII.get(Opc);
1322 LHSReg = constrainOperandRegClass(II, LHSReg, II.getNumDefs());
1323 RHSReg = constrainOperandRegClass(II, RHSReg, II.getNumDefs() + 1);
1324 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
1325 .addReg(LHSReg)
1326 .addReg(RHSReg);
1327 return ResultReg;
1328}
1329
1330Register AArch64FastISel::emitAddSub_ri(bool UseAdd, MVT RetVT, Register LHSReg,
1331 uint64_t Imm, bool SetFlags,
1332 bool WantResult) {
1333 assert(LHSReg && "Invalid register number.");
1334
1335 if (RetVT != MVT::i32 && RetVT != MVT::i64)
1336 return Register();
1337
1338 unsigned ShiftImm;
1339 if (isUInt<12>(Imm))
1340 ShiftImm = 0;
1341 else if ((Imm & 0xfff000) == Imm) {
1342 ShiftImm = 12;
1343 Imm >>= 12;
1344 } else
1345 return Register();
1346
1347 static const unsigned OpcTable[2][2][2] = {
1348 { { AArch64::SUBWri, AArch64::SUBXri },
1349 { AArch64::ADDWri, AArch64::ADDXri } },
1350 { { AArch64::SUBSWri, AArch64::SUBSXri },
1351 { AArch64::ADDSWri, AArch64::ADDSXri } }
1352 };
1353 bool Is64Bit = RetVT == MVT::i64;
1354 unsigned Opc = OpcTable[SetFlags][UseAdd][Is64Bit];
1355 const TargetRegisterClass *RC;
1356 if (SetFlags)
1357 RC = Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
1358 else
1359 RC = Is64Bit ? &AArch64::GPR64spRegClass : &AArch64::GPR32spRegClass;
1360 Register ResultReg;
1361 if (WantResult)
1362 ResultReg = createResultReg(RC);
1363 else
1364 ResultReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
1365
1366 const MCInstrDesc &II = TII.get(Opc);
1367 LHSReg = constrainOperandRegClass(II, LHSReg, II.getNumDefs());
1368 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
1369 .addReg(LHSReg)
1370 .addImm(Imm)
1371 .addImm(getShifterImm(AArch64_AM::LSL, ShiftImm));
1372 return ResultReg;
1373}
1374
1375Register AArch64FastISel::emitAddSub_rs(bool UseAdd, MVT RetVT, Register LHSReg,
1376 Register RHSReg,
1378 uint64_t ShiftImm, bool SetFlags,
1379 bool WantResult) {
1380 assert(LHSReg && RHSReg && "Invalid register number.");
1381 assert(LHSReg != AArch64::SP && LHSReg != AArch64::WSP &&
1382 RHSReg != AArch64::SP && RHSReg != AArch64::WSP);
1383
1384 if (RetVT != MVT::i32 && RetVT != MVT::i64)
1385 return Register();
1386
1387 // Don't deal with undefined shifts.
1388 if (ShiftImm >= RetVT.getSizeInBits())
1389 return Register();
1390
1391 static const unsigned OpcTable[2][2][2] = {
1392 { { AArch64::SUBWrs, AArch64::SUBXrs },
1393 { AArch64::ADDWrs, AArch64::ADDXrs } },
1394 { { AArch64::SUBSWrs, AArch64::SUBSXrs },
1395 { AArch64::ADDSWrs, AArch64::ADDSXrs } }
1396 };
1397 bool Is64Bit = RetVT == MVT::i64;
1398 unsigned Opc = OpcTable[SetFlags][UseAdd][Is64Bit];
1399 const TargetRegisterClass *RC =
1400 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
1401 Register ResultReg;
1402 if (WantResult)
1403 ResultReg = createResultReg(RC);
1404 else
1405 ResultReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
1406
1407 const MCInstrDesc &II = TII.get(Opc);
1408 LHSReg = constrainOperandRegClass(II, LHSReg, II.getNumDefs());
1409 RHSReg = constrainOperandRegClass(II, RHSReg, II.getNumDefs() + 1);
1410 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
1411 .addReg(LHSReg)
1412 .addReg(RHSReg)
1413 .addImm(getShifterImm(ShiftType, ShiftImm));
1414 return ResultReg;
1415}
1416
1417Register AArch64FastISel::emitAddSub_rx(bool UseAdd, MVT RetVT, Register LHSReg,
1418 Register RHSReg,
1420 uint64_t ShiftImm, bool SetFlags,
1421 bool WantResult) {
1422 assert(LHSReg && RHSReg && "Invalid register number.");
1423 assert(LHSReg != AArch64::XZR && LHSReg != AArch64::WZR &&
1424 RHSReg != AArch64::XZR && RHSReg != AArch64::WZR);
1425
1426 if (RetVT != MVT::i32 && RetVT != MVT::i64)
1427 return Register();
1428
1429 if (ShiftImm >= 4)
1430 return Register();
1431
1432 static const unsigned OpcTable[2][2][2] = {
1433 { { AArch64::SUBWrx, AArch64::SUBXrx },
1434 { AArch64::ADDWrx, AArch64::ADDXrx } },
1435 { { AArch64::SUBSWrx, AArch64::SUBSXrx },
1436 { AArch64::ADDSWrx, AArch64::ADDSXrx } }
1437 };
1438 bool Is64Bit = RetVT == MVT::i64;
1439 unsigned Opc = OpcTable[SetFlags][UseAdd][Is64Bit];
1440 const TargetRegisterClass *RC = nullptr;
1441 if (SetFlags)
1442 RC = Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
1443 else
1444 RC = Is64Bit ? &AArch64::GPR64spRegClass : &AArch64::GPR32spRegClass;
1445 Register ResultReg;
1446 if (WantResult)
1447 ResultReg = createResultReg(RC);
1448 else
1449 ResultReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
1450
1451 const MCInstrDesc &II = TII.get(Opc);
1452 LHSReg = constrainOperandRegClass(II, LHSReg, II.getNumDefs());
1453 RHSReg = constrainOperandRegClass(II, RHSReg, II.getNumDefs() + 1);
1454 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)
1455 .addReg(LHSReg)
1456 .addReg(RHSReg)
1457 .addImm(getArithExtendImm(ExtType, ShiftImm));
1458 return ResultReg;
1459}
1460
1461bool AArch64FastISel::emitCmp(const Value *LHS, const Value *RHS, bool IsZExt) {
1462 Type *Ty = LHS->getType();
1463 EVT EVT = TLI.getValueType(DL, Ty, true);
1464 if (!EVT.isSimple())
1465 return false;
1466 MVT VT = EVT.getSimpleVT();
1467
1468 switch (VT.SimpleTy) {
1469 default:
1470 return false;
1471 case MVT::i1:
1472 case MVT::i8:
1473 case MVT::i16:
1474 case MVT::i32:
1475 case MVT::i64:
1476 return emitICmp(VT, LHS, RHS, IsZExt);
1477 case MVT::f32:
1478 case MVT::f64:
1479 return emitFCmp(VT, LHS, RHS);
1480 }
1481}
1482
1483bool AArch64FastISel::emitICmp(MVT RetVT, const Value *LHS, const Value *RHS,
1484 bool IsZExt) {
1485 return emitSub(RetVT, LHS, RHS, /*SetFlags=*/true, /*WantResult=*/false,
1486 IsZExt)
1487 .isValid();
1488}
1489
1490bool AArch64FastISel::emitICmp_ri(MVT RetVT, Register LHSReg, uint64_t Imm) {
1491 return emitAddSub_ri(/*UseAdd=*/false, RetVT, LHSReg, Imm,
1492 /*SetFlags=*/true, /*WantResult=*/false)
1493 .isValid();
1494}
1495
1496bool AArch64FastISel::emitFCmp(MVT RetVT, const Value *LHS, const Value *RHS) {
1497 if (RetVT != MVT::f32 && RetVT != MVT::f64)
1498 return false;
1499
1500 // Check to see if the 2nd operand is a constant that we can encode directly
1501 // in the compare.
1502 bool UseImm = false;
1503 if (const auto *CFP = dyn_cast<ConstantFP>(RHS))
1504 if (CFP->isZero() && !CFP->isNegative())
1505 UseImm = true;
1506
1507 Register LHSReg = getRegForValue(LHS);
1508 if (!LHSReg)
1509 return false;
1510
1511 if (UseImm) {
1512 unsigned Opc = (RetVT == MVT::f64) ? AArch64::FCMPDri : AArch64::FCMPSri;
1513 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
1514 .addReg(LHSReg);
1515 return true;
1516 }
1517
1518 Register RHSReg = getRegForValue(RHS);
1519 if (!RHSReg)
1520 return false;
1521
1522 unsigned Opc = (RetVT == MVT::f64) ? AArch64::FCMPDrr : AArch64::FCMPSrr;
1523 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
1524 .addReg(LHSReg)
1525 .addReg(RHSReg);
1526 return true;
1527}
1528
1529Register AArch64FastISel::emitAdd(MVT RetVT, const Value *LHS, const Value *RHS,
1530 bool SetFlags, bool WantResult, bool IsZExt) {
1531 return emitAddSub(/*UseAdd=*/true, RetVT, LHS, RHS, SetFlags, WantResult,
1532 IsZExt);
1533}
1534
1535/// This method is a wrapper to simplify add emission.
1536///
1537/// First try to emit an add with an immediate operand using emitAddSub_ri. If
1538/// that fails, then try to materialize the immediate into a register and use
1539/// emitAddSub_rr instead.
1540Register AArch64FastISel::emitAdd_ri_(MVT VT, Register Op0, int64_t Imm) {
1541 Register ResultReg;
1542 if (Imm < 0)
1543 ResultReg = emitAddSub_ri(false, VT, Op0, -Imm);
1544 else
1545 ResultReg = emitAddSub_ri(true, VT, Op0, Imm);
1546
1547 if (ResultReg)
1548 return ResultReg;
1549
1550 Register CReg = fastEmit_i(VT, VT, ISD::Constant, Imm);
1551 if (!CReg)
1552 return Register();
1553
1554 ResultReg = emitAddSub_rr(true, VT, Op0, CReg);
1555 return ResultReg;
1556}
1557
1558Register AArch64FastISel::emitSub(MVT RetVT, const Value *LHS, const Value *RHS,
1559 bool SetFlags, bool WantResult, bool IsZExt) {
1560 return emitAddSub(/*UseAdd=*/false, RetVT, LHS, RHS, SetFlags, WantResult,
1561 IsZExt);
1562}
1563
1564Register AArch64FastISel::emitSubs_rr(MVT RetVT, Register LHSReg,
1565 Register RHSReg, bool WantResult) {
1566 return emitAddSub_rr(/*UseAdd=*/false, RetVT, LHSReg, RHSReg,
1567 /*SetFlags=*/true, WantResult);
1568}
1569
1570Register AArch64FastISel::emitSubs_rs(MVT RetVT, Register LHSReg,
1571 Register RHSReg,
1573 uint64_t ShiftImm, bool WantResult) {
1574 return emitAddSub_rs(/*UseAdd=*/false, RetVT, LHSReg, RHSReg, ShiftType,
1575 ShiftImm, /*SetFlags=*/true, WantResult);
1576}
1577
1578Register AArch64FastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,
1579 const Value *LHS, const Value *RHS) {
1580 // Canonicalize immediates to the RHS first.
1582 std::swap(LHS, RHS);
1583
1584 // Canonicalize mul by power-of-2 to the RHS.
1585 if (LHS->hasOneUse() && isValueAvailable(LHS))
1586 if (isMulPowOf2(LHS))
1587 std::swap(LHS, RHS);
1588
1589 // Canonicalize shift immediate to the RHS.
1590 if (LHS->hasOneUse() && isValueAvailable(LHS))
1591 if (const auto *SI = dyn_cast<ShlOperator>(LHS))
1592 if (isa<ConstantInt>(SI->getOperand(1)))
1593 std::swap(LHS, RHS);
1594
1595 Register LHSReg = getRegForValue(LHS);
1596 if (!LHSReg)
1597 return Register();
1598
1599 Register ResultReg;
1600 if (const auto *C = dyn_cast<ConstantInt>(RHS)) {
1601 uint64_t Imm = C->getZExtValue();
1602 ResultReg = emitLogicalOp_ri(ISDOpc, RetVT, LHSReg, Imm);
1603 }
1604 if (ResultReg)
1605 return ResultReg;
1606
1607 // Check if the mul can be folded into the instruction.
1608 if (RHS->hasOneUse() && isValueAvailable(RHS)) {
1609 if (isMulPowOf2(RHS)) {
1610 const Value *MulLHS = cast<MulOperator>(RHS)->getOperand(0);
1611 const Value *MulRHS = cast<MulOperator>(RHS)->getOperand(1);
1612
1613 if (const auto *C = dyn_cast<ConstantInt>(MulLHS))
1614 if (C->getValue().isPowerOf2())
1615 std::swap(MulLHS, MulRHS);
1616
1617 assert(isa<ConstantInt>(MulRHS) && "Expected a ConstantInt.");
1618 uint64_t ShiftVal = cast<ConstantInt>(MulRHS)->getValue().logBase2();
1619
1620 Register RHSReg = getRegForValue(MulLHS);
1621 if (!RHSReg)
1622 return Register();
1623 ResultReg = emitLogicalOp_rs(ISDOpc, RetVT, LHSReg, RHSReg, ShiftVal);
1624 if (ResultReg)
1625 return ResultReg;
1626 }
1627 }
1628
1629 // Check if the shift can be folded into the instruction.
1630 if (RHS->hasOneUse() && isValueAvailable(RHS)) {
1631 if (const auto *SI = dyn_cast<ShlOperator>(RHS))
1632 if (const auto *C = dyn_cast<ConstantInt>(SI->getOperand(1))) {
1633 uint64_t ShiftVal = C->getZExtValue();
1634 Register RHSReg = getRegForValue(SI->getOperand(0));
1635 if (!RHSReg)
1636 return Register();
1637 ResultReg = emitLogicalOp_rs(ISDOpc, RetVT, LHSReg, RHSReg, ShiftVal);
1638 if (ResultReg)
1639 return ResultReg;
1640 }
1641 }
1642
1643 Register RHSReg = getRegForValue(RHS);
1644 if (!RHSReg)
1645 return Register();
1646
1647 MVT VT = std::max(MVT::i32, RetVT.SimpleTy);
1648 ResultReg = fastEmit_rr(VT, VT, ISDOpc, LHSReg, RHSReg);
1649 if (RetVT >= MVT::i8 && RetVT <= MVT::i16) {
1650 uint64_t Mask = (RetVT == MVT::i8) ? 0xff : 0xffff;
1651 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
1652 }
1653 return ResultReg;
1654}
1655
1656Register AArch64FastISel::emitLogicalOp_ri(unsigned ISDOpc, MVT RetVT,
1657 Register LHSReg, uint64_t Imm) {
1658 static_assert((ISD::AND + 1 == ISD::OR) && (ISD::AND + 2 == ISD::XOR),
1659 "ISD nodes are not consecutive!");
1660 static const unsigned OpcTable[3][2] = {
1661 { AArch64::ANDWri, AArch64::ANDXri },
1662 { AArch64::ORRWri, AArch64::ORRXri },
1663 { AArch64::EORWri, AArch64::EORXri }
1664 };
1665 const TargetRegisterClass *RC;
1666 unsigned Opc;
1667 unsigned RegSize;
1668 switch (RetVT.SimpleTy) {
1669 default:
1670 return Register();
1671 case MVT::i1:
1672 case MVT::i8:
1673 case MVT::i16:
1674 case MVT::i32: {
1675 unsigned Idx = ISDOpc - ISD::AND;
1676 Opc = OpcTable[Idx][0];
1677 RC = &AArch64::GPR32spRegClass;
1678 RegSize = 32;
1679 break;
1680 }
1681 case MVT::i64:
1682 Opc = OpcTable[ISDOpc - ISD::AND][1];
1683 RC = &AArch64::GPR64spRegClass;
1684 RegSize = 64;
1685 break;
1686 }
1687
1689 return Register();
1690
1691 Register ResultReg =
1692 fastEmitInst_ri(Opc, RC, LHSReg,
1694 if (RetVT >= MVT::i8 && RetVT <= MVT::i16 && ISDOpc != ISD::AND) {
1695 uint64_t Mask = (RetVT == MVT::i8) ? 0xff : 0xffff;
1696 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
1697 }
1698 return ResultReg;
1699}
1700
1701Register AArch64FastISel::emitLogicalOp_rs(unsigned ISDOpc, MVT RetVT,
1702 Register LHSReg, Register RHSReg,
1703 uint64_t ShiftImm) {
1704 static_assert((ISD::AND + 1 == ISD::OR) && (ISD::AND + 2 == ISD::XOR),
1705 "ISD nodes are not consecutive!");
1706 static const unsigned OpcTable[3][2] = {
1707 { AArch64::ANDWrs, AArch64::ANDXrs },
1708 { AArch64::ORRWrs, AArch64::ORRXrs },
1709 { AArch64::EORWrs, AArch64::EORXrs }
1710 };
1711
1712 // Don't deal with undefined shifts.
1713 if (ShiftImm >= RetVT.getSizeInBits())
1714 return Register();
1715
1716 const TargetRegisterClass *RC;
1717 unsigned Opc;
1718 switch (RetVT.SimpleTy) {
1719 default:
1720 return Register();
1721 case MVT::i1:
1722 case MVT::i8:
1723 case MVT::i16:
1724 case MVT::i32:
1725 Opc = OpcTable[ISDOpc - ISD::AND][0];
1726 RC = &AArch64::GPR32RegClass;
1727 break;
1728 case MVT::i64:
1729 Opc = OpcTable[ISDOpc - ISD::AND][1];
1730 RC = &AArch64::GPR64RegClass;
1731 break;
1732 }
1733 Register ResultReg =
1734 fastEmitInst_rri(Opc, RC, LHSReg, RHSReg,
1736 if (RetVT >= MVT::i8 && RetVT <= MVT::i16) {
1737 uint64_t Mask = (RetVT == MVT::i8) ? 0xff : 0xffff;
1738 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
1739 }
1740 return ResultReg;
1741}
1742
1743Register AArch64FastISel::emitAnd_ri(MVT RetVT, Register LHSReg, uint64_t Imm) {
1744 return emitLogicalOp_ri(ISD::AND, RetVT, LHSReg, Imm);
1745}
1746
1747Register AArch64FastISel::emitLoad(MVT VT, MVT RetVT, Address Addr,
1748 bool WantZExt, MachineMemOperand *MMO) {
1749 if (!TLI.allowsMisalignedMemoryAccesses(VT))
1750 return Register();
1751
1752 // Simplify this down to something we can handle.
1753 if (!simplifyAddress(Addr, VT))
1754 return Register();
1755
1756 unsigned ScaleFactor = getImplicitScaleFactor(VT);
1757 if (!ScaleFactor)
1758 llvm_unreachable("Unexpected value type.");
1759
1760 // Negative offsets require unscaled, 9-bit, signed immediate offsets.
1761 // Otherwise, we try using scaled, 12-bit, unsigned immediate offsets.
1762 bool UseScaled = true;
1763 if ((Addr.getOffset() < 0) || (Addr.getOffset() & (ScaleFactor - 1))) {
1764 UseScaled = false;
1765 ScaleFactor = 1;
1766 }
1767
1768 static const unsigned GPOpcTable[2][8][4] = {
1769 // Sign-extend.
1770 { { AArch64::LDURSBWi, AArch64::LDURSHWi, AArch64::LDURWi,
1771 AArch64::LDURXi },
1772 { AArch64::LDURSBXi, AArch64::LDURSHXi, AArch64::LDURSWi,
1773 AArch64::LDURXi },
1774 { AArch64::LDRSBWui, AArch64::LDRSHWui, AArch64::LDRWui,
1775 AArch64::LDRXui },
1776 { AArch64::LDRSBXui, AArch64::LDRSHXui, AArch64::LDRSWui,
1777 AArch64::LDRXui },
1778 { AArch64::LDRSBWroX, AArch64::LDRSHWroX, AArch64::LDRWroX,
1779 AArch64::LDRXroX },
1780 { AArch64::LDRSBXroX, AArch64::LDRSHXroX, AArch64::LDRSWroX,
1781 AArch64::LDRXroX },
1782 { AArch64::LDRSBWroW, AArch64::LDRSHWroW, AArch64::LDRWroW,
1783 AArch64::LDRXroW },
1784 { AArch64::LDRSBXroW, AArch64::LDRSHXroW, AArch64::LDRSWroW,
1785 AArch64::LDRXroW }
1786 },
1787 // Zero-extend.
1788 { { AArch64::LDURBBi, AArch64::LDURHHi, AArch64::LDURWi,
1789 AArch64::LDURXi },
1790 { AArch64::LDURBBi, AArch64::LDURHHi, AArch64::LDURWi,
1791 AArch64::LDURXi },
1792 { AArch64::LDRBBui, AArch64::LDRHHui, AArch64::LDRWui,
1793 AArch64::LDRXui },
1794 { AArch64::LDRBBui, AArch64::LDRHHui, AArch64::LDRWui,
1795 AArch64::LDRXui },
1796 { AArch64::LDRBBroX, AArch64::LDRHHroX, AArch64::LDRWroX,
1797 AArch64::LDRXroX },
1798 { AArch64::LDRBBroX, AArch64::LDRHHroX, AArch64::LDRWroX,
1799 AArch64::LDRXroX },
1800 { AArch64::LDRBBroW, AArch64::LDRHHroW, AArch64::LDRWroW,
1801 AArch64::LDRXroW },
1802 { AArch64::LDRBBroW, AArch64::LDRHHroW, AArch64::LDRWroW,
1803 AArch64::LDRXroW }
1804 }
1805 };
1806
1807 static const unsigned FPOpcTable[4][2] = {
1808 { AArch64::LDURSi, AArch64::LDURDi },
1809 { AArch64::LDRSui, AArch64::LDRDui },
1810 { AArch64::LDRSroX, AArch64::LDRDroX },
1811 { AArch64::LDRSroW, AArch64::LDRDroW }
1812 };
1813
1814 unsigned Opc;
1815 const TargetRegisterClass *RC;
1816 bool UseRegOffset = Addr.isRegBase() && !Addr.getOffset() && Addr.getReg() &&
1817 Addr.getOffsetReg();
1818 unsigned Idx = UseRegOffset ? 2 : UseScaled ? 1 : 0;
1819 if (Addr.getExtendType() == AArch64_AM::UXTW ||
1820 Addr.getExtendType() == AArch64_AM::SXTW)
1821 Idx++;
1822
1823 bool IsRet64Bit = RetVT == MVT::i64;
1824 switch (VT.SimpleTy) {
1825 default:
1826 llvm_unreachable("Unexpected value type.");
1827 case MVT::i1: // Intentional fall-through.
1828 case MVT::i8:
1829 Opc = GPOpcTable[WantZExt][2 * Idx + IsRet64Bit][0];
1830 RC = (IsRet64Bit && !WantZExt) ?
1831 &AArch64::GPR64RegClass: &AArch64::GPR32RegClass;
1832 break;
1833 case MVT::i16:
1834 Opc = GPOpcTable[WantZExt][2 * Idx + IsRet64Bit][1];
1835 RC = (IsRet64Bit && !WantZExt) ?
1836 &AArch64::GPR64RegClass: &AArch64::GPR32RegClass;
1837 break;
1838 case MVT::i32:
1839 Opc = GPOpcTable[WantZExt][2 * Idx + IsRet64Bit][2];
1840 RC = (IsRet64Bit && !WantZExt) ?
1841 &AArch64::GPR64RegClass: &AArch64::GPR32RegClass;
1842 break;
1843 case MVT::i64:
1844 Opc = GPOpcTable[WantZExt][2 * Idx + IsRet64Bit][3];
1845 RC = &AArch64::GPR64RegClass;
1846 break;
1847 case MVT::f32:
1848 Opc = FPOpcTable[Idx][0];
1849 RC = &AArch64::FPR32RegClass;
1850 break;
1851 case MVT::f64:
1852 Opc = FPOpcTable[Idx][1];
1853 RC = &AArch64::FPR64RegClass;
1854 break;
1855 }
1856
1857 // Create the base instruction, then add the operands.
1858 Register ResultReg = createResultReg(RC);
1859 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1860 TII.get(Opc), ResultReg);
1861 addLoadStoreOperands(Addr, MIB, MachineMemOperand::MOLoad, ScaleFactor, MMO);
1862
1863 // Loading an i1 requires special handling.
1864 if (VT == MVT::i1) {
1865 Register ANDReg = emitAnd_ri(MVT::i32, ResultReg, 1);
1866 assert(ANDReg && "Unexpected AND instruction emission failure.");
1867 ResultReg = ANDReg;
1868 }
1869
1870 // For zero-extending loads to 64bit we emit a 32bit load and then convert
1871 // the 32bit reg to a 64bit reg.
1872 if (WantZExt && RetVT == MVT::i64 && VT <= MVT::i32) {
1873 Register Reg64 = createResultReg(&AArch64::GPR64RegClass);
1874 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1875 TII.get(AArch64::SUBREG_TO_REG), Reg64)
1876 .addReg(ResultReg, getKillRegState(true))
1877 .addImm(AArch64::sub_32);
1878 ResultReg = Reg64;
1879 }
1880 return ResultReg;
1881}
1882
1883bool AArch64FastISel::selectAddSub(const Instruction *I) {
1884 MVT VT;
1885 if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true))
1886 return false;
1887
1888 if (VT.isVector())
1889 return selectOperator(I, I->getOpcode());
1890
1891 Register ResultReg;
1892 switch (I->getOpcode()) {
1893 default:
1894 llvm_unreachable("Unexpected instruction.");
1895 case Instruction::Add:
1896 ResultReg = emitAdd(VT, I->getOperand(0), I->getOperand(1));
1897 break;
1898 case Instruction::Sub:
1899 ResultReg = emitSub(VT, I->getOperand(0), I->getOperand(1));
1900 break;
1901 }
1902 if (!ResultReg)
1903 return false;
1904
1905 updateValueMap(I, ResultReg);
1906 return true;
1907}
1908
1909bool AArch64FastISel::selectLogicalOp(const Instruction *I) {
1910 MVT VT;
1911 if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true))
1912 return false;
1913
1914 if (VT.isVector())
1915 return selectOperator(I, I->getOpcode());
1916
1917 Register ResultReg;
1918 switch (I->getOpcode()) {
1919 default:
1920 llvm_unreachable("Unexpected instruction.");
1921 case Instruction::And:
1922 ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));
1923 break;
1924 case Instruction::Or:
1925 ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));
1926 break;
1927 case Instruction::Xor:
1928 ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));
1929 break;
1930 }
1931 if (!ResultReg)
1932 return false;
1933
1934 updateValueMap(I, ResultReg);
1935 return true;
1936}
1937
1938bool AArch64FastISel::selectLoad(const Instruction *I) {
1939 MVT VT;
1940 // Verify we have a legal type before going any further. Currently, we handle
1941 // simple types that will directly fit in a register (i32/f32/i64/f64) or
1942 // those that can be sign or zero-extended to a basic operation (i1/i8/i16).
1943 if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true) ||
1944 cast<LoadInst>(I)->isAtomic())
1945 return false;
1946
1947 const Value *SV = I->getOperand(0);
1948 if (TLI.supportSwiftError()) {
1949 // Swifterror values can come from either a function parameter with
1950 // swifterror attribute or an alloca with swifterror attribute.
1951 if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1952 if (Arg->hasSwiftErrorAttr())
1953 return false;
1954 }
1955
1956 if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1957 if (Alloca->isSwiftError())
1958 return false;
1959 }
1960 }
1961
1962 // See if we can handle this address.
1963 Address Addr;
1964 if (!computeAddress(I->getOperand(0), Addr, I->getType()))
1965 return false;
1966
1967 // Fold the following sign-/zero-extend into the load instruction.
1968 bool WantZExt = true;
1969 MVT RetVT = VT;
1970 const Value *IntExtVal = nullptr;
1971 if (I->hasOneUse()) {
1972 if (const auto *ZE = dyn_cast<ZExtInst>(I->use_begin()->getUser())) {
1973 if (isTypeSupported(ZE->getType(), RetVT))
1974 IntExtVal = ZE;
1975 else
1976 RetVT = VT;
1977 } else if (const auto *SE = dyn_cast<SExtInst>(I->use_begin()->getUser())) {
1978 if (isTypeSupported(SE->getType(), RetVT))
1979 IntExtVal = SE;
1980 else
1981 RetVT = VT;
1982 WantZExt = false;
1983 }
1984 }
1985
1986 Register ResultReg =
1987 emitLoad(VT, RetVT, Addr, WantZExt, createMachineMemOperandFor(I));
1988 if (!ResultReg)
1989 return false;
1990
1991 // There are a few different cases we have to handle, because the load or the
1992 // sign-/zero-extend might not be selected by FastISel if we fall-back to
1993 // SelectionDAG. There is also an ordering issue when both instructions are in
1994 // different basic blocks.
1995 // 1.) The load instruction is selected by FastISel, but the integer extend
1996 // not. This usually happens when the integer extend is in a different
1997 // basic block and SelectionDAG took over for that basic block.
1998 // 2.) The load instruction is selected before the integer extend. This only
1999 // happens when the integer extend is in a different basic block.
2000 // 3.) The load instruction is selected by SelectionDAG and the integer extend
2001 // by FastISel. This happens if there are instructions between the load
2002 // and the integer extend that couldn't be selected by FastISel.
2003 if (IntExtVal) {
2004 // The integer extend hasn't been emitted yet. FastISel or SelectionDAG
2005 // could select it. Emit a copy to subreg if necessary. FastISel will remove
2006 // it when it selects the integer extend.
2007 Register Reg = lookUpRegForValue(IntExtVal);
2008 auto *MI = MRI.getUniqueVRegDef(Reg);
2009 if (!MI) {
2010 if (RetVT == MVT::i64 && VT <= MVT::i32) {
2011 if (WantZExt) {
2012 // Delete the last emitted instruction from emitLoad (SUBREG_TO_REG).
2013 MachineBasicBlock::iterator I(std::prev(FuncInfo.InsertPt));
2014 ResultReg = std::prev(I)->getOperand(0).getReg();
2015 removeDeadCode(I, std::next(I));
2016 } else
2017 ResultReg = fastEmitInst_extractsubreg(MVT::i32, ResultReg,
2018 AArch64::sub_32);
2019 }
2020 updateValueMap(I, ResultReg);
2021 return true;
2022 }
2023
2024 // The integer extend has already been emitted - delete all the instructions
2025 // that have been emitted by the integer extend lowering code and use the
2026 // result from the load instruction directly.
2027 while (MI) {
2028 Reg = 0;
2029 for (auto &Opnd : MI->uses()) {
2030 if (Opnd.isReg()) {
2031 Reg = Opnd.getReg();
2032 break;
2033 }
2034 }
2036 removeDeadCode(I, std::next(I));
2037 MI = nullptr;
2038 if (Reg)
2039 MI = MRI.getUniqueVRegDef(Reg);
2040 }
2041 updateValueMap(IntExtVal, ResultReg);
2042 return true;
2043 }
2044
2045 updateValueMap(I, ResultReg);
2046 return true;
2047}
2048
2049bool AArch64FastISel::emitStoreRelease(MVT VT, Register SrcReg,
2050 Register AddrReg,
2051 MachineMemOperand *MMO) {
2052 unsigned Opc;
2053 switch (VT.SimpleTy) {
2054 default: return false;
2055 case MVT::i8: Opc = AArch64::STLRB; break;
2056 case MVT::i16: Opc = AArch64::STLRH; break;
2057 case MVT::i32: Opc = AArch64::STLRW; break;
2058 case MVT::i64: Opc = AArch64::STLRX; break;
2059 }
2060
2061 const MCInstrDesc &II = TII.get(Opc);
2062 SrcReg = constrainOperandRegClass(II, SrcReg, 0);
2063 AddrReg = constrainOperandRegClass(II, AddrReg, 1);
2064 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
2065 .addReg(SrcReg)
2066 .addReg(AddrReg)
2067 .addMemOperand(MMO);
2068 return true;
2069}
2070
2071bool AArch64FastISel::emitStore(MVT VT, Register SrcReg, Address Addr,
2072 MachineMemOperand *MMO) {
2073 if (!TLI.allowsMisalignedMemoryAccesses(VT))
2074 return false;
2075
2076 // Simplify this down to something we can handle.
2077 if (!simplifyAddress(Addr, VT))
2078 return false;
2079
2080 unsigned ScaleFactor = getImplicitScaleFactor(VT);
2081 if (!ScaleFactor)
2082 llvm_unreachable("Unexpected value type.");
2083
2084 // Negative offsets require unscaled, 9-bit, signed immediate offsets.
2085 // Otherwise, we try using scaled, 12-bit, unsigned immediate offsets.
2086 bool UseScaled = true;
2087 if ((Addr.getOffset() < 0) || (Addr.getOffset() & (ScaleFactor - 1))) {
2088 UseScaled = false;
2089 ScaleFactor = 1;
2090 }
2091
2092 static const unsigned OpcTable[4][6] = {
2093 { AArch64::STURBBi, AArch64::STURHHi, AArch64::STURWi, AArch64::STURXi,
2094 AArch64::STURSi, AArch64::STURDi },
2095 { AArch64::STRBBui, AArch64::STRHHui, AArch64::STRWui, AArch64::STRXui,
2096 AArch64::STRSui, AArch64::STRDui },
2097 { AArch64::STRBBroX, AArch64::STRHHroX, AArch64::STRWroX, AArch64::STRXroX,
2098 AArch64::STRSroX, AArch64::STRDroX },
2099 { AArch64::STRBBroW, AArch64::STRHHroW, AArch64::STRWroW, AArch64::STRXroW,
2100 AArch64::STRSroW, AArch64::STRDroW }
2101 };
2102
2103 unsigned Opc;
2104 bool VTIsi1 = false;
2105 bool UseRegOffset = Addr.isRegBase() && !Addr.getOffset() && Addr.getReg() &&
2106 Addr.getOffsetReg();
2107 unsigned Idx = UseRegOffset ? 2 : UseScaled ? 1 : 0;
2108 if (Addr.getExtendType() == AArch64_AM::UXTW ||
2109 Addr.getExtendType() == AArch64_AM::SXTW)
2110 Idx++;
2111
2112 switch (VT.SimpleTy) {
2113 default: llvm_unreachable("Unexpected value type.");
2114 case MVT::i1: VTIsi1 = true; [[fallthrough]];
2115 case MVT::i8: Opc = OpcTable[Idx][0]; break;
2116 case MVT::i16: Opc = OpcTable[Idx][1]; break;
2117 case MVT::i32: Opc = OpcTable[Idx][2]; break;
2118 case MVT::i64: Opc = OpcTable[Idx][3]; break;
2119 case MVT::f32: Opc = OpcTable[Idx][4]; break;
2120 case MVT::f64: Opc = OpcTable[Idx][5]; break;
2121 }
2122
2123 // Storing an i1 requires special handling.
2124 if (VTIsi1 && SrcReg != AArch64::WZR) {
2125 Register ANDReg = emitAnd_ri(MVT::i32, SrcReg, 1);
2126 assert(ANDReg && "Unexpected AND instruction emission failure.");
2127 SrcReg = ANDReg;
2128 }
2129 // Create the base instruction, then add the operands.
2130 const MCInstrDesc &II = TII.get(Opc);
2131 SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs());
2132 MachineInstrBuilder MIB =
2133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addReg(SrcReg);
2134 addLoadStoreOperands(Addr, MIB, MachineMemOperand::MOStore, ScaleFactor, MMO);
2135
2136 return true;
2137}
2138
2139bool AArch64FastISel::selectStore(const Instruction *I) {
2140 MVT VT;
2141 const Value *Op0 = I->getOperand(0);
2142 // Verify we have a legal type before going any further. Currently, we handle
2143 // simple types that will directly fit in a register (i32/f32/i64/f64) or
2144 // those that can be sign or zero-extended to a basic operation (i1/i8/i16).
2145 if (!isTypeSupported(Op0->getType(), VT, /*IsVectorAllowed=*/true))
2146 return false;
2147
2148 const Value *PtrV = I->getOperand(1);
2149 if (TLI.supportSwiftError()) {
2150 // Swifterror values can come from either a function parameter with
2151 // swifterror attribute or an alloca with swifterror attribute.
2152 if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
2153 if (Arg->hasSwiftErrorAttr())
2154 return false;
2155 }
2156
2157 if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
2158 if (Alloca->isSwiftError())
2159 return false;
2160 }
2161 }
2162
2163 // Get the value to be stored into a register. Use the zero register directly
2164 // when possible to avoid an unnecessary copy and a wasted register.
2165 Register SrcReg;
2166 if (const auto *CI = dyn_cast<ConstantInt>(Op0)) {
2167 if (CI->isZero())
2168 SrcReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
2169 } else if (const auto *CF = dyn_cast<ConstantFP>(Op0)) {
2170 if (CF->isZero() && !CF->isNegative()) {
2172 SrcReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
2173 }
2174 }
2175
2176 if (!SrcReg)
2177 SrcReg = getRegForValue(Op0);
2178
2179 if (!SrcReg)
2180 return false;
2181
2182 auto *SI = cast<StoreInst>(I);
2183
2184 // Try to emit a STLR for seq_cst/release.
2185 if (SI->isAtomic()) {
2186 AtomicOrdering Ord = SI->getOrdering();
2187 // The non-atomic instructions are sufficient for relaxed stores.
2188 if (isReleaseOrStronger(Ord)) {
2189 // The STLR addressing mode only supports a base reg; pass that directly.
2190 Register AddrReg = getRegForValue(PtrV);
2191 if (!AddrReg)
2192 return false;
2193 return emitStoreRelease(VT, SrcReg, AddrReg,
2194 createMachineMemOperandFor(I));
2195 }
2196 }
2197
2198 // See if we can handle this address.
2199 Address Addr;
2200 if (!computeAddress(PtrV, Addr, Op0->getType()))
2201 return false;
2202
2203 if (!emitStore(VT, SrcReg, Addr, createMachineMemOperandFor(I)))
2204 return false;
2205 return true;
2206}
2207
2209 switch (Pred) {
2210 case CmpInst::FCMP_ONE:
2211 case CmpInst::FCMP_UEQ:
2212 default:
2213 // AL is our "false" for now. The other two need more compares.
2214 return AArch64CC::AL;
2215 case CmpInst::ICMP_EQ:
2216 case CmpInst::FCMP_OEQ:
2217 return AArch64CC::EQ;
2218 case CmpInst::ICMP_SGT:
2219 case CmpInst::FCMP_OGT:
2220 return AArch64CC::GT;
2221 case CmpInst::ICMP_SGE:
2222 case CmpInst::FCMP_OGE:
2223 return AArch64CC::GE;
2224 case CmpInst::ICMP_UGT:
2225 case CmpInst::FCMP_UGT:
2226 return AArch64CC::HI;
2227 case CmpInst::FCMP_OLT:
2228 return AArch64CC::MI;
2229 case CmpInst::ICMP_ULE:
2230 case CmpInst::FCMP_OLE:
2231 return AArch64CC::LS;
2232 case CmpInst::FCMP_ORD:
2233 return AArch64CC::VC;
2234 case CmpInst::FCMP_UNO:
2235 return AArch64CC::VS;
2236 case CmpInst::FCMP_UGE:
2237 return AArch64CC::PL;
2238 case CmpInst::ICMP_SLT:
2239 case CmpInst::FCMP_ULT:
2240 return AArch64CC::LT;
2241 case CmpInst::ICMP_SLE:
2242 case CmpInst::FCMP_ULE:
2243 return AArch64CC::LE;
2244 case CmpInst::FCMP_UNE:
2245 case CmpInst::ICMP_NE:
2246 return AArch64CC::NE;
2247 case CmpInst::ICMP_UGE:
2248 return AArch64CC::HS;
2249 case CmpInst::ICMP_ULT:
2250 return AArch64CC::LO;
2251 }
2252}
2253
2254/// Try to emit a combined compare-and-branch instruction.
2255bool AArch64FastISel::emitCompareAndBranch(const CondBrInst *BI) {
2256 // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z instructions
2257 // will not be produced, as they are conditional branch instructions that do
2258 // not set flags.
2259 if (FuncInfo.MF->getFunction().hasFnAttribute(
2260 Attribute::SpeculativeLoadHardening))
2261 return false;
2262
2263 assert(isa<CmpInst>(BI->getCondition()) && "Expected cmp instruction");
2264 const CmpInst *CI = cast<CmpInst>(BI->getCondition());
2265 CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
2266
2267 const Value *LHS = CI->getOperand(0);
2268 const Value *RHS = CI->getOperand(1);
2269
2270 MVT VT;
2271 if (!isTypeSupported(LHS->getType(), VT))
2272 return false;
2273
2274 unsigned BW = VT.getSizeInBits();
2275 if (BW > 64)
2276 return false;
2277
2278 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));
2279 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));
2280
2281 // Try to take advantage of fallthrough opportunities.
2282 if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
2283 std::swap(TBB, FBB);
2285 }
2286
2287 int TestBit = -1;
2288 bool IsCmpNE;
2289 switch (Predicate) {
2290 default:
2291 return false;
2292 case CmpInst::ICMP_EQ:
2293 case CmpInst::ICMP_NE:
2294 if (isa<Constant>(LHS) && cast<Constant>(LHS)->isNullValue())
2295 std::swap(LHS, RHS);
2296
2297 if (!isa<Constant>(RHS) || !cast<Constant>(RHS)->isNullValue())
2298 return false;
2299
2300 if (const auto *AI = dyn_cast<BinaryOperator>(LHS))
2301 if (AI->getOpcode() == Instruction::And && isValueAvailable(AI)) {
2302 const Value *AndLHS = AI->getOperand(0);
2303 const Value *AndRHS = AI->getOperand(1);
2304
2305 if (const auto *C = dyn_cast<ConstantInt>(AndLHS))
2306 if (C->getValue().isPowerOf2())
2307 std::swap(AndLHS, AndRHS);
2308
2309 if (const auto *C = dyn_cast<ConstantInt>(AndRHS))
2310 if (C->getValue().isPowerOf2()) {
2311 TestBit = C->getValue().logBase2();
2312 LHS = AndLHS;
2313 }
2314 }
2315
2316 if (VT == MVT::i1)
2317 TestBit = 0;
2318
2319 IsCmpNE = Predicate == CmpInst::ICMP_NE;
2320 break;
2321 case CmpInst::ICMP_SLT:
2322 case CmpInst::ICMP_SGE:
2323 if (!isa<Constant>(RHS) || !cast<Constant>(RHS)->isNullValue())
2324 return false;
2325
2326 TestBit = BW - 1;
2327 IsCmpNE = Predicate == CmpInst::ICMP_SLT;
2328 break;
2329 case CmpInst::ICMP_SGT:
2330 case CmpInst::ICMP_SLE:
2331 if (!isa<ConstantInt>(RHS))
2332 return false;
2333
2334 if (cast<ConstantInt>(RHS)->getValue() != APInt(BW, -1, true))
2335 return false;
2336
2337 TestBit = BW - 1;
2338 IsCmpNE = Predicate == CmpInst::ICMP_SLE;
2339 break;
2340 } // end switch
2341
2342 static const unsigned OpcTable[2][2][2] = {
2343 { {AArch64::CBZW, AArch64::CBZX },
2344 {AArch64::CBNZW, AArch64::CBNZX} },
2345 { {AArch64::TBZW, AArch64::TBZX },
2346 {AArch64::TBNZW, AArch64::TBNZX} }
2347 };
2348
2349 bool IsBitTest = TestBit != -1;
2350 bool Is64Bit = BW == 64;
2351 if (TestBit < 32 && TestBit >= 0)
2352 Is64Bit = false;
2353
2354 unsigned Opc = OpcTable[IsBitTest][IsCmpNE][Is64Bit];
2355 const MCInstrDesc &II = TII.get(Opc);
2356
2357 Register SrcReg = getRegForValue(LHS);
2358 if (!SrcReg)
2359 return false;
2360
2361 if (BW == 64 && !Is64Bit)
2362 SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, AArch64::sub_32);
2363
2364 if ((BW < 32) && !IsBitTest)
2365 SrcReg = emitIntExt(VT, SrcReg, MVT::i32, /*isZExt=*/true);
2366
2367 // Emit the combined compare and branch instruction.
2368 SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs());
2369 MachineInstrBuilder MIB =
2370 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
2371 .addReg(SrcReg);
2372 if (IsBitTest)
2373 MIB.addImm(TestBit);
2374 MIB.addMBB(TBB);
2375
2376 finishCondBranch(BI->getParent(), TBB, FBB);
2377 return true;
2378}
2379
2380bool AArch64FastISel::selectBranch(const Instruction *I) {
2381 const CondBrInst *BI = cast<CondBrInst>(I);
2382
2383 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));
2384 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));
2385
2386 if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
2387 if (CI->hasOneUse() && isValueAvailable(CI)) {
2388 // Try to optimize or fold the cmp.
2389 CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
2390 switch (Predicate) {
2391 default:
2392 break;
2394 fastEmitBranch(FBB, MIMD.getDL());
2395 return true;
2396 case CmpInst::FCMP_TRUE:
2397 fastEmitBranch(TBB, MIMD.getDL());
2398 return true;
2399 }
2400
2401 // Try to emit a combined compare-and-branch first.
2402 if (emitCompareAndBranch(BI))
2403 return true;
2404
2405 // Try to take advantage of fallthrough opportunities.
2406 if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
2407 std::swap(TBB, FBB);
2409 }
2410
2411 // Emit the cmp.
2412 if (!emitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
2413 return false;
2414
2415 // FCMP_UEQ and FCMP_ONE cannot be checked with a single branch
2416 // instruction.
2417 AArch64CC::CondCode CC = getCompareCC(Predicate);
2419 switch (Predicate) {
2420 default:
2421 break;
2422 case CmpInst::FCMP_UEQ:
2423 ExtraCC = AArch64CC::EQ;
2424 CC = AArch64CC::VS;
2425 break;
2426 case CmpInst::FCMP_ONE:
2427 ExtraCC = AArch64CC::MI;
2428 CC = AArch64CC::GT;
2429 break;
2430 }
2431 assert((CC != AArch64CC::AL) && "Unexpected condition code.");
2432
2433 // Emit the extra branch for FCMP_UEQ and FCMP_ONE.
2434 if (ExtraCC != AArch64CC::AL) {
2435 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::Bcc))
2436 .addImm(ExtraCC)
2437 .addMBB(TBB);
2438 }
2439
2440 // Emit the branch.
2441 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::Bcc))
2442 .addImm(CC)
2443 .addMBB(TBB);
2444
2445 finishCondBranch(BI->getParent(), TBB, FBB);
2446 return true;
2447 }
2448 } else if (const auto *CI = dyn_cast<ConstantInt>(BI->getCondition())) {
2449 uint64_t Imm = CI->getZExtValue();
2450 MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
2451 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::B))
2452 .addMBB(Target);
2453
2454 // Obtain the branch probability and add the target to the successor list.
2455 if (FuncInfo.BPI) {
2456 auto BranchProbability = FuncInfo.BPI->getEdgeProbability(
2457 BI->getParent(), Target->getBasicBlock());
2458 FuncInfo.MBB->addSuccessor(Target, BranchProbability);
2459 } else
2460 FuncInfo.MBB->addSuccessorWithoutProb(Target);
2461 return true;
2462 } else {
2464 if (foldXALUIntrinsic(CC, I, BI->getCondition())) {
2465 // Fake request the condition, otherwise the intrinsic might be completely
2466 // optimized away.
2467 Register CondReg = getRegForValue(BI->getCondition());
2468 if (!CondReg)
2469 return false;
2470
2471 // Emit the branch.
2472 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::Bcc))
2473 .addImm(CC)
2474 .addMBB(TBB);
2475
2476 finishCondBranch(BI->getParent(), TBB, FBB);
2477 return true;
2478 }
2479 }
2480
2481 Register CondReg = getRegForValue(BI->getCondition());
2482 if (!CondReg)
2483 return false;
2484
2485 // i1 conditions come as i32 values, test the lowest bit with tb(n)z.
2486 // However, that's not allowed with SLH.
2487 if (FuncInfo.MF->getFunction().hasFnAttribute(
2488 Attribute::SpeculativeLoadHardening))
2489 return false;
2490
2491 unsigned Opcode = AArch64::TBNZW;
2492 if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
2493 std::swap(TBB, FBB);
2494 Opcode = AArch64::TBZW;
2495 }
2496
2497 const MCInstrDesc &II = TII.get(Opcode);
2498 Register ConstrainedCondReg
2499 = constrainOperandRegClass(II, CondReg, II.getNumDefs());
2500 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
2501 .addReg(ConstrainedCondReg)
2502 .addImm(0)
2503 .addMBB(TBB);
2504
2505 finishCondBranch(BI->getParent(), TBB, FBB);
2506 return true;
2507}
2508
2509bool AArch64FastISel::selectIndirectBr(const Instruction *I) {
2510 const IndirectBrInst *BI = cast<IndirectBrInst>(I);
2511 Register AddrReg = getRegForValue(BI->getOperand(0));
2512 if (!AddrReg)
2513 return false;
2514
2515 // Authenticated indirectbr is not implemented yet.
2516 if (FuncInfo.MF->getFunction().hasFnAttribute("ptrauth-indirect-gotos"))
2517 return false;
2518
2519 // Emit the indirect branch.
2520 const MCInstrDesc &II = TII.get(AArch64::BR);
2521 AddrReg = constrainOperandRegClass(II, AddrReg, II.getNumDefs());
2522 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addReg(AddrReg);
2523
2524 // Make sure the CFG is up-to-date.
2525 for (const auto *Succ : BI->successors())
2526 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(Succ));
2527
2528 return true;
2529}
2530
2531bool AArch64FastISel::selectCmp(const Instruction *I) {
2532 const CmpInst *CI = cast<CmpInst>(I);
2533
2534 // Vectors of i1 are weird: bail out.
2535 if (CI->getType()->isVectorTy())
2536 return false;
2537
2538 // Try to optimize or fold the cmp.
2539 CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);
2540 Register ResultReg;
2541 switch (Predicate) {
2542 default:
2543 break;
2545 ResultReg = createResultReg(&AArch64::GPR32RegClass);
2546 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2547 TII.get(TargetOpcode::COPY), ResultReg)
2548 .addReg(AArch64::WZR, getKillRegState(true));
2549 break;
2550 case CmpInst::FCMP_TRUE:
2551 ResultReg = fastEmit_i(MVT::i32, MVT::i32, ISD::Constant, 1);
2552 break;
2553 }
2554
2555 if (ResultReg) {
2556 updateValueMap(I, ResultReg);
2557 return true;
2558 }
2559
2560 // Emit the cmp.
2561 if (!emitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
2562 return false;
2563
2564 ResultReg = createResultReg(&AArch64::GPR32RegClass);
2565
2566 // FCMP_UEQ and FCMP_ONE cannot be checked with a single instruction. These
2567 // condition codes are inverted, because they are used by CSINC.
2568 static unsigned CondCodeTable[2][2] = {
2571 };
2572 unsigned *CondCodes = nullptr;
2573 switch (Predicate) {
2574 default:
2575 break;
2576 case CmpInst::FCMP_UEQ:
2577 CondCodes = &CondCodeTable[0][0];
2578 break;
2579 case CmpInst::FCMP_ONE:
2580 CondCodes = &CondCodeTable[1][0];
2581 break;
2582 }
2583
2584 if (CondCodes) {
2585 Register TmpReg1 = createResultReg(&AArch64::GPR32RegClass);
2586 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::CSINCWr),
2587 TmpReg1)
2588 .addReg(AArch64::WZR, getKillRegState(true))
2589 .addReg(AArch64::WZR, getKillRegState(true))
2590 .addImm(CondCodes[0]);
2591 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::CSINCWr),
2592 ResultReg)
2593 .addReg(TmpReg1, getKillRegState(true))
2594 .addReg(AArch64::WZR, getKillRegState(true))
2595 .addImm(CondCodes[1]);
2596
2597 updateValueMap(I, ResultReg);
2598 return true;
2599 }
2600
2601 // Now set a register based on the comparison.
2602 AArch64CC::CondCode CC = getCompareCC(Predicate);
2603 assert((CC != AArch64CC::AL) && "Unexpected condition code.");
2604 AArch64CC::CondCode invertedCC = getInvertedCondCode(CC);
2605 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::CSINCWr),
2606 ResultReg)
2607 .addReg(AArch64::WZR, getKillRegState(true))
2608 .addReg(AArch64::WZR, getKillRegState(true))
2609 .addImm(invertedCC);
2610
2611 updateValueMap(I, ResultReg);
2612 return true;
2613}
2614
2615/// Optimize selects of i1 if one of the operands has a 'true' or 'false'
2616/// value.
2617bool AArch64FastISel::optimizeSelect(const SelectInst *SI) {
2618 if (!SI->getType()->isIntegerTy(1))
2619 return false;
2620
2621 const Value *Src1Val, *Src2Val;
2622 unsigned Opc = 0;
2623 bool NeedExtraOp = false;
2624 if (auto *CI = dyn_cast<ConstantInt>(SI->getTrueValue())) {
2625 if (CI->isOne()) {
2626 Src1Val = SI->getCondition();
2627 Src2Val = SI->getFalseValue();
2628 Opc = AArch64::ORRWrr;
2629 } else {
2630 assert(CI->isZero());
2631 Src1Val = SI->getFalseValue();
2632 Src2Val = SI->getCondition();
2633 Opc = AArch64::BICWrr;
2634 }
2635 } else if (auto *CI = dyn_cast<ConstantInt>(SI->getFalseValue())) {
2636 if (CI->isOne()) {
2637 Src1Val = SI->getCondition();
2638 Src2Val = SI->getTrueValue();
2639 Opc = AArch64::ORRWrr;
2640 NeedExtraOp = true;
2641 } else {
2642 assert(CI->isZero());
2643 Src1Val = SI->getCondition();
2644 Src2Val = SI->getTrueValue();
2645 Opc = AArch64::ANDWrr;
2646 }
2647 }
2648
2649 if (!Opc)
2650 return false;
2651
2652 Register Src1Reg = getRegForValue(Src1Val);
2653 if (!Src1Reg)
2654 return false;
2655
2656 Register Src2Reg = getRegForValue(Src2Val);
2657 if (!Src2Reg)
2658 return false;
2659
2660 if (NeedExtraOp)
2661 Src1Reg = emitLogicalOp_ri(ISD::XOR, MVT::i32, Src1Reg, 1);
2662
2663 Register ResultReg = fastEmitInst_rr(Opc, &AArch64::GPR32RegClass, Src1Reg,
2664 Src2Reg);
2665 updateValueMap(SI, ResultReg);
2666 return true;
2667}
2668
2669bool AArch64FastISel::selectSelect(const Instruction *I) {
2670 assert(isa<SelectInst>(I) && "Expected a select instruction.");
2671 MVT VT;
2672 if (!isTypeSupported(I->getType(), VT))
2673 return false;
2674
2675 unsigned Opc;
2676 const TargetRegisterClass *RC;
2677 switch (VT.SimpleTy) {
2678 default:
2679 return false;
2680 case MVT::i1:
2681 case MVT::i8:
2682 case MVT::i16:
2683 case MVT::i32:
2684 Opc = AArch64::CSELWr;
2685 RC = &AArch64::GPR32RegClass;
2686 break;
2687 case MVT::i64:
2688 Opc = AArch64::CSELXr;
2689 RC = &AArch64::GPR64RegClass;
2690 break;
2691 case MVT::f32:
2692 Opc = AArch64::FCSELSrrr;
2693 RC = &AArch64::FPR32RegClass;
2694 break;
2695 case MVT::f64:
2696 Opc = AArch64::FCSELDrrr;
2697 RC = &AArch64::FPR64RegClass;
2698 break;
2699 }
2700
2701 const SelectInst *SI = cast<SelectInst>(I);
2702 const Value *Cond = SI->getCondition();
2705
2706 if (optimizeSelect(SI))
2707 return true;
2708
2709 // Try to pickup the flags, so we don't have to emit another compare.
2710 if (foldXALUIntrinsic(CC, I, Cond)) {
2711 // Fake request the condition to force emission of the XALU intrinsic.
2712 Register CondReg = getRegForValue(Cond);
2713 if (!CondReg)
2714 return false;
2715 } else if (isa<CmpInst>(Cond) && cast<CmpInst>(Cond)->hasOneUse() &&
2716 isValueAvailable(Cond)) {
2717 const auto *Cmp = cast<CmpInst>(Cond);
2718 // Try to optimize or fold the cmp.
2719 CmpInst::Predicate Predicate = optimizeCmpPredicate(Cmp);
2720 const Value *FoldSelect = nullptr;
2721 switch (Predicate) {
2722 default:
2723 break;
2725 FoldSelect = SI->getFalseValue();
2726 break;
2727 case CmpInst::FCMP_TRUE:
2728 FoldSelect = SI->getTrueValue();
2729 break;
2730 }
2731
2732 if (FoldSelect) {
2733 Register SrcReg = getRegForValue(FoldSelect);
2734 if (!SrcReg)
2735 return false;
2736
2737 updateValueMap(I, SrcReg);
2738 return true;
2739 }
2740
2741 // Emit the cmp.
2742 if (!emitCmp(Cmp->getOperand(0), Cmp->getOperand(1), Cmp->isUnsigned()))
2743 return false;
2744
2745 // FCMP_UEQ and FCMP_ONE cannot be checked with a single select instruction.
2746 CC = getCompareCC(Predicate);
2747 switch (Predicate) {
2748 default:
2749 break;
2750 case CmpInst::FCMP_UEQ:
2751 ExtraCC = AArch64CC::EQ;
2752 CC = AArch64CC::VS;
2753 break;
2754 case CmpInst::FCMP_ONE:
2755 ExtraCC = AArch64CC::MI;
2756 CC = AArch64CC::GT;
2757 break;
2758 }
2759 assert((CC != AArch64CC::AL) && "Unexpected condition code.");
2760 } else {
2761 Register CondReg = getRegForValue(Cond);
2762 if (!CondReg)
2763 return false;
2764
2765 const MCInstrDesc &II = TII.get(AArch64::ANDSWri);
2766 CondReg = constrainOperandRegClass(II, CondReg, 1);
2767
2768 // Emit a TST instruction (ANDS wzr, reg, #imm).
2769 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II,
2770 AArch64::WZR)
2771 .addReg(CondReg)
2773 }
2774
2775 Register Src1Reg = getRegForValue(SI->getTrueValue());
2776 Register Src2Reg = getRegForValue(SI->getFalseValue());
2777
2778 if (!Src1Reg || !Src2Reg)
2779 return false;
2780
2781 if (ExtraCC != AArch64CC::AL)
2782 Src2Reg = fastEmitInst_rri(Opc, RC, Src1Reg, Src2Reg, ExtraCC);
2783
2784 Register ResultReg = fastEmitInst_rri(Opc, RC, Src1Reg, Src2Reg, CC);
2785 updateValueMap(I, ResultReg);
2786 return true;
2787}
2788
2789bool AArch64FastISel::selectFPExt(const Instruction *I) {
2790 Value *V = I->getOperand(0);
2791 if (!I->getType()->isDoubleTy() || !V->getType()->isFloatTy())
2792 return false;
2793
2794 Register Op = getRegForValue(V);
2795 if (Op == 0)
2796 return false;
2797
2798 Register ResultReg = createResultReg(&AArch64::FPR64RegClass);
2799 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::FCVTDSr),
2800 ResultReg).addReg(Op);
2801 updateValueMap(I, ResultReg);
2802 return true;
2803}
2804
2805bool AArch64FastISel::selectFPTrunc(const Instruction *I) {
2806 Value *V = I->getOperand(0);
2807 if (!I->getType()->isFloatTy() || !V->getType()->isDoubleTy())
2808 return false;
2809
2810 Register Op = getRegForValue(V);
2811 if (Op == 0)
2812 return false;
2813
2814 Register ResultReg = createResultReg(&AArch64::FPR32RegClass);
2815 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::FCVTSDr),
2816 ResultReg).addReg(Op);
2817 updateValueMap(I, ResultReg);
2818 return true;
2819}
2820
2821// FPToUI and FPToSI
2822bool AArch64FastISel::selectFPToInt(const Instruction *I, bool Signed) {
2823 MVT DestVT;
2824 if (!isTypeLegal(I->getType(), DestVT) || DestVT.isVector())
2825 return false;
2826
2827 Register SrcReg = getRegForValue(I->getOperand(0));
2828 if (!SrcReg)
2829 return false;
2830
2831 EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType(), true);
2832 if (SrcVT == MVT::f128 || SrcVT == MVT::f16 || SrcVT == MVT::bf16)
2833 return false;
2834
2835 unsigned Opc;
2836 if (SrcVT == MVT::f64) {
2837 if (Signed)
2838 Opc = (DestVT == MVT::i32) ? AArch64::FCVTZSUWDr : AArch64::FCVTZSUXDr;
2839 else
2840 Opc = (DestVT == MVT::i32) ? AArch64::FCVTZUUWDr : AArch64::FCVTZUUXDr;
2841 } else {
2842 if (Signed)
2843 Opc = (DestVT == MVT::i32) ? AArch64::FCVTZSUWSr : AArch64::FCVTZSUXSr;
2844 else
2845 Opc = (DestVT == MVT::i32) ? AArch64::FCVTZUUWSr : AArch64::FCVTZUUXSr;
2846 }
2847 Register ResultReg = createResultReg(
2848 DestVT == MVT::i32 ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass);
2849 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
2850 .addReg(SrcReg);
2851 updateValueMap(I, ResultReg);
2852 return true;
2853}
2854
2855bool AArch64FastISel::selectIntToFP(const Instruction *I, bool Signed) {
2856 MVT DestVT;
2857 if (!isTypeLegal(I->getType(), DestVT) || DestVT.isVector())
2858 return false;
2859 // Let regular ISEL handle FP16
2860 if (DestVT == MVT::f16 || DestVT == MVT::bf16)
2861 return false;
2862
2863 assert((DestVT == MVT::f32 || DestVT == MVT::f64) &&
2864 "Unexpected value type.");
2865
2866 Register SrcReg = getRegForValue(I->getOperand(0));
2867 if (!SrcReg)
2868 return false;
2869
2870 EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType(), true);
2871
2872 // Handle sign-extension.
2873 if (SrcVT == MVT::i16 || SrcVT == MVT::i8 || SrcVT == MVT::i1) {
2874 SrcReg =
2875 emitIntExt(SrcVT.getSimpleVT(), SrcReg, MVT::i32, /*isZExt*/ !Signed);
2876 if (!SrcReg)
2877 return false;
2878 }
2879
2880 unsigned Opc;
2881 if (SrcVT == MVT::i64) {
2882 if (Signed)
2883 Opc = (DestVT == MVT::f32) ? AArch64::SCVTFUXSri : AArch64::SCVTFUXDri;
2884 else
2885 Opc = (DestVT == MVT::f32) ? AArch64::UCVTFUXSri : AArch64::UCVTFUXDri;
2886 } else {
2887 if (Signed)
2888 Opc = (DestVT == MVT::f32) ? AArch64::SCVTFUWSri : AArch64::SCVTFUWDri;
2889 else
2890 Opc = (DestVT == MVT::f32) ? AArch64::UCVTFUWSri : AArch64::UCVTFUWDri;
2891 }
2892
2893 Register ResultReg = fastEmitInst_r(Opc, TLI.getRegClassFor(DestVT), SrcReg);
2894 updateValueMap(I, ResultReg);
2895 return true;
2896}
2897
2898bool AArch64FastISel::fastLowerArguments() {
2899 if (!FuncInfo.CanLowerReturn)
2900 return false;
2901
2902 const Function *F = FuncInfo.Fn;
2903 if (F->isVarArg())
2904 return false;
2905
2906 CallingConv::ID CC = F->getCallingConv();
2907 if (CC != CallingConv::C && CC != CallingConv::Swift)
2908 return false;
2909
2910 if (Subtarget->hasCustomCallingConv())
2911 return false;
2912
2913 // Only handle simple cases of up to 8 GPR and FPR each.
2914 unsigned GPRCnt = 0;
2915 unsigned FPRCnt = 0;
2916 for (auto const &Arg : F->args()) {
2917 if (Arg.hasAttribute(Attribute::ByVal) ||
2918 Arg.hasAttribute(Attribute::InReg) ||
2919 Arg.hasAttribute(Attribute::StructRet) ||
2920 Arg.hasAttribute(Attribute::SwiftSelf) ||
2921 Arg.hasAttribute(Attribute::SwiftAsync) ||
2922 Arg.hasAttribute(Attribute::SwiftError) ||
2923 Arg.hasAttribute(Attribute::Nest))
2924 return false;
2925
2926 Type *ArgTy = Arg.getType();
2927 if (ArgTy->isStructTy() || ArgTy->isArrayTy())
2928 return false;
2929
2930 EVT ArgVT = TLI.getValueType(DL, ArgTy);
2931 if (!ArgVT.isSimple())
2932 return false;
2933
2934 MVT VT = ArgVT.getSimpleVT().SimpleTy;
2935 if (VT.isFloatingPoint() && !Subtarget->hasFPARMv8())
2936 return false;
2937
2938 if (VT.isVector() &&
2939 (!Subtarget->hasNEON() || !Subtarget->isLittleEndian()))
2940 return false;
2941
2942 if (VT >= MVT::i1 && VT <= MVT::i64)
2943 ++GPRCnt;
2944 else if ((VT >= MVT::f16 && VT <= MVT::f64) || VT.is64BitVector() ||
2945 VT.is128BitVector())
2946 ++FPRCnt;
2947 else
2948 return false;
2949
2950 if (GPRCnt > 8 || FPRCnt > 8)
2951 return false;
2952 }
2953
2954 static const MCPhysReg Registers[6][8] = {
2955 { AArch64::W0, AArch64::W1, AArch64::W2, AArch64::W3, AArch64::W4,
2956 AArch64::W5, AArch64::W6, AArch64::W7 },
2957 { AArch64::X0, AArch64::X1, AArch64::X2, AArch64::X3, AArch64::X4,
2958 AArch64::X5, AArch64::X6, AArch64::X7 },
2959 { AArch64::H0, AArch64::H1, AArch64::H2, AArch64::H3, AArch64::H4,
2960 AArch64::H5, AArch64::H6, AArch64::H7 },
2961 { AArch64::S0, AArch64::S1, AArch64::S2, AArch64::S3, AArch64::S4,
2962 AArch64::S5, AArch64::S6, AArch64::S7 },
2963 { AArch64::D0, AArch64::D1, AArch64::D2, AArch64::D3, AArch64::D4,
2964 AArch64::D5, AArch64::D6, AArch64::D7 },
2965 { AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
2966 AArch64::Q5, AArch64::Q6, AArch64::Q7 }
2967 };
2968
2969 unsigned GPRIdx = 0;
2970 unsigned FPRIdx = 0;
2971 for (auto const &Arg : F->args()) {
2972 MVT VT = TLI.getSimpleValueType(DL, Arg.getType());
2973 unsigned SrcReg;
2974 const TargetRegisterClass *RC;
2975 if (VT >= MVT::i1 && VT <= MVT::i32) {
2976 SrcReg = Registers[0][GPRIdx++];
2977 RC = &AArch64::GPR32RegClass;
2978 VT = MVT::i32;
2979 } else if (VT == MVT::i64) {
2980 SrcReg = Registers[1][GPRIdx++];
2981 RC = &AArch64::GPR64RegClass;
2982 } else if (VT == MVT::f16 || VT == MVT::bf16) {
2983 SrcReg = Registers[2][FPRIdx++];
2984 RC = &AArch64::FPR16RegClass;
2985 } else if (VT == MVT::f32) {
2986 SrcReg = Registers[3][FPRIdx++];
2987 RC = &AArch64::FPR32RegClass;
2988 } else if ((VT == MVT::f64) || VT.is64BitVector()) {
2989 SrcReg = Registers[4][FPRIdx++];
2990 RC = &AArch64::FPR64RegClass;
2991 } else if (VT.is128BitVector()) {
2992 SrcReg = Registers[5][FPRIdx++];
2993 RC = &AArch64::FPR128RegClass;
2994 } else
2995 llvm_unreachable("Unexpected value type.");
2996
2997 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
2998 // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.
2999 // Without this, EmitLiveInCopies may eliminate the livein if its only
3000 // use is a bitcast (which isn't turned into an instruction).
3001 Register ResultReg = createResultReg(RC);
3002 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3003 TII.get(TargetOpcode::COPY), ResultReg)
3004 .addReg(DstReg, getKillRegState(true));
3005 updateValueMap(&Arg, ResultReg);
3006 }
3007 return true;
3008}
3009
3010bool AArch64FastISel::processCallArgs(CallLoweringInfo &CLI,
3011 SmallVectorImpl<MVT> &OutVTs,
3012 SmallVectorImpl<Type *> &OrigTys,
3013 unsigned &NumBytes) {
3014 CallingConv::ID CC = CLI.CallConv;
3016 CCState CCInfo(CC, false, *FuncInfo.MF, ArgLocs, *Context);
3017 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, OrigTys,
3018 CCAssignFnForCall(CC));
3019
3020 // Get a count of how many bytes are to be pushed on the stack.
3021 NumBytes = CCInfo.getStackSize();
3022
3023 // Issue CALLSEQ_START
3024 unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
3025 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AdjStackDown))
3026 .addImm(NumBytes).addImm(0);
3027
3028 // Process the args.
3029 for (CCValAssign &VA : ArgLocs) {
3030 const Value *ArgVal = CLI.OutVals[VA.getValNo()];
3031 MVT ArgVT = OutVTs[VA.getValNo()];
3032
3033 Register ArgReg = getRegForValue(ArgVal);
3034 if (!ArgReg)
3035 return false;
3036
3037 // Handle arg promotion: SExt, ZExt, AExt.
3038 switch (VA.getLocInfo()) {
3039 case CCValAssign::Full:
3040 break;
3041 case CCValAssign::SExt: {
3042 MVT DestVT = VA.getLocVT();
3043 MVT SrcVT = ArgVT;
3044 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/false);
3045 if (!ArgReg)
3046 return false;
3047 break;
3048 }
3049 case CCValAssign::AExt:
3050 // Intentional fall-through.
3051 case CCValAssign::ZExt: {
3052 MVT DestVT = VA.getLocVT();
3053 MVT SrcVT = ArgVT;
3054 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/true);
3055 if (!ArgReg)
3056 return false;
3057 break;
3058 }
3059 default:
3060 llvm_unreachable("Unknown arg promotion!");
3061 }
3062
3063 // Now copy/store arg to correct locations.
3064 if (VA.isRegLoc() && !VA.needsCustom()) {
3065 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3066 TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(ArgReg);
3067 CLI.OutRegs.push_back(VA.getLocReg());
3068 } else if (VA.needsCustom()) {
3069 // FIXME: Handle custom args.
3070 return false;
3071 } else {
3072 assert(VA.isMemLoc() && "Assuming store on stack.");
3073
3074 // Don't emit stores for undef values.
3075 if (isa<UndefValue>(ArgVal))
3076 continue;
3077
3078 // Need to store on the stack.
3079 unsigned ArgSize = (ArgVT.getSizeInBits() + 7) / 8;
3080
3081 unsigned BEAlign = 0;
3082 if (ArgSize < 8 && !Subtarget->isLittleEndian())
3083 BEAlign = 8 - ArgSize;
3084
3085 Address Addr;
3086 Addr.setKind(Address::RegBase);
3087 Addr.setReg(AArch64::SP);
3088 Addr.setOffset(VA.getLocMemOffset() + BEAlign);
3089
3090 Align Alignment = DL.getABITypeAlign(ArgVal->getType());
3091 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3092 MachinePointerInfo::getStack(*FuncInfo.MF, Addr.getOffset()),
3093 MachineMemOperand::MOStore, ArgVT.getStoreSize(), Alignment);
3094
3095 if (!emitStore(ArgVT, ArgReg, Addr, MMO))
3096 return false;
3097 }
3098 }
3099 return true;
3100}
3101
3102bool AArch64FastISel::finishCall(CallLoweringInfo &CLI, unsigned NumBytes) {
3103 CallingConv::ID CC = CLI.CallConv;
3104
3105 // Issue CALLSEQ_END
3106 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
3107 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AdjStackUp))
3108 .addImm(NumBytes).addImm(0);
3109
3110 // Now the return values.
3112 CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
3113 CCInfo.AnalyzeCallResult(CLI.Ins, CCAssignFnForCall(CC));
3114
3115 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3116 for (unsigned i = 0; i != RVLocs.size(); ++i) {
3117 CCValAssign &VA = RVLocs[i];
3118 MVT CopyVT = VA.getValVT();
3119 Register CopyReg = ResultReg + i;
3120
3121 // TODO: Handle big-endian results
3122 if (CopyVT.isVector() && !Subtarget->isLittleEndian())
3123 return false;
3124
3125 // Copy result out of their specified physreg.
3126 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
3127 CopyReg)
3128 .addReg(VA.getLocReg());
3129 CLI.InRegs.push_back(VA.getLocReg());
3130 }
3131
3132 CLI.ResultReg = ResultReg;
3133 CLI.NumResultRegs = RVLocs.size();
3134
3135 return true;
3136}
3137
3138bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3139 CallingConv::ID CC = CLI.CallConv;
3140 bool IsTailCall = CLI.IsTailCall;
3141 bool IsVarArg = CLI.IsVarArg;
3142 const Value *Callee = CLI.Callee;
3143 MCSymbol *Symbol = CLI.Symbol;
3144
3145 if (!Callee && !Symbol)
3146 return false;
3147
3148 // Allow SelectionDAG isel to handle calls to functions like setjmp that need
3149 // a bti instruction following the call.
3150 if (CLI.CB && CLI.CB->hasFnAttr(Attribute::ReturnsTwice) &&
3151 !Subtarget->noBTIAtReturnTwice() &&
3152 MF->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement())
3153 return false;
3154
3155 // Allow SelectionDAG isel to handle indirect calls with KCFI checks.
3156 if (CLI.CB && CLI.CB->isIndirectCall() &&
3157 CLI.CB->getOperandBundle(LLVMContext::OB_kcfi))
3158 return false;
3159
3160 // Allow SelectionDAG isel to handle tail calls.
3161 if (IsTailCall)
3162 return false;
3163
3164 // FIXME: we could and should support this, but for now correctness at -O0 is
3165 // more important.
3166 if (Subtarget->isTargetILP32())
3167 return false;
3168
3169 CodeModel::Model CM = TM.getCodeModel();
3170 // Only support the small-addressing and large code models.
3171 if (CM != CodeModel::Large && !Subtarget->useSmallAddressing())
3172 return false;
3173
3174 // FIXME: Add large code model support for ELF.
3175 if (CM == CodeModel::Large && !Subtarget->isTargetMachO())
3176 return false;
3177
3178 // ELF -fno-plt compiled intrinsic calls do not have the nonlazybind
3179 // attribute. Check "RtLibUseGOT" instead.
3180 if (MF->getFunction().getParent()->getRtLibUseGOT())
3181 return false;
3182
3183 // Let SDISel handle vararg functions.
3184 if (IsVarArg)
3185 return false;
3186
3187 if (Subtarget->isWindowsArm64EC())
3188 return false;
3189
3190 for (auto Flag : CLI.OutFlags)
3191 if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal() ||
3192 Flag.isSwiftSelf() || Flag.isSwiftAsync() || Flag.isSwiftError())
3193 return false;
3194
3195 // Set up the argument vectors.
3196 SmallVector<MVT, 16> OutVTs;
3198 OutVTs.reserve(CLI.OutVals.size());
3199
3200 for (auto *Val : CLI.OutVals) {
3201 MVT VT;
3202 if (!isTypeLegal(Val->getType(), VT) &&
3203 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
3204 return false;
3205
3206 // We don't handle vector parameters yet.
3207 if (VT.isVector() || VT.getSizeInBits() > 64)
3208 return false;
3209
3210 OutVTs.push_back(VT);
3211 OrigTys.push_back(Val->getType());
3212 }
3213
3214 Address Addr;
3215 if (Callee && !computeCallAddress(Callee, Addr))
3216 return false;
3217
3218 // The weak function target may be zero; in that case we must use indirect
3219 // addressing via a stub on windows as it may be out of range for a
3220 // PC-relative jump.
3221 if (Subtarget->isTargetWindows() && Addr.getGlobalValue() &&
3222 Addr.getGlobalValue()->hasExternalWeakLinkage())
3223 return false;
3224
3225 // Handle the arguments now that we've gotten them.
3226 unsigned NumBytes;
3227 if (!processCallArgs(CLI, OutVTs, OrigTys, NumBytes))
3228 return false;
3229
3230 const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3231 if (RegInfo->isAnyArgRegReserved(*MF))
3232 RegInfo->emitReservedArgRegCallError(*MF);
3233
3234 // Issue the call.
3235 MachineInstrBuilder MIB;
3236 if (Subtarget->useSmallAddressing()) {
3237 const MCInstrDesc &II =
3238 TII.get(Addr.getReg() ? getBLRCallOpcode(*MF) : (unsigned)AArch64::BL);
3239 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II);
3240 if (Symbol)
3241 MIB.addSym(Symbol, 0);
3242 else if (Addr.getGlobalValue())
3243 MIB.addGlobalAddress(Addr.getGlobalValue(), 0, 0);
3244 else if (Addr.getReg()) {
3245 Register Reg = constrainOperandRegClass(II, Addr.getReg(), 0);
3246 MIB.addReg(Reg);
3247 } else
3248 return false;
3249 } else {
3250 Register CallReg;
3251 if (Symbol) {
3252 Register ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
3253 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADRP),
3254 ADRPReg)
3256
3257 CallReg = createResultReg(&AArch64::GPR64RegClass);
3258 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3259 TII.get(AArch64::LDRXui), CallReg)
3260 .addReg(ADRPReg)
3261 .addSym(Symbol,
3263 } else if (Addr.getGlobalValue())
3264 CallReg = materializeGV(Addr.getGlobalValue());
3265 else if (Addr.getReg())
3266 CallReg = Addr.getReg();
3267
3268 if (!CallReg)
3269 return false;
3270
3271 const MCInstrDesc &II = TII.get(getBLRCallOpcode(*MF));
3272 CallReg = constrainOperandRegClass(II, CallReg, 0);
3273 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addReg(CallReg);
3274 }
3275
3276 // Add implicit physical register uses to the call.
3277 for (auto Reg : CLI.OutRegs)
3278 MIB.addReg(Reg, RegState::Implicit);
3279
3280 // Add a register mask with the call-preserved registers.
3281 // Proper defs for return values will be added by setPhysRegsDeadExcept().
3282 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
3283
3284 CLI.Call = MIB;
3285
3286 // Finish off the call including any return values.
3287 return finishCall(CLI, NumBytes);
3288}
3289
3290bool AArch64FastISel::isMemCpySmall(uint64_t Len, MaybeAlign Alignment) {
3291 if (Alignment)
3292 return Len / Alignment->value() <= 4;
3293 else
3294 return Len < 32;
3295}
3296
3297bool AArch64FastISel::tryEmitSmallMemCpy(Address Dest, Address Src,
3298 uint64_t Len, MaybeAlign Alignment) {
3299 // Make sure we don't bloat code by inlining very large memcpy's.
3300 if (!isMemCpySmall(Len, Alignment))
3301 return false;
3302
3303 int64_t UnscaledOffset = 0;
3304 Address OrigDest = Dest;
3305 Address OrigSrc = Src;
3306
3307 while (Len) {
3308 MVT VT;
3309 if (!Alignment || *Alignment >= 8) {
3310 if (Len >= 8)
3311 VT = MVT::i64;
3312 else if (Len >= 4)
3313 VT = MVT::i32;
3314 else if (Len >= 2)
3315 VT = MVT::i16;
3316 else {
3317 VT = MVT::i8;
3318 }
3319 } else {
3320 assert(Alignment && "Alignment is set in this branch");
3321 // Bound based on alignment.
3322 if (Len >= 4 && *Alignment == 4)
3323 VT = MVT::i32;
3324 else if (Len >= 2 && *Alignment == 2)
3325 VT = MVT::i16;
3326 else {
3327 VT = MVT::i8;
3328 }
3329 }
3330
3331 Register ResultReg = emitLoad(VT, VT, Src);
3332 if (!ResultReg)
3333 return false;
3334
3335 if (!emitStore(VT, ResultReg, Dest))
3336 return false;
3337
3338 int64_t Size = VT.getSizeInBits() / 8;
3339 Len -= Size;
3340 UnscaledOffset += Size;
3341
3342 // We need to recompute the unscaled offset for each iteration.
3343 Dest.setOffset(OrigDest.getOffset() + UnscaledOffset);
3344 Src.setOffset(OrigSrc.getOffset() + UnscaledOffset);
3345 }
3346
3347 return true;
3348}
3349
3350/// Check if it is possible to fold the condition from the XALU intrinsic
3351/// into the user. The condition code will only be updated on success.
3352bool AArch64FastISel::foldXALUIntrinsic(AArch64CC::CondCode &CC,
3353 const Instruction *I,
3354 const Value *Cond) {
3356 return false;
3357
3358 const auto *EV = cast<ExtractValueInst>(Cond);
3359 if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
3360 return false;
3361
3362 const auto *II = cast<IntrinsicInst>(EV->getAggregateOperand());
3363 MVT RetVT;
3364 const Function *Callee = II->getCalledFunction();
3365 Type *RetTy =
3366 cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
3367 if (!isTypeLegal(RetTy, RetVT))
3368 return false;
3369
3370 if (RetVT != MVT::i32 && RetVT != MVT::i64)
3371 return false;
3372
3373 const Value *LHS = II->getArgOperand(0);
3374 const Value *RHS = II->getArgOperand(1);
3375
3376 // Canonicalize immediate to the RHS.
3377 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
3378 std::swap(LHS, RHS);
3379
3380 // Simplify multiplies.
3381 Intrinsic::ID IID = II->getIntrinsicID();
3382 switch (IID) {
3383 default:
3384 break;
3385 case Intrinsic::smul_with_overflow:
3386 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3387 if (C->getValue() == 2)
3388 IID = Intrinsic::sadd_with_overflow;
3389 break;
3390 case Intrinsic::umul_with_overflow:
3391 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3392 if (C->getValue() == 2)
3393 IID = Intrinsic::uadd_with_overflow;
3394 break;
3395 }
3396
3397 AArch64CC::CondCode TmpCC;
3398 switch (IID) {
3399 default:
3400 return false;
3401 case Intrinsic::sadd_with_overflow:
3402 case Intrinsic::ssub_with_overflow:
3403 TmpCC = AArch64CC::VS;
3404 break;
3405 case Intrinsic::uadd_with_overflow:
3406 TmpCC = AArch64CC::HS;
3407 break;
3408 case Intrinsic::usub_with_overflow:
3409 TmpCC = AArch64CC::LO;
3410 break;
3411 case Intrinsic::smul_with_overflow:
3412 case Intrinsic::umul_with_overflow:
3413 TmpCC = AArch64CC::NE;
3414 break;
3415 }
3416
3417 // Check if both instructions are in the same basic block.
3418 if (!isValueAvailable(II))
3419 return false;
3420
3421 // Make sure nothing is in the way
3424 for (auto Itr = std::prev(Start); Itr != End; --Itr) {
3425 // We only expect extractvalue instructions between the intrinsic and the
3426 // instruction to be selected.
3427 if (!isa<ExtractValueInst>(Itr))
3428 return false;
3429
3430 // Check that the extractvalue operand comes from the intrinsic.
3431 const auto *EVI = cast<ExtractValueInst>(Itr);
3432 if (EVI->getAggregateOperand() != II)
3433 return false;
3434 }
3435
3436 CC = TmpCC;
3437 return true;
3438}
3439
3440bool AArch64FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
3441 // FIXME: Handle more intrinsics.
3442 switch (II->getIntrinsicID()) {
3443 default: return false;
3444 case Intrinsic::frameaddress: {
3445 MachineFrameInfo &MFI = FuncInfo.MF->getFrameInfo();
3446 MFI.setFrameAddressIsTaken(true);
3447
3448 const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3449 Register FramePtr = RegInfo->getFrameRegister(*(FuncInfo.MF));
3450 Register SrcReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
3451 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3452 TII.get(TargetOpcode::COPY), SrcReg).addReg(FramePtr);
3453 // Recursively load frame address
3454 // ldr x0, [fp]
3455 // ldr x0, [x0]
3456 // ldr x0, [x0]
3457 // ...
3458 Register DestReg;
3459 unsigned Depth = cast<ConstantInt>(II->getOperand(0))->getZExtValue();
3460 while (Depth--) {
3461 DestReg = fastEmitInst_ri(AArch64::LDRXui, &AArch64::GPR64RegClass,
3462 SrcReg, 0);
3463 assert(DestReg && "Unexpected LDR instruction emission failure.");
3464 SrcReg = DestReg;
3465 }
3466
3467 updateValueMap(II, SrcReg);
3468 return true;
3469 }
3470 case Intrinsic::sponentry: {
3471 MachineFrameInfo &MFI = FuncInfo.MF->getFrameInfo();
3472
3473 // SP = FP + Fixed Object + 16
3474 int FI = MFI.CreateFixedObject(4, 0, false);
3475 Register ResultReg = createResultReg(&AArch64::GPR64spRegClass);
3476 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3477 TII.get(AArch64::ADDXri), ResultReg)
3478 .addFrameIndex(FI)
3479 .addImm(0)
3480 .addImm(0);
3481
3482 updateValueMap(II, ResultReg);
3483 return true;
3484 }
3485 case Intrinsic::memcpy:
3486 case Intrinsic::memmove: {
3487 const auto *MTI = cast<MemTransferInst>(II);
3488 // Don't handle volatile.
3489 if (MTI->isVolatile())
3490 return false;
3491
3492 // Disable inlining for memmove before calls to ComputeAddress. Otherwise,
3493 // we would emit dead code because we don't currently handle memmoves.
3494 bool IsMemCpy = (II->getIntrinsicID() == Intrinsic::memcpy);
3495 if (isa<ConstantInt>(MTI->getLength()) && IsMemCpy) {
3496 // Small memcpy's are common enough that we want to do them without a call
3497 // if possible.
3498 uint64_t Len = cast<ConstantInt>(MTI->getLength())->getZExtValue();
3499 MaybeAlign Alignment;
3500 if (MTI->getDestAlign() || MTI->getSourceAlign())
3501 Alignment = std::min(MTI->getDestAlign().valueOrOne(),
3502 MTI->getSourceAlign().valueOrOne());
3503 if (isMemCpySmall(Len, Alignment)) {
3504 Address Dest, Src;
3505 if (!computeAddress(MTI->getRawDest(), Dest) ||
3506 !computeAddress(MTI->getRawSource(), Src))
3507 return false;
3508 if (tryEmitSmallMemCpy(Dest, Src, Len, Alignment))
3509 return true;
3510 }
3511 }
3512
3513 if (!MTI->getLength()->getType()->isIntegerTy(64))
3514 return false;
3515
3516 if (MTI->getSourceAddressSpace() > 255 || MTI->getDestAddressSpace() > 255)
3517 // Fast instruction selection doesn't support the special
3518 // address spaces.
3519 return false;
3520
3521 const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";
3522 return lowerCallTo(II, IntrMemName, II->arg_size() - 1);
3523 }
3524 case Intrinsic::memset: {
3525 const MemSetInst *MSI = cast<MemSetInst>(II);
3526 // Don't handle volatile.
3527 if (MSI->isVolatile())
3528 return false;
3529
3530 if (!MSI->getLength()->getType()->isIntegerTy(64))
3531 return false;
3532
3533 if (MSI->getDestAddressSpace() > 255)
3534 // Fast instruction selection doesn't support the special
3535 // address spaces.
3536 return false;
3537
3538 return lowerCallTo(II, "memset", II->arg_size() - 1);
3539 }
3540 case Intrinsic::sin:
3541 case Intrinsic::cos:
3542 case Intrinsic::tan:
3543 case Intrinsic::pow: {
3544 MVT RetVT;
3545 if (!isTypeLegal(II->getType(), RetVT))
3546 return false;
3547
3548 if (RetVT != MVT::f32 && RetVT != MVT::f64)
3549 return false;
3550
3551 static const RTLIB::Libcall LibCallTable[4][2] = {
3552 {RTLIB::SIN_F32, RTLIB::SIN_F64},
3553 {RTLIB::COS_F32, RTLIB::COS_F64},
3554 {RTLIB::TAN_F32, RTLIB::TAN_F64},
3555 {RTLIB::POW_F32, RTLIB::POW_F64}};
3556 RTLIB::Libcall LC;
3557 bool Is64Bit = RetVT == MVT::f64;
3558 switch (II->getIntrinsicID()) {
3559 default:
3560 llvm_unreachable("Unexpected intrinsic.");
3561 case Intrinsic::sin:
3562 LC = LibCallTable[0][Is64Bit];
3563 break;
3564 case Intrinsic::cos:
3565 LC = LibCallTable[1][Is64Bit];
3566 break;
3567 case Intrinsic::tan:
3568 LC = LibCallTable[2][Is64Bit];
3569 break;
3570 case Intrinsic::pow:
3571 LC = LibCallTable[3][Is64Bit];
3572 break;
3573 }
3574
3575 ArgListTy Args;
3576 Args.reserve(II->arg_size());
3577
3578 // Populate the argument list.
3579 for (auto &Arg : II->args())
3580 Args.emplace_back(Arg);
3581
3582 CallLoweringInfo CLI;
3583 MCContext &Ctx = MF->getContext();
3584
3585 RTLIB::LibcallImpl LCImpl = LibcallLowering->getLibcallImpl(LC);
3586 if (LCImpl == RTLIB::Unsupported)
3587 return false;
3588
3589 CallingConv::ID CC = LibcallLowering->getLibcallImplCallingConv(LCImpl);
3590 StringRef FuncName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LCImpl);
3591 CLI.setCallee(DL, Ctx, CC, II->getType(), FuncName, std::move(Args));
3592 if (!lowerCallTo(CLI))
3593 return false;
3594 updateValueMap(II, CLI.ResultReg);
3595 return true;
3596 }
3597 case Intrinsic::fabs: {
3598 MVT VT;
3599 if (!isTypeLegal(II->getType(), VT))
3600 return false;
3601
3602 unsigned Opc;
3603 switch (VT.SimpleTy) {
3604 default:
3605 return false;
3606 case MVT::f32:
3607 Opc = AArch64::FABSSr;
3608 break;
3609 case MVT::f64:
3610 Opc = AArch64::FABSDr;
3611 break;
3612 }
3613 Register SrcReg = getRegForValue(II->getOperand(0));
3614 if (!SrcReg)
3615 return false;
3616 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3617 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
3618 .addReg(SrcReg);
3619 updateValueMap(II, ResultReg);
3620 return true;
3621 }
3622 case Intrinsic::trap:
3623 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::BRK))
3624 .addImm(1);
3625 return true;
3626 case Intrinsic::debugtrap:
3627 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::BRK))
3628 .addImm(0xF000);
3629 return true;
3630
3631 case Intrinsic::sqrt: {
3632 Type *RetTy = II->getCalledFunction()->getReturnType();
3633
3634 MVT VT;
3635 if (!isTypeLegal(RetTy, VT))
3636 return false;
3637
3638 Register Op0Reg = getRegForValue(II->getOperand(0));
3639 if (!Op0Reg)
3640 return false;
3641
3642 Register ResultReg = fastEmit_r(VT, VT, ISD::FSQRT, Op0Reg);
3643 if (!ResultReg)
3644 return false;
3645
3646 updateValueMap(II, ResultReg);
3647 return true;
3648 }
3649 case Intrinsic::sadd_with_overflow:
3650 case Intrinsic::uadd_with_overflow:
3651 case Intrinsic::ssub_with_overflow:
3652 case Intrinsic::usub_with_overflow:
3653 case Intrinsic::smul_with_overflow:
3654 case Intrinsic::umul_with_overflow: {
3655 // This implements the basic lowering of the xalu with overflow intrinsics.
3656 const Function *Callee = II->getCalledFunction();
3657 auto *Ty = cast<StructType>(Callee->getReturnType());
3658 Type *RetTy = Ty->getTypeAtIndex(0U);
3659
3660 MVT VT;
3661 if (!isTypeLegal(RetTy, VT))
3662 return false;
3663
3664 if (VT != MVT::i32 && VT != MVT::i64)
3665 return false;
3666
3667 const Value *LHS = II->getArgOperand(0);
3668 const Value *RHS = II->getArgOperand(1);
3669 // Canonicalize immediate to the RHS.
3670 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
3671 std::swap(LHS, RHS);
3672
3673 // Simplify multiplies.
3674 Intrinsic::ID IID = II->getIntrinsicID();
3675 switch (IID) {
3676 default:
3677 break;
3678 case Intrinsic::smul_with_overflow:
3679 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3680 if (C->getValue() == 2) {
3681 IID = Intrinsic::sadd_with_overflow;
3682 RHS = LHS;
3683 }
3684 break;
3685 case Intrinsic::umul_with_overflow:
3686 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3687 if (C->getValue() == 2) {
3688 IID = Intrinsic::uadd_with_overflow;
3689 RHS = LHS;
3690 }
3691 break;
3692 }
3693
3694 Register ResultReg1, ResultReg2, MulReg;
3696 switch (IID) {
3697 default: llvm_unreachable("Unexpected intrinsic!");
3698 case Intrinsic::sadd_with_overflow:
3699 ResultReg1 = emitAdd(VT, LHS, RHS, /*SetFlags=*/true);
3700 CC = AArch64CC::VS;
3701 break;
3702 case Intrinsic::uadd_with_overflow:
3703 ResultReg1 = emitAdd(VT, LHS, RHS, /*SetFlags=*/true);
3704 CC = AArch64CC::HS;
3705 break;
3706 case Intrinsic::ssub_with_overflow:
3707 ResultReg1 = emitSub(VT, LHS, RHS, /*SetFlags=*/true);
3708 CC = AArch64CC::VS;
3709 break;
3710 case Intrinsic::usub_with_overflow:
3711 ResultReg1 = emitSub(VT, LHS, RHS, /*SetFlags=*/true);
3712 CC = AArch64CC::LO;
3713 break;
3714 case Intrinsic::smul_with_overflow: {
3715 CC = AArch64CC::NE;
3716 Register LHSReg = getRegForValue(LHS);
3717 if (!LHSReg)
3718 return false;
3719
3720 Register RHSReg = getRegForValue(RHS);
3721 if (!RHSReg)
3722 return false;
3723
3724 if (VT == MVT::i32) {
3725 MulReg = emitSMULL_rr(MVT::i64, LHSReg, RHSReg);
3726 Register MulSubReg =
3727 fastEmitInst_extractsubreg(VT, MulReg, AArch64::sub_32);
3728 // cmp xreg, wreg, sxtw
3729 emitAddSub_rx(/*UseAdd=*/false, MVT::i64, MulReg, MulSubReg,
3730 AArch64_AM::SXTW, /*ShiftImm=*/0, /*SetFlags=*/true,
3731 /*WantResult=*/false);
3732 MulReg = MulSubReg;
3733 } else {
3734 assert(VT == MVT::i64 && "Unexpected value type.");
3735 // LHSReg and RHSReg cannot be killed by this Mul, since they are
3736 // reused in the next instruction.
3737 MulReg = emitMul_rr(VT, LHSReg, RHSReg);
3738 Register SMULHReg = fastEmit_rr(VT, VT, ISD::MULHS, LHSReg, RHSReg);
3739 emitSubs_rs(VT, SMULHReg, MulReg, AArch64_AM::ASR, 63,
3740 /*WantResult=*/false);
3741 }
3742 break;
3743 }
3744 case Intrinsic::umul_with_overflow: {
3745 CC = AArch64CC::NE;
3746 Register LHSReg = getRegForValue(LHS);
3747 if (!LHSReg)
3748 return false;
3749
3750 Register RHSReg = getRegForValue(RHS);
3751 if (!RHSReg)
3752 return false;
3753
3754 if (VT == MVT::i32) {
3755 MulReg = emitUMULL_rr(MVT::i64, LHSReg, RHSReg);
3756 // tst xreg, #0xffffffff00000000
3757 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3758 TII.get(AArch64::ANDSXri), AArch64::XZR)
3759 .addReg(MulReg)
3760 .addImm(AArch64_AM::encodeLogicalImmediate(0xFFFFFFFF00000000, 64));
3761 MulReg = fastEmitInst_extractsubreg(VT, MulReg, AArch64::sub_32);
3762 } else {
3763 assert(VT == MVT::i64 && "Unexpected value type.");
3764 // LHSReg and RHSReg cannot be killed by this Mul, since they are
3765 // reused in the next instruction.
3766 MulReg = emitMul_rr(VT, LHSReg, RHSReg);
3767 Register UMULHReg = fastEmit_rr(VT, VT, ISD::MULHU, LHSReg, RHSReg);
3768 emitSubs_rr(VT, AArch64::XZR, UMULHReg, /*WantResult=*/false);
3769 }
3770 break;
3771 }
3772 }
3773
3774 if (MulReg) {
3775 ResultReg1 = createResultReg(TLI.getRegClassFor(VT));
3776 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3777 TII.get(TargetOpcode::COPY), ResultReg1).addReg(MulReg);
3778 }
3779
3780 if (!ResultReg1)
3781 return false;
3782
3783 ResultReg2 = fastEmitInst_rri(AArch64::CSINCWr, &AArch64::GPR32RegClass,
3784 AArch64::WZR, AArch64::WZR,
3785 getInvertedCondCode(CC));
3786 (void)ResultReg2;
3787 assert((ResultReg1 + 1) == ResultReg2 &&
3788 "Nonconsecutive result registers.");
3789 updateValueMap(II, ResultReg1, 2);
3790 return true;
3791 }
3792 case Intrinsic::aarch64_crc32b:
3793 case Intrinsic::aarch64_crc32h:
3794 case Intrinsic::aarch64_crc32w:
3795 case Intrinsic::aarch64_crc32x:
3796 case Intrinsic::aarch64_crc32cb:
3797 case Intrinsic::aarch64_crc32ch:
3798 case Intrinsic::aarch64_crc32cw:
3799 case Intrinsic::aarch64_crc32cx: {
3800 if (!Subtarget->hasCRC())
3801 return false;
3802
3803 unsigned Opc;
3804 switch (II->getIntrinsicID()) {
3805 default:
3806 llvm_unreachable("Unexpected intrinsic!");
3807 case Intrinsic::aarch64_crc32b:
3808 Opc = AArch64::CRC32Brr;
3809 break;
3810 case Intrinsic::aarch64_crc32h:
3811 Opc = AArch64::CRC32Hrr;
3812 break;
3813 case Intrinsic::aarch64_crc32w:
3814 Opc = AArch64::CRC32Wrr;
3815 break;
3816 case Intrinsic::aarch64_crc32x:
3817 Opc = AArch64::CRC32Xrr;
3818 break;
3819 case Intrinsic::aarch64_crc32cb:
3820 Opc = AArch64::CRC32CBrr;
3821 break;
3822 case Intrinsic::aarch64_crc32ch:
3823 Opc = AArch64::CRC32CHrr;
3824 break;
3825 case Intrinsic::aarch64_crc32cw:
3826 Opc = AArch64::CRC32CWrr;
3827 break;
3828 case Intrinsic::aarch64_crc32cx:
3829 Opc = AArch64::CRC32CXrr;
3830 break;
3831 }
3832
3833 Register LHSReg = getRegForValue(II->getArgOperand(0));
3834 Register RHSReg = getRegForValue(II->getArgOperand(1));
3835 if (!LHSReg || !RHSReg)
3836 return false;
3837
3838 Register ResultReg =
3839 fastEmitInst_rr(Opc, &AArch64::GPR32RegClass, LHSReg, RHSReg);
3840 updateValueMap(II, ResultReg);
3841 return true;
3842 }
3843 }
3844 return false;
3845}
3846
3847bool AArch64FastISel::selectRet(const Instruction *I) {
3848 const ReturnInst *Ret = cast<ReturnInst>(I);
3849 const Function &F = *I->getParent()->getParent();
3850
3851 if (!FuncInfo.CanLowerReturn)
3852 return false;
3853
3854 if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->getSRetReturnReg())
3855 return false;
3856
3857 if (F.isVarArg())
3858 return false;
3859
3860 if (TLI.supportSwiftError() &&
3861 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
3862 return false;
3863
3864 if (TLI.supportSplitCSR(FuncInfo.MF))
3865 return false;
3866
3867 // Build a list of return value registers.
3869
3870 if (Ret->getNumOperands() > 0) {
3871 CallingConv::ID CC = F.getCallingConv();
3873 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
3874
3875 // Analyze operands of the call, assigning locations to each operand.
3877 CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, I->getContext());
3878 CCInfo.AnalyzeReturn(Outs, RetCC_AArch64_AAPCS);
3879
3880 // Only handle a single return value for now.
3881 if (ValLocs.size() != 1)
3882 return false;
3883
3884 CCValAssign &VA = ValLocs[0];
3885 const Value *RV = Ret->getOperand(0);
3886
3887 // Don't bother handling odd stuff for now.
3888 if ((VA.getLocInfo() != CCValAssign::Full) &&
3889 (VA.getLocInfo() != CCValAssign::BCvt))
3890 return false;
3891
3892 // Only handle register returns for now.
3893 if (!VA.isRegLoc())
3894 return false;
3895
3896 Register Reg = getRegForValue(RV);
3897 if (!Reg)
3898 return false;
3899
3900 Register SrcReg = Reg + VA.getValNo();
3901 Register DestReg = VA.getLocReg();
3902 // Avoid a cross-class copy. This is very unlikely.
3903 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
3904 return false;
3905
3906 EVT RVEVT = TLI.getValueType(DL, RV->getType());
3907 if (!RVEVT.isSimple())
3908 return false;
3909
3910 // Vectors (of > 1 lane) in big endian need tricky handling.
3911 if (RVEVT.isVector() && RVEVT.getVectorElementCount().isVector() &&
3912 !Subtarget->isLittleEndian())
3913 return false;
3914
3915 MVT RVVT = RVEVT.getSimpleVT();
3916 if (RVVT == MVT::f128)
3917 return false;
3918
3919 MVT DestVT = VA.getValVT();
3920 // Special handling for extended integers.
3921 if (RVVT != DestVT) {
3922 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
3923 return false;
3924
3925 if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
3926 return false;
3927
3928 bool IsZExt = Outs[0].Flags.isZExt();
3929 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
3930 if (!SrcReg)
3931 return false;
3932 }
3933
3934 // "Callee" (i.e. value producer) zero extends pointers at function
3935 // boundary.
3936 if (Subtarget->isTargetILP32() && RV->getType()->isPointerTy())
3937 SrcReg = emitAnd_ri(MVT::i64, SrcReg, 0xffffffff);
3938
3939 // Make the copy.
3940 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3941 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
3942
3943 // Add register to return instruction.
3944 RetRegs.push_back(VA.getLocReg());
3945 }
3946
3947 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3948 TII.get(AArch64::RET_ReallyLR));
3949 for (Register RetReg : RetRegs)
3950 MIB.addReg(RetReg, RegState::Implicit);
3951 return true;
3952}
3953
3954bool AArch64FastISel::selectTrunc(const Instruction *I) {
3955 Type *DestTy = I->getType();
3956 Value *Op = I->getOperand(0);
3957 Type *SrcTy = Op->getType();
3958
3959 EVT SrcEVT = TLI.getValueType(DL, SrcTy, true);
3960 EVT DestEVT = TLI.getValueType(DL, DestTy, true);
3961 if (!SrcEVT.isSimple())
3962 return false;
3963 if (!DestEVT.isSimple())
3964 return false;
3965
3966 MVT SrcVT = SrcEVT.getSimpleVT();
3967 MVT DestVT = DestEVT.getSimpleVT();
3968
3969 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
3970 SrcVT != MVT::i8)
3971 return false;
3972 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8 &&
3973 DestVT != MVT::i1)
3974 return false;
3975
3976 Register SrcReg = getRegForValue(Op);
3977 if (!SrcReg)
3978 return false;
3979
3980 // If we're truncating from i64 to a smaller non-legal type then generate an
3981 // AND. Otherwise, we know the high bits are undefined and a truncate only
3982 // generate a COPY. We cannot mark the source register also as result
3983 // register, because this can incorrectly transfer the kill flag onto the
3984 // source register.
3985 Register ResultReg;
3986 if (SrcVT == MVT::i64) {
3987 uint64_t Mask = 0;
3988 switch (DestVT.SimpleTy) {
3989 default:
3990 // Trunc i64 to i32 is handled by the target-independent fast-isel.
3991 return false;
3992 case MVT::i1:
3993 Mask = 0x1;
3994 break;
3995 case MVT::i8:
3996 Mask = 0xff;
3997 break;
3998 case MVT::i16:
3999 Mask = 0xffff;
4000 break;
4001 }
4002 // Issue an extract_subreg to get the lower 32-bits.
4003 Register Reg32 = fastEmitInst_extractsubreg(MVT::i32, SrcReg,
4004 AArch64::sub_32);
4005 // Create the AND instruction which performs the actual truncation.
4006 ResultReg = emitAnd_ri(MVT::i32, Reg32, Mask);
4007 assert(ResultReg && "Unexpected AND instruction emission failure.");
4008 } else {
4009 ResultReg = createResultReg(&AArch64::GPR32RegClass);
4010 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4011 TII.get(TargetOpcode::COPY), ResultReg)
4012 .addReg(SrcReg);
4013 }
4014
4015 updateValueMap(I, ResultReg);
4016 return true;
4017}
4018
4019Register AArch64FastISel::emiti1Ext(Register SrcReg, MVT DestVT, bool IsZExt) {
4020 assert((DestVT == MVT::i8 || DestVT == MVT::i16 || DestVT == MVT::i32 ||
4021 DestVT == MVT::i64) &&
4022 "Unexpected value type.");
4023 // Handle i8 and i16 as i32.
4024 if (DestVT == MVT::i8 || DestVT == MVT::i16)
4025 DestVT = MVT::i32;
4026
4027 if (IsZExt) {
4028 Register ResultReg = emitAnd_ri(MVT::i32, SrcReg, 1);
4029 assert(ResultReg && "Unexpected AND instruction emission failure.");
4030 if (DestVT == MVT::i64) {
4031 // We're ZExt i1 to i64. The ANDWri Wd, Ws, #1 implicitly clears the
4032 // upper 32 bits. Emit a SUBREG_TO_REG to extend from Wd to Xd.
4033 Register Reg64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
4034 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4035 TII.get(AArch64::SUBREG_TO_REG), Reg64)
4036 .addReg(ResultReg)
4037 .addImm(AArch64::sub_32);
4038 ResultReg = Reg64;
4039 }
4040 return ResultReg;
4041 } else {
4042 if (DestVT == MVT::i64) {
4043 // FIXME: We're SExt i1 to i64.
4044 return Register();
4045 }
4046 return fastEmitInst_rii(AArch64::SBFMWri, &AArch64::GPR32RegClass, SrcReg,
4047 0, 0);
4048 }
4049}
4050
4051Register AArch64FastISel::emitMul_rr(MVT RetVT, Register Op0, Register Op1) {
4052 unsigned Opc;
4053 Register ZReg;
4054 switch (RetVT.SimpleTy) {
4055 default:
4056 return Register();
4057 case MVT::i8:
4058 case MVT::i16:
4059 case MVT::i32:
4060 RetVT = MVT::i32;
4061 Opc = AArch64::MADDWrrr; ZReg = AArch64::WZR; break;
4062 case MVT::i64:
4063 Opc = AArch64::MADDXrrr; ZReg = AArch64::XZR; break;
4064 }
4065
4066 const TargetRegisterClass *RC =
4067 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4068 return fastEmitInst_rrr(Opc, RC, Op0, Op1, ZReg);
4069}
4070
4071Register AArch64FastISel::emitSMULL_rr(MVT RetVT, Register Op0, Register Op1) {
4072 if (RetVT != MVT::i64)
4073 return Register();
4074
4075 return fastEmitInst_rrr(AArch64::SMADDLrrr, &AArch64::GPR64RegClass,
4076 Op0, Op1, AArch64::XZR);
4077}
4078
4079Register AArch64FastISel::emitUMULL_rr(MVT RetVT, Register Op0, Register Op1) {
4080 if (RetVT != MVT::i64)
4081 return Register();
4082
4083 return fastEmitInst_rrr(AArch64::UMADDLrrr, &AArch64::GPR64RegClass,
4084 Op0, Op1, AArch64::XZR);
4085}
4086
4087Register AArch64FastISel::emitLSL_rr(MVT RetVT, Register Op0Reg,
4088 Register Op1Reg) {
4089 unsigned Opc = 0;
4090 bool NeedTrunc = false;
4091 uint64_t Mask = 0;
4092 switch (RetVT.SimpleTy) {
4093 default:
4094 return Register();
4095 case MVT::i8: Opc = AArch64::LSLVWr; NeedTrunc = true; Mask = 0xff; break;
4096 case MVT::i16: Opc = AArch64::LSLVWr; NeedTrunc = true; Mask = 0xffff; break;
4097 case MVT::i32: Opc = AArch64::LSLVWr; break;
4098 case MVT::i64: Opc = AArch64::LSLVXr; break;
4099 }
4100
4101 const TargetRegisterClass *RC =
4102 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4103 if (NeedTrunc)
4104 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4105
4106 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4107 if (NeedTrunc)
4108 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4109 return ResultReg;
4110}
4111
4112Register AArch64FastISel::emitLSL_ri(MVT RetVT, MVT SrcVT, Register Op0,
4113 uint64_t Shift, bool IsZExt) {
4114 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4115 "Unexpected source/return type pair.");
4116 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4117 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4118 "Unexpected source value type.");
4119 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4120 RetVT == MVT::i64) && "Unexpected return value type.");
4121
4122 bool Is64Bit = (RetVT == MVT::i64);
4123 unsigned RegSize = Is64Bit ? 64 : 32;
4124 unsigned DstBits = RetVT.getSizeInBits();
4125 unsigned SrcBits = SrcVT.getSizeInBits();
4126 const TargetRegisterClass *RC =
4127 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4128
4129 // Just emit a copy for "zero" shifts.
4130 if (Shift == 0) {
4131 if (RetVT == SrcVT) {
4132 Register ResultReg = createResultReg(RC);
4133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4134 TII.get(TargetOpcode::COPY), ResultReg)
4135 .addReg(Op0);
4136 return ResultReg;
4137 } else
4138 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4139 }
4140
4141 // Don't deal with undefined shifts.
4142 if (Shift >= DstBits)
4143 return Register();
4144
4145 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4146 // {S|U}BFM Wd, Wn, #r, #s
4147 // Wd<32+s-r,32-r> = Wn<s:0> when r > s
4148
4149 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4150 // %2 = shl i16 %1, 4
4151 // Wd<32+7-28,32-28> = Wn<7:0> <- clamp s to 7
4152 // 0b1111_1111_1111_1111__1111_1010_1010_0000 sext
4153 // 0b0000_0000_0000_0000__0000_0101_0101_0000 sext | zext
4154 // 0b0000_0000_0000_0000__0000_1010_1010_0000 zext
4155
4156 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4157 // %2 = shl i16 %1, 8
4158 // Wd<32+7-24,32-24> = Wn<7:0>
4159 // 0b1111_1111_1111_1111__1010_1010_0000_0000 sext
4160 // 0b0000_0000_0000_0000__0101_0101_0000_0000 sext | zext
4161 // 0b0000_0000_0000_0000__1010_1010_0000_0000 zext
4162
4163 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4164 // %2 = shl i16 %1, 12
4165 // Wd<32+3-20,32-20> = Wn<3:0>
4166 // 0b1111_1111_1111_1111__1010_0000_0000_0000 sext
4167 // 0b0000_0000_0000_0000__0101_0000_0000_0000 sext | zext
4168 // 0b0000_0000_0000_0000__1010_0000_0000_0000 zext
4169
4170 unsigned ImmR = RegSize - Shift;
4171 // Limit the width to the length of the source type.
4172 unsigned ImmS = std::min<unsigned>(SrcBits - 1, DstBits - 1 - Shift);
4173 static const unsigned OpcTable[2][2] = {
4174 {AArch64::SBFMWri, AArch64::SBFMXri},
4175 {AArch64::UBFMWri, AArch64::UBFMXri}
4176 };
4177 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4178 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4179 Register TmpReg = MRI.createVirtualRegister(RC);
4180 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4181 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4182 .addReg(Op0)
4183 .addImm(AArch64::sub_32);
4184 Op0 = TmpReg;
4185 }
4186 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4187}
4188
4189Register AArch64FastISel::emitLSR_rr(MVT RetVT, Register Op0Reg,
4190 Register Op1Reg) {
4191 unsigned Opc = 0;
4192 bool NeedTrunc = false;
4193 uint64_t Mask = 0;
4194 switch (RetVT.SimpleTy) {
4195 default:
4196 return Register();
4197 case MVT::i8: Opc = AArch64::LSRVWr; NeedTrunc = true; Mask = 0xff; break;
4198 case MVT::i16: Opc = AArch64::LSRVWr; NeedTrunc = true; Mask = 0xffff; break;
4199 case MVT::i32: Opc = AArch64::LSRVWr; break;
4200 case MVT::i64: Opc = AArch64::LSRVXr; break;
4201 }
4202
4203 const TargetRegisterClass *RC =
4204 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4205 if (NeedTrunc) {
4206 Op0Reg = emitAnd_ri(MVT::i32, Op0Reg, Mask);
4207 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4208 }
4209 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4210 if (NeedTrunc)
4211 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4212 return ResultReg;
4213}
4214
4215Register AArch64FastISel::emitLSR_ri(MVT RetVT, MVT SrcVT, Register Op0,
4216 uint64_t Shift, bool IsZExt) {
4217 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4218 "Unexpected source/return type pair.");
4219 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4220 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4221 "Unexpected source value type.");
4222 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4223 RetVT == MVT::i64) && "Unexpected return value type.");
4224
4225 bool Is64Bit = (RetVT == MVT::i64);
4226 unsigned RegSize = Is64Bit ? 64 : 32;
4227 unsigned DstBits = RetVT.getSizeInBits();
4228 unsigned SrcBits = SrcVT.getSizeInBits();
4229 const TargetRegisterClass *RC =
4230 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4231
4232 // Just emit a copy for "zero" shifts.
4233 if (Shift == 0) {
4234 if (RetVT == SrcVT) {
4235 Register ResultReg = createResultReg(RC);
4236 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4237 TII.get(TargetOpcode::COPY), ResultReg)
4238 .addReg(Op0);
4239 return ResultReg;
4240 } else
4241 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4242 }
4243
4244 // Don't deal with undefined shifts.
4245 if (Shift >= DstBits)
4246 return Register();
4247
4248 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4249 // {S|U}BFM Wd, Wn, #r, #s
4250 // Wd<s-r:0> = Wn<s:r> when r <= s
4251
4252 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4253 // %2 = lshr i16 %1, 4
4254 // Wd<7-4:0> = Wn<7:4>
4255 // 0b0000_0000_0000_0000__0000_1111_1111_1010 sext
4256 // 0b0000_0000_0000_0000__0000_0000_0000_0101 sext | zext
4257 // 0b0000_0000_0000_0000__0000_0000_0000_1010 zext
4258
4259 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4260 // %2 = lshr i16 %1, 8
4261 // Wd<7-7,0> = Wn<7:7>
4262 // 0b0000_0000_0000_0000__0000_0000_1111_1111 sext
4263 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4264 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4265
4266 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4267 // %2 = lshr i16 %1, 12
4268 // Wd<7-7,0> = Wn<7:7> <- clamp r to 7
4269 // 0b0000_0000_0000_0000__0000_0000_0000_1111 sext
4270 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4271 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4272
4273 if (Shift >= SrcBits && IsZExt)
4274 return materializeInt(ConstantInt::get(*Context, APInt(RegSize, 0)), RetVT);
4275
4276 // It is not possible to fold a sign-extend into the LShr instruction. In this
4277 // case emit a sign-extend.
4278 if (!IsZExt) {
4279 Op0 = emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4280 if (!Op0)
4281 return Register();
4282 SrcVT = RetVT;
4283 SrcBits = SrcVT.getSizeInBits();
4284 IsZExt = true;
4285 }
4286
4287 unsigned ImmR = std::min<unsigned>(SrcBits - 1, Shift);
4288 unsigned ImmS = SrcBits - 1;
4289 static const unsigned OpcTable[2][2] = {
4290 {AArch64::SBFMWri, AArch64::SBFMXri},
4291 {AArch64::UBFMWri, AArch64::UBFMXri}
4292 };
4293 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4294 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4295 Register TmpReg = MRI.createVirtualRegister(RC);
4296 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4297 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4298 .addReg(Op0)
4299 .addImm(AArch64::sub_32);
4300 Op0 = TmpReg;
4301 }
4302 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4303}
4304
4305Register AArch64FastISel::emitASR_rr(MVT RetVT, Register Op0Reg,
4306 Register Op1Reg) {
4307 unsigned Opc = 0;
4308 bool NeedTrunc = false;
4309 uint64_t Mask = 0;
4310 switch (RetVT.SimpleTy) {
4311 default:
4312 return Register();
4313 case MVT::i8: Opc = AArch64::ASRVWr; NeedTrunc = true; Mask = 0xff; break;
4314 case MVT::i16: Opc = AArch64::ASRVWr; NeedTrunc = true; Mask = 0xffff; break;
4315 case MVT::i32: Opc = AArch64::ASRVWr; break;
4316 case MVT::i64: Opc = AArch64::ASRVXr; break;
4317 }
4318
4319 const TargetRegisterClass *RC =
4320 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4321 if (NeedTrunc) {
4322 Op0Reg = emitIntExt(RetVT, Op0Reg, MVT::i32, /*isZExt=*/false);
4323 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4324 }
4325 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4326 if (NeedTrunc)
4327 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4328 return ResultReg;
4329}
4330
4331Register AArch64FastISel::emitASR_ri(MVT RetVT, MVT SrcVT, Register Op0,
4332 uint64_t Shift, bool IsZExt) {
4333 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4334 "Unexpected source/return type pair.");
4335 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4336 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4337 "Unexpected source value type.");
4338 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4339 RetVT == MVT::i64) && "Unexpected return value type.");
4340
4341 bool Is64Bit = (RetVT == MVT::i64);
4342 unsigned RegSize = Is64Bit ? 64 : 32;
4343 unsigned DstBits = RetVT.getSizeInBits();
4344 unsigned SrcBits = SrcVT.getSizeInBits();
4345 const TargetRegisterClass *RC =
4346 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4347
4348 // Just emit a copy for "zero" shifts.
4349 if (Shift == 0) {
4350 if (RetVT == SrcVT) {
4351 Register ResultReg = createResultReg(RC);
4352 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4353 TII.get(TargetOpcode::COPY), ResultReg)
4354 .addReg(Op0);
4355 return ResultReg;
4356 } else
4357 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4358 }
4359
4360 // Don't deal with undefined shifts.
4361 if (Shift >= DstBits)
4362 return Register();
4363
4364 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4365 // {S|U}BFM Wd, Wn, #r, #s
4366 // Wd<s-r:0> = Wn<s:r> when r <= s
4367
4368 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4369 // %2 = ashr i16 %1, 4
4370 // Wd<7-4:0> = Wn<7:4>
4371 // 0b1111_1111_1111_1111__1111_1111_1111_1010 sext
4372 // 0b0000_0000_0000_0000__0000_0000_0000_0101 sext | zext
4373 // 0b0000_0000_0000_0000__0000_0000_0000_1010 zext
4374
4375 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4376 // %2 = ashr i16 %1, 8
4377 // Wd<7-7,0> = Wn<7:7>
4378 // 0b1111_1111_1111_1111__1111_1111_1111_1111 sext
4379 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4380 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4381
4382 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4383 // %2 = ashr i16 %1, 12
4384 // Wd<7-7,0> = Wn<7:7> <- clamp r to 7
4385 // 0b1111_1111_1111_1111__1111_1111_1111_1111 sext
4386 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4387 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4388
4389 if (Shift >= SrcBits && IsZExt)
4390 return materializeInt(ConstantInt::get(*Context, APInt(RegSize, 0)), RetVT);
4391
4392 unsigned ImmR = std::min<unsigned>(SrcBits - 1, Shift);
4393 unsigned ImmS = SrcBits - 1;
4394 static const unsigned OpcTable[2][2] = {
4395 {AArch64::SBFMWri, AArch64::SBFMXri},
4396 {AArch64::UBFMWri, AArch64::UBFMXri}
4397 };
4398 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4399 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4400 Register TmpReg = MRI.createVirtualRegister(RC);
4401 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4402 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4403 .addReg(Op0)
4404 .addImm(AArch64::sub_32);
4405 Op0 = TmpReg;
4406 }
4407 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4408}
4409
4410Register AArch64FastISel::emitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT,
4411 bool IsZExt) {
4412 assert(DestVT != MVT::i1 && "ZeroExt/SignExt an i1?");
4413
4414 // FastISel does not have plumbing to deal with extensions where the SrcVT or
4415 // DestVT are odd things, so test to make sure that they are both types we can
4416 // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise
4417 // bail out to SelectionDAG.
4418 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) &&
4419 (DestVT != MVT::i32) && (DestVT != MVT::i64)) ||
4420 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) &&
4421 (SrcVT != MVT::i16) && (SrcVT != MVT::i32)))
4422 return Register();
4423
4424 unsigned Opc;
4425 unsigned Imm = 0;
4426
4427 switch (SrcVT.SimpleTy) {
4428 default:
4429 return Register();
4430 case MVT::i1:
4431 return emiti1Ext(SrcReg, DestVT, IsZExt);
4432 case MVT::i8:
4433 if (DestVT == MVT::i64)
4434 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4435 else
4436 Opc = IsZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
4437 Imm = 7;
4438 break;
4439 case MVT::i16:
4440 if (DestVT == MVT::i64)
4441 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4442 else
4443 Opc = IsZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
4444 Imm = 15;
4445 break;
4446 case MVT::i32:
4447 assert(DestVT == MVT::i64 && "IntExt i32 to i32?!?");
4448 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4449 Imm = 31;
4450 break;
4451 }
4452
4453 // Handle i8 and i16 as i32.
4454 if (DestVT == MVT::i8 || DestVT == MVT::i16)
4455 DestVT = MVT::i32;
4456 else if (DestVT == MVT::i64) {
4457 Register Src64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
4458 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4459 TII.get(AArch64::SUBREG_TO_REG), Src64)
4460 .addReg(SrcReg)
4461 .addImm(AArch64::sub_32);
4462 SrcReg = Src64;
4463 }
4464
4465 const TargetRegisterClass *RC =
4466 (DestVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4467 return fastEmitInst_rii(Opc, RC, SrcReg, 0, Imm);
4468}
4469
4470bool AArch64FastISel::optimizeIntExtLoad(const Instruction *I, MVT RetVT,
4471 MVT SrcVT) {
4472 const auto *LI = dyn_cast<LoadInst>(I->getOperand(0));
4473 if (!LI || !LI->hasOneUse())
4474 return false;
4475
4476 // Check if the load instruction has already been selected.
4477 Register Reg = lookUpRegForValue(LI);
4478 if (!Reg)
4479 return false;
4480
4481 MachineInstr *MI = MRI.getUniqueVRegDef(Reg);
4482 if (!MI)
4483 return false;
4484
4485 // Check if the correct load instruction has been emitted - SelectionDAG might
4486 // have emitted a zero-extending load, but we need a sign-extending load.
4487 bool IsZExt = isa<ZExtInst>(I);
4488 const auto *LoadMI = MI;
4489 if (LoadMI->getOpcode() == TargetOpcode::COPY &&
4490 LoadMI->getOperand(1).getSubReg() == AArch64::sub_32) {
4491 Register LoadReg = MI->getOperand(1).getReg();
4492 LoadMI = MRI.getUniqueVRegDef(LoadReg);
4493 assert(LoadMI && "Expected valid instruction");
4494 }
4495 if (!(IsZExt && AArch64InstrInfo::isZExtLoad(*LoadMI)) &&
4496 !(!IsZExt && AArch64InstrInfo::isSExtLoad(*LoadMI)))
4497 return false;
4498
4499 // Nothing to be done.
4500 if (RetVT != MVT::i64 || SrcVT > MVT::i32) {
4501 updateValueMap(I, Reg);
4502 return true;
4503 }
4504
4505 if (IsZExt) {
4506 Register Reg64 = createResultReg(&AArch64::GPR64RegClass);
4507 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4508 TII.get(AArch64::SUBREG_TO_REG), Reg64)
4509 .addReg(Reg, getKillRegState(true))
4510 .addImm(AArch64::sub_32);
4511 Reg = Reg64;
4512 } else {
4513 assert((MI->getOpcode() == TargetOpcode::COPY &&
4514 MI->getOperand(1).getSubReg() == AArch64::sub_32) &&
4515 "Expected copy instruction");
4516 Reg = MI->getOperand(1).getReg();
4518 removeDeadCode(I, std::next(I));
4519 }
4520 updateValueMap(I, Reg);
4521 return true;
4522}
4523
4524bool AArch64FastISel::selectIntExt(const Instruction *I) {
4526 "Unexpected integer extend instruction.");
4527 MVT RetVT;
4528 MVT SrcVT;
4529 if (!isTypeSupported(I->getType(), RetVT))
4530 return false;
4531
4532 if (!isTypeSupported(I->getOperand(0)->getType(), SrcVT))
4533 return false;
4534
4535 // Try to optimize already sign-/zero-extended values from load instructions.
4536 if (optimizeIntExtLoad(I, RetVT, SrcVT))
4537 return true;
4538
4539 Register SrcReg = getRegForValue(I->getOperand(0));
4540 if (!SrcReg)
4541 return false;
4542
4543 // Try to optimize already sign-/zero-extended values from function arguments.
4544 bool IsZExt = isa<ZExtInst>(I);
4545 if (const auto *Arg = dyn_cast<Argument>(I->getOperand(0))) {
4546 if ((IsZExt && Arg->hasZExtAttr()) || (!IsZExt && Arg->hasSExtAttr())) {
4547 if (RetVT == MVT::i64 && SrcVT != MVT::i64) {
4548 Register ResultReg = createResultReg(&AArch64::GPR64RegClass);
4549 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4550 TII.get(AArch64::SUBREG_TO_REG), ResultReg)
4551 .addReg(SrcReg)
4552 .addImm(AArch64::sub_32);
4553 SrcReg = ResultReg;
4554 }
4555
4556 updateValueMap(I, SrcReg);
4557 return true;
4558 }
4559 }
4560
4561 Register ResultReg = emitIntExt(SrcVT, SrcReg, RetVT, IsZExt);
4562 if (!ResultReg)
4563 return false;
4564
4565 updateValueMap(I, ResultReg);
4566 return true;
4567}
4568
4569bool AArch64FastISel::selectRem(const Instruction *I, unsigned ISDOpcode) {
4570 EVT DestEVT = TLI.getValueType(DL, I->getType(), true);
4571 if (!DestEVT.isSimple())
4572 return false;
4573
4574 MVT DestVT = DestEVT.getSimpleVT();
4575 if (DestVT != MVT::i64 && DestVT != MVT::i32)
4576 return false;
4577
4578 unsigned DivOpc;
4579 bool Is64bit = (DestVT == MVT::i64);
4580 switch (ISDOpcode) {
4581 default:
4582 return false;
4583 case ISD::SREM:
4584 DivOpc = Is64bit ? AArch64::SDIVXr : AArch64::SDIVWr;
4585 break;
4586 case ISD::UREM:
4587 DivOpc = Is64bit ? AArch64::UDIVXr : AArch64::UDIVWr;
4588 break;
4589 }
4590 unsigned MSubOpc = Is64bit ? AArch64::MSUBXrrr : AArch64::MSUBWrrr;
4591 Register Src0Reg = getRegForValue(I->getOperand(0));
4592 if (!Src0Reg)
4593 return false;
4594
4595 Register Src1Reg = getRegForValue(I->getOperand(1));
4596 if (!Src1Reg)
4597 return false;
4598
4599 const TargetRegisterClass *RC =
4600 (DestVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4601 Register QuotReg = fastEmitInst_rr(DivOpc, RC, Src0Reg, Src1Reg);
4602 assert(QuotReg && "Unexpected DIV instruction emission failure.");
4603 // The remainder is computed as numerator - (quotient * denominator) using the
4604 // MSUB instruction.
4605 Register ResultReg = fastEmitInst_rrr(MSubOpc, RC, QuotReg, Src1Reg, Src0Reg);
4606 updateValueMap(I, ResultReg);
4607 return true;
4608}
4609
4610bool AArch64FastISel::selectMul(const Instruction *I) {
4611 MVT VT;
4612 if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true))
4613 return false;
4614
4615 if (VT.isVector())
4616 return selectBinaryOp(I, ISD::MUL);
4617
4618 const Value *Src0 = I->getOperand(0);
4619 const Value *Src1 = I->getOperand(1);
4620 if (const auto *C = dyn_cast<ConstantInt>(Src0))
4621 if (C->getValue().isPowerOf2())
4622 std::swap(Src0, Src1);
4623
4624 // Try to simplify to a shift instruction.
4625 if (const auto *C = dyn_cast<ConstantInt>(Src1))
4626 if (C->getValue().isPowerOf2()) {
4627 uint64_t ShiftVal = C->getValue().logBase2();
4628 MVT SrcVT = VT;
4629 bool IsZExt = true;
4630 if (const auto *ZExt = dyn_cast<ZExtInst>(Src0)) {
4631 if (!isIntExtFree(ZExt)) {
4632 MVT VT;
4633 if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(), VT)) {
4634 SrcVT = VT;
4635 IsZExt = true;
4636 Src0 = ZExt->getOperand(0);
4637 }
4638 }
4639 } else if (const auto *SExt = dyn_cast<SExtInst>(Src0)) {
4640 if (!isIntExtFree(SExt)) {
4641 MVT VT;
4642 if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(), VT)) {
4643 SrcVT = VT;
4644 IsZExt = false;
4645 Src0 = SExt->getOperand(0);
4646 }
4647 }
4648 }
4649
4650 Register Src0Reg = getRegForValue(Src0);
4651 if (!Src0Reg)
4652 return false;
4653
4654 Register ResultReg = emitLSL_ri(VT, SrcVT, Src0Reg, ShiftVal, IsZExt);
4655
4656 if (ResultReg) {
4657 updateValueMap(I, ResultReg);
4658 return true;
4659 }
4660 }
4661
4662 Register Src0Reg = getRegForValue(I->getOperand(0));
4663 if (!Src0Reg)
4664 return false;
4665
4666 Register Src1Reg = getRegForValue(I->getOperand(1));
4667 if (!Src1Reg)
4668 return false;
4669
4670 Register ResultReg = emitMul_rr(VT, Src0Reg, Src1Reg);
4671
4672 if (!ResultReg)
4673 return false;
4674
4675 updateValueMap(I, ResultReg);
4676 return true;
4677}
4678
4679bool AArch64FastISel::selectShift(const Instruction *I) {
4680 MVT RetVT;
4681 if (!isTypeSupported(I->getType(), RetVT, /*IsVectorAllowed=*/true))
4682 return false;
4683
4684 if (RetVT.isVector())
4685 return selectOperator(I, I->getOpcode());
4686
4687 if (const auto *C = dyn_cast<ConstantInt>(I->getOperand(1))) {
4688 Register ResultReg;
4689 uint64_t ShiftVal = C->getZExtValue();
4690 MVT SrcVT = RetVT;
4691 bool IsZExt = I->getOpcode() != Instruction::AShr;
4692 const Value *Op0 = I->getOperand(0);
4693 if (const auto *ZExt = dyn_cast<ZExtInst>(Op0)) {
4694 if (!isIntExtFree(ZExt)) {
4695 MVT TmpVT;
4696 if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(), TmpVT)) {
4697 SrcVT = TmpVT;
4698 IsZExt = true;
4699 Op0 = ZExt->getOperand(0);
4700 }
4701 }
4702 } else if (const auto *SExt = dyn_cast<SExtInst>(Op0)) {
4703 if (!isIntExtFree(SExt)) {
4704 MVT TmpVT;
4705 if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(), TmpVT)) {
4706 SrcVT = TmpVT;
4707 IsZExt = false;
4708 Op0 = SExt->getOperand(0);
4709 }
4710 }
4711 }
4712
4713 Register Op0Reg = getRegForValue(Op0);
4714 if (!Op0Reg)
4715 return false;
4716
4717 switch (I->getOpcode()) {
4718 default: llvm_unreachable("Unexpected instruction.");
4719 case Instruction::Shl:
4720 ResultReg = emitLSL_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4721 break;
4722 case Instruction::AShr:
4723 ResultReg = emitASR_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4724 break;
4725 case Instruction::LShr:
4726 ResultReg = emitLSR_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4727 break;
4728 }
4729 if (!ResultReg)
4730 return false;
4731
4732 updateValueMap(I, ResultReg);
4733 return true;
4734 }
4735
4736 Register Op0Reg = getRegForValue(I->getOperand(0));
4737 if (!Op0Reg)
4738 return false;
4739
4740 Register Op1Reg = getRegForValue(I->getOperand(1));
4741 if (!Op1Reg)
4742 return false;
4743
4744 Register ResultReg;
4745 switch (I->getOpcode()) {
4746 default: llvm_unreachable("Unexpected instruction.");
4747 case Instruction::Shl:
4748 ResultReg = emitLSL_rr(RetVT, Op0Reg, Op1Reg);
4749 break;
4750 case Instruction::AShr:
4751 ResultReg = emitASR_rr(RetVT, Op0Reg, Op1Reg);
4752 break;
4753 case Instruction::LShr:
4754 ResultReg = emitLSR_rr(RetVT, Op0Reg, Op1Reg);
4755 break;
4756 }
4757
4758 if (!ResultReg)
4759 return false;
4760
4761 updateValueMap(I, ResultReg);
4762 return true;
4763}
4764
4765bool AArch64FastISel::selectBitCast(const Instruction *I) {
4766 MVT RetVT, SrcVT;
4767
4768 if (!isTypeLegal(I->getOperand(0)->getType(), SrcVT))
4769 return false;
4770 if (!isTypeLegal(I->getType(), RetVT))
4771 return false;
4772
4773 unsigned Opc;
4774 if (RetVT == MVT::f32 && SrcVT == MVT::i32)
4775 Opc = AArch64::FMOVWSr;
4776 else if (RetVT == MVT::f64 && SrcVT == MVT::i64)
4777 Opc = AArch64::FMOVXDr;
4778 else if (RetVT == MVT::i32 && SrcVT == MVT::f32)
4779 Opc = AArch64::FMOVSWr;
4780 else if (RetVT == MVT::i64 && SrcVT == MVT::f64)
4781 Opc = AArch64::FMOVDXr;
4782 else
4783 return false;
4784
4785 const TargetRegisterClass *RC = nullptr;
4786 switch (RetVT.SimpleTy) {
4787 default: llvm_unreachable("Unexpected value type.");
4788 case MVT::i32: RC = &AArch64::GPR32RegClass; break;
4789 case MVT::i64: RC = &AArch64::GPR64RegClass; break;
4790 case MVT::f32: RC = &AArch64::FPR32RegClass; break;
4791 case MVT::f64: RC = &AArch64::FPR64RegClass; break;
4792 }
4793 Register Op0Reg = getRegForValue(I->getOperand(0));
4794 if (!Op0Reg)
4795 return false;
4796
4797 Register ResultReg = fastEmitInst_r(Opc, RC, Op0Reg);
4798 if (!ResultReg)
4799 return false;
4800
4801 updateValueMap(I, ResultReg);
4802 return true;
4803}
4804
4805bool AArch64FastISel::selectFRem(const Instruction *I) {
4806 MVT RetVT;
4807 if (!isTypeLegal(I->getType(), RetVT))
4808 return false;
4809
4810 RTLIB::LibcallImpl LCImpl =
4811 LibcallLowering->getLibcallImpl(RTLIB::getREM(RetVT));
4812 if (LCImpl == RTLIB::Unsupported)
4813 return false;
4814
4815 ArgListTy Args;
4816 Args.reserve(I->getNumOperands());
4817
4818 // Populate the argument list.
4819 for (auto &Arg : I->operands())
4820 Args.emplace_back(Arg);
4821
4822 CallLoweringInfo CLI;
4823 MCContext &Ctx = MF->getContext();
4824 CallingConv::ID CC = LibcallLowering->getLibcallImplCallingConv(LCImpl);
4825 StringRef FuncName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LCImpl);
4826
4827 CLI.setCallee(DL, Ctx, CC, I->getType(), FuncName, std::move(Args));
4828 if (!lowerCallTo(CLI))
4829 return false;
4830 updateValueMap(I, CLI.ResultReg);
4831 return true;
4832}
4833
4834bool AArch64FastISel::selectSDiv(const Instruction *I) {
4835 MVT VT;
4836 if (!isTypeLegal(I->getType(), VT))
4837 return false;
4838
4839 if (!isa<ConstantInt>(I->getOperand(1)))
4840 return selectBinaryOp(I, ISD::SDIV);
4841
4842 const APInt &C = cast<ConstantInt>(I->getOperand(1))->getValue();
4843 if ((VT != MVT::i32 && VT != MVT::i64) || !C ||
4844 !(C.isPowerOf2() || C.isNegatedPowerOf2()))
4845 return selectBinaryOp(I, ISD::SDIV);
4846
4847 unsigned Lg2 = C.countr_zero();
4848 Register Src0Reg = getRegForValue(I->getOperand(0));
4849 if (!Src0Reg)
4850 return false;
4851
4852 if (cast<BinaryOperator>(I)->isExact()) {
4853 Register ResultReg = emitASR_ri(VT, VT, Src0Reg, Lg2);
4854 if (!ResultReg)
4855 return false;
4856 updateValueMap(I, ResultReg);
4857 return true;
4858 }
4859
4860 int64_t Pow2MinusOne = (1ULL << Lg2) - 1;
4861 Register AddReg = emitAdd_ri_(VT, Src0Reg, Pow2MinusOne);
4862 if (!AddReg)
4863 return false;
4864
4865 // (Src0 < 0) ? Pow2 - 1 : 0;
4866 if (!emitICmp_ri(VT, Src0Reg, 0))
4867 return false;
4868
4869 unsigned SelectOpc;
4870 const TargetRegisterClass *RC;
4871 if (VT == MVT::i64) {
4872 SelectOpc = AArch64::CSELXr;
4873 RC = &AArch64::GPR64RegClass;
4874 } else {
4875 SelectOpc = AArch64::CSELWr;
4876 RC = &AArch64::GPR32RegClass;
4877 }
4878 Register SelectReg = fastEmitInst_rri(SelectOpc, RC, AddReg, Src0Reg,
4880 if (!SelectReg)
4881 return false;
4882
4883 // Divide by Pow2 --> ashr. If we're dividing by a negative value we must also
4884 // negate the result.
4885 Register ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
4886 Register ResultReg;
4887 if (C.isNegative())
4888 ResultReg = emitAddSub_rs(/*UseAdd=*/false, VT, ZeroReg, SelectReg,
4889 AArch64_AM::ASR, Lg2);
4890 else
4891 ResultReg = emitASR_ri(VT, VT, SelectReg, Lg2);
4892
4893 if (!ResultReg)
4894 return false;
4895
4896 updateValueMap(I, ResultReg);
4897 return true;
4898}
4899
4900/// This is mostly a copy of the existing FastISel getRegForGEPIndex code. We
4901/// have to duplicate it for AArch64, because otherwise we would fail during the
4902/// sign-extend emission.
4903Register AArch64FastISel::getRegForGEPIndex(const Value *Idx) {
4904 Register IdxN = getRegForValue(Idx);
4905 if (!IdxN)
4906 // Unhandled operand. Halt "fast" selection and bail.
4907 return Register();
4908
4909 // If the index is smaller or larger than intptr_t, truncate or extend it.
4910 MVT PtrVT = TLI.getPointerTy(DL);
4911 EVT IdxVT = EVT::getEVT(Idx->getType(), /*HandleUnknown=*/false);
4912 if (IdxVT.bitsLT(PtrVT)) {
4913 IdxN = emitIntExt(IdxVT.getSimpleVT(), IdxN, PtrVT, /*isZExt=*/false);
4914 } else if (IdxVT.bitsGT(PtrVT))
4915 llvm_unreachable("AArch64 FastISel doesn't support types larger than i64");
4916 return IdxN;
4917}
4918
4919/// This is mostly a copy of the existing FastISel GEP code, but we have to
4920/// duplicate it for AArch64, because otherwise we would bail out even for
4921/// simple cases. This is because the standard fastEmit functions don't cover
4922/// MUL at all and ADD is lowered very inefficientily.
4923bool AArch64FastISel::selectGetElementPtr(const Instruction *I) {
4924 if (Subtarget->isTargetILP32())
4925 return false;
4926
4927 Register N = getRegForValue(I->getOperand(0));
4928 if (!N)
4929 return false;
4930
4931 // Keep a running tab of the total offset to coalesce multiple N = N + Offset
4932 // into a single N = N + TotalOffset.
4933 uint64_t TotalOffs = 0;
4934 MVT VT = TLI.getPointerTy(DL);
4936 GTI != E; ++GTI) {
4937 const Value *Idx = GTI.getOperand();
4938 if (auto *StTy = GTI.getStructTypeOrNull()) {
4939 unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
4940 // N = N + Offset
4941 if (Field)
4942 TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field);
4943 } else {
4944 // If this is a constant subscript, handle it quickly.
4945 if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
4946 if (CI->isZero())
4947 continue;
4948 // N = N + Offset
4949 TotalOffs += GTI.getSequentialElementStride(DL) *
4950 cast<ConstantInt>(CI)->getSExtValue();
4951 continue;
4952 }
4953 if (TotalOffs) {
4954 N = emitAdd_ri_(VT, N, TotalOffs);
4955 if (!N)
4956 return false;
4957 TotalOffs = 0;
4958 }
4959
4960 // N = N + Idx * ElementSize;
4961 uint64_t ElementSize = GTI.getSequentialElementStride(DL);
4962 Register IdxN = getRegForGEPIndex(Idx);
4963 if (!IdxN)
4964 return false;
4965
4966 if (ElementSize != 1) {
4967 Register C = fastEmit_i(VT, VT, ISD::Constant, ElementSize);
4968 if (!C)
4969 return false;
4970 IdxN = emitMul_rr(VT, IdxN, C);
4971 if (!IdxN)
4972 return false;
4973 }
4974 N = fastEmit_rr(VT, VT, ISD::ADD, N, IdxN);
4975 if (!N)
4976 return false;
4977 }
4978 }
4979 if (TotalOffs) {
4980 N = emitAdd_ri_(VT, N, TotalOffs);
4981 if (!N)
4982 return false;
4983 }
4984 updateValueMap(I, N);
4985 return true;
4986}
4987
4988bool AArch64FastISel::selectAtomicCmpXchg(const AtomicCmpXchgInst *I) {
4989 assert(TM.getOptLevel() == CodeGenOptLevel::None &&
4990 "cmpxchg survived AtomicExpand at optlevel > -O0");
4991
4992 auto *RetPairTy = cast<StructType>(I->getType());
4993 Type *RetTy = RetPairTy->getTypeAtIndex(0U);
4994 assert(RetPairTy->getTypeAtIndex(1U)->isIntegerTy(1) &&
4995 "cmpxchg has a non-i1 status result");
4996
4997 MVT VT;
4998 if (!isTypeLegal(RetTy, VT))
4999 return false;
5000
5001 const TargetRegisterClass *ResRC;
5002 unsigned Opc, CmpOpc;
5003 // This only supports i32/i64, because i8/i16 aren't legal, and the generic
5004 // extractvalue selection doesn't support that.
5005 if (VT == MVT::i32) {
5006 Opc = AArch64::CMP_SWAP_32;
5007 CmpOpc = AArch64::SUBSWrs;
5008 ResRC = &AArch64::GPR32RegClass;
5009 } else if (VT == MVT::i64) {
5010 Opc = AArch64::CMP_SWAP_64;
5011 CmpOpc = AArch64::SUBSXrs;
5012 ResRC = &AArch64::GPR64RegClass;
5013 } else {
5014 return false;
5015 }
5016
5017 const MCInstrDesc &II = TII.get(Opc);
5018
5019 Register AddrReg = getRegForValue(I->getPointerOperand());
5020 Register DesiredReg = getRegForValue(I->getCompareOperand());
5021 Register NewReg = getRegForValue(I->getNewValOperand());
5022
5023 if (!AddrReg || !DesiredReg || !NewReg)
5024 return false;
5025
5026 AddrReg = constrainOperandRegClass(II, AddrReg, II.getNumDefs());
5027 DesiredReg = constrainOperandRegClass(II, DesiredReg, II.getNumDefs() + 1);
5028 NewReg = constrainOperandRegClass(II, NewReg, II.getNumDefs() + 2);
5029
5030 const Register ResultReg1 = createResultReg(ResRC);
5031 const Register ResultReg2 = createResultReg(&AArch64::GPR32RegClass);
5032 const Register ScratchReg = createResultReg(&AArch64::GPR32RegClass);
5033
5034 // FIXME: MachineMemOperand doesn't support cmpxchg yet.
5035 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
5036 .addDef(ResultReg1)
5037 .addDef(ScratchReg)
5038 .addUse(AddrReg)
5039 .addUse(DesiredReg)
5040 .addUse(NewReg);
5041
5042 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc))
5043 .addDef(VT == MVT::i32 ? AArch64::WZR : AArch64::XZR)
5044 .addUse(ResultReg1)
5045 .addUse(DesiredReg)
5046 .addImm(0);
5047
5048 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::CSINCWr))
5049 .addDef(ResultReg2)
5050 .addUse(AArch64::WZR)
5051 .addUse(AArch64::WZR)
5053
5054 assert((ResultReg1 + 1) == ResultReg2 && "Nonconsecutive result registers.");
5055 updateValueMap(I, ResultReg1, 2);
5056 return true;
5057}
5058
5059bool AArch64FastISel::fastSelectInstruction(const Instruction *I) {
5060 if (TLI.fallBackToDAGISel(*I))
5061 return false;
5062 switch (I->getOpcode()) {
5063 default:
5064 break;
5065 case Instruction::Add:
5066 case Instruction::Sub:
5067 return selectAddSub(I);
5068 case Instruction::Mul:
5069 return selectMul(I);
5070 case Instruction::SDiv:
5071 return selectSDiv(I);
5072 case Instruction::SRem:
5073 if (!selectBinaryOp(I, ISD::SREM))
5074 return selectRem(I, ISD::SREM);
5075 return true;
5076 case Instruction::URem:
5077 if (!selectBinaryOp(I, ISD::UREM))
5078 return selectRem(I, ISD::UREM);
5079 return true;
5080 case Instruction::Shl:
5081 case Instruction::LShr:
5082 case Instruction::AShr:
5083 return selectShift(I);
5084 case Instruction::And:
5085 case Instruction::Or:
5086 case Instruction::Xor:
5087 return selectLogicalOp(I);
5088 case Instruction::CondBr:
5089 return selectBranch(I);
5090 case Instruction::IndirectBr:
5091 return selectIndirectBr(I);
5092 case Instruction::BitCast:
5094 return selectBitCast(I);
5095 return true;
5096 case Instruction::FPToSI:
5097 if (!selectCast(I, ISD::FP_TO_SINT))
5098 return selectFPToInt(I, /*Signed=*/true);
5099 return true;
5100 case Instruction::FPToUI:
5101 return selectFPToInt(I, /*Signed=*/false);
5102 case Instruction::ZExt:
5103 case Instruction::SExt:
5104 return selectIntExt(I);
5105 case Instruction::Trunc:
5106 if (!selectCast(I, ISD::TRUNCATE))
5107 return selectTrunc(I);
5108 return true;
5109 case Instruction::FPExt:
5110 return selectFPExt(I);
5111 case Instruction::FPTrunc:
5112 return selectFPTrunc(I);
5113 case Instruction::SIToFP:
5114 if (!selectCast(I, ISD::SINT_TO_FP))
5115 return selectIntToFP(I, /*Signed=*/true);
5116 return true;
5117 case Instruction::UIToFP:
5118 return selectIntToFP(I, /*Signed=*/false);
5119 case Instruction::Load:
5120 return selectLoad(I);
5121 case Instruction::Store:
5122 return selectStore(I);
5123 case Instruction::FCmp:
5124 case Instruction::ICmp:
5125 return selectCmp(I);
5126 case Instruction::Select:
5127 return selectSelect(I);
5128 case Instruction::Ret:
5129 return selectRet(I);
5130 case Instruction::FRem:
5131 return selectFRem(I);
5132 case Instruction::GetElementPtr:
5133 return selectGetElementPtr(I);
5134 case Instruction::AtomicCmpXchg:
5135 return selectAtomicCmpXchg(cast<AtomicCmpXchgInst>(I));
5136 }
5137
5138 // fall-back to target-independent instruction selection.
5139 return selectOperator(I, I->getOpcode());
5140}
5141
5143 const TargetLibraryInfo *LibInfo,
5144 const LibcallLoweringInfo *LibcallLowering) {
5145
5146 SMEAttrs CallerAttrs =
5147 FuncInfo.MF->getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
5148 if (CallerAttrs.hasZAState() || CallerAttrs.hasZT0State() ||
5149 CallerAttrs.hasStreamingInterfaceOrBody() ||
5150 CallerAttrs.hasStreamingCompatibleInterface() ||
5151 CallerAttrs.hasAgnosticZAInterface())
5152 return nullptr;
5153 return new AArch64FastISel(FuncInfo, LibInfo, LibcallLowering);
5154}
static bool isIntExtFree(const Instruction *I)
Check if the sign-/zero-extend will be a noop.
static AArch64CC::CondCode getCompareCC(CmpInst::Predicate Pred)
static bool isMulPowOf2(const Value *I)
Check if the multiply is by a power-of-2 constant.
static unsigned getImplicitScaleFactor(MVT VT)
Determine the implicit scale factor that is applied by a memory operation for a given value type.
static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Select the AArch64 opcode for the basic binary operation GenericOpc, appropriate for the register ban...
static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)
Emit a load-pair instruction for frame-destroy.
static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)
Emit a store-pair instruction for frame-setup.
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
unsigned uint64_t
AMDGPU Reserve WWM Registers
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
basic Basic Alias true
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
static constexpr Value * getValue(Ty &ValueOrUse)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
Value * RHS
Value * LHS
static const unsigned FramePtr
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
static bool isZExtLoad(const MachineInstr &MI)
Returns whether the instruction is a zero-extending load.
static bool isSExtLoad(const MachineInstr &MI)
Returns whether the instruction is a sign-extending load.
bool isAnyArgRegReserved(const MachineFunction &MF) const
void emitReservedArgRegCallError(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
const AArch64RegisterInfo * getRegisterInfo() const override
unsigned ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const
ClassifyGlobalReference - Find the target operand flags that describe how a global value should be re...
bool hasCustomCallingConv() const
PointerType * getType() const
Overload to return most specific pointer type.
InstListType::const_iterator const_iterator
Definition BasicBlock.h:171
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
Definition InstrTypes.h:757
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:746
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
Definition InstrTypes.h:755
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:745
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ FCMP_ULT
1 1 0 0 True if unordered or less than
Definition InstrTypes.h:754
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
Definition InstrTypes.h:752
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
Definition InstrTypes.h:749
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Definition InstrTypes.h:756
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Definition InstrTypes.h:753
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
Definition InstrTypes.h:742
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
bool isUnsigned() const
Definition InstrTypes.h:999
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
const APFloat & getValueAPF() const
Definition Constants.h:463
bool isNegative() const
Return true if the sign bit is set.
Definition Constants.h:476
bool isZero() const
Return true if the value is positive or negative zero.
Definition Constants.h:467
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition Constants.h:219
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constant.h:64
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:320
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition FastISel.h:67
bool selectBitCast(const User *I)
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
PointerType * getType() const
Global values are always pointers.
iterator_range< succ_iterator > successors()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Tracks which library functions to use for a particular subtarget or function.
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
SimpleValueType SimpleTy
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
bool isValid() const
Return true if this is a valid simple valuetype.
static MVT getIntegerVT(unsigned BitWidth)
bool is64BitVector() const
Return true if this is a 64-bit vector type.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setFrameAddressIsTaken(bool T)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Value * getLength() const
unsigned getDestAddressSpace() const
bool isVolatile() const
constexpr unsigned id() const
Definition Register.h:100
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool hasStreamingCompatibleInterface() const
bool hasAgnosticZAInterface() const
bool hasStreamingInterfaceOrBody() const
void reserve(size_type N)
void push_back(const T &Elt)
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
Provides information about what library functions are available for the current target.
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition Type.h:274
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
bool isStructTy() const
True if this is an instance of StructType.
Definition Type.h:271
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
const ParentTy * getParent() const
Definition ilist_node.h:34
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
@ MO_PREL
MO_PREL - Indicates that the bits of the symbol operand represented by MO_G0 etc are PC relative.
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
@ MO_G3
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address,...
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:891
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:707
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:937
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:742
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:867
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition Utils.cpp:60
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
bool CC_AArch64_Win64PCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool CC_AArch64_DarwinPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
gep_type_iterator gep_type_end(const User *GEP)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
bool isReleaseOrStronger(AtomicOrdering AO)
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool CC_AArch64_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool CC_AArch64_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
bool RetCC_AArch64_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
gep_type_iterator gep_type_begin(const User *GEP)
bool CC_AArch64_Win64_CFGuard_Check(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
Definition ValueTypes.h:307
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition ValueTypes.h:323
ElementCount getVectorElementCount() const
Definition ValueTypes.h:373
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.