1//===- ARMISelLowering.h - ARM DAG Lowering Interface -----------*- C++ -*-===//
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 interfaces that ARM uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
15#define LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
16
17#include "MCTargetDesc/ARMBaseInfo.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/CodeGen/CallingConvLower.h"
21#include "llvm/CodeGen/ISDOpcodes.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/SelectionDAGNodes.h"
24#include "llvm/CodeGen/TargetLowering.h"
25#include "llvm/CodeGen/ValueTypes.h"
26#include "llvm/CodeGenTypes/MachineValueType.h"
27#include "llvm/IR/Attributes.h"
28#include "llvm/IR/CallingConv.h"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/InlineAsm.h"
31#include "llvm/Support/CodeGen.h"
32#include <optional>
33#include <utility>
34
35namespace llvm {
36
37class ARMBaseTargetMachine;
38class ARMSubtarget;
39class DataLayout;
40class FastISel;
41class FunctionLoweringInfo;
42class GlobalValue;
43class InstrItineraryData;
44class Instruction;
45class IRBuilderBase;
46class MachineBasicBlock;
47class MachineInstr;
48class SelectionDAG;
49class TargetLibraryInfo;
50class TargetMachine;
51class TargetRegisterInfo;
52class VectorType;
53
54 namespace ARM {
55 /// Possible values of current rounding mode, which is specified in bits
56 /// 23:22 of FPSCR.
57 enum Rounding {
58 RN = 0, // Round to Nearest
59 RP = 1, // Round towards Plus infinity
60 RM = 2, // Round towards Minus infinity
61 RZ = 3, // Round towards Zero
62 rmMask = 3 // Bit mask selecting rounding mode
63 };
64
65 // Bit position of rounding mode bits in FPSCR.
66 const unsigned RoundingBitsPos = 22;
67
68 // Bits of floating-point status. These are NZCV flags, QC bit and cumulative
69 // FP exception bits.
70 const unsigned FPStatusBits = 0xf800009f;
71
72 // Some bits in the FPSCR are not yet defined. They must be preserved when
73 // modifying the contents.
74 const unsigned FPReservedBits = 0x00006060;
75 } // namespace ARM
76
77 /// Define some predicates that are used for node matching.
78 namespace ARM {
79
80 bool isBitFieldInvertedMask(unsigned v);
81
82 } // end namespace ARM
83
84 //===--------------------------------------------------------------------===//
85 // ARMTargetLowering - ARM Implementation of the TargetLowering interface
86
87 class ARMTargetLowering : public TargetLowering {
88 // Copying needed for an outgoing byval argument.
89 enum ByValCopyKind {
90 // Argument is already in the correct location, no copy needed.
91 NoCopy,
92 // Argument value is currently in the local stack frame, needs copying to
93 // outgoing arguemnt area.
94 CopyOnce,
95 // Argument value is currently in the outgoing argument area, but not at
96 // the correct offset, so needs copying via a temporary in local stack
97 // space.
98 CopyViaTemp,
99 };
100
101 public:
102 explicit ARMTargetLowering(const TargetMachine &TM,
103 const ARMSubtarget &STI);
104
105 const ARMBaseTargetMachine &getTM() const;
106
107 unsigned getJumpTableEncoding() const override;
108 bool useSoftFloat() const override;
109
110 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
111
112 /// ReplaceNodeResults - Replace the results of node with an illegal result
113 /// type with new values built out of custom code.
114 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
115 SelectionDAG &DAG) const override;
116
117 bool isSelectSupported(SelectSupportKind Kind) const override {
118 // ARM does not support scalar condition selects on vectors.
119 return (Kind != ScalarCondVectorVal);
120 }
121
122 bool isReadOnly(const GlobalValue *GV) const;
123
124 /// getSetCCResultType - Return the value type to use for ISD::SETCC.
125 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
126 EVT VT) const override;
127
128 MachineBasicBlock *
129 EmitInstrWithCustomInserter(MachineInstr &MI,
130 MachineBasicBlock *MBB) const override;
131
132 void AdjustInstrPostInstrSelection(MachineInstr &MI,
133 SDNode *Node) const override;
134
135 bool supportKCFIBundles() const override;
136
137 MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB,
138 MachineBasicBlock::instr_iterator &MBBI,
139 const TargetInstrInfo *TII) const override;
140
141 SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const;
142 SDValue PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG) const;
143 SDValue PerformCMOVToBFICombine(SDNode *N, SelectionDAG &DAG) const;
144 SDValue PerformIntrinsicCombine(SDNode *N, DAGCombinerInfo &DCI) const;
145 SDValue PerformMVEExtCombine(SDNode *N, DAGCombinerInfo &DCI) const;
146 SDValue PerformMVETruncCombine(SDNode *N, DAGCombinerInfo &DCI) const;
147 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
148
149 bool SimplifyDemandedBitsForTargetNode(SDValue Op,
150 const APInt &OriginalDemandedBits,
151 const APInt &OriginalDemandedElts,
152 KnownBits &Known,
153 TargetLoweringOpt &TLO,
154 unsigned Depth) const override;
155
156 bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const override;
157
158 /// allowsMisalignedMemoryAccesses - Returns true if the target allows
159 /// unaligned memory accesses of the specified type. Returns whether it
160 /// is "fast" by reference in the second argument.
161 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
162 Align Alignment,
163 MachineMemOperand::Flags Flags,
164 unsigned *Fast) const override;
165
166 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
167 const AttributeList &FuncAttributes) const override;
168
169 bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
170 bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
171 bool isZExtFree(SDValue Val, EVT VT2) const override;
172 Type* shouldConvertSplatType(ShuffleVectorInst* SVI) const override;
173
174 bool isFNegFree(EVT VT) const override;
175
176 bool isVectorLoadExtDesirable(SDValue ExtVal) const override;
177
178 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
179
180
181 /// isLegalAddressingMode - Return true if the addressing mode represented
182 /// by AM is legal for this target, for a load/store of the specified type.
183 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
184 Type *Ty, unsigned AS,
185 Instruction *I = nullptr) const override;
186
187 bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const;
188
189 /// Returns true if the addressing mode representing by AM is legal
190 /// for the Thumb1 target, for a load/store of the specified type.
191 bool isLegalT1ScaledAddressingMode(const AddrMode &AM, EVT VT) const;
192
193 /// isLegalICmpImmediate - Return true if the specified immediate is legal
194 /// icmp immediate, that is the target has icmp instructions which can
195 /// compare a register against the immediate without having to materialize
196 /// the immediate into a register.
197 bool isLegalICmpImmediate(int64_t Imm) const override;
198
199 /// isLegalAddImmediate - Return true if the specified immediate is legal
200 /// add immediate, that is the target has add instructions which can
201 /// add a register and the immediate without having to materialize
202 /// the immediate into a register.
203 bool isLegalAddImmediate(int64_t Imm) const override;
204
205 /// getPreIndexedAddressParts - returns true by value, base pointer and
206 /// offset pointer and addressing mode by reference if the node's address
207 /// can be legally represented as pre-indexed load / store address.
208 bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset,
209 ISD::MemIndexedMode &AM,
210 SelectionDAG &DAG) const override;
211
212 /// getPostIndexedAddressParts - returns true by value, base pointer and
213 /// offset pointer and addressing mode by reference if this node can be
214 /// combined with a load / store to form a post-indexed load / store.
215 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base,
216 SDValue &Offset, ISD::MemIndexedMode &AM,
217 SelectionDAG &DAG) const override;
218
219 void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known,
220 const APInt &DemandedElts,
221 const SelectionDAG &DAG,
222 unsigned Depth) const override;
223
224 bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
225 const APInt &DemandedElts,
226 TargetLoweringOpt &TLO) const override;
227
228 ConstraintType getConstraintType(StringRef Constraint) const override;
229
230 /// Examine constraint string and operand type and determine a weight value.
231 /// The operand object must already have been set up with the operand type.
232 ConstraintWeight getSingleConstraintMatchWeight(
233 AsmOperandInfo &info, const char *constraint) const override;
234
235 std::pair<unsigned, const TargetRegisterClass *>
236 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
237 StringRef Constraint, MVT VT) const override;
238
239 const char *LowerXConstraint(EVT ConstraintVT) const override;
240
241 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
242 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is
243 /// true it means one of the asm constraint of the inline asm instruction
244 /// being processed is 'm'.
245 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
246 std::vector<SDValue> &Ops,
247 SelectionDAG &DAG) const override;
248
249 InlineAsm::ConstraintCode
250 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
251 if (ConstraintCode == "Q")
252 return InlineAsm::ConstraintCode::Q;
253 if (ConstraintCode.size() == 2) {
254 if (ConstraintCode[0] == 'U') {
255 switch(ConstraintCode[1]) {
256 default:
257 break;
258 case 'm':
259 return InlineAsm::ConstraintCode::Um;
260 case 'n':
261 return InlineAsm::ConstraintCode::Un;
262 case 'q':
263 return InlineAsm::ConstraintCode::Uq;
264 case 's':
265 return InlineAsm::ConstraintCode::Us;
266 case 't':
267 return InlineAsm::ConstraintCode::Ut;
268 case 'v':
269 return InlineAsm::ConstraintCode::Uv;
270 case 'y':
271 return InlineAsm::ConstraintCode::Uy;
272 }
273 }
274 }
275 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
276 }
277
278 const ARMSubtarget* getSubtarget() const {
279 return Subtarget;
280 }
281
282 /// getRegClassFor - Return the register class that should be used for the
283 /// specified value type.
284 const TargetRegisterClass *
285 getRegClassFor(MVT VT, bool isDivergent = false) const override;
286
287 bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize,
288 Align &PrefAlign) const override;
289
290 /// createFastISel - This method returns a target specific FastISel object,
291 /// or null if the target does not support "fast" ISel.
292 FastISel *
293 createFastISel(FunctionLoweringInfo &funcInfo,
294 const TargetLibraryInfo *libInfo,
295 const LibcallLoweringInfo *libcallLowering) const override;
296
297 Sched::Preference getSchedulingPreference(SDNode *N) const override;
298
299 bool preferZeroCompareBranch() const override { return true; }
300
301 bool preferSelectsOverBooleanArithmetic(EVT VT) const override;
302
303 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
304
305 bool hasAndNotCompare(SDValue V) const override {
306 // We can use bics for any scalar.
307 return V.getValueType().isScalarInteger();
308 }
309
310 bool hasAndNot(SDValue Y) const override;
311
312 bool
313 isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;
314 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
315
316 /// isFPImmLegal - Returns true if the target can instruction select the
317 /// specified FP immediate natively. If false, the legalizer will
318 /// materialize the FP immediate as a load from a constant pool.
319 bool isFPImmLegal(const APFloat &Imm, EVT VT,
320 bool ForCodeSize = false) const override;
321
322 void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos,
323 const CallBase &I, MachineFunction &MF,
324 unsigned Intrinsic) const override;
325
326 /// Returns true if it is beneficial to convert a load of a constant
327 /// to just the constant itself.
328 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
329 Type *Ty) const override;
330
331 /// Return true if EXTRACT_SUBVECTOR is cheap for this result type
332 /// with this index.
333 bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
334 unsigned Index) const override;
335
336 bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
337 bool MathUsed) const override {
338 // Using overflow ops for overflow checks only should beneficial on ARM.
339 return TargetLowering::shouldFormOverflowOp(Opcode, VT, MathUsed: true);
340 }
341
342 bool shouldReassociateReduction(unsigned Opc, EVT VT) const override {
343 return Opc != ISD::VECREDUCE_ADD;
344 }
345
346 /// Returns true if an argument of type Ty needs to be passed in a
347 /// contiguous block of registers in calling convention CallConv.
348 bool functionArgumentNeedsConsecutiveRegisters(
349 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
350 const DataLayout &DL) const override;
351
352 /// If a physical register, this returns the register that receives the
353 /// exception address on entry to an EH pad.
354 Register
355 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
356
357 /// If a physical register, this returns the register that receives the
358 /// exception typeid on entry to a landing pad.
359 Register
360 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
361
362 Instruction *makeDMB(IRBuilderBase &Builder, ARM_MB::MemBOpt Domain) const;
363 Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,
364 AtomicOrdering Ord) const override;
365 Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,
366 AtomicOrdering Ord) const override;
367
368 void
369 emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const override;
370
371 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
372 AtomicOrdering Ord) const override;
373 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
374 AtomicOrdering Ord) const override;
375
376 unsigned getMaxSupportedInterleaveFactor() const override;
377
378 bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
379 ArrayRef<ShuffleVectorInst *> Shuffles,
380 ArrayRef<unsigned> Indices, unsigned Factor,
381 const APInt &GapMask) const override;
382 bool lowerInterleavedStore(Instruction *Store, Value *Mask,
383 ShuffleVectorInst *SVI, unsigned Factor,
384 const APInt &GapMask) const override;
385
386 bool shouldInsertFencesForAtomic(const Instruction *I) const override;
387 TargetLoweringBase::AtomicExpansionKind
388 shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
389 TargetLoweringBase::AtomicExpansionKind
390 shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
391 TargetLoweringBase::AtomicExpansionKind
392 shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
393 TargetLoweringBase::AtomicExpansionKind
394 shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override;
395
396 bool useLoadStackGuardNode(const Module &M) const override;
397
398 void
399 insertSSPDeclarations(Module &M,
400 const LibcallLoweringInfo &Libcalls) const override;
401
402 bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
403 unsigned &Cost) const override;
404
405 bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
406 const APInt &DemandedElts,
407 const SelectionDAG &DAG,
408 UndefPoisonKind Kind,
409 bool ConsiderFlags,
410 unsigned Depth) const override;
411
412 bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
413 const MachineFunction &MF) const override {
414 // Do not merge to larger than i32.
415 return (MemVT.getSizeInBits() <= 32);
416 }
417
418 bool isCheapToSpeculateCttz(Type *Ty) const override;
419 bool isCheapToSpeculateCtlz(Type *Ty) const override;
420
421 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
422 return VT.isScalarInteger();
423 }
424
425 bool supportSwiftError() const override {
426 return true;
427 }
428
429 bool supportSplitCSR(MachineFunction *MF) const override {
430 return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&
431 MF->getFunction().hasFnAttribute(Kind: Attribute::NoUnwind);
432 }
433
434 bool hasStandaloneRem(EVT VT) const override {
435 return HasStandaloneRem;
436 }
437
438 ShiftLegalizationStrategy
439 preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
440 unsigned ExpansionFactor) const override;
441
442 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool isVarArg) const;
443 CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool isVarArg) const;
444
445 /// Returns true if \p VecTy is a legal interleaved access type. This
446 /// function checks the vector element type and the overall width of the
447 /// vector.
448 bool isLegalInterleavedAccessType(unsigned Factor, FixedVectorType *VecTy,
449 Align Alignment,
450 const DataLayout &DL) const;
451
452 bool isMulAddWithConstProfitable(SDValue AddNode,
453 SDValue ConstNode) const override;
454
455 bool alignLoopsWithOptSize() const override;
456
457 /// Returns the number of interleaved accesses that will be generated when
458 /// lowering accesses of the given type.
459 unsigned getNumInterleavedAccesses(VectorType *VecTy,
460 const DataLayout &DL) const;
461
462 void finalizeLowering(MachineFunction &MF) const override;
463
464 /// Return the correct alignment for the current calling convention.
465 Align getABIAlignmentForCallingConv(Type *ArgTy,
466 const DataLayout &DL) const override;
467
468 bool isDesirableToCommuteWithShift(const SDNode *N,
469 CombineLevel Level) const override;
470
471 bool isDesirableToCommuteXorWithShift(const SDNode *N) const override;
472
473 bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override;
474
475 /// Return true if it is profitable to fold a pair of shifts into a mask.
476 bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override {
477 EVT VT = Y.getValueType();
478
479 if (VT.isVector())
480 return false;
481
482 return VT.getScalarSizeInBits() <= 32;
483 }
484
485 bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT,
486 unsigned SelectOpcode, SDValue X,
487 SDValue Y) const override;
488
489 bool preferIncOfAddToSubOfNot(EVT VT) const override;
490
491 bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;
492
493 bool isComplexDeinterleavingSupported() const override;
494 bool isComplexDeinterleavingOperationSupported(
495 ComplexDeinterleavingOperation Operation, Type *Ty) const override;
496
497 Value *createComplexDeinterleavingIR(
498 IRBuilderBase &B, ComplexDeinterleavingOperation OperationType,
499 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
500 Value *Accumulator = nullptr) const override;
501
502 bool useFPRegsForHalfType() const override { return true; }
503
504 protected:
505 std::pair<const TargetRegisterClass *, uint8_t>
506 findRepresentativeClass(const TargetRegisterInfo *TRI,
507 MVT VT) const override;
508
509 private:
510 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
511 /// make the right decision when generating code for different targets.
512 const ARMSubtarget *Subtarget;
513
514 const TargetRegisterInfo *RegInfo;
515
516 const InstrItineraryData *Itins;
517
518 // TODO: remove this, and have shouldInsertFencesForAtomic do the proper
519 // check.
520 bool InsertFencesForAtomic;
521
522 bool HasStandaloneRem = true;
523
524 void addTypeForNEON(MVT VT, MVT PromotedLdStVT);
525 void addDRTypeForNEON(MVT VT);
526 void addQRTypeForNEON(MVT VT);
527 std::pair<SDValue, SDValue> getARMXALUOOp(SDValue Op, SelectionDAG &DAG, SDValue &ARMcc) const;
528
529 using RegsToPassVector = SmallVector<std::pair<unsigned, SDValue>, 8>;
530
531 void PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG, SDValue Chain,
532 SDValue &Arg, RegsToPassVector &RegsToPass,
533 CCValAssign &VA, CCValAssign &NextVA,
534 SDValue &StackPtr,
535 SmallVectorImpl<SDValue> &MemOpChains,
536 bool IsTailCall,
537 int SPDiff) const;
538 SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
539 SDValue &Root, SelectionDAG &DAG,
540 const SDLoc &dl) const;
541
542 CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC,
543 bool isVarArg) const;
544 CCAssignFn *CCAssignFnForNode(CallingConv::ID CC, bool Return,
545 bool isVarArg) const;
546 std::pair<SDValue, MachinePointerInfo>
547 computeAddrForCallArg(const SDLoc &dl, SelectionDAG &DAG,
548 const CCValAssign &VA, SDValue StackPtr,
549 bool IsTailCall, int SPDiff) const;
550 ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src,
551 SDValue Dst,
552 ISD::ArgFlagsTy Flags) const;
553 SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
554 SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
555 SDValue LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
556 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG,
557 const ARMSubtarget *Subtarget) const;
558 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
559 const ARMSubtarget *Subtarget) const;
560 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
561 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
562 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
563 SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
564 SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const;
565 SDValue LowerGlobalAddressWindows(SDValue Op, SelectionDAG &DAG) const;
566 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
567 SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
568 SelectionDAG &DAG) const;
569 SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,
570 SelectionDAG &DAG,
571 TLSModel::Model model) const;
572 SDValue LowerGlobalTLSAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
573 SDValue LowerGlobalTLSAddressWindows(SDValue Op, SelectionDAG &DAG) const;
574 SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
575 SDValue LowerALUO(SDValue Op, SelectionDAG &DAG) const;
576 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
577 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
578 SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
579 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
580 SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
581 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
582 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
583 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
584 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
585 SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
586 SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
587 SDValue LowerSET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
588 SDValue LowerRESET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
589 SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG,
590 const ARMSubtarget *ST) const;
591 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
592 const ARMSubtarget *ST) const;
593 SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
594 SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
595 SDValue LowerDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed) const;
596 void ExpandDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed,
597 SmallVectorImpl<SDValue> &Results) const;
598 SDValue ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
599 const ARMSubtarget *Subtarget) const;
600 SDValue LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG, bool Signed,
601 SDValue &Chain) const;
602 SDValue LowerREM(SDNode *N, SelectionDAG &DAG) const;
603 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
604 SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
605 SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
606 SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
607 SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
608 SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
609 SDValue LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const;
610 void LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
611 SelectionDAG &DAG) const;
612 SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG,
613 const ARMSubtarget *Subtarget) const;
614 std::pair<SDValue, SDValue>
615 LowerAEABIUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
616 SDValue LowerAEABIUnalignedStore(SDValue Op, SelectionDAG &DAG) const;
617 SDValue LowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;
618 SDValue LowerCMP(SDValue Op, SelectionDAG &DAG) const;
619 SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
620 Register getRegisterByName(const char* RegName, LLT VT,
621 const MachineFunction &MF) const override;
622
623 SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
624 SmallVectorImpl<SDNode *> &Created) const override;
625
626 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
627 EVT VT) const override;
628
629 SDValue MoveToHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT, MVT ValVT,
630 SDValue Val) const;
631 SDValue MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT,
632 MVT ValVT, SDValue Val) const;
633
634 SDValue ReconstructShuffle(SDValue Op, SelectionDAG &DAG) const;
635
636 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
637 CallingConv::ID CallConv, bool isVarArg,
638 const SmallVectorImpl<ISD::InputArg> &Ins,
639 const SDLoc &dl, SelectionDAG &DAG,
640 SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
641 SDValue ThisVal, bool isCmseNSCall) const;
642
643 void initializeSplitCSR(MachineBasicBlock *Entry) const override;
644 void insertCopiesSplitCSR(
645 MachineBasicBlock *Entry,
646 const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;
647
648 bool splitValueIntoRegisterParts(
649 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
650 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
651 const override;
652
653 SDValue joinRegisterPartsIntoValue(
654 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
655 unsigned NumParts, MVT PartVT, EVT ValueVT,
656 std::optional<CallingConv::ID> CC) const override;
657
658 SDValue
659 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
660 const SmallVectorImpl<ISD::InputArg> &Ins,
661 const SDLoc &dl, SelectionDAG &DAG,
662 SmallVectorImpl<SDValue> &InVals) const override;
663
664 int StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, const SDLoc &dl,
665 SDValue &Chain, const Value *OrigArg,
666 unsigned InRegsParamRecordIdx, int ArgOffset,
667 unsigned ArgSize) const;
668
669 void VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
670 const SDLoc &dl, SDValue &Chain,
671 unsigned ArgOffset, unsigned TotalArgRegsSaveSize,
672 bool ForceMutable = false) const;
673
674 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
675 SmallVectorImpl<SDValue> &InVals) const override;
676
677 /// HandleByVal - Target-specific cleanup for ByVal support.
678 void HandleByVal(CCState *, unsigned &, Align) const override;
679
680 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
681 /// for tail call optimization. Targets which want to do tail call
682 /// optimization should implement this function.
683 bool IsEligibleForTailCallOptimization(
684 TargetLowering::CallLoweringInfo &CLI, CCState &CCInfo,
685 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const;
686
687 bool CanLowerReturn(CallingConv::ID CallConv,
688 MachineFunction &MF, bool isVarArg,
689 const SmallVectorImpl<ISD::OutputArg> &Outs,
690 LLVMContext &Context, const Type *RetTy) const override;
691
692 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
693 const SmallVectorImpl<ISD::OutputArg> &Outs,
694 const SmallVectorImpl<SDValue> &OutVals,
695 const SDLoc &dl, SelectionDAG &DAG) const override;
696
697 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
698
699 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
700
701 bool shouldConsiderGEPOffsetSplit() const override { return true; }
702
703 bool isUnsupportedFloatingType(EVT VT) const;
704
705 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
706
707 SDValue getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal, SDValue TrueVal,
708 SDValue ARMcc, SDValue Flags, SelectionDAG &DAG) const;
709 SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
710 SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const;
711 SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
712 const SDLoc &dl, bool Signaling = false) const;
713
714 SDValue OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const;
715
716 void SetupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
717 MachineBasicBlock *DispatchBB, int FI) const;
718
719 void EmitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *MBB) const;
720
721 MachineBasicBlock *EmitStructByval(MachineInstr &MI,
722 MachineBasicBlock *MBB) const;
723
724 MachineBasicBlock *EmitLowered__chkstk(MachineInstr &MI,
725 MachineBasicBlock *MBB) const;
726 MachineBasicBlock *EmitLowered__dbzchk(MachineInstr &MI,
727 MachineBasicBlock *MBB) const;
728 void addMVEVectorTypes(bool HasMVEFP);
729 void addAllExtLoads(const MVT From, const MVT To, LegalizeAction Action);
730 void setAllExpand(MVT VT);
731 };
732
733 enum VMOVModImmType {
734 VMOVModImm,
735 VMVNModImm,
736 MVEVMVNModImm,
737 OtherModImm
738 };
739
740 namespace ARM {
741
742 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
743 const TargetLibraryInfo *libInfo,
744 const LibcallLoweringInfo *libcallLowering);
745
746 } // end namespace ARM
747
748} // end namespace llvm
749
750#endif // LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
751