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 (F.isVarArg())
3855 return false;
3856
3857 if (TLI.supportSwiftError() &&
3858 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
3859 return false;
3860
3861 if (TLI.supportSplitCSR(FuncInfo.MF))
3862 return false;
3863
3864 // Build a list of return value registers.
3866
3867 if (Ret->getNumOperands() > 0) {
3868 CallingConv::ID CC = F.getCallingConv();
3870 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
3871
3872 // Analyze operands of the call, assigning locations to each operand.
3874 CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, I->getContext());
3875 CCInfo.AnalyzeReturn(Outs, RetCC_AArch64_AAPCS);
3876
3877 // Only handle a single return value for now.
3878 if (ValLocs.size() != 1)
3879 return false;
3880
3881 CCValAssign &VA = ValLocs[0];
3882 const Value *RV = Ret->getOperand(0);
3883
3884 // Don't bother handling odd stuff for now.
3885 if ((VA.getLocInfo() != CCValAssign::Full) &&
3886 (VA.getLocInfo() != CCValAssign::BCvt))
3887 return false;
3888
3889 // Only handle register returns for now.
3890 if (!VA.isRegLoc())
3891 return false;
3892
3893 Register Reg = getRegForValue(RV);
3894 if (!Reg)
3895 return false;
3896
3897 Register SrcReg = Reg + VA.getValNo();
3898 Register DestReg = VA.getLocReg();
3899 // Avoid a cross-class copy. This is very unlikely.
3900 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
3901 return false;
3902
3903 EVT RVEVT = TLI.getValueType(DL, RV->getType());
3904 if (!RVEVT.isSimple())
3905 return false;
3906
3907 // Vectors (of > 1 lane) in big endian need tricky handling.
3908 if (RVEVT.isVector() && RVEVT.getVectorElementCount().isVector() &&
3909 !Subtarget->isLittleEndian())
3910 return false;
3911
3912 MVT RVVT = RVEVT.getSimpleVT();
3913 if (RVVT == MVT::f128)
3914 return false;
3915
3916 MVT DestVT = VA.getValVT();
3917 // Special handling for extended integers.
3918 if (RVVT != DestVT) {
3919 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
3920 return false;
3921
3922 if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
3923 return false;
3924
3925 bool IsZExt = Outs[0].Flags.isZExt();
3926 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
3927 if (!SrcReg)
3928 return false;
3929 }
3930
3931 // "Callee" (i.e. value producer) zero extends pointers at function
3932 // boundary.
3933 if (Subtarget->isTargetILP32() && RV->getType()->isPointerTy())
3934 SrcReg = emitAnd_ri(MVT::i64, SrcReg, 0xffffffff);
3935
3936 // Make the copy.
3937 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3938 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
3939
3940 // Add register to return instruction.
3941 RetRegs.push_back(VA.getLocReg());
3942 }
3943
3944 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3945 TII.get(AArch64::RET_ReallyLR));
3946 for (Register RetReg : RetRegs)
3947 MIB.addReg(RetReg, RegState::Implicit);
3948 return true;
3949}
3950
3951bool AArch64FastISel::selectTrunc(const Instruction *I) {
3952 Type *DestTy = I->getType();
3953 Value *Op = I->getOperand(0);
3954 Type *SrcTy = Op->getType();
3955
3956 EVT SrcEVT = TLI.getValueType(DL, SrcTy, true);
3957 EVT DestEVT = TLI.getValueType(DL, DestTy, true);
3958 if (!SrcEVT.isSimple())
3959 return false;
3960 if (!DestEVT.isSimple())
3961 return false;
3962
3963 MVT SrcVT = SrcEVT.getSimpleVT();
3964 MVT DestVT = DestEVT.getSimpleVT();
3965
3966 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
3967 SrcVT != MVT::i8)
3968 return false;
3969 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8 &&
3970 DestVT != MVT::i1)
3971 return false;
3972
3973 Register SrcReg = getRegForValue(Op);
3974 if (!SrcReg)
3975 return false;
3976
3977 // If we're truncating from i64 to a smaller non-legal type then generate an
3978 // AND. Otherwise, we know the high bits are undefined and a truncate only
3979 // generate a COPY. We cannot mark the source register also as result
3980 // register, because this can incorrectly transfer the kill flag onto the
3981 // source register.
3982 Register ResultReg;
3983 if (SrcVT == MVT::i64) {
3984 uint64_t Mask = 0;
3985 switch (DestVT.SimpleTy) {
3986 default:
3987 // Trunc i64 to i32 is handled by the target-independent fast-isel.
3988 return false;
3989 case MVT::i1:
3990 Mask = 0x1;
3991 break;
3992 case MVT::i8:
3993 Mask = 0xff;
3994 break;
3995 case MVT::i16:
3996 Mask = 0xffff;
3997 break;
3998 }
3999 // Issue an extract_subreg to get the lower 32-bits.
4000 Register Reg32 = fastEmitInst_extractsubreg(MVT::i32, SrcReg,
4001 AArch64::sub_32);
4002 // Create the AND instruction which performs the actual truncation.
4003 ResultReg = emitAnd_ri(MVT::i32, Reg32, Mask);
4004 assert(ResultReg && "Unexpected AND instruction emission failure.");
4005 } else {
4006 ResultReg = createResultReg(&AArch64::GPR32RegClass);
4007 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4008 TII.get(TargetOpcode::COPY), ResultReg)
4009 .addReg(SrcReg);
4010 }
4011
4012 updateValueMap(I, ResultReg);
4013 return true;
4014}
4015
4016Register AArch64FastISel::emiti1Ext(Register SrcReg, MVT DestVT, bool IsZExt) {
4017 assert((DestVT == MVT::i8 || DestVT == MVT::i16 || DestVT == MVT::i32 ||
4018 DestVT == MVT::i64) &&
4019 "Unexpected value type.");
4020 // Handle i8 and i16 as i32.
4021 if (DestVT == MVT::i8 || DestVT == MVT::i16)
4022 DestVT = MVT::i32;
4023
4024 if (IsZExt) {
4025 Register ResultReg = emitAnd_ri(MVT::i32, SrcReg, 1);
4026 assert(ResultReg && "Unexpected AND instruction emission failure.");
4027 if (DestVT == MVT::i64) {
4028 // We're ZExt i1 to i64. The ANDWri Wd, Ws, #1 implicitly clears the
4029 // upper 32 bits. Emit a SUBREG_TO_REG to extend from Wd to Xd.
4030 Register Reg64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
4031 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4032 TII.get(AArch64::SUBREG_TO_REG), Reg64)
4033 .addReg(ResultReg)
4034 .addImm(AArch64::sub_32);
4035 ResultReg = Reg64;
4036 }
4037 return ResultReg;
4038 } else {
4039 if (DestVT == MVT::i64) {
4040 // FIXME: We're SExt i1 to i64.
4041 return Register();
4042 }
4043 return fastEmitInst_rii(AArch64::SBFMWri, &AArch64::GPR32RegClass, SrcReg,
4044 0, 0);
4045 }
4046}
4047
4048Register AArch64FastISel::emitMul_rr(MVT RetVT, Register Op0, Register Op1) {
4049 unsigned Opc;
4050 Register ZReg;
4051 switch (RetVT.SimpleTy) {
4052 default:
4053 return Register();
4054 case MVT::i8:
4055 case MVT::i16:
4056 case MVT::i32:
4057 RetVT = MVT::i32;
4058 Opc = AArch64::MADDWrrr; ZReg = AArch64::WZR; break;
4059 case MVT::i64:
4060 Opc = AArch64::MADDXrrr; ZReg = AArch64::XZR; break;
4061 }
4062
4063 const TargetRegisterClass *RC =
4064 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4065 return fastEmitInst_rrr(Opc, RC, Op0, Op1, ZReg);
4066}
4067
4068Register AArch64FastISel::emitSMULL_rr(MVT RetVT, Register Op0, Register Op1) {
4069 if (RetVT != MVT::i64)
4070 return Register();
4071
4072 return fastEmitInst_rrr(AArch64::SMADDLrrr, &AArch64::GPR64RegClass,
4073 Op0, Op1, AArch64::XZR);
4074}
4075
4076Register AArch64FastISel::emitUMULL_rr(MVT RetVT, Register Op0, Register Op1) {
4077 if (RetVT != MVT::i64)
4078 return Register();
4079
4080 return fastEmitInst_rrr(AArch64::UMADDLrrr, &AArch64::GPR64RegClass,
4081 Op0, Op1, AArch64::XZR);
4082}
4083
4084Register AArch64FastISel::emitLSL_rr(MVT RetVT, Register Op0Reg,
4085 Register Op1Reg) {
4086 unsigned Opc = 0;
4087 bool NeedTrunc = false;
4088 uint64_t Mask = 0;
4089 switch (RetVT.SimpleTy) {
4090 default:
4091 return Register();
4092 case MVT::i8: Opc = AArch64::LSLVWr; NeedTrunc = true; Mask = 0xff; break;
4093 case MVT::i16: Opc = AArch64::LSLVWr; NeedTrunc = true; Mask = 0xffff; break;
4094 case MVT::i32: Opc = AArch64::LSLVWr; break;
4095 case MVT::i64: Opc = AArch64::LSLVXr; break;
4096 }
4097
4098 const TargetRegisterClass *RC =
4099 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4100 if (NeedTrunc)
4101 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4102
4103 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4104 if (NeedTrunc)
4105 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4106 return ResultReg;
4107}
4108
4109Register AArch64FastISel::emitLSL_ri(MVT RetVT, MVT SrcVT, Register Op0,
4110 uint64_t Shift, bool IsZExt) {
4111 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4112 "Unexpected source/return type pair.");
4113 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4114 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4115 "Unexpected source value type.");
4116 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4117 RetVT == MVT::i64) && "Unexpected return value type.");
4118
4119 bool Is64Bit = (RetVT == MVT::i64);
4120 unsigned RegSize = Is64Bit ? 64 : 32;
4121 unsigned DstBits = RetVT.getSizeInBits();
4122 unsigned SrcBits = SrcVT.getSizeInBits();
4123 const TargetRegisterClass *RC =
4124 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4125
4126 // Just emit a copy for "zero" shifts.
4127 if (Shift == 0) {
4128 if (RetVT == SrcVT) {
4129 Register ResultReg = createResultReg(RC);
4130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4131 TII.get(TargetOpcode::COPY), ResultReg)
4132 .addReg(Op0);
4133 return ResultReg;
4134 } else
4135 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4136 }
4137
4138 // Don't deal with undefined shifts.
4139 if (Shift >= DstBits)
4140 return Register();
4141
4142 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4143 // {S|U}BFM Wd, Wn, #r, #s
4144 // Wd<32+s-r,32-r> = Wn<s:0> when r > s
4145
4146 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4147 // %2 = shl i16 %1, 4
4148 // Wd<32+7-28,32-28> = Wn<7:0> <- clamp s to 7
4149 // 0b1111_1111_1111_1111__1111_1010_1010_0000 sext
4150 // 0b0000_0000_0000_0000__0000_0101_0101_0000 sext | zext
4151 // 0b0000_0000_0000_0000__0000_1010_1010_0000 zext
4152
4153 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4154 // %2 = shl i16 %1, 8
4155 // Wd<32+7-24,32-24> = Wn<7:0>
4156 // 0b1111_1111_1111_1111__1010_1010_0000_0000 sext
4157 // 0b0000_0000_0000_0000__0101_0101_0000_0000 sext | zext
4158 // 0b0000_0000_0000_0000__1010_1010_0000_0000 zext
4159
4160 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4161 // %2 = shl i16 %1, 12
4162 // Wd<32+3-20,32-20> = Wn<3:0>
4163 // 0b1111_1111_1111_1111__1010_0000_0000_0000 sext
4164 // 0b0000_0000_0000_0000__0101_0000_0000_0000 sext | zext
4165 // 0b0000_0000_0000_0000__1010_0000_0000_0000 zext
4166
4167 unsigned ImmR = RegSize - Shift;
4168 // Limit the width to the length of the source type.
4169 unsigned ImmS = std::min<unsigned>(SrcBits - 1, DstBits - 1 - Shift);
4170 static const unsigned OpcTable[2][2] = {
4171 {AArch64::SBFMWri, AArch64::SBFMXri},
4172 {AArch64::UBFMWri, AArch64::UBFMXri}
4173 };
4174 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4175 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4176 Register TmpReg = MRI.createVirtualRegister(RC);
4177 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4178 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4179 .addReg(Op0)
4180 .addImm(AArch64::sub_32);
4181 Op0 = TmpReg;
4182 }
4183 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4184}
4185
4186Register AArch64FastISel::emitLSR_rr(MVT RetVT, Register Op0Reg,
4187 Register Op1Reg) {
4188 unsigned Opc = 0;
4189 bool NeedTrunc = false;
4190 uint64_t Mask = 0;
4191 switch (RetVT.SimpleTy) {
4192 default:
4193 return Register();
4194 case MVT::i8: Opc = AArch64::LSRVWr; NeedTrunc = true; Mask = 0xff; break;
4195 case MVT::i16: Opc = AArch64::LSRVWr; NeedTrunc = true; Mask = 0xffff; break;
4196 case MVT::i32: Opc = AArch64::LSRVWr; break;
4197 case MVT::i64: Opc = AArch64::LSRVXr; break;
4198 }
4199
4200 const TargetRegisterClass *RC =
4201 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4202 if (NeedTrunc) {
4203 Op0Reg = emitAnd_ri(MVT::i32, Op0Reg, Mask);
4204 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4205 }
4206 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4207 if (NeedTrunc)
4208 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4209 return ResultReg;
4210}
4211
4212Register AArch64FastISel::emitLSR_ri(MVT RetVT, MVT SrcVT, Register Op0,
4213 uint64_t Shift, bool IsZExt) {
4214 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4215 "Unexpected source/return type pair.");
4216 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4217 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4218 "Unexpected source value type.");
4219 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4220 RetVT == MVT::i64) && "Unexpected return value type.");
4221
4222 bool Is64Bit = (RetVT == MVT::i64);
4223 unsigned RegSize = Is64Bit ? 64 : 32;
4224 unsigned DstBits = RetVT.getSizeInBits();
4225 unsigned SrcBits = SrcVT.getSizeInBits();
4226 const TargetRegisterClass *RC =
4227 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4228
4229 // Just emit a copy for "zero" shifts.
4230 if (Shift == 0) {
4231 if (RetVT == SrcVT) {
4232 Register ResultReg = createResultReg(RC);
4233 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4234 TII.get(TargetOpcode::COPY), ResultReg)
4235 .addReg(Op0);
4236 return ResultReg;
4237 } else
4238 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4239 }
4240
4241 // Don't deal with undefined shifts.
4242 if (Shift >= DstBits)
4243 return Register();
4244
4245 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4246 // {S|U}BFM Wd, Wn, #r, #s
4247 // Wd<s-r:0> = Wn<s:r> when r <= s
4248
4249 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4250 // %2 = lshr i16 %1, 4
4251 // Wd<7-4:0> = Wn<7:4>
4252 // 0b0000_0000_0000_0000__0000_1111_1111_1010 sext
4253 // 0b0000_0000_0000_0000__0000_0000_0000_0101 sext | zext
4254 // 0b0000_0000_0000_0000__0000_0000_0000_1010 zext
4255
4256 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4257 // %2 = lshr i16 %1, 8
4258 // Wd<7-7,0> = Wn<7:7>
4259 // 0b0000_0000_0000_0000__0000_0000_1111_1111 sext
4260 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4261 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4262
4263 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4264 // %2 = lshr i16 %1, 12
4265 // Wd<7-7,0> = Wn<7:7> <- clamp r to 7
4266 // 0b0000_0000_0000_0000__0000_0000_0000_1111 sext
4267 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4268 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4269
4270 if (Shift >= SrcBits && IsZExt)
4271 return materializeInt(ConstantInt::get(*Context, APInt(RegSize, 0)), RetVT);
4272
4273 // It is not possible to fold a sign-extend into the LShr instruction. In this
4274 // case emit a sign-extend.
4275 if (!IsZExt) {
4276 Op0 = emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4277 if (!Op0)
4278 return Register();
4279 SrcVT = RetVT;
4280 SrcBits = SrcVT.getSizeInBits();
4281 IsZExt = true;
4282 }
4283
4284 unsigned ImmR = std::min<unsigned>(SrcBits - 1, Shift);
4285 unsigned ImmS = SrcBits - 1;
4286 static const unsigned OpcTable[2][2] = {
4287 {AArch64::SBFMWri, AArch64::SBFMXri},
4288 {AArch64::UBFMWri, AArch64::UBFMXri}
4289 };
4290 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4291 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4292 Register TmpReg = MRI.createVirtualRegister(RC);
4293 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4294 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4295 .addReg(Op0)
4296 .addImm(AArch64::sub_32);
4297 Op0 = TmpReg;
4298 }
4299 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4300}
4301
4302Register AArch64FastISel::emitASR_rr(MVT RetVT, Register Op0Reg,
4303 Register Op1Reg) {
4304 unsigned Opc = 0;
4305 bool NeedTrunc = false;
4306 uint64_t Mask = 0;
4307 switch (RetVT.SimpleTy) {
4308 default:
4309 return Register();
4310 case MVT::i8: Opc = AArch64::ASRVWr; NeedTrunc = true; Mask = 0xff; break;
4311 case MVT::i16: Opc = AArch64::ASRVWr; NeedTrunc = true; Mask = 0xffff; break;
4312 case MVT::i32: Opc = AArch64::ASRVWr; break;
4313 case MVT::i64: Opc = AArch64::ASRVXr; break;
4314 }
4315
4316 const TargetRegisterClass *RC =
4317 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4318 if (NeedTrunc) {
4319 Op0Reg = emitIntExt(RetVT, Op0Reg, MVT::i32, /*isZExt=*/false);
4320 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4321 }
4322 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4323 if (NeedTrunc)
4324 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4325 return ResultReg;
4326}
4327
4328Register AArch64FastISel::emitASR_ri(MVT RetVT, MVT SrcVT, Register Op0,
4329 uint64_t Shift, bool IsZExt) {
4330 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4331 "Unexpected source/return type pair.");
4332 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4333 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4334 "Unexpected source value type.");
4335 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4336 RetVT == MVT::i64) && "Unexpected return value type.");
4337
4338 bool Is64Bit = (RetVT == MVT::i64);
4339 unsigned RegSize = Is64Bit ? 64 : 32;
4340 unsigned DstBits = RetVT.getSizeInBits();
4341 unsigned SrcBits = SrcVT.getSizeInBits();
4342 const TargetRegisterClass *RC =
4343 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4344
4345 // Just emit a copy for "zero" shifts.
4346 if (Shift == 0) {
4347 if (RetVT == SrcVT) {
4348 Register ResultReg = createResultReg(RC);
4349 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4350 TII.get(TargetOpcode::COPY), ResultReg)
4351 .addReg(Op0);
4352 return ResultReg;
4353 } else
4354 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4355 }
4356
4357 // Don't deal with undefined shifts.
4358 if (Shift >= DstBits)
4359 return Register();
4360
4361 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4362 // {S|U}BFM Wd, Wn, #r, #s
4363 // Wd<s-r:0> = Wn<s:r> when r <= s
4364
4365 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4366 // %2 = ashr i16 %1, 4
4367 // Wd<7-4:0> = Wn<7:4>
4368 // 0b1111_1111_1111_1111__1111_1111_1111_1010 sext
4369 // 0b0000_0000_0000_0000__0000_0000_0000_0101 sext | zext
4370 // 0b0000_0000_0000_0000__0000_0000_0000_1010 zext
4371
4372 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4373 // %2 = ashr i16 %1, 8
4374 // Wd<7-7,0> = Wn<7:7>
4375 // 0b1111_1111_1111_1111__1111_1111_1111_1111 sext
4376 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4377 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4378
4379 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4380 // %2 = ashr i16 %1, 12
4381 // Wd<7-7,0> = Wn<7:7> <- clamp r to 7
4382 // 0b1111_1111_1111_1111__1111_1111_1111_1111 sext
4383 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4384 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4385
4386 if (Shift >= SrcBits && IsZExt)
4387 return materializeInt(ConstantInt::get(*Context, APInt(RegSize, 0)), RetVT);
4388
4389 unsigned ImmR = std::min<unsigned>(SrcBits - 1, Shift);
4390 unsigned ImmS = SrcBits - 1;
4391 static const unsigned OpcTable[2][2] = {
4392 {AArch64::SBFMWri, AArch64::SBFMXri},
4393 {AArch64::UBFMWri, AArch64::UBFMXri}
4394 };
4395 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4396 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4397 Register TmpReg = MRI.createVirtualRegister(RC);
4398 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4399 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4400 .addReg(Op0)
4401 .addImm(AArch64::sub_32);
4402 Op0 = TmpReg;
4403 }
4404 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4405}
4406
4407Register AArch64FastISel::emitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT,
4408 bool IsZExt) {
4409 assert(DestVT != MVT::i1 && "ZeroExt/SignExt an i1?");
4410
4411 // FastISel does not have plumbing to deal with extensions where the SrcVT or
4412 // DestVT are odd things, so test to make sure that they are both types we can
4413 // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise
4414 // bail out to SelectionDAG.
4415 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) &&
4416 (DestVT != MVT::i32) && (DestVT != MVT::i64)) ||
4417 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) &&
4418 (SrcVT != MVT::i16) && (SrcVT != MVT::i32)))
4419 return Register();
4420
4421 unsigned Opc;
4422 unsigned Imm = 0;
4423
4424 switch (SrcVT.SimpleTy) {
4425 default:
4426 return Register();
4427 case MVT::i1:
4428 return emiti1Ext(SrcReg, DestVT, IsZExt);
4429 case MVT::i8:
4430 if (DestVT == MVT::i64)
4431 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4432 else
4433 Opc = IsZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
4434 Imm = 7;
4435 break;
4436 case MVT::i16:
4437 if (DestVT == MVT::i64)
4438 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4439 else
4440 Opc = IsZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
4441 Imm = 15;
4442 break;
4443 case MVT::i32:
4444 assert(DestVT == MVT::i64 && "IntExt i32 to i32?!?");
4445 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4446 Imm = 31;
4447 break;
4448 }
4449
4450 // Handle i8 and i16 as i32.
4451 if (DestVT == MVT::i8 || DestVT == MVT::i16)
4452 DestVT = MVT::i32;
4453 else if (DestVT == MVT::i64) {
4454 Register Src64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
4455 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4456 TII.get(AArch64::SUBREG_TO_REG), Src64)
4457 .addReg(SrcReg)
4458 .addImm(AArch64::sub_32);
4459 SrcReg = Src64;
4460 }
4461
4462 const TargetRegisterClass *RC =
4463 (DestVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4464 return fastEmitInst_rii(Opc, RC, SrcReg, 0, Imm);
4465}
4466
4467bool AArch64FastISel::optimizeIntExtLoad(const Instruction *I, MVT RetVT,
4468 MVT SrcVT) {
4469 const auto *LI = dyn_cast<LoadInst>(I->getOperand(0));
4470 if (!LI || !LI->hasOneUse())
4471 return false;
4472
4473 // Check if the load instruction has already been selected.
4474 Register Reg = lookUpRegForValue(LI);
4475 if (!Reg)
4476 return false;
4477
4478 MachineInstr *MI = MRI.getUniqueVRegDef(Reg);
4479 if (!MI)
4480 return false;
4481
4482 // Check if the correct load instruction has been emitted - SelectionDAG might
4483 // have emitted a zero-extending load, but we need a sign-extending load.
4484 bool IsZExt = isa<ZExtInst>(I);
4485 const auto *LoadMI = MI;
4486 if (LoadMI->getOpcode() == TargetOpcode::COPY &&
4487 LoadMI->getOperand(1).getSubReg() == AArch64::sub_32) {
4488 Register LoadReg = MI->getOperand(1).getReg();
4489 LoadMI = MRI.getUniqueVRegDef(LoadReg);
4490 assert(LoadMI && "Expected valid instruction");
4491 }
4492 if (!(IsZExt && AArch64InstrInfo::isZExtLoad(*LoadMI)) &&
4493 !(!IsZExt && AArch64InstrInfo::isSExtLoad(*LoadMI)))
4494 return false;
4495
4496 // Nothing to be done.
4497 if (RetVT != MVT::i64 || SrcVT > MVT::i32) {
4498 updateValueMap(I, Reg);
4499 return true;
4500 }
4501
4502 if (IsZExt) {
4503 Register Reg64 = createResultReg(&AArch64::GPR64RegClass);
4504 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4505 TII.get(AArch64::SUBREG_TO_REG), Reg64)
4506 .addReg(Reg, getKillRegState(true))
4507 .addImm(AArch64::sub_32);
4508 Reg = Reg64;
4509 } else {
4510 assert((MI->getOpcode() == TargetOpcode::COPY &&
4511 MI->getOperand(1).getSubReg() == AArch64::sub_32) &&
4512 "Expected copy instruction");
4513 Reg = MI->getOperand(1).getReg();
4515 removeDeadCode(I, std::next(I));
4516 }
4517 updateValueMap(I, Reg);
4518 return true;
4519}
4520
4521bool AArch64FastISel::selectIntExt(const Instruction *I) {
4523 "Unexpected integer extend instruction.");
4524 MVT RetVT;
4525 MVT SrcVT;
4526 if (!isTypeSupported(I->getType(), RetVT))
4527 return false;
4528
4529 if (!isTypeSupported(I->getOperand(0)->getType(), SrcVT))
4530 return false;
4531
4532 // Try to optimize already sign-/zero-extended values from load instructions.
4533 if (optimizeIntExtLoad(I, RetVT, SrcVT))
4534 return true;
4535
4536 Register SrcReg = getRegForValue(I->getOperand(0));
4537 if (!SrcReg)
4538 return false;
4539
4540 // Try to optimize already sign-/zero-extended values from function arguments.
4541 bool IsZExt = isa<ZExtInst>(I);
4542 if (const auto *Arg = dyn_cast<Argument>(I->getOperand(0))) {
4543 if ((IsZExt && Arg->hasZExtAttr()) || (!IsZExt && Arg->hasSExtAttr())) {
4544 if (RetVT == MVT::i64 && SrcVT != MVT::i64) {
4545 Register ResultReg = createResultReg(&AArch64::GPR64RegClass);
4546 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4547 TII.get(AArch64::SUBREG_TO_REG), ResultReg)
4548 .addReg(SrcReg)
4549 .addImm(AArch64::sub_32);
4550 SrcReg = ResultReg;
4551 }
4552
4553 updateValueMap(I, SrcReg);
4554 return true;
4555 }
4556 }
4557
4558 Register ResultReg = emitIntExt(SrcVT, SrcReg, RetVT, IsZExt);
4559 if (!ResultReg)
4560 return false;
4561
4562 updateValueMap(I, ResultReg);
4563 return true;
4564}
4565
4566bool AArch64FastISel::selectRem(const Instruction *I, unsigned ISDOpcode) {
4567 EVT DestEVT = TLI.getValueType(DL, I->getType(), true);
4568 if (!DestEVT.isSimple())
4569 return false;
4570
4571 MVT DestVT = DestEVT.getSimpleVT();
4572 if (DestVT != MVT::i64 && DestVT != MVT::i32)
4573 return false;
4574
4575 unsigned DivOpc;
4576 bool Is64bit = (DestVT == MVT::i64);
4577 switch (ISDOpcode) {
4578 default:
4579 return false;
4580 case ISD::SREM:
4581 DivOpc = Is64bit ? AArch64::SDIVXr : AArch64::SDIVWr;
4582 break;
4583 case ISD::UREM:
4584 DivOpc = Is64bit ? AArch64::UDIVXr : AArch64::UDIVWr;
4585 break;
4586 }
4587 unsigned MSubOpc = Is64bit ? AArch64::MSUBXrrr : AArch64::MSUBWrrr;
4588 Register Src0Reg = getRegForValue(I->getOperand(0));
4589 if (!Src0Reg)
4590 return false;
4591
4592 Register Src1Reg = getRegForValue(I->getOperand(1));
4593 if (!Src1Reg)
4594 return false;
4595
4596 const TargetRegisterClass *RC =
4597 (DestVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4598 Register QuotReg = fastEmitInst_rr(DivOpc, RC, Src0Reg, Src1Reg);
4599 assert(QuotReg && "Unexpected DIV instruction emission failure.");
4600 // The remainder is computed as numerator - (quotient * denominator) using the
4601 // MSUB instruction.
4602 Register ResultReg = fastEmitInst_rrr(MSubOpc, RC, QuotReg, Src1Reg, Src0Reg);
4603 updateValueMap(I, ResultReg);
4604 return true;
4605}
4606
4607bool AArch64FastISel::selectMul(const Instruction *I) {
4608 MVT VT;
4609 if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true))
4610 return false;
4611
4612 if (VT.isVector())
4613 return selectBinaryOp(I, ISD::MUL);
4614
4615 const Value *Src0 = I->getOperand(0);
4616 const Value *Src1 = I->getOperand(1);
4617 if (const auto *C = dyn_cast<ConstantInt>(Src0))
4618 if (C->getValue().isPowerOf2())
4619 std::swap(Src0, Src1);
4620
4621 // Try to simplify to a shift instruction.
4622 if (const auto *C = dyn_cast<ConstantInt>(Src1))
4623 if (C->getValue().isPowerOf2()) {
4624 uint64_t ShiftVal = C->getValue().logBase2();
4625 MVT SrcVT = VT;
4626 bool IsZExt = true;
4627 if (const auto *ZExt = dyn_cast<ZExtInst>(Src0)) {
4628 if (!isIntExtFree(ZExt)) {
4629 MVT VT;
4630 if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(), VT)) {
4631 SrcVT = VT;
4632 IsZExt = true;
4633 Src0 = ZExt->getOperand(0);
4634 }
4635 }
4636 } else if (const auto *SExt = dyn_cast<SExtInst>(Src0)) {
4637 if (!isIntExtFree(SExt)) {
4638 MVT VT;
4639 if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(), VT)) {
4640 SrcVT = VT;
4641 IsZExt = false;
4642 Src0 = SExt->getOperand(0);
4643 }
4644 }
4645 }
4646
4647 Register Src0Reg = getRegForValue(Src0);
4648 if (!Src0Reg)
4649 return false;
4650
4651 Register ResultReg = emitLSL_ri(VT, SrcVT, Src0Reg, ShiftVal, IsZExt);
4652
4653 if (ResultReg) {
4654 updateValueMap(I, ResultReg);
4655 return true;
4656 }
4657 }
4658
4659 Register Src0Reg = getRegForValue(I->getOperand(0));
4660 if (!Src0Reg)
4661 return false;
4662
4663 Register Src1Reg = getRegForValue(I->getOperand(1));
4664 if (!Src1Reg)
4665 return false;
4666
4667 Register ResultReg = emitMul_rr(VT, Src0Reg, Src1Reg);
4668
4669 if (!ResultReg)
4670 return false;
4671
4672 updateValueMap(I, ResultReg);
4673 return true;
4674}
4675
4676bool AArch64FastISel::selectShift(const Instruction *I) {
4677 MVT RetVT;
4678 if (!isTypeSupported(I->getType(), RetVT, /*IsVectorAllowed=*/true))
4679 return false;
4680
4681 if (RetVT.isVector())
4682 return selectOperator(I, I->getOpcode());
4683
4684 if (const auto *C = dyn_cast<ConstantInt>(I->getOperand(1))) {
4685 Register ResultReg;
4686 uint64_t ShiftVal = C->getZExtValue();
4687 MVT SrcVT = RetVT;
4688 bool IsZExt = I->getOpcode() != Instruction::AShr;
4689 const Value *Op0 = I->getOperand(0);
4690 if (const auto *ZExt = dyn_cast<ZExtInst>(Op0)) {
4691 if (!isIntExtFree(ZExt)) {
4692 MVT TmpVT;
4693 if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(), TmpVT)) {
4694 SrcVT = TmpVT;
4695 IsZExt = true;
4696 Op0 = ZExt->getOperand(0);
4697 }
4698 }
4699 } else if (const auto *SExt = dyn_cast<SExtInst>(Op0)) {
4700 if (!isIntExtFree(SExt)) {
4701 MVT TmpVT;
4702 if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(), TmpVT)) {
4703 SrcVT = TmpVT;
4704 IsZExt = false;
4705 Op0 = SExt->getOperand(0);
4706 }
4707 }
4708 }
4709
4710 Register Op0Reg = getRegForValue(Op0);
4711 if (!Op0Reg)
4712 return false;
4713
4714 switch (I->getOpcode()) {
4715 default: llvm_unreachable("Unexpected instruction.");
4716 case Instruction::Shl:
4717 ResultReg = emitLSL_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4718 break;
4719 case Instruction::AShr:
4720 ResultReg = emitASR_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4721 break;
4722 case Instruction::LShr:
4723 ResultReg = emitLSR_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4724 break;
4725 }
4726 if (!ResultReg)
4727 return false;
4728
4729 updateValueMap(I, ResultReg);
4730 return true;
4731 }
4732
4733 Register Op0Reg = getRegForValue(I->getOperand(0));
4734 if (!Op0Reg)
4735 return false;
4736
4737 Register Op1Reg = getRegForValue(I->getOperand(1));
4738 if (!Op1Reg)
4739 return false;
4740
4741 Register ResultReg;
4742 switch (I->getOpcode()) {
4743 default: llvm_unreachable("Unexpected instruction.");
4744 case Instruction::Shl:
4745 ResultReg = emitLSL_rr(RetVT, Op0Reg, Op1Reg);
4746 break;
4747 case Instruction::AShr:
4748 ResultReg = emitASR_rr(RetVT, Op0Reg, Op1Reg);
4749 break;
4750 case Instruction::LShr:
4751 ResultReg = emitLSR_rr(RetVT, Op0Reg, Op1Reg);
4752 break;
4753 }
4754
4755 if (!ResultReg)
4756 return false;
4757
4758 updateValueMap(I, ResultReg);
4759 return true;
4760}
4761
4762bool AArch64FastISel::selectBitCast(const Instruction *I) {
4763 MVT RetVT, SrcVT;
4764
4765 if (!isTypeLegal(I->getOperand(0)->getType(), SrcVT))
4766 return false;
4767 if (!isTypeLegal(I->getType(), RetVT))
4768 return false;
4769
4770 unsigned Opc;
4771 if (RetVT == MVT::f32 && SrcVT == MVT::i32)
4772 Opc = AArch64::FMOVWSr;
4773 else if (RetVT == MVT::f64 && SrcVT == MVT::i64)
4774 Opc = AArch64::FMOVXDr;
4775 else if (RetVT == MVT::i32 && SrcVT == MVT::f32)
4776 Opc = AArch64::FMOVSWr;
4777 else if (RetVT == MVT::i64 && SrcVT == MVT::f64)
4778 Opc = AArch64::FMOVDXr;
4779 else
4780 return false;
4781
4782 const TargetRegisterClass *RC = nullptr;
4783 switch (RetVT.SimpleTy) {
4784 default: llvm_unreachable("Unexpected value type.");
4785 case MVT::i32: RC = &AArch64::GPR32RegClass; break;
4786 case MVT::i64: RC = &AArch64::GPR64RegClass; break;
4787 case MVT::f32: RC = &AArch64::FPR32RegClass; break;
4788 case MVT::f64: RC = &AArch64::FPR64RegClass; break;
4789 }
4790 Register Op0Reg = getRegForValue(I->getOperand(0));
4791 if (!Op0Reg)
4792 return false;
4793
4794 Register ResultReg = fastEmitInst_r(Opc, RC, Op0Reg);
4795 if (!ResultReg)
4796 return false;
4797
4798 updateValueMap(I, ResultReg);
4799 return true;
4800}
4801
4802bool AArch64FastISel::selectFRem(const Instruction *I) {
4803 MVT RetVT;
4804 if (!isTypeLegal(I->getType(), RetVT))
4805 return false;
4806
4807 RTLIB::LibcallImpl LCImpl =
4808 LibcallLowering->getLibcallImpl(RTLIB::getREM(RetVT));
4809 if (LCImpl == RTLIB::Unsupported)
4810 return false;
4811
4812 ArgListTy Args;
4813 Args.reserve(I->getNumOperands());
4814
4815 // Populate the argument list.
4816 for (auto &Arg : I->operands())
4817 Args.emplace_back(Arg);
4818
4819 CallLoweringInfo CLI;
4820 MCContext &Ctx = MF->getContext();
4821 CallingConv::ID CC = LibcallLowering->getLibcallImplCallingConv(LCImpl);
4822 StringRef FuncName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LCImpl);
4823
4824 CLI.setCallee(DL, Ctx, CC, I->getType(), FuncName, std::move(Args));
4825 if (!lowerCallTo(CLI))
4826 return false;
4827 updateValueMap(I, CLI.ResultReg);
4828 return true;
4829}
4830
4831bool AArch64FastISel::selectSDiv(const Instruction *I) {
4832 MVT VT;
4833 if (!isTypeLegal(I->getType(), VT))
4834 return false;
4835
4836 if (!isa<ConstantInt>(I->getOperand(1)))
4837 return selectBinaryOp(I, ISD::SDIV);
4838
4839 const APInt &C = cast<ConstantInt>(I->getOperand(1))->getValue();
4840 if ((VT != MVT::i32 && VT != MVT::i64) || !C ||
4841 !(C.isPowerOf2() || C.isNegatedPowerOf2()))
4842 return selectBinaryOp(I, ISD::SDIV);
4843
4844 unsigned Lg2 = C.countr_zero();
4845 Register Src0Reg = getRegForValue(I->getOperand(0));
4846 if (!Src0Reg)
4847 return false;
4848
4849 if (cast<BinaryOperator>(I)->isExact()) {
4850 Register ResultReg = emitASR_ri(VT, VT, Src0Reg, Lg2);
4851 if (!ResultReg)
4852 return false;
4853 updateValueMap(I, ResultReg);
4854 return true;
4855 }
4856
4857 int64_t Pow2MinusOne = (1ULL << Lg2) - 1;
4858 Register AddReg = emitAdd_ri_(VT, Src0Reg, Pow2MinusOne);
4859 if (!AddReg)
4860 return false;
4861
4862 // (Src0 < 0) ? Pow2 - 1 : 0;
4863 if (!emitICmp_ri(VT, Src0Reg, 0))
4864 return false;
4865
4866 unsigned SelectOpc;
4867 const TargetRegisterClass *RC;
4868 if (VT == MVT::i64) {
4869 SelectOpc = AArch64::CSELXr;
4870 RC = &AArch64::GPR64RegClass;
4871 } else {
4872 SelectOpc = AArch64::CSELWr;
4873 RC = &AArch64::GPR32RegClass;
4874 }
4875 Register SelectReg = fastEmitInst_rri(SelectOpc, RC, AddReg, Src0Reg,
4877 if (!SelectReg)
4878 return false;
4879
4880 // Divide by Pow2 --> ashr. If we're dividing by a negative value we must also
4881 // negate the result.
4882 Register ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
4883 Register ResultReg;
4884 if (C.isNegative())
4885 ResultReg = emitAddSub_rs(/*UseAdd=*/false, VT, ZeroReg, SelectReg,
4886 AArch64_AM::ASR, Lg2);
4887 else
4888 ResultReg = emitASR_ri(VT, VT, SelectReg, Lg2);
4889
4890 if (!ResultReg)
4891 return false;
4892
4893 updateValueMap(I, ResultReg);
4894 return true;
4895}
4896
4897/// This is mostly a copy of the existing FastISel getRegForGEPIndex code. We
4898/// have to duplicate it for AArch64, because otherwise we would fail during the
4899/// sign-extend emission.
4900Register AArch64FastISel::getRegForGEPIndex(const Value *Idx) {
4901 Register IdxN = getRegForValue(Idx);
4902 if (!IdxN)
4903 // Unhandled operand. Halt "fast" selection and bail.
4904 return Register();
4905
4906 // If the index is smaller or larger than intptr_t, truncate or extend it.
4907 MVT PtrVT = TLI.getPointerTy(DL);
4908 EVT IdxVT = EVT::getEVT(Idx->getType(), /*HandleUnknown=*/false);
4909 if (IdxVT.bitsLT(PtrVT)) {
4910 IdxN = emitIntExt(IdxVT.getSimpleVT(), IdxN, PtrVT, /*isZExt=*/false);
4911 } else if (IdxVT.bitsGT(PtrVT))
4912 llvm_unreachable("AArch64 FastISel doesn't support types larger than i64");
4913 return IdxN;
4914}
4915
4916/// This is mostly a copy of the existing FastISel GEP code, but we have to
4917/// duplicate it for AArch64, because otherwise we would bail out even for
4918/// simple cases. This is because the standard fastEmit functions don't cover
4919/// MUL at all and ADD is lowered very inefficientily.
4920bool AArch64FastISel::selectGetElementPtr(const Instruction *I) {
4921 if (Subtarget->isTargetILP32())
4922 return false;
4923
4924 Register N = getRegForValue(I->getOperand(0));
4925 if (!N)
4926 return false;
4927
4928 // Keep a running tab of the total offset to coalesce multiple N = N + Offset
4929 // into a single N = N + TotalOffset.
4930 uint64_t TotalOffs = 0;
4931 MVT VT = TLI.getPointerTy(DL);
4933 GTI != E; ++GTI) {
4934 const Value *Idx = GTI.getOperand();
4935 if (auto *StTy = GTI.getStructTypeOrNull()) {
4936 unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
4937 // N = N + Offset
4938 if (Field)
4939 TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field);
4940 } else {
4941 // If this is a constant subscript, handle it quickly.
4942 if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
4943 if (CI->isZero())
4944 continue;
4945 // N = N + Offset
4946 TotalOffs += GTI.getSequentialElementStride(DL) *
4947 cast<ConstantInt>(CI)->getSExtValue();
4948 continue;
4949 }
4950 if (TotalOffs) {
4951 N = emitAdd_ri_(VT, N, TotalOffs);
4952 if (!N)
4953 return false;
4954 TotalOffs = 0;
4955 }
4956
4957 // N = N + Idx * ElementSize;
4958 uint64_t ElementSize = GTI.getSequentialElementStride(DL);
4959 Register IdxN = getRegForGEPIndex(Idx);
4960 if (!IdxN)
4961 return false;
4962
4963 if (ElementSize != 1) {
4964 Register C = fastEmit_i(VT, VT, ISD::Constant, ElementSize);
4965 if (!C)
4966 return false;
4967 IdxN = emitMul_rr(VT, IdxN, C);
4968 if (!IdxN)
4969 return false;
4970 }
4971 N = fastEmit_rr(VT, VT, ISD::ADD, N, IdxN);
4972 if (!N)
4973 return false;
4974 }
4975 }
4976 if (TotalOffs) {
4977 N = emitAdd_ri_(VT, N, TotalOffs);
4978 if (!N)
4979 return false;
4980 }
4981 updateValueMap(I, N);
4982 return true;
4983}
4984
4985bool AArch64FastISel::selectAtomicCmpXchg(const AtomicCmpXchgInst *I) {
4986 assert(TM.getOptLevel() == CodeGenOptLevel::None &&
4987 "cmpxchg survived AtomicExpand at optlevel > -O0");
4988
4989 auto *RetPairTy = cast<StructType>(I->getType());
4990 Type *RetTy = RetPairTy->getTypeAtIndex(0U);
4991 assert(RetPairTy->getTypeAtIndex(1U)->isIntegerTy(1) &&
4992 "cmpxchg has a non-i1 status result");
4993
4994 MVT VT;
4995 if (!isTypeLegal(RetTy, VT))
4996 return false;
4997
4998 const TargetRegisterClass *ResRC;
4999 unsigned Opc, CmpOpc;
5000 // This only supports i32/i64, because i8/i16 aren't legal, and the generic
5001 // extractvalue selection doesn't support that.
5002 if (VT == MVT::i32) {
5003 Opc = AArch64::CMP_SWAP_32;
5004 CmpOpc = AArch64::SUBSWrs;
5005 ResRC = &AArch64::GPR32RegClass;
5006 } else if (VT == MVT::i64) {
5007 Opc = AArch64::CMP_SWAP_64;
5008 CmpOpc = AArch64::SUBSXrs;
5009 ResRC = &AArch64::GPR64RegClass;
5010 } else {
5011 return false;
5012 }
5013
5014 const MCInstrDesc &II = TII.get(Opc);
5015
5016 Register AddrReg = getRegForValue(I->getPointerOperand());
5017 Register DesiredReg = getRegForValue(I->getCompareOperand());
5018 Register NewReg = getRegForValue(I->getNewValOperand());
5019
5020 if (!AddrReg || !DesiredReg || !NewReg)
5021 return false;
5022
5023 AddrReg = constrainOperandRegClass(II, AddrReg, II.getNumDefs());
5024 DesiredReg = constrainOperandRegClass(II, DesiredReg, II.getNumDefs() + 1);
5025 NewReg = constrainOperandRegClass(II, NewReg, II.getNumDefs() + 2);
5026
5027 const Register ResultReg1 = createResultReg(ResRC);
5028 const Register ResultReg2 = createResultReg(&AArch64::GPR32RegClass);
5029 const Register ScratchReg = createResultReg(&AArch64::GPR32RegClass);
5030
5031 // FIXME: MachineMemOperand doesn't support cmpxchg yet.
5032 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
5033 .addDef(ResultReg1)
5034 .addDef(ScratchReg)
5035 .addUse(AddrReg)
5036 .addUse(DesiredReg)
5037 .addUse(NewReg);
5038
5039 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc))
5040 .addDef(VT == MVT::i32 ? AArch64::WZR : AArch64::XZR)
5041 .addUse(ResultReg1)
5042 .addUse(DesiredReg)
5043 .addImm(0);
5044
5045 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::CSINCWr))
5046 .addDef(ResultReg2)
5047 .addUse(AArch64::WZR)
5048 .addUse(AArch64::WZR)
5050
5051 assert((ResultReg1 + 1) == ResultReg2 && "Nonconsecutive result registers.");
5052 updateValueMap(I, ResultReg1, 2);
5053 return true;
5054}
5055
5056bool AArch64FastISel::fastSelectInstruction(const Instruction *I) {
5057 if (TLI.fallBackToDAGISel(*I))
5058 return false;
5059 switch (I->getOpcode()) {
5060 default:
5061 break;
5062 case Instruction::Add:
5063 case Instruction::Sub:
5064 return selectAddSub(I);
5065 case Instruction::Mul:
5066 return selectMul(I);
5067 case Instruction::SDiv:
5068 return selectSDiv(I);
5069 case Instruction::SRem:
5070 if (!selectBinaryOp(I, ISD::SREM))
5071 return selectRem(I, ISD::SREM);
5072 return true;
5073 case Instruction::URem:
5074 if (!selectBinaryOp(I, ISD::UREM))
5075 return selectRem(I, ISD::UREM);
5076 return true;
5077 case Instruction::Shl:
5078 case Instruction::LShr:
5079 case Instruction::AShr:
5080 return selectShift(I);
5081 case Instruction::And:
5082 case Instruction::Or:
5083 case Instruction::Xor:
5084 return selectLogicalOp(I);
5085 case Instruction::CondBr:
5086 return selectBranch(I);
5087 case Instruction::IndirectBr:
5088 return selectIndirectBr(I);
5089 case Instruction::BitCast:
5091 return selectBitCast(I);
5092 return true;
5093 case Instruction::FPToSI:
5094 if (!selectCast(I, ISD::FP_TO_SINT))
5095 return selectFPToInt(I, /*Signed=*/true);
5096 return true;
5097 case Instruction::FPToUI:
5098 return selectFPToInt(I, /*Signed=*/false);
5099 case Instruction::ZExt:
5100 case Instruction::SExt:
5101 return selectIntExt(I);
5102 case Instruction::Trunc:
5103 if (!selectCast(I, ISD::TRUNCATE))
5104 return selectTrunc(I);
5105 return true;
5106 case Instruction::FPExt:
5107 return selectFPExt(I);
5108 case Instruction::FPTrunc:
5109 return selectFPTrunc(I);
5110 case Instruction::SIToFP:
5111 if (!selectCast(I, ISD::SINT_TO_FP))
5112 return selectIntToFP(I, /*Signed=*/true);
5113 return true;
5114 case Instruction::UIToFP:
5115 return selectIntToFP(I, /*Signed=*/false);
5116 case Instruction::Load:
5117 return selectLoad(I);
5118 case Instruction::Store:
5119 return selectStore(I);
5120 case Instruction::FCmp:
5121 case Instruction::ICmp:
5122 return selectCmp(I);
5123 case Instruction::Select:
5124 return selectSelect(I);
5125 case Instruction::Ret:
5126 return selectRet(I);
5127 case Instruction::FRem:
5128 return selectFRem(I);
5129 case Instruction::GetElementPtr:
5130 return selectGetElementPtr(I);
5131 case Instruction::AtomicCmpXchg:
5132 return selectAtomicCmpXchg(cast<AtomicCmpXchgInst>(I));
5133 }
5134
5135 // fall-back to target-independent instruction selection.
5136 return selectOperator(I, I->getOpcode());
5137}
5138
5140 const TargetLibraryInfo *LibInfo,
5141 const LibcallLoweringInfo *LibcallLowering) {
5142
5143 SMEAttrs CallerAttrs =
5144 FuncInfo.MF->getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
5145 if (CallerAttrs.hasZAState() || CallerAttrs.hasZT0State() ||
5146 CallerAttrs.hasStreamingInterfaceOrBody() ||
5147 CallerAttrs.hasStreamingCompatibleInterface() ||
5148 CallerAttrs.hasAgnosticZAInterface())
5149 return nullptr;
5150 return new AArch64FastISel(FuncInfo, LibInfo, LibcallLowering);
5151}
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
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
SI Pre allocate WWM Registers
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:324
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:353
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:288
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition Type.h:279
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
bool isStructTy() const
True if this is an instance of StructType.
Definition Type.h:276
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition Type.h:326
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:255
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
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:890
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
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:578
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.