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->isTargetWindowsOrUEFI())
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, TII.get(TargetOpcode::COPY),
414 ResultReg)
415 .addReg(TmpReg);
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)
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)
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)
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)
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, TII.get(TargetOpcode::COPY),
3003 ResultReg)
3004 .addReg(DstReg);
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 // On Windows, callers of functions that pop their own stack arguments need a
3165 // frame pointer. Allow SelectionDAG isel to handle these calls, as that is
3166 // where it gets requested.
3167 if (Subtarget->isTargetWindows() &&
3168 (CC == CallingConv::Tail || CC == CallingConv::SwiftTail ||
3169 (CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt)))
3170 return false;
3171
3172 // FIXME: we could and should support this, but for now correctness at -O0 is
3173 // more important.
3174 if (Subtarget->isTargetILP32())
3175 return false;
3176
3177 CodeModel::Model CM = TM.getCodeModel();
3178 // Only support the small-addressing and large code models.
3179 if (CM != CodeModel::Large && !Subtarget->useSmallAddressing())
3180 return false;
3181
3182 // FIXME: Add large code model support for ELF.
3183 if (CM == CodeModel::Large && !Subtarget->isTargetMachO())
3184 return false;
3185
3186 // ELF -fno-plt compiled intrinsic calls do not have the nonlazybind
3187 // attribute. Check "RtLibUseGOT" instead.
3188 if (MF->getFunction().getParent()->getRtLibUseGOT())
3189 return false;
3190
3191 // Let SDISel handle vararg functions.
3192 if (IsVarArg)
3193 return false;
3194
3195 if (Subtarget->isWindowsArm64EC())
3196 return false;
3197
3198 for (auto Flag : CLI.OutFlags)
3199 if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal() ||
3200 Flag.isSwiftSelf() || Flag.isSwiftAsync() || Flag.isSwiftError())
3201 return false;
3202
3203 // Set up the argument vectors.
3204 SmallVector<MVT, 16> OutVTs;
3206 OutVTs.reserve(CLI.OutVals.size());
3207
3208 for (auto *Val : CLI.OutVals) {
3209 MVT VT;
3210 if (!isTypeLegal(Val->getType(), VT) &&
3211 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
3212 return false;
3213
3214 // We don't handle vector parameters yet.
3215 if (VT.isVector() || VT.getSizeInBits() > 64)
3216 return false;
3217
3218 OutVTs.push_back(VT);
3219 OrigTys.push_back(Val->getType());
3220 }
3221
3222 Address Addr;
3223 if (Callee && !computeCallAddress(Callee, Addr))
3224 return false;
3225
3226 // The weak function target may be zero; in that case we must use indirect
3227 // addressing via a stub on windows as it may be out of range for a
3228 // PC-relative jump.
3229 if (Subtarget->isTargetWindowsOrUEFI() && Addr.getGlobalValue() &&
3230 Addr.getGlobalValue()->hasExternalWeakLinkage())
3231 return false;
3232
3233 // Handle the arguments now that we've gotten them.
3234 unsigned NumBytes;
3235 if (!processCallArgs(CLI, OutVTs, OrigTys, NumBytes))
3236 return false;
3237
3238 const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3239 if (RegInfo->isAnyArgRegReserved(*MF))
3240 RegInfo->emitReservedArgRegCallError(*MF);
3241
3242 // Issue the call.
3243 MachineInstrBuilder MIB;
3244 if (Subtarget->useSmallAddressing()) {
3245 const MCInstrDesc &II =
3246 TII.get(Addr.getReg() ? getBLRCallOpcode(*MF) : (unsigned)AArch64::BL);
3247 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II);
3248 if (Symbol)
3249 MIB.addSym(Symbol, 0);
3250 else if (Addr.getGlobalValue())
3251 MIB.addGlobalAddress(Addr.getGlobalValue(), 0, 0);
3252 else if (Addr.getReg()) {
3253 Register Reg = constrainOperandRegClass(II, Addr.getReg(), 0);
3254 MIB.addReg(Reg);
3255 } else
3256 return false;
3257 } else {
3258 Register CallReg;
3259 if (Symbol) {
3260 Register ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
3261 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::ADRP),
3262 ADRPReg)
3264
3265 CallReg = createResultReg(&AArch64::GPR64RegClass);
3266 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3267 TII.get(AArch64::LDRXui), CallReg)
3268 .addReg(ADRPReg)
3269 .addSym(Symbol,
3271 } else if (Addr.getGlobalValue())
3272 CallReg = materializeGV(Addr.getGlobalValue());
3273 else if (Addr.getReg())
3274 CallReg = Addr.getReg();
3275
3276 if (!CallReg)
3277 return false;
3278
3279 const MCInstrDesc &II = TII.get(getBLRCallOpcode(*MF));
3280 CallReg = constrainOperandRegClass(II, CallReg, 0);
3281 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addReg(CallReg);
3282 }
3283
3284 // Add implicit physical register uses to the call.
3285 for (auto Reg : CLI.OutRegs)
3286 MIB.addReg(Reg, RegState::Implicit);
3287
3288 // Add a register mask with the call-preserved registers.
3289 // Proper defs for return values will be added by setPhysRegsDeadExcept().
3290 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
3291
3292 CLI.Call = MIB;
3293
3294 // Finish off the call including any return values.
3295 return finishCall(CLI, NumBytes);
3296}
3297
3298bool AArch64FastISel::isMemCpySmall(uint64_t Len, MaybeAlign Alignment) {
3299 if (Alignment)
3300 return Len / Alignment->value() <= 4;
3301 else
3302 return Len < 32;
3303}
3304
3305bool AArch64FastISel::tryEmitSmallMemCpy(Address Dest, Address Src,
3306 uint64_t Len, MaybeAlign Alignment) {
3307 // Make sure we don't bloat code by inlining very large memcpy's.
3308 if (!isMemCpySmall(Len, Alignment))
3309 return false;
3310
3311 int64_t UnscaledOffset = 0;
3312 Address OrigDest = Dest;
3313 Address OrigSrc = Src;
3314
3315 while (Len) {
3316 MVT VT;
3317 if (!Alignment || *Alignment >= 8) {
3318 if (Len >= 8)
3319 VT = MVT::i64;
3320 else if (Len >= 4)
3321 VT = MVT::i32;
3322 else if (Len >= 2)
3323 VT = MVT::i16;
3324 else {
3325 VT = MVT::i8;
3326 }
3327 } else {
3328 assert(Alignment && "Alignment is set in this branch");
3329 // Bound based on alignment.
3330 if (Len >= 4 && *Alignment == 4)
3331 VT = MVT::i32;
3332 else if (Len >= 2 && *Alignment == 2)
3333 VT = MVT::i16;
3334 else {
3335 VT = MVT::i8;
3336 }
3337 }
3338
3339 Register ResultReg = emitLoad(VT, VT, Src);
3340 if (!ResultReg)
3341 return false;
3342
3343 if (!emitStore(VT, ResultReg, Dest))
3344 return false;
3345
3346 int64_t Size = VT.getSizeInBits() / 8;
3347 Len -= Size;
3348 UnscaledOffset += Size;
3349
3350 // We need to recompute the unscaled offset for each iteration.
3351 Dest.setOffset(OrigDest.getOffset() + UnscaledOffset);
3352 Src.setOffset(OrigSrc.getOffset() + UnscaledOffset);
3353 }
3354
3355 return true;
3356}
3357
3358/// Check if it is possible to fold the condition from the XALU intrinsic
3359/// into the user. The condition code will only be updated on success.
3360bool AArch64FastISel::foldXALUIntrinsic(AArch64CC::CondCode &CC,
3361 const Instruction *I,
3362 const Value *Cond) {
3364 return false;
3365
3366 const auto *EV = cast<ExtractValueInst>(Cond);
3367 if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
3368 return false;
3369
3370 const auto *II = cast<IntrinsicInst>(EV->getAggregateOperand());
3371 MVT RetVT;
3372 const Function *Callee = II->getCalledFunction();
3373 Type *RetTy =
3374 cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
3375 if (!isTypeLegal(RetTy, RetVT))
3376 return false;
3377
3378 if (RetVT != MVT::i32 && RetVT != MVT::i64)
3379 return false;
3380
3381 const Value *LHS = II->getArgOperand(0);
3382 const Value *RHS = II->getArgOperand(1);
3383
3384 // Canonicalize immediate to the RHS.
3385 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
3386 std::swap(LHS, RHS);
3387
3388 // Simplify multiplies.
3389 Intrinsic::ID IID = II->getIntrinsicID();
3390 switch (IID) {
3391 default:
3392 break;
3393 case Intrinsic::smul_with_overflow:
3394 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3395 if (C->getValue() == 2)
3396 IID = Intrinsic::sadd_with_overflow;
3397 break;
3398 case Intrinsic::umul_with_overflow:
3399 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3400 if (C->getValue() == 2)
3401 IID = Intrinsic::uadd_with_overflow;
3402 break;
3403 }
3404
3405 AArch64CC::CondCode TmpCC;
3406 switch (IID) {
3407 default:
3408 return false;
3409 case Intrinsic::sadd_with_overflow:
3410 case Intrinsic::ssub_with_overflow:
3411 TmpCC = AArch64CC::VS;
3412 break;
3413 case Intrinsic::uadd_with_overflow:
3414 TmpCC = AArch64CC::HS;
3415 break;
3416 case Intrinsic::usub_with_overflow:
3417 TmpCC = AArch64CC::LO;
3418 break;
3419 case Intrinsic::smul_with_overflow:
3420 case Intrinsic::umul_with_overflow:
3421 TmpCC = AArch64CC::NE;
3422 break;
3423 }
3424
3425 // Check if both instructions are in the same basic block.
3426 if (!isValueAvailable(II))
3427 return false;
3428
3429 // Make sure nothing is in the way
3432 for (auto Itr = std::prev(Start); Itr != End; --Itr) {
3433 // We only expect extractvalue instructions between the intrinsic and the
3434 // instruction to be selected.
3435 if (!isa<ExtractValueInst>(Itr))
3436 return false;
3437
3438 // Check that the extractvalue operand comes from the intrinsic.
3439 const auto *EVI = cast<ExtractValueInst>(Itr);
3440 if (EVI->getAggregateOperand() != II)
3441 return false;
3442 }
3443
3444 CC = TmpCC;
3445 return true;
3446}
3447
3448bool AArch64FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
3449 // FIXME: Handle more intrinsics.
3450 switch (II->getIntrinsicID()) {
3451 default: return false;
3452 case Intrinsic::frameaddress: {
3453 MachineFrameInfo &MFI = FuncInfo.MF->getFrameInfo();
3454 MFI.setFrameAddressIsTaken(true);
3455
3456 const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3457 Register FramePtr = RegInfo->getFrameRegister(*(FuncInfo.MF));
3458 Register SrcReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
3459 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3460 TII.get(TargetOpcode::COPY), SrcReg).addReg(FramePtr);
3461 // Recursively load frame address
3462 // ldr x0, [fp]
3463 // ldr x0, [x0]
3464 // ldr x0, [x0]
3465 // ...
3466 Register DestReg;
3467 unsigned Depth = cast<ConstantInt>(II->getOperand(0))->getZExtValue();
3468 while (Depth--) {
3469 DestReg = fastEmitInst_ri(AArch64::LDRXui, &AArch64::GPR64RegClass,
3470 SrcReg, 0);
3471 assert(DestReg && "Unexpected LDR instruction emission failure.");
3472 SrcReg = DestReg;
3473 }
3474
3475 updateValueMap(II, SrcReg);
3476 return true;
3477 }
3478 case Intrinsic::sponentry: {
3479 MachineFrameInfo &MFI = FuncInfo.MF->getFrameInfo();
3480
3481 // SP = FP + Fixed Object + 16
3482 int FI = MFI.CreateFixedObject(4, 0, false);
3483 Register ResultReg = createResultReg(&AArch64::GPR64spRegClass);
3484 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3485 TII.get(AArch64::ADDXri), ResultReg)
3486 .addFrameIndex(FI)
3487 .addImm(0)
3488 .addImm(0);
3489
3490 updateValueMap(II, ResultReg);
3491 return true;
3492 }
3493 case Intrinsic::memcpy:
3494 case Intrinsic::memmove: {
3495 const auto *MTI = cast<MemTransferInst>(II);
3496 // Don't handle volatile.
3497 if (MTI->isVolatile())
3498 return false;
3499
3500 // Disable inlining for memmove before calls to ComputeAddress. Otherwise,
3501 // we would emit dead code because we don't currently handle memmoves.
3502 bool IsMemCpy = (II->getIntrinsicID() == Intrinsic::memcpy);
3503 if (isa<ConstantInt>(MTI->getLength()) && IsMemCpy) {
3504 // Small memcpy's are common enough that we want to do them without a call
3505 // if possible.
3506 uint64_t Len = cast<ConstantInt>(MTI->getLength())->getZExtValue();
3507 MaybeAlign Alignment;
3508 if (MTI->getDestAlign() || MTI->getSourceAlign())
3509 Alignment = std::min(MTI->getDestAlign().valueOrOne(),
3510 MTI->getSourceAlign().valueOrOne());
3511 if (isMemCpySmall(Len, Alignment)) {
3512 Address Dest, Src;
3513 if (!computeAddress(MTI->getRawDest(), Dest) ||
3514 !computeAddress(MTI->getRawSource(), Src))
3515 return false;
3516 if (tryEmitSmallMemCpy(Dest, Src, Len, Alignment))
3517 return true;
3518 }
3519 }
3520
3521 if (!MTI->getLength()->getType()->isIntegerTy(64))
3522 return false;
3523
3524 if (MTI->getSourceAddressSpace() > 255 || MTI->getDestAddressSpace() > 255)
3525 // Fast instruction selection doesn't support the special
3526 // address spaces.
3527 return false;
3528
3529 const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";
3530 return lowerCallTo(II, IntrMemName, II->arg_size() - 1);
3531 }
3532 case Intrinsic::memset: {
3533 const MemSetInst *MSI = cast<MemSetInst>(II);
3534 // Don't handle volatile.
3535 if (MSI->isVolatile())
3536 return false;
3537
3538 if (!MSI->getLength()->getType()->isIntegerTy(64))
3539 return false;
3540
3541 if (MSI->getDestAddressSpace() > 255)
3542 // Fast instruction selection doesn't support the special
3543 // address spaces.
3544 return false;
3545
3546 return lowerCallTo(II, "memset", II->arg_size() - 1);
3547 }
3548 case Intrinsic::sin:
3549 case Intrinsic::cos:
3550 case Intrinsic::tan:
3551 case Intrinsic::pow: {
3552 MVT RetVT;
3553 if (!isTypeLegal(II->getType(), RetVT))
3554 return false;
3555
3556 if (RetVT != MVT::f32 && RetVT != MVT::f64)
3557 return false;
3558
3559 static const RTLIB::Libcall LibCallTable[4][2] = {
3560 {RTLIB::SIN_F32, RTLIB::SIN_F64},
3561 {RTLIB::COS_F32, RTLIB::COS_F64},
3562 {RTLIB::TAN_F32, RTLIB::TAN_F64},
3563 {RTLIB::POW_F32, RTLIB::POW_F64}};
3564 RTLIB::Libcall LC;
3565 bool Is64Bit = RetVT == MVT::f64;
3566 switch (II->getIntrinsicID()) {
3567 default:
3568 llvm_unreachable("Unexpected intrinsic.");
3569 case Intrinsic::sin:
3570 LC = LibCallTable[0][Is64Bit];
3571 break;
3572 case Intrinsic::cos:
3573 LC = LibCallTable[1][Is64Bit];
3574 break;
3575 case Intrinsic::tan:
3576 LC = LibCallTable[2][Is64Bit];
3577 break;
3578 case Intrinsic::pow:
3579 LC = LibCallTable[3][Is64Bit];
3580 break;
3581 }
3582
3583 ArgListTy Args;
3584 Args.reserve(II->arg_size());
3585
3586 // Populate the argument list.
3587 for (auto &Arg : II->args())
3588 Args.emplace_back(Arg);
3589
3590 CallLoweringInfo CLI;
3591 MCContext &Ctx = MF->getContext();
3592
3593 RTLIB::LibcallImpl LCImpl = LibcallLowering->getLibcallImpl(LC);
3594 if (LCImpl == RTLIB::Unsupported)
3595 return false;
3596
3597 CallingConv::ID CC = LibcallLowering->getLibcallImplCallingConv(LCImpl);
3598 StringRef FuncName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LCImpl);
3599 CLI.setCallee(DL, Ctx, CC, II->getType(), FuncName, std::move(Args));
3600 if (!lowerCallTo(CLI))
3601 return false;
3602 updateValueMap(II, CLI.ResultReg);
3603 return true;
3604 }
3605 case Intrinsic::fabs: {
3606 MVT VT;
3607 if (!isTypeLegal(II->getType(), VT))
3608 return false;
3609
3610 unsigned Opc;
3611 switch (VT.SimpleTy) {
3612 default:
3613 return false;
3614 case MVT::f32:
3615 Opc = AArch64::FABSSr;
3616 break;
3617 case MVT::f64:
3618 Opc = AArch64::FABSDr;
3619 break;
3620 }
3621 Register SrcReg = getRegForValue(II->getOperand(0));
3622 if (!SrcReg)
3623 return false;
3624 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3625 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
3626 .addReg(SrcReg);
3627 updateValueMap(II, ResultReg);
3628 return true;
3629 }
3630 case Intrinsic::trap:
3631 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::BRK))
3632 .addImm(1);
3633 return true;
3634 case Intrinsic::debugtrap:
3635 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::BRK))
3636 .addImm(0xF000);
3637 return true;
3638
3639 case Intrinsic::sqrt: {
3640 Type *RetTy = II->getCalledFunction()->getReturnType();
3641
3642 MVT VT;
3643 if (!isTypeLegal(RetTy, VT))
3644 return false;
3645
3646 Register Op0Reg = getRegForValue(II->getOperand(0));
3647 if (!Op0Reg)
3648 return false;
3649
3650 Register ResultReg = fastEmit_r(VT, VT, ISD::FSQRT, Op0Reg);
3651 if (!ResultReg)
3652 return false;
3653
3654 updateValueMap(II, ResultReg);
3655 return true;
3656 }
3657 case Intrinsic::sadd_with_overflow:
3658 case Intrinsic::uadd_with_overflow:
3659 case Intrinsic::ssub_with_overflow:
3660 case Intrinsic::usub_with_overflow:
3661 case Intrinsic::smul_with_overflow:
3662 case Intrinsic::umul_with_overflow: {
3663 // This implements the basic lowering of the xalu with overflow intrinsics.
3664 const Function *Callee = II->getCalledFunction();
3665 auto *Ty = cast<StructType>(Callee->getReturnType());
3666 Type *RetTy = Ty->getTypeAtIndex(0U);
3667
3668 MVT VT;
3669 if (!isTypeLegal(RetTy, VT))
3670 return false;
3671
3672 if (VT != MVT::i32 && VT != MVT::i64)
3673 return false;
3674
3675 const Value *LHS = II->getArgOperand(0);
3676 const Value *RHS = II->getArgOperand(1);
3677 // Canonicalize immediate to the RHS.
3678 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
3679 std::swap(LHS, RHS);
3680
3681 // Simplify multiplies.
3682 Intrinsic::ID IID = II->getIntrinsicID();
3683 switch (IID) {
3684 default:
3685 break;
3686 case Intrinsic::smul_with_overflow:
3687 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3688 if (C->getValue() == 2) {
3689 IID = Intrinsic::sadd_with_overflow;
3690 RHS = LHS;
3691 }
3692 break;
3693 case Intrinsic::umul_with_overflow:
3694 if (const auto *C = dyn_cast<ConstantInt>(RHS))
3695 if (C->getValue() == 2) {
3696 IID = Intrinsic::uadd_with_overflow;
3697 RHS = LHS;
3698 }
3699 break;
3700 }
3701
3702 Register ResultReg1, ResultReg2, MulReg;
3704 switch (IID) {
3705 default: llvm_unreachable("Unexpected intrinsic!");
3706 case Intrinsic::sadd_with_overflow:
3707 ResultReg1 = emitAdd(VT, LHS, RHS, /*SetFlags=*/true);
3708 CC = AArch64CC::VS;
3709 break;
3710 case Intrinsic::uadd_with_overflow:
3711 ResultReg1 = emitAdd(VT, LHS, RHS, /*SetFlags=*/true);
3712 CC = AArch64CC::HS;
3713 break;
3714 case Intrinsic::ssub_with_overflow:
3715 ResultReg1 = emitSub(VT, LHS, RHS, /*SetFlags=*/true);
3716 CC = AArch64CC::VS;
3717 break;
3718 case Intrinsic::usub_with_overflow:
3719 ResultReg1 = emitSub(VT, LHS, RHS, /*SetFlags=*/true);
3720 CC = AArch64CC::LO;
3721 break;
3722 case Intrinsic::smul_with_overflow: {
3723 CC = AArch64CC::NE;
3724 Register LHSReg = getRegForValue(LHS);
3725 if (!LHSReg)
3726 return false;
3727
3728 Register RHSReg = getRegForValue(RHS);
3729 if (!RHSReg)
3730 return false;
3731
3732 if (VT == MVT::i32) {
3733 MulReg = emitSMULL_rr(MVT::i64, LHSReg, RHSReg);
3734 Register MulSubReg =
3735 fastEmitInst_extractsubreg(VT, MulReg, AArch64::sub_32);
3736 // cmp xreg, wreg, sxtw
3737 emitAddSub_rx(/*UseAdd=*/false, MVT::i64, MulReg, MulSubReg,
3738 AArch64_AM::SXTW, /*ShiftImm=*/0, /*SetFlags=*/true,
3739 /*WantResult=*/false);
3740 MulReg = MulSubReg;
3741 } else {
3742 assert(VT == MVT::i64 && "Unexpected value type.");
3743 // LHSReg and RHSReg cannot be killed by this Mul, since they are
3744 // reused in the next instruction.
3745 MulReg = emitMul_rr(VT, LHSReg, RHSReg);
3746 Register SMULHReg = fastEmit_rr(VT, VT, ISD::MULHS, LHSReg, RHSReg);
3747 emitSubs_rs(VT, SMULHReg, MulReg, AArch64_AM::ASR, 63,
3748 /*WantResult=*/false);
3749 }
3750 break;
3751 }
3752 case Intrinsic::umul_with_overflow: {
3753 CC = AArch64CC::NE;
3754 Register LHSReg = getRegForValue(LHS);
3755 if (!LHSReg)
3756 return false;
3757
3758 Register RHSReg = getRegForValue(RHS);
3759 if (!RHSReg)
3760 return false;
3761
3762 if (VT == MVT::i32) {
3763 MulReg = emitUMULL_rr(MVT::i64, LHSReg, RHSReg);
3764 // tst xreg, #0xffffffff00000000
3765 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3766 TII.get(AArch64::ANDSXri), AArch64::XZR)
3767 .addReg(MulReg)
3768 .addImm(AArch64_AM::encodeLogicalImmediate(0xFFFFFFFF00000000, 64));
3769 MulReg = fastEmitInst_extractsubreg(VT, MulReg, AArch64::sub_32);
3770 } else {
3771 assert(VT == MVT::i64 && "Unexpected value type.");
3772 // LHSReg and RHSReg cannot be killed by this Mul, since they are
3773 // reused in the next instruction.
3774 MulReg = emitMul_rr(VT, LHSReg, RHSReg);
3775 Register UMULHReg = fastEmit_rr(VT, VT, ISD::MULHU, LHSReg, RHSReg);
3776 emitSubs_rr(VT, AArch64::XZR, UMULHReg, /*WantResult=*/false);
3777 }
3778 break;
3779 }
3780 }
3781
3782 if (MulReg) {
3783 ResultReg1 = createResultReg(TLI.getRegClassFor(VT));
3784 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3785 TII.get(TargetOpcode::COPY), ResultReg1).addReg(MulReg);
3786 }
3787
3788 if (!ResultReg1)
3789 return false;
3790
3791 ResultReg2 = fastEmitInst_rri(AArch64::CSINCWr, &AArch64::GPR32RegClass,
3792 AArch64::WZR, AArch64::WZR,
3793 getInvertedCondCode(CC));
3794 (void)ResultReg2;
3795 assert((ResultReg1 + 1) == ResultReg2 &&
3796 "Nonconsecutive result registers.");
3797 updateValueMap(II, ResultReg1, 2);
3798 return true;
3799 }
3800 case Intrinsic::aarch64_crc32b:
3801 case Intrinsic::aarch64_crc32h:
3802 case Intrinsic::aarch64_crc32w:
3803 case Intrinsic::aarch64_crc32x:
3804 case Intrinsic::aarch64_crc32cb:
3805 case Intrinsic::aarch64_crc32ch:
3806 case Intrinsic::aarch64_crc32cw:
3807 case Intrinsic::aarch64_crc32cx: {
3808 if (!Subtarget->hasCRC())
3809 return false;
3810
3811 unsigned Opc;
3812 switch (II->getIntrinsicID()) {
3813 default:
3814 llvm_unreachable("Unexpected intrinsic!");
3815 case Intrinsic::aarch64_crc32b:
3816 Opc = AArch64::CRC32Brr;
3817 break;
3818 case Intrinsic::aarch64_crc32h:
3819 Opc = AArch64::CRC32Hrr;
3820 break;
3821 case Intrinsic::aarch64_crc32w:
3822 Opc = AArch64::CRC32Wrr;
3823 break;
3824 case Intrinsic::aarch64_crc32x:
3825 Opc = AArch64::CRC32Xrr;
3826 break;
3827 case Intrinsic::aarch64_crc32cb:
3828 Opc = AArch64::CRC32CBrr;
3829 break;
3830 case Intrinsic::aarch64_crc32ch:
3831 Opc = AArch64::CRC32CHrr;
3832 break;
3833 case Intrinsic::aarch64_crc32cw:
3834 Opc = AArch64::CRC32CWrr;
3835 break;
3836 case Intrinsic::aarch64_crc32cx:
3837 Opc = AArch64::CRC32CXrr;
3838 break;
3839 }
3840
3841 Register LHSReg = getRegForValue(II->getArgOperand(0));
3842 Register RHSReg = getRegForValue(II->getArgOperand(1));
3843 if (!LHSReg || !RHSReg)
3844 return false;
3845
3846 Register ResultReg =
3847 fastEmitInst_rr(Opc, &AArch64::GPR32RegClass, LHSReg, RHSReg);
3848 updateValueMap(II, ResultReg);
3849 return true;
3850 }
3851 }
3852 return false;
3853}
3854
3855bool AArch64FastISel::selectRet(const Instruction *I) {
3856 const ReturnInst *Ret = cast<ReturnInst>(I);
3857 const Function &F = *I->getParent()->getParent();
3858
3859 if (!FuncInfo.CanLowerReturn)
3860 return false;
3861
3862 if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->getSRetReturnReg())
3863 return false;
3864
3865 if (F.isVarArg())
3866 return false;
3867
3868 if (TLI.supportSwiftError() &&
3869 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
3870 return false;
3871
3872 if (TLI.supportSplitCSR(FuncInfo.MF))
3873 return false;
3874
3875 // Build a list of return value registers.
3877
3878 if (Ret->getNumOperands() > 0) {
3879 CallingConv::ID CC = F.getCallingConv();
3881 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
3882
3883 // Analyze operands of the call, assigning locations to each operand.
3885 CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, I->getContext());
3886 CCInfo.AnalyzeReturn(Outs, RetCC_AArch64_AAPCS);
3887
3888 // Only handle a single return value for now.
3889 if (ValLocs.size() != 1)
3890 return false;
3891
3892 CCValAssign &VA = ValLocs[0];
3893 const Value *RV = Ret->getOperand(0);
3894
3895 // Don't bother handling odd stuff for now.
3896 if ((VA.getLocInfo() != CCValAssign::Full) &&
3897 (VA.getLocInfo() != CCValAssign::BCvt))
3898 return false;
3899
3900 // Only handle register returns for now.
3901 if (!VA.isRegLoc())
3902 return false;
3903
3904 Register Reg = getRegForValue(RV);
3905 if (!Reg)
3906 return false;
3907
3908 Register SrcReg = Reg + VA.getValNo();
3909 Register DestReg = VA.getLocReg();
3910 // Avoid a cross-class copy. This is very unlikely.
3911 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
3912 return false;
3913
3914 EVT RVEVT = TLI.getValueType(DL, RV->getType());
3915 if (!RVEVT.isSimple())
3916 return false;
3917
3918 // Vectors (of > 1 lane) in big endian need tricky handling.
3919 if (RVEVT.isVector() && RVEVT.getVectorElementCount().isVector() &&
3920 !Subtarget->isLittleEndian())
3921 return false;
3922
3923 MVT RVVT = RVEVT.getSimpleVT();
3924 if (RVVT == MVT::f128)
3925 return false;
3926
3927 MVT DestVT = VA.getValVT();
3928 // Special handling for extended integers.
3929 if (RVVT != DestVT) {
3930 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
3931 return false;
3932
3933 if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
3934 return false;
3935
3936 bool IsZExt = Outs[0].Flags.isZExt();
3937 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
3938 if (!SrcReg)
3939 return false;
3940 }
3941
3942 // "Callee" (i.e. value producer) zero extends pointers at function
3943 // boundary.
3944 if (Subtarget->isTargetILP32() && RV->getType()->isPointerTy())
3945 SrcReg = emitAnd_ri(MVT::i64, SrcReg, 0xffffffff);
3946
3947 // Make the copy.
3948 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3949 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
3950
3951 // Add register to return instruction.
3952 RetRegs.push_back(VA.getLocReg());
3953 }
3954
3955 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3956 TII.get(AArch64::RET_ReallyLR));
3957 for (Register RetReg : RetRegs)
3958 MIB.addReg(RetReg, RegState::Implicit);
3959 return true;
3960}
3961
3962bool AArch64FastISel::selectTrunc(const Instruction *I) {
3963 Type *DestTy = I->getType();
3964 Value *Op = I->getOperand(0);
3965 Type *SrcTy = Op->getType();
3966
3967 EVT SrcEVT = TLI.getValueType(DL, SrcTy, true);
3968 EVT DestEVT = TLI.getValueType(DL, DestTy, true);
3969 if (!SrcEVT.isSimple())
3970 return false;
3971 if (!DestEVT.isSimple())
3972 return false;
3973
3974 MVT SrcVT = SrcEVT.getSimpleVT();
3975 MVT DestVT = DestEVT.getSimpleVT();
3976
3977 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
3978 SrcVT != MVT::i8)
3979 return false;
3980 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8 &&
3981 DestVT != MVT::i1)
3982 return false;
3983
3984 Register SrcReg = getRegForValue(Op);
3985 if (!SrcReg)
3986 return false;
3987
3988 // If we're truncating from i64 to a smaller non-legal type then generate an
3989 // AND. Otherwise, we know the high bits are undefined and a truncate only
3990 // generate a COPY. We cannot mark the source register also as result
3991 // register, because this can incorrectly transfer the kill flag onto the
3992 // source register.
3993 Register ResultReg;
3994 if (SrcVT == MVT::i64) {
3995 uint64_t Mask = 0;
3996 switch (DestVT.SimpleTy) {
3997 default:
3998 // Trunc i64 to i32 is handled by the target-independent fast-isel.
3999 return false;
4000 case MVT::i1:
4001 Mask = 0x1;
4002 break;
4003 case MVT::i8:
4004 Mask = 0xff;
4005 break;
4006 case MVT::i16:
4007 Mask = 0xffff;
4008 break;
4009 }
4010 // Issue an extract_subreg to get the lower 32-bits.
4011 Register Reg32 = fastEmitInst_extractsubreg(MVT::i32, SrcReg,
4012 AArch64::sub_32);
4013 // Create the AND instruction which performs the actual truncation.
4014 ResultReg = emitAnd_ri(MVT::i32, Reg32, Mask);
4015 assert(ResultReg && "Unexpected AND instruction emission failure.");
4016 } else {
4017 ResultReg = createResultReg(&AArch64::GPR32RegClass);
4018 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4019 TII.get(TargetOpcode::COPY), ResultReg)
4020 .addReg(SrcReg);
4021 }
4022
4023 updateValueMap(I, ResultReg);
4024 return true;
4025}
4026
4027Register AArch64FastISel::emiti1Ext(Register SrcReg, MVT DestVT, bool IsZExt) {
4028 assert((DestVT == MVT::i8 || DestVT == MVT::i16 || DestVT == MVT::i32 ||
4029 DestVT == MVT::i64) &&
4030 "Unexpected value type.");
4031 // Handle i8 and i16 as i32.
4032 if (DestVT == MVT::i8 || DestVT == MVT::i16)
4033 DestVT = MVT::i32;
4034
4035 if (IsZExt) {
4036 Register ResultReg = emitAnd_ri(MVT::i32, SrcReg, 1);
4037 assert(ResultReg && "Unexpected AND instruction emission failure.");
4038 if (DestVT == MVT::i64) {
4039 // We're ZExt i1 to i64. The ANDWri Wd, Ws, #1 implicitly clears the
4040 // upper 32 bits. Emit a SUBREG_TO_REG to extend from Wd to Xd.
4041 Register Reg64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
4042 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4043 TII.get(AArch64::SUBREG_TO_REG), Reg64)
4044 .addReg(ResultReg)
4045 .addImm(AArch64::sub_32);
4046 ResultReg = Reg64;
4047 }
4048 return ResultReg;
4049 } else {
4050 if (DestVT == MVT::i64) {
4051 // FIXME: We're SExt i1 to i64.
4052 return Register();
4053 }
4054 return fastEmitInst_rii(AArch64::SBFMWri, &AArch64::GPR32RegClass, SrcReg,
4055 0, 0);
4056 }
4057}
4058
4059Register AArch64FastISel::emitMul_rr(MVT RetVT, Register Op0, Register Op1) {
4060 unsigned Opc;
4061 Register ZReg;
4062 switch (RetVT.SimpleTy) {
4063 default:
4064 return Register();
4065 case MVT::i8:
4066 case MVT::i16:
4067 case MVT::i32:
4068 RetVT = MVT::i32;
4069 Opc = AArch64::MADDWrrr; ZReg = AArch64::WZR; break;
4070 case MVT::i64:
4071 Opc = AArch64::MADDXrrr; ZReg = AArch64::XZR; break;
4072 }
4073
4074 const TargetRegisterClass *RC =
4075 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4076 return fastEmitInst_rrr(Opc, RC, Op0, Op1, ZReg);
4077}
4078
4079Register AArch64FastISel::emitSMULL_rr(MVT RetVT, Register Op0, Register Op1) {
4080 if (RetVT != MVT::i64)
4081 return Register();
4082
4083 return fastEmitInst_rrr(AArch64::SMADDLrrr, &AArch64::GPR64RegClass,
4084 Op0, Op1, AArch64::XZR);
4085}
4086
4087Register AArch64FastISel::emitUMULL_rr(MVT RetVT, Register Op0, Register Op1) {
4088 if (RetVT != MVT::i64)
4089 return Register();
4090
4091 return fastEmitInst_rrr(AArch64::UMADDLrrr, &AArch64::GPR64RegClass,
4092 Op0, Op1, AArch64::XZR);
4093}
4094
4095Register AArch64FastISel::emitLSL_rr(MVT RetVT, Register Op0Reg,
4096 Register Op1Reg) {
4097 unsigned Opc = 0;
4098 bool NeedTrunc = false;
4099 uint64_t Mask = 0;
4100 switch (RetVT.SimpleTy) {
4101 default:
4102 return Register();
4103 case MVT::i8: Opc = AArch64::LSLVWr; NeedTrunc = true; Mask = 0xff; break;
4104 case MVT::i16: Opc = AArch64::LSLVWr; NeedTrunc = true; Mask = 0xffff; break;
4105 case MVT::i32: Opc = AArch64::LSLVWr; break;
4106 case MVT::i64: Opc = AArch64::LSLVXr; break;
4107 }
4108
4109 const TargetRegisterClass *RC =
4110 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4111 if (NeedTrunc)
4112 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4113
4114 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4115 if (NeedTrunc)
4116 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4117 return ResultReg;
4118}
4119
4120Register AArch64FastISel::emitLSL_ri(MVT RetVT, MVT SrcVT, Register Op0,
4121 uint64_t Shift, bool IsZExt) {
4122 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4123 "Unexpected source/return type pair.");
4124 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4125 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4126 "Unexpected source value type.");
4127 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4128 RetVT == MVT::i64) && "Unexpected return value type.");
4129
4130 bool Is64Bit = (RetVT == MVT::i64);
4131 unsigned RegSize = Is64Bit ? 64 : 32;
4132 unsigned DstBits = RetVT.getSizeInBits();
4133 unsigned SrcBits = SrcVT.getSizeInBits();
4134 const TargetRegisterClass *RC =
4135 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4136
4137 // Just emit a copy for "zero" shifts.
4138 if (Shift == 0) {
4139 if (RetVT == SrcVT) {
4140 Register ResultReg = createResultReg(RC);
4141 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4142 TII.get(TargetOpcode::COPY), ResultReg)
4143 .addReg(Op0);
4144 return ResultReg;
4145 } else
4146 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4147 }
4148
4149 // Don't deal with undefined shifts.
4150 if (Shift >= DstBits)
4151 return Register();
4152
4153 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4154 // {S|U}BFM Wd, Wn, #r, #s
4155 // Wd<32+s-r,32-r> = Wn<s:0> when r > s
4156
4157 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4158 // %2 = shl i16 %1, 4
4159 // Wd<32+7-28,32-28> = Wn<7:0> <- clamp s to 7
4160 // 0b1111_1111_1111_1111__1111_1010_1010_0000 sext
4161 // 0b0000_0000_0000_0000__0000_0101_0101_0000 sext | zext
4162 // 0b0000_0000_0000_0000__0000_1010_1010_0000 zext
4163
4164 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4165 // %2 = shl i16 %1, 8
4166 // Wd<32+7-24,32-24> = Wn<7:0>
4167 // 0b1111_1111_1111_1111__1010_1010_0000_0000 sext
4168 // 0b0000_0000_0000_0000__0101_0101_0000_0000 sext | zext
4169 // 0b0000_0000_0000_0000__1010_1010_0000_0000 zext
4170
4171 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4172 // %2 = shl i16 %1, 12
4173 // Wd<32+3-20,32-20> = Wn<3:0>
4174 // 0b1111_1111_1111_1111__1010_0000_0000_0000 sext
4175 // 0b0000_0000_0000_0000__0101_0000_0000_0000 sext | zext
4176 // 0b0000_0000_0000_0000__1010_0000_0000_0000 zext
4177
4178 unsigned ImmR = RegSize - Shift;
4179 // Limit the width to the length of the source type.
4180 unsigned ImmS = std::min<unsigned>(SrcBits - 1, DstBits - 1 - Shift);
4181 static const unsigned OpcTable[2][2] = {
4182 {AArch64::SBFMWri, AArch64::SBFMXri},
4183 {AArch64::UBFMWri, AArch64::UBFMXri}
4184 };
4185 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4186 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4187 Register TmpReg = MRI.createVirtualRegister(RC);
4188 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4189 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4190 .addReg(Op0)
4191 .addImm(AArch64::sub_32);
4192 Op0 = TmpReg;
4193 }
4194 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4195}
4196
4197Register AArch64FastISel::emitLSR_rr(MVT RetVT, Register Op0Reg,
4198 Register Op1Reg) {
4199 unsigned Opc = 0;
4200 bool NeedTrunc = false;
4201 uint64_t Mask = 0;
4202 switch (RetVT.SimpleTy) {
4203 default:
4204 return Register();
4205 case MVT::i8: Opc = AArch64::LSRVWr; NeedTrunc = true; Mask = 0xff; break;
4206 case MVT::i16: Opc = AArch64::LSRVWr; NeedTrunc = true; Mask = 0xffff; break;
4207 case MVT::i32: Opc = AArch64::LSRVWr; break;
4208 case MVT::i64: Opc = AArch64::LSRVXr; break;
4209 }
4210
4211 const TargetRegisterClass *RC =
4212 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4213 if (NeedTrunc) {
4214 Op0Reg = emitAnd_ri(MVT::i32, Op0Reg, Mask);
4215 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4216 }
4217 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4218 if (NeedTrunc)
4219 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4220 return ResultReg;
4221}
4222
4223Register AArch64FastISel::emitLSR_ri(MVT RetVT, MVT SrcVT, Register Op0,
4224 uint64_t Shift, bool IsZExt) {
4225 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4226 "Unexpected source/return type pair.");
4227 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4228 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4229 "Unexpected source value type.");
4230 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4231 RetVT == MVT::i64) && "Unexpected return value type.");
4232
4233 bool Is64Bit = (RetVT == MVT::i64);
4234 unsigned RegSize = Is64Bit ? 64 : 32;
4235 unsigned DstBits = RetVT.getSizeInBits();
4236 unsigned SrcBits = SrcVT.getSizeInBits();
4237 const TargetRegisterClass *RC =
4238 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4239
4240 // Just emit a copy for "zero" shifts.
4241 if (Shift == 0) {
4242 if (RetVT == SrcVT) {
4243 Register ResultReg = createResultReg(RC);
4244 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4245 TII.get(TargetOpcode::COPY), ResultReg)
4246 .addReg(Op0);
4247 return ResultReg;
4248 } else
4249 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4250 }
4251
4252 // Don't deal with undefined shifts.
4253 if (Shift >= DstBits)
4254 return Register();
4255
4256 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4257 // {S|U}BFM Wd, Wn, #r, #s
4258 // Wd<s-r:0> = Wn<s:r> when r <= s
4259
4260 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4261 // %2 = lshr i16 %1, 4
4262 // Wd<7-4:0> = Wn<7:4>
4263 // 0b0000_0000_0000_0000__0000_1111_1111_1010 sext
4264 // 0b0000_0000_0000_0000__0000_0000_0000_0101 sext | zext
4265 // 0b0000_0000_0000_0000__0000_0000_0000_1010 zext
4266
4267 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4268 // %2 = lshr i16 %1, 8
4269 // Wd<7-7,0> = Wn<7:7>
4270 // 0b0000_0000_0000_0000__0000_0000_1111_1111 sext
4271 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4272 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4273
4274 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4275 // %2 = lshr i16 %1, 12
4276 // Wd<7-7,0> = Wn<7:7> <- clamp r to 7
4277 // 0b0000_0000_0000_0000__0000_0000_0000_1111 sext
4278 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4279 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4280
4281 if (Shift >= SrcBits && IsZExt)
4282 return materializeInt(ConstantInt::get(*Context, APInt(RegSize, 0)), RetVT);
4283
4284 // It is not possible to fold a sign-extend into the LShr instruction. In this
4285 // case emit a sign-extend.
4286 if (!IsZExt) {
4287 Op0 = emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4288 if (!Op0)
4289 return Register();
4290 SrcVT = RetVT;
4291 SrcBits = SrcVT.getSizeInBits();
4292 IsZExt = true;
4293 }
4294
4295 unsigned ImmR = std::min<unsigned>(SrcBits - 1, Shift);
4296 unsigned ImmS = SrcBits - 1;
4297 static const unsigned OpcTable[2][2] = {
4298 {AArch64::SBFMWri, AArch64::SBFMXri},
4299 {AArch64::UBFMWri, AArch64::UBFMXri}
4300 };
4301 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4302 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4303 Register TmpReg = MRI.createVirtualRegister(RC);
4304 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4305 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4306 .addReg(Op0)
4307 .addImm(AArch64::sub_32);
4308 Op0 = TmpReg;
4309 }
4310 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4311}
4312
4313Register AArch64FastISel::emitASR_rr(MVT RetVT, Register Op0Reg,
4314 Register Op1Reg) {
4315 unsigned Opc = 0;
4316 bool NeedTrunc = false;
4317 uint64_t Mask = 0;
4318 switch (RetVT.SimpleTy) {
4319 default:
4320 return Register();
4321 case MVT::i8: Opc = AArch64::ASRVWr; NeedTrunc = true; Mask = 0xff; break;
4322 case MVT::i16: Opc = AArch64::ASRVWr; NeedTrunc = true; Mask = 0xffff; break;
4323 case MVT::i32: Opc = AArch64::ASRVWr; break;
4324 case MVT::i64: Opc = AArch64::ASRVXr; break;
4325 }
4326
4327 const TargetRegisterClass *RC =
4328 (RetVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4329 if (NeedTrunc) {
4330 Op0Reg = emitIntExt(RetVT, Op0Reg, MVT::i32, /*isZExt=*/false);
4331 Op1Reg = emitAnd_ri(MVT::i32, Op1Reg, Mask);
4332 }
4333 Register ResultReg = fastEmitInst_rr(Opc, RC, Op0Reg, Op1Reg);
4334 if (NeedTrunc)
4335 ResultReg = emitAnd_ri(MVT::i32, ResultReg, Mask);
4336 return ResultReg;
4337}
4338
4339Register AArch64FastISel::emitASR_ri(MVT RetVT, MVT SrcVT, Register Op0,
4340 uint64_t Shift, bool IsZExt) {
4341 assert(RetVT.SimpleTy >= SrcVT.SimpleTy &&
4342 "Unexpected source/return type pair.");
4343 assert((SrcVT == MVT::i1 || SrcVT == MVT::i8 || SrcVT == MVT::i16 ||
4344 SrcVT == MVT::i32 || SrcVT == MVT::i64) &&
4345 "Unexpected source value type.");
4346 assert((RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32 ||
4347 RetVT == MVT::i64) && "Unexpected return value type.");
4348
4349 bool Is64Bit = (RetVT == MVT::i64);
4350 unsigned RegSize = Is64Bit ? 64 : 32;
4351 unsigned DstBits = RetVT.getSizeInBits();
4352 unsigned SrcBits = SrcVT.getSizeInBits();
4353 const TargetRegisterClass *RC =
4354 Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4355
4356 // Just emit a copy for "zero" shifts.
4357 if (Shift == 0) {
4358 if (RetVT == SrcVT) {
4359 Register ResultReg = createResultReg(RC);
4360 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4361 TII.get(TargetOpcode::COPY), ResultReg)
4362 .addReg(Op0);
4363 return ResultReg;
4364 } else
4365 return emitIntExt(SrcVT, Op0, RetVT, IsZExt);
4366 }
4367
4368 // Don't deal with undefined shifts.
4369 if (Shift >= DstBits)
4370 return Register();
4371
4372 // For immediate shifts we can fold the zero-/sign-extension into the shift.
4373 // {S|U}BFM Wd, Wn, #r, #s
4374 // Wd<s-r:0> = Wn<s:r> when r <= s
4375
4376 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4377 // %2 = ashr i16 %1, 4
4378 // Wd<7-4:0> = Wn<7:4>
4379 // 0b1111_1111_1111_1111__1111_1111_1111_1010 sext
4380 // 0b0000_0000_0000_0000__0000_0000_0000_0101 sext | zext
4381 // 0b0000_0000_0000_0000__0000_0000_0000_1010 zext
4382
4383 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4384 // %2 = ashr i16 %1, 8
4385 // Wd<7-7,0> = Wn<7:7>
4386 // 0b1111_1111_1111_1111__1111_1111_1111_1111 sext
4387 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4388 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4389
4390 // %1 = {s|z}ext i8 {0b1010_1010|0b0101_0101} to i16
4391 // %2 = ashr i16 %1, 12
4392 // Wd<7-7,0> = Wn<7:7> <- clamp r to 7
4393 // 0b1111_1111_1111_1111__1111_1111_1111_1111 sext
4394 // 0b0000_0000_0000_0000__0000_0000_0000_0000 sext
4395 // 0b0000_0000_0000_0000__0000_0000_0000_0000 zext
4396
4397 if (Shift >= SrcBits && IsZExt)
4398 return materializeInt(ConstantInt::get(*Context, APInt(RegSize, 0)), RetVT);
4399
4400 unsigned ImmR = std::min<unsigned>(SrcBits - 1, Shift);
4401 unsigned ImmS = SrcBits - 1;
4402 static const unsigned OpcTable[2][2] = {
4403 {AArch64::SBFMWri, AArch64::SBFMXri},
4404 {AArch64::UBFMWri, AArch64::UBFMXri}
4405 };
4406 unsigned Opc = OpcTable[IsZExt][Is64Bit];
4407 if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) {
4408 Register TmpReg = MRI.createVirtualRegister(RC);
4409 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4410 TII.get(AArch64::SUBREG_TO_REG), TmpReg)
4411 .addReg(Op0)
4412 .addImm(AArch64::sub_32);
4413 Op0 = TmpReg;
4414 }
4415 return fastEmitInst_rii(Opc, RC, Op0, ImmR, ImmS);
4416}
4417
4418Register AArch64FastISel::emitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT,
4419 bool IsZExt) {
4420 assert(DestVT != MVT::i1 && "ZeroExt/SignExt an i1?");
4421
4422 // FastISel does not have plumbing to deal with extensions where the SrcVT or
4423 // DestVT are odd things, so test to make sure that they are both types we can
4424 // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise
4425 // bail out to SelectionDAG.
4426 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) &&
4427 (DestVT != MVT::i32) && (DestVT != MVT::i64)) ||
4428 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) &&
4429 (SrcVT != MVT::i16) && (SrcVT != MVT::i32)))
4430 return Register();
4431
4432 unsigned Opc;
4433 unsigned Imm = 0;
4434
4435 switch (SrcVT.SimpleTy) {
4436 default:
4437 return Register();
4438 case MVT::i1:
4439 return emiti1Ext(SrcReg, DestVT, IsZExt);
4440 case MVT::i8:
4441 if (DestVT == MVT::i64)
4442 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4443 else
4444 Opc = IsZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
4445 Imm = 7;
4446 break;
4447 case MVT::i16:
4448 if (DestVT == MVT::i64)
4449 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4450 else
4451 Opc = IsZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
4452 Imm = 15;
4453 break;
4454 case MVT::i32:
4455 assert(DestVT == MVT::i64 && "IntExt i32 to i32?!?");
4456 Opc = IsZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
4457 Imm = 31;
4458 break;
4459 }
4460
4461 // Handle i8 and i16 as i32.
4462 if (DestVT == MVT::i8 || DestVT == MVT::i16)
4463 DestVT = MVT::i32;
4464 else if (DestVT == MVT::i64) {
4465 Register Src64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
4466 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4467 TII.get(AArch64::SUBREG_TO_REG), Src64)
4468 .addReg(SrcReg)
4469 .addImm(AArch64::sub_32);
4470 SrcReg = Src64;
4471 }
4472
4473 const TargetRegisterClass *RC =
4474 (DestVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4475 return fastEmitInst_rii(Opc, RC, SrcReg, 0, Imm);
4476}
4477
4478bool AArch64FastISel::optimizeIntExtLoad(const Instruction *I, MVT RetVT,
4479 MVT SrcVT) {
4480 const auto *LI = dyn_cast<LoadInst>(I->getOperand(0));
4481 if (!LI || !LI->hasOneUse())
4482 return false;
4483
4484 // Check if the load instruction has already been selected.
4485 Register Reg = lookUpRegForValue(LI);
4486 if (!Reg)
4487 return false;
4488
4489 MachineInstr *MI = MRI.getUniqueVRegDef(Reg);
4490 if (!MI)
4491 return false;
4492
4493 // Check if the correct load instruction has been emitted - SelectionDAG might
4494 // have emitted a zero-extending load, but we need a sign-extending load.
4495 bool IsZExt = isa<ZExtInst>(I);
4496 const auto *LoadMI = MI;
4497 if (LoadMI->getOpcode() == TargetOpcode::COPY &&
4498 LoadMI->getOperand(1).getSubReg() == AArch64::sub_32) {
4499 Register LoadReg = MI->getOperand(1).getReg();
4500 LoadMI = MRI.getUniqueVRegDef(LoadReg);
4501 assert(LoadMI && "Expected valid instruction");
4502 }
4503 if (!(IsZExt && AArch64InstrInfo::isZExtLoad(*LoadMI)) &&
4504 !(!IsZExt && AArch64InstrInfo::isSExtLoad(*LoadMI)))
4505 return false;
4506
4507 // Nothing to be done.
4508 if (RetVT != MVT::i64 || SrcVT > MVT::i32) {
4509 updateValueMap(I, Reg);
4510 return true;
4511 }
4512
4513 if (IsZExt) {
4514 Register Reg64 = createResultReg(&AArch64::GPR64RegClass);
4515 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4516 TII.get(AArch64::SUBREG_TO_REG), Reg64)
4517 .addReg(Reg)
4518 .addImm(AArch64::sub_32);
4519 Reg = Reg64;
4520 } else {
4521 assert((MI->getOpcode() == TargetOpcode::COPY &&
4522 MI->getOperand(1).getSubReg() == AArch64::sub_32) &&
4523 "Expected copy instruction");
4524 Reg = MI->getOperand(1).getReg();
4526 removeDeadCode(I, std::next(I));
4527 }
4528 updateValueMap(I, Reg);
4529 return true;
4530}
4531
4532bool AArch64FastISel::selectIntExt(const Instruction *I) {
4534 "Unexpected integer extend instruction.");
4535 MVT RetVT;
4536 MVT SrcVT;
4537 if (!isTypeSupported(I->getType(), RetVT))
4538 return false;
4539
4540 if (!isTypeSupported(I->getOperand(0)->getType(), SrcVT))
4541 return false;
4542
4543 // Try to optimize already sign-/zero-extended values from load instructions.
4544 if (optimizeIntExtLoad(I, RetVT, SrcVT))
4545 return true;
4546
4547 Register SrcReg = getRegForValue(I->getOperand(0));
4548 if (!SrcReg)
4549 return false;
4550
4551 // Try to optimize already sign-/zero-extended values from function arguments.
4552 bool IsZExt = isa<ZExtInst>(I);
4553 if (const auto *Arg = dyn_cast<Argument>(I->getOperand(0))) {
4554 if ((IsZExt && Arg->hasZExtAttr()) || (!IsZExt && Arg->hasSExtAttr())) {
4555 if (RetVT == MVT::i64 && SrcVT != MVT::i64) {
4556 Register ResultReg = createResultReg(&AArch64::GPR64RegClass);
4557 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4558 TII.get(AArch64::SUBREG_TO_REG), ResultReg)
4559 .addReg(SrcReg)
4560 .addImm(AArch64::sub_32);
4561 SrcReg = ResultReg;
4562 }
4563
4564 updateValueMap(I, SrcReg);
4565 return true;
4566 }
4567 }
4568
4569 Register ResultReg = emitIntExt(SrcVT, SrcReg, RetVT, IsZExt);
4570 if (!ResultReg)
4571 return false;
4572
4573 updateValueMap(I, ResultReg);
4574 return true;
4575}
4576
4577bool AArch64FastISel::selectRem(const Instruction *I, unsigned ISDOpcode) {
4578 EVT DestEVT = TLI.getValueType(DL, I->getType(), true);
4579 if (!DestEVT.isSimple())
4580 return false;
4581
4582 MVT DestVT = DestEVT.getSimpleVT();
4583 if (DestVT != MVT::i64 && DestVT != MVT::i32)
4584 return false;
4585
4586 unsigned DivOpc;
4587 bool Is64bit = (DestVT == MVT::i64);
4588 switch (ISDOpcode) {
4589 default:
4590 return false;
4591 case ISD::SREM:
4592 DivOpc = Is64bit ? AArch64::SDIVXr : AArch64::SDIVWr;
4593 break;
4594 case ISD::UREM:
4595 DivOpc = Is64bit ? AArch64::UDIVXr : AArch64::UDIVWr;
4596 break;
4597 }
4598 unsigned MSubOpc = Is64bit ? AArch64::MSUBXrrr : AArch64::MSUBWrrr;
4599 Register Src0Reg = getRegForValue(I->getOperand(0));
4600 if (!Src0Reg)
4601 return false;
4602
4603 Register Src1Reg = getRegForValue(I->getOperand(1));
4604 if (!Src1Reg)
4605 return false;
4606
4607 const TargetRegisterClass *RC =
4608 (DestVT == MVT::i64) ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
4609 Register QuotReg = fastEmitInst_rr(DivOpc, RC, Src0Reg, Src1Reg);
4610 assert(QuotReg && "Unexpected DIV instruction emission failure.");
4611 // The remainder is computed as numerator - (quotient * denominator) using the
4612 // MSUB instruction.
4613 Register ResultReg = fastEmitInst_rrr(MSubOpc, RC, QuotReg, Src1Reg, Src0Reg);
4614 updateValueMap(I, ResultReg);
4615 return true;
4616}
4617
4618bool AArch64FastISel::selectMul(const Instruction *I) {
4619 MVT VT;
4620 if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true))
4621 return false;
4622
4623 if (VT.isVector())
4624 return selectBinaryOp(I, ISD::MUL);
4625
4626 const Value *Src0 = I->getOperand(0);
4627 const Value *Src1 = I->getOperand(1);
4628 if (const auto *C = dyn_cast<ConstantInt>(Src0))
4629 if (C->getValue().isPowerOf2())
4630 std::swap(Src0, Src1);
4631
4632 // Try to simplify to a shift instruction.
4633 if (const auto *C = dyn_cast<ConstantInt>(Src1))
4634 if (C->getValue().isPowerOf2()) {
4635 uint64_t ShiftVal = C->getValue().logBase2();
4636 MVT SrcVT = VT;
4637 bool IsZExt = true;
4638 if (const auto *ZExt = dyn_cast<ZExtInst>(Src0)) {
4639 if (!isIntExtFree(ZExt)) {
4640 MVT VT;
4641 if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(), VT)) {
4642 SrcVT = VT;
4643 IsZExt = true;
4644 Src0 = ZExt->getOperand(0);
4645 }
4646 }
4647 } else if (const auto *SExt = dyn_cast<SExtInst>(Src0)) {
4648 if (!isIntExtFree(SExt)) {
4649 MVT VT;
4650 if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(), VT)) {
4651 SrcVT = VT;
4652 IsZExt = false;
4653 Src0 = SExt->getOperand(0);
4654 }
4655 }
4656 }
4657
4658 Register Src0Reg = getRegForValue(Src0);
4659 if (!Src0Reg)
4660 return false;
4661
4662 Register ResultReg = emitLSL_ri(VT, SrcVT, Src0Reg, ShiftVal, IsZExt);
4663
4664 if (ResultReg) {
4665 updateValueMap(I, ResultReg);
4666 return true;
4667 }
4668 }
4669
4670 Register Src0Reg = getRegForValue(I->getOperand(0));
4671 if (!Src0Reg)
4672 return false;
4673
4674 Register Src1Reg = getRegForValue(I->getOperand(1));
4675 if (!Src1Reg)
4676 return false;
4677
4678 Register ResultReg = emitMul_rr(VT, Src0Reg, Src1Reg);
4679
4680 if (!ResultReg)
4681 return false;
4682
4683 updateValueMap(I, ResultReg);
4684 return true;
4685}
4686
4687bool AArch64FastISel::selectShift(const Instruction *I) {
4688 MVT RetVT;
4689 if (!isTypeSupported(I->getType(), RetVT, /*IsVectorAllowed=*/true))
4690 return false;
4691
4692 if (RetVT.isVector())
4693 return selectOperator(I, I->getOpcode());
4694
4695 if (const auto *C = dyn_cast<ConstantInt>(I->getOperand(1))) {
4696 Register ResultReg;
4697 uint64_t ShiftVal = C->getZExtValue();
4698 MVT SrcVT = RetVT;
4699 bool IsZExt = I->getOpcode() != Instruction::AShr;
4700 const Value *Op0 = I->getOperand(0);
4701 if (const auto *ZExt = dyn_cast<ZExtInst>(Op0)) {
4702 if (!isIntExtFree(ZExt)) {
4703 MVT TmpVT;
4704 if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(), TmpVT)) {
4705 SrcVT = TmpVT;
4706 IsZExt = true;
4707 Op0 = ZExt->getOperand(0);
4708 }
4709 }
4710 } else if (const auto *SExt = dyn_cast<SExtInst>(Op0)) {
4711 if (!isIntExtFree(SExt)) {
4712 MVT TmpVT;
4713 if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(), TmpVT)) {
4714 SrcVT = TmpVT;
4715 IsZExt = false;
4716 Op0 = SExt->getOperand(0);
4717 }
4718 }
4719 }
4720
4721 Register Op0Reg = getRegForValue(Op0);
4722 if (!Op0Reg)
4723 return false;
4724
4725 switch (I->getOpcode()) {
4726 default: llvm_unreachable("Unexpected instruction.");
4727 case Instruction::Shl:
4728 ResultReg = emitLSL_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4729 break;
4730 case Instruction::AShr:
4731 ResultReg = emitASR_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4732 break;
4733 case Instruction::LShr:
4734 ResultReg = emitLSR_ri(RetVT, SrcVT, Op0Reg, ShiftVal, IsZExt);
4735 break;
4736 }
4737 if (!ResultReg)
4738 return false;
4739
4740 updateValueMap(I, ResultReg);
4741 return true;
4742 }
4743
4744 Register Op0Reg = getRegForValue(I->getOperand(0));
4745 if (!Op0Reg)
4746 return false;
4747
4748 Register Op1Reg = getRegForValue(I->getOperand(1));
4749 if (!Op1Reg)
4750 return false;
4751
4752 Register ResultReg;
4753 switch (I->getOpcode()) {
4754 default: llvm_unreachable("Unexpected instruction.");
4755 case Instruction::Shl:
4756 ResultReg = emitLSL_rr(RetVT, Op0Reg, Op1Reg);
4757 break;
4758 case Instruction::AShr:
4759 ResultReg = emitASR_rr(RetVT, Op0Reg, Op1Reg);
4760 break;
4761 case Instruction::LShr:
4762 ResultReg = emitLSR_rr(RetVT, Op0Reg, Op1Reg);
4763 break;
4764 }
4765
4766 if (!ResultReg)
4767 return false;
4768
4769 updateValueMap(I, ResultReg);
4770 return true;
4771}
4772
4773bool AArch64FastISel::selectBitCast(const Instruction *I) {
4774 MVT RetVT, SrcVT;
4775
4776 if (!isTypeLegal(I->getOperand(0)->getType(), SrcVT))
4777 return false;
4778 if (!isTypeLegal(I->getType(), RetVT))
4779 return false;
4780
4781 unsigned Opc;
4782 if (RetVT == MVT::f32 && SrcVT == MVT::i32)
4783 Opc = AArch64::FMOVWSr;
4784 else if (RetVT == MVT::f64 && SrcVT == MVT::i64)
4785 Opc = AArch64::FMOVXDr;
4786 else if (RetVT == MVT::i32 && SrcVT == MVT::f32)
4787 Opc = AArch64::FMOVSWr;
4788 else if (RetVT == MVT::i64 && SrcVT == MVT::f64)
4789 Opc = AArch64::FMOVDXr;
4790 else
4791 return false;
4792
4793 const TargetRegisterClass *RC = nullptr;
4794 switch (RetVT.SimpleTy) {
4795 default: llvm_unreachable("Unexpected value type.");
4796 case MVT::i32: RC = &AArch64::GPR32RegClass; break;
4797 case MVT::i64: RC = &AArch64::GPR64RegClass; break;
4798 case MVT::f32: RC = &AArch64::FPR32RegClass; break;
4799 case MVT::f64: RC = &AArch64::FPR64RegClass; break;
4800 }
4801 Register Op0Reg = getRegForValue(I->getOperand(0));
4802 if (!Op0Reg)
4803 return false;
4804
4805 Register ResultReg = fastEmitInst_r(Opc, RC, Op0Reg);
4806 if (!ResultReg)
4807 return false;
4808
4809 updateValueMap(I, ResultReg);
4810 return true;
4811}
4812
4813bool AArch64FastISel::selectFRem(const Instruction *I) {
4814 MVT RetVT;
4815 if (!isTypeLegal(I->getType(), RetVT))
4816 return false;
4817
4818 RTLIB::LibcallImpl LCImpl =
4819 LibcallLowering->getLibcallImpl(RTLIB::getREM(RetVT));
4820 if (LCImpl == RTLIB::Unsupported)
4821 return false;
4822
4823 ArgListTy Args;
4824 Args.reserve(I->getNumOperands());
4825
4826 // Populate the argument list.
4827 for (auto &Arg : I->operands())
4828 Args.emplace_back(Arg);
4829
4830 CallLoweringInfo CLI;
4831 MCContext &Ctx = MF->getContext();
4832 CallingConv::ID CC = LibcallLowering->getLibcallImplCallingConv(LCImpl);
4833 StringRef FuncName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LCImpl);
4834
4835 CLI.setCallee(DL, Ctx, CC, I->getType(), FuncName, std::move(Args));
4836 if (!lowerCallTo(CLI))
4837 return false;
4838 updateValueMap(I, CLI.ResultReg);
4839 return true;
4840}
4841
4842bool AArch64FastISel::selectSDiv(const Instruction *I) {
4843 MVT VT;
4844 if (!isTypeLegal(I->getType(), VT))
4845 return false;
4846
4847 if (!isa<ConstantInt>(I->getOperand(1)))
4848 return selectBinaryOp(I, ISD::SDIV);
4849
4850 const APInt &C = cast<ConstantInt>(I->getOperand(1))->getValue();
4851 if ((VT != MVT::i32 && VT != MVT::i64) || !C ||
4852 !(C.isPowerOf2() || C.isNegatedPowerOf2()))
4853 return selectBinaryOp(I, ISD::SDIV);
4854
4855 unsigned Lg2 = C.countr_zero();
4856 Register Src0Reg = getRegForValue(I->getOperand(0));
4857 if (!Src0Reg)
4858 return false;
4859
4860 if (cast<BinaryOperator>(I)->isExact()) {
4861 Register ResultReg = emitASR_ri(VT, VT, Src0Reg, Lg2);
4862 if (!ResultReg)
4863 return false;
4864 updateValueMap(I, ResultReg);
4865 return true;
4866 }
4867
4868 int64_t Pow2MinusOne = (1ULL << Lg2) - 1;
4869 Register AddReg = emitAdd_ri_(VT, Src0Reg, Pow2MinusOne);
4870 if (!AddReg)
4871 return false;
4872
4873 // (Src0 < 0) ? Pow2 - 1 : 0;
4874 if (!emitICmp_ri(VT, Src0Reg, 0))
4875 return false;
4876
4877 unsigned SelectOpc;
4878 const TargetRegisterClass *RC;
4879 if (VT == MVT::i64) {
4880 SelectOpc = AArch64::CSELXr;
4881 RC = &AArch64::GPR64RegClass;
4882 } else {
4883 SelectOpc = AArch64::CSELWr;
4884 RC = &AArch64::GPR32RegClass;
4885 }
4886 Register SelectReg = fastEmitInst_rri(SelectOpc, RC, AddReg, Src0Reg,
4888 if (!SelectReg)
4889 return false;
4890
4891 // Divide by Pow2 --> ashr. If we're dividing by a negative value we must also
4892 // negate the result.
4893 Register ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
4894 Register ResultReg;
4895 if (C.isNegative())
4896 ResultReg = emitAddSub_rs(/*UseAdd=*/false, VT, ZeroReg, SelectReg,
4897 AArch64_AM::ASR, Lg2);
4898 else
4899 ResultReg = emitASR_ri(VT, VT, SelectReg, Lg2);
4900
4901 if (!ResultReg)
4902 return false;
4903
4904 updateValueMap(I, ResultReg);
4905 return true;
4906}
4907
4908/// This is mostly a copy of the existing FastISel getRegForGEPIndex code. We
4909/// have to duplicate it for AArch64, because otherwise we would fail during the
4910/// sign-extend emission.
4911Register AArch64FastISel::getRegForGEPIndex(const Value *Idx) {
4912 Register IdxN = getRegForValue(Idx);
4913 if (!IdxN)
4914 // Unhandled operand. Halt "fast" selection and bail.
4915 return Register();
4916
4917 // If the index is smaller or larger than intptr_t, truncate or extend it.
4918 MVT PtrVT = TLI.getPointerTy(DL);
4919 EVT IdxVT = EVT::getEVT(Idx->getType(), /*HandleUnknown=*/false);
4920 if (IdxVT.bitsLT(PtrVT)) {
4921 IdxN = emitIntExt(IdxVT.getSimpleVT(), IdxN, PtrVT, /*isZExt=*/false);
4922 } else if (IdxVT.bitsGT(PtrVT))
4923 llvm_unreachable("AArch64 FastISel doesn't support types larger than i64");
4924 return IdxN;
4925}
4926
4927/// This is mostly a copy of the existing FastISel GEP code, but we have to
4928/// duplicate it for AArch64, because otherwise we would bail out even for
4929/// simple cases. This is because the standard fastEmit functions don't cover
4930/// MUL at all and ADD is lowered very inefficientily.
4931bool AArch64FastISel::selectGetElementPtr(const Instruction *I) {
4932 if (Subtarget->isTargetILP32())
4933 return false;
4934
4935 Register N = getRegForValue(I->getOperand(0));
4936 if (!N)
4937 return false;
4938
4939 // Keep a running tab of the total offset to coalesce multiple N = N + Offset
4940 // into a single N = N + TotalOffset.
4941 uint64_t TotalOffs = 0;
4942 MVT VT = TLI.getPointerTy(DL);
4944 GTI != E; ++GTI) {
4945 const Value *Idx = GTI.getOperand();
4946 if (auto *StTy = GTI.getStructTypeOrNull()) {
4947 unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
4948 // N = N + Offset
4949 if (Field)
4950 TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field);
4951 } else {
4952 // If this is a constant subscript, handle it quickly.
4953 if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
4954 if (CI->isZero())
4955 continue;
4956 // N = N + Offset
4957 TotalOffs += GTI.getSequentialElementStride(DL) *
4958 cast<ConstantInt>(CI)->getSExtValue();
4959 continue;
4960 }
4961 if (TotalOffs) {
4962 N = emitAdd_ri_(VT, N, TotalOffs);
4963 if (!N)
4964 return false;
4965 TotalOffs = 0;
4966 }
4967
4968 // N = N + Idx * ElementSize;
4969 uint64_t ElementSize = GTI.getSequentialElementStride(DL);
4970 Register IdxN = getRegForGEPIndex(Idx);
4971 if (!IdxN)
4972 return false;
4973
4974 if (ElementSize != 1) {
4975 Register C = fastEmit_i(VT, VT, ISD::Constant, ElementSize);
4976 if (!C)
4977 return false;
4978 IdxN = emitMul_rr(VT, IdxN, C);
4979 if (!IdxN)
4980 return false;
4981 }
4982 N = fastEmit_rr(VT, VT, ISD::ADD, N, IdxN);
4983 if (!N)
4984 return false;
4985 }
4986 }
4987 if (TotalOffs) {
4988 N = emitAdd_ri_(VT, N, TotalOffs);
4989 if (!N)
4990 return false;
4991 }
4992 updateValueMap(I, N);
4993 return true;
4994}
4995
4996bool AArch64FastISel::selectAtomicCmpXchg(const AtomicCmpXchgInst *I) {
4997 assert(TM.getOptLevel() == CodeGenOptLevel::None &&
4998 "cmpxchg survived AtomicExpand at optlevel > -O0");
4999
5000 auto *RetPairTy = cast<StructType>(I->getType());
5001 Type *RetTy = RetPairTy->getTypeAtIndex(0U);
5002 assert(RetPairTy->getTypeAtIndex(1U)->isIntegerTy(1) &&
5003 "cmpxchg has a non-i1 status result");
5004
5005 MVT VT;
5006 if (!isTypeLegal(RetTy, VT))
5007 return false;
5008
5009 const TargetRegisterClass *ResRC;
5010 unsigned Opc, CmpOpc;
5011 // This only supports i32/i64, because i8/i16 aren't legal, and the generic
5012 // extractvalue selection doesn't support that.
5013 if (VT == MVT::i32) {
5014 Opc = AArch64::CMP_SWAP_32;
5015 CmpOpc = AArch64::SUBSWrs;
5016 ResRC = &AArch64::GPR32RegClass;
5017 } else if (VT == MVT::i64) {
5018 Opc = AArch64::CMP_SWAP_64;
5019 CmpOpc = AArch64::SUBSXrs;
5020 ResRC = &AArch64::GPR64RegClass;
5021 } else {
5022 return false;
5023 }
5024
5025 const MCInstrDesc &II = TII.get(Opc);
5026
5027 Register AddrReg = getRegForValue(I->getPointerOperand());
5028 Register DesiredReg = getRegForValue(I->getCompareOperand());
5029 Register NewReg = getRegForValue(I->getNewValOperand());
5030
5031 if (!AddrReg || !DesiredReg || !NewReg)
5032 return false;
5033
5034 AddrReg = constrainOperandRegClass(II, AddrReg, II.getNumDefs());
5035 DesiredReg = constrainOperandRegClass(II, DesiredReg, II.getNumDefs() + 1);
5036 NewReg = constrainOperandRegClass(II, NewReg, II.getNumDefs() + 2);
5037
5038 const Register ResultReg1 = createResultReg(ResRC);
5039 const Register ResultReg2 = createResultReg(&AArch64::GPR32RegClass);
5040 const Register ScratchReg = createResultReg(&AArch64::GPR32RegClass);
5041
5042 // FIXME: MachineMemOperand doesn't support cmpxchg yet.
5043 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
5044 .addDef(ResultReg1)
5045 .addDef(ScratchReg)
5046 .addUse(AddrReg)
5047 .addUse(DesiredReg)
5048 .addUse(NewReg);
5049
5050 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc))
5051 .addDef(VT == MVT::i32 ? AArch64::WZR : AArch64::XZR)
5052 .addUse(ResultReg1)
5053 .addUse(DesiredReg)
5054 .addImm(0);
5055
5056 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AArch64::CSINCWr))
5057 .addDef(ResultReg2)
5058 .addUse(AArch64::WZR)
5059 .addUse(AArch64::WZR)
5061
5062 assert((ResultReg1 + 1) == ResultReg2 && "Nonconsecutive result registers.");
5063 updateValueMap(I, ResultReg1, 2);
5064 return true;
5065}
5066
5067bool AArch64FastISel::fastSelectInstruction(const Instruction *I) {
5068 if (TLI.fallBackToDAGISel(*I))
5069 return false;
5070 switch (I->getOpcode()) {
5071 default:
5072 break;
5073 case Instruction::Add:
5074 case Instruction::Sub:
5075 return selectAddSub(I);
5076 case Instruction::Mul:
5077 return selectMul(I);
5078 case Instruction::SDiv:
5079 return selectSDiv(I);
5080 case Instruction::SRem:
5081 if (!selectBinaryOp(I, ISD::SREM))
5082 return selectRem(I, ISD::SREM);
5083 return true;
5084 case Instruction::URem:
5085 if (!selectBinaryOp(I, ISD::UREM))
5086 return selectRem(I, ISD::UREM);
5087 return true;
5088 case Instruction::Shl:
5089 case Instruction::LShr:
5090 case Instruction::AShr:
5091 return selectShift(I);
5092 case Instruction::And:
5093 case Instruction::Or:
5094 case Instruction::Xor:
5095 return selectLogicalOp(I);
5096 case Instruction::CondBr:
5097 return selectBranch(I);
5098 case Instruction::IndirectBr:
5099 return selectIndirectBr(I);
5100 case Instruction::BitCast:
5102 return selectBitCast(I);
5103 return true;
5104 case Instruction::FPToSI:
5105 if (!selectCast(I, ISD::FP_TO_SINT))
5106 return selectFPToInt(I, /*Signed=*/true);
5107 return true;
5108 case Instruction::FPToUI:
5109 return selectFPToInt(I, /*Signed=*/false);
5110 case Instruction::ZExt:
5111 case Instruction::SExt:
5112 return selectIntExt(I);
5113 case Instruction::Trunc:
5114 if (!selectCast(I, ISD::TRUNCATE))
5115 return selectTrunc(I);
5116 return true;
5117 case Instruction::FPExt:
5118 return selectFPExt(I);
5119 case Instruction::FPTrunc:
5120 return selectFPTrunc(I);
5121 case Instruction::SIToFP:
5122 if (!selectCast(I, ISD::SINT_TO_FP))
5123 return selectIntToFP(I, /*Signed=*/true);
5124 return true;
5125 case Instruction::UIToFP:
5126 return selectIntToFP(I, /*Signed=*/false);
5127 case Instruction::Load:
5128 return selectLoad(I);
5129 case Instruction::Store:
5130 return selectStore(I);
5131 case Instruction::FCmp:
5132 case Instruction::ICmp:
5133 return selectCmp(I);
5134 case Instruction::Select:
5135 return selectSelect(I);
5136 case Instruction::Ret:
5137 return selectRet(I);
5138 case Instruction::FRem:
5139 return selectFRem(I);
5140 case Instruction::GetElementPtr:
5141 return selectGetElementPtr(I);
5142 case Instruction::AtomicCmpXchg:
5143 return selectAtomicCmpXchg(cast<AtomicCmpXchgInst>(I));
5144 }
5145
5146 // fall-back to target-independent instruction selection.
5147 return selectOperator(I, I->getOpcode());
5148}
5149
5151 const TargetLibraryInfo *LibInfo,
5152 const LibcallLoweringInfo *LibcallLowering) {
5153
5154 SMEAttrs CallerAttrs =
5155 FuncInfo.MF->getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
5156 if (CallerAttrs.hasZAState() || CallerAttrs.hasZT0State() ||
5157 CallerAttrs.hasStreamingInterfaceOrBody() ||
5158 CallerAttrs.hasStreamingCompatibleInterface() ||
5159 CallerAttrs.hasAgnosticZAInterface())
5160 return nullptr;
5161 return new AArch64FastISel(FuncInfo, LibInfo, LibcallLowering);
5162}
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!")
uint64_t uint64_t
uint64_t Imm
AMDGPU Reserve WWM Registers
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
basic Basic Alias true
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
static constexpr Value * getValue(Ty &ValueOrUse)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
SmallVector< MachineOperand, 4 > Cond
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
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 isTargetWindowsOrUEFI() const
UEFI follows the Windows ARM64 ABI and produces PE/COFF images, so most of the Windows specific ABI h...
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:65
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:321
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:352
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.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
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.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Value * getLength() const
unsigned getDestAddressSpace() const
bool isVolatile() const
constexpr unsigned id() const
Definition Register.h:100
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool hasStreamingCompatibleInterface() const
bool hasAgnosticZAInterface() const
bool hasStreamingInterfaceOrBody() const
void reserve(size_type N)
void push_back(const T &Elt)
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
Provides information about what library functions are available for the current target.
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition Type.h:274
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
bool isStructTy() const
True if this is an instance of StructType.
Definition Type.h:271
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
const ParentTy * getParent() const
Definition ilist_node.h:34
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
@ MO_PREL
MO_PREL - Indicates that the bits of the symbol operand represented by MO_G0 etc are PC relative.
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
@ MO_G3
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address,...
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:906
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:952
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition Utils.cpp:60
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
bool CC_AArch64_Win64PCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool CC_AArch64_DarwinPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
gep_type_iterator gep_type_end(const User *GEP)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
bool isReleaseOrStronger(AtomicOrdering AO)
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool CC_AArch64_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool CC_AArch64_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
bool RetCC_AArch64_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
gep_type_iterator gep_type_begin(const User *GEP)
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
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.