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 the cost of EXTRACT_SUBVECTOR for this result type with this
332 /// index.
333 ExtractSubvectorCost getExtractSubvectorCost(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(ExceptionHandling EH,
356 const Constant *PersonalityFn) const override;
357
358 /// If a physical register, this returns the register that receives the
359 /// exception typeid on entry to a landing pad.
360 Register
361 getExceptionSelectorRegister(ExceptionHandling EH,
362 const Constant *PersonalityFn) const override;
363
364 Instruction *makeDMB(IRBuilderBase &Builder, ARM_MB::MemBOpt Domain) const;
365 Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,
366 AtomicOrdering Ord) const override;
367 Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,
368 AtomicOrdering Ord) const override;
369
370 void
371 emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const override;
372
373 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
374 AtomicOrdering Ord) const override;
375 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
376 AtomicOrdering Ord) const override;
377
378 unsigned getMaxSupportedInterleaveFactor() const override;
379
380 bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
381 ArrayRef<ShuffleVectorInst *> Shuffles,
382 ArrayRef<unsigned> Indices, unsigned Factor,
383 const APInt &GapMask) const override;
384 bool lowerInterleavedStore(Instruction *Store, Value *Mask,
385 ShuffleVectorInst *SVI, unsigned Factor,
386 const APInt &GapMask) const override;
387
388 bool shouldInsertFencesForAtomic(const Instruction *I) const override;
389 TargetLoweringBase::AtomicExpansionKind
390 shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
391 TargetLoweringBase::AtomicExpansionKind
392 shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
393 TargetLoweringBase::AtomicExpansionKind
394 shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
395 TargetLoweringBase::AtomicExpansionKind
396 shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override;
397
398 bool useLoadStackGuardNode(const Module &M) const override;
399
400 void
401 insertSSPDeclarations(Module &M,
402 const LibcallLoweringInfo &Libcalls) const override;
403
404 bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
405 unsigned &Cost) const override;
406
407 bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
408 const APInt &DemandedElts,
409 const SelectionDAG &DAG,
410 UndefPoisonKind Kind,
411 bool ConsiderFlags,
412 unsigned Depth) const override;
413
414 bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
415 const MachineFunction &MF) const override {
416 // Do not merge to larger than i32.
417 return (MemVT.getSizeInBits() <= 32);
418 }
419
420 bool isCheapToSpeculateCttz(Type *Ty) const override;
421 bool isCheapToSpeculateCtlz(Type *Ty) const override;
422
423 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
424 return VT.isScalarInteger();
425 }
426
427 bool supportSwiftError() const override {
428 return true;
429 }
430
431 bool supportSplitCSR(MachineFunction *MF) const override {
432 return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&
433 MF->getFunction().hasFnAttribute(Kind: Attribute::NoUnwind);
434 }
435
436 bool hasStandaloneRem(EVT VT) const override {
437 return HasStandaloneRem;
438 }
439
440 ShiftLegalizationStrategy
441 preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
442 unsigned ExpansionFactor) const override;
443
444 CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC,
445 bool isVarArg) const;
446 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool isVarArg) const;
447 CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool isVarArg) const;
448
449 /// Returns true if \p VecTy is a legal interleaved access type. This
450 /// function checks the vector element type and the overall width of the
451 /// vector.
452 bool isLegalInterleavedAccessType(unsigned Factor, FixedVectorType *VecTy,
453 Align Alignment,
454 const DataLayout &DL) const;
455
456 bool isMulAddWithConstProfitable(SDValue AddNode,
457 SDValue ConstNode) const override;
458
459 bool alignLoopsWithOptSize() const override;
460
461 /// Returns the number of interleaved accesses that will be generated when
462 /// lowering accesses of the given type.
463 unsigned getNumInterleavedAccesses(VectorType *VecTy,
464 const DataLayout &DL) const;
465
466 void finalizeLowering(MachineFunction &MF) const override;
467
468 /// Return the correct alignment for the current calling convention.
469 Align getABIAlignmentForCallingConv(Type *ArgTy,
470 const DataLayout &DL) const override;
471
472 bool isDesirableToCommuteWithShift(const SDNode *N,
473 CombineLevel Level) const override;
474
475 bool isDesirableToCommuteXorWithShift(const SDNode *N) const override;
476
477 bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override;
478
479 /// Return true if it is profitable to fold a pair of shifts into a mask.
480 bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override {
481 EVT VT = Y.getValueType();
482
483 if (VT.isVector())
484 return false;
485
486 return VT.getScalarSizeInBits() <= 32;
487 }
488
489 bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT,
490 unsigned SelectOpcode, SDValue X,
491 SDValue Y) const override;
492
493 bool preferIncOfAddToSubOfNot(EVT VT) const override;
494
495 bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;
496
497 bool isComplexDeinterleavingSupported() const override;
498 bool isComplexDeinterleavingOperationSupported(
499 ComplexDeinterleavingOperation Operation, Type *Ty) const override;
500
501 Value *createComplexDeinterleavingIR(
502 IRBuilderBase &B, ComplexDeinterleavingOperation OperationType,
503 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
504 Value *Accumulator = nullptr) const override;
505
506 bool useFPRegsForHalfType() const override { return true; }
507
508 protected:
509 std::pair<const TargetRegisterClass *, uint8_t>
510 findRepresentativeClass(const TargetRegisterInfo *TRI,
511 MVT VT) const override;
512
513 private:
514 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
515 /// make the right decision when generating code for different targets.
516 const ARMSubtarget *Subtarget;
517
518 const TargetRegisterInfo *RegInfo;
519
520 const InstrItineraryData *Itins;
521
522 // TODO: remove this, and have shouldInsertFencesForAtomic do the proper
523 // check.
524 bool InsertFencesForAtomic;
525
526 bool HasStandaloneRem = true;
527
528 void addTypeForNEON(MVT VT, MVT PromotedLdStVT);
529 void addDRTypeForNEON(MVT VT);
530 void addQRTypeForNEON(MVT VT);
531 std::pair<SDValue, SDValue> getARMXALUOOp(SDValue Op, SelectionDAG &DAG, SDValue &ARMcc) const;
532
533 using RegsToPassVector = SmallVector<std::pair<unsigned, SDValue>, 8>;
534
535 void PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG, SDValue Chain,
536 SDValue &Arg, RegsToPassVector &RegsToPass,
537 CCValAssign &VA, CCValAssign &NextVA,
538 SDValue &StackPtr,
539 SmallVectorImpl<SDValue> &MemOpChains,
540 bool IsTailCall,
541 int SPDiff) const;
542 SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
543 SDValue &Root, SelectionDAG &DAG,
544 const SDLoc &dl) const;
545
546 CCAssignFn *CCAssignFnForNode(CallingConv::ID CC, bool Return,
547 bool isVarArg) const;
548 std::pair<SDValue, MachinePointerInfo>
549 computeAddrForCallArg(const SDLoc &dl, SelectionDAG &DAG,
550 const CCValAssign &VA, SDValue StackPtr,
551 bool IsTailCall, int SPDiff) const;
552 ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src,
553 SDValue Dst,
554 ISD::ArgFlagsTy Flags) const;
555 SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
556 SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
557 SDValue LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
558 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG,
559 const ARMSubtarget *Subtarget) const;
560 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
561 const ARMSubtarget *Subtarget) const;
562 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
563 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
564 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
565 SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
566 SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const;
567 SDValue LowerGlobalAddressWindows(SDValue Op, SelectionDAG &DAG) const;
568 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
569 SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
570 SelectionDAG &DAG) const;
571 SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,
572 SelectionDAG &DAG,
573 TLSModel::Model model) const;
574 SDValue LowerGlobalTLSAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
575 SDValue LowerGlobalTLSAddressWindows(SDValue Op, SelectionDAG &DAG) const;
576 SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
577 SDValue LowerALUO(SDValue Op, SelectionDAG &DAG) const;
578 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
579 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
580 SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
581 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
582 SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
583 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
584 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
585 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
586 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
587 SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
588 SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
589 SDValue LowerSET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
590 SDValue LowerRESET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
591 SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG,
592 const ARMSubtarget *ST) const;
593 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
594 const ARMSubtarget *ST) const;
595 SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
596 SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
597 SDValue LowerDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed) const;
598 void ExpandDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed,
599 SmallVectorImpl<SDValue> &Results) const;
600 SDValue ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
601 const ARMSubtarget *Subtarget) const;
602 SDValue LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG, bool Signed,
603 SDValue &Chain) const;
604 SDValue LowerREM(SDNode *N, SelectionDAG &DAG) const;
605 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
606 SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
607 SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
608 SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
609 SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
610 SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
611 SDValue LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const;
612 void LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
613 SelectionDAG &DAG) const;
614 SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG,
615 const ARMSubtarget *Subtarget) const;
616 std::pair<SDValue, SDValue>
617 LowerAEABIUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
618 SDValue LowerAEABIUnalignedStore(SDValue Op, SelectionDAG &DAG) const;
619 SDValue LowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;
620 SDValue LowerCMP(SDValue Op, SelectionDAG &DAG) const;
621 SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
622 Register getRegisterByName(const char* RegName, LLT VT,
623 const MachineFunction &MF) const override;
624
625 SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
626 SmallVectorImpl<SDNode *> &Created) const override;
627
628 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
629 EVT VT) const override;
630
631 SDValue MoveToHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT, MVT ValVT,
632 SDValue Val) const;
633 SDValue MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT,
634 MVT ValVT, SDValue Val) const;
635
636 SDValue ReconstructShuffle(SDValue Op, SelectionDAG &DAG) const;
637
638 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
639 CallingConv::ID CallConv, bool isVarArg,
640 const SmallVectorImpl<ISD::InputArg> &Ins,
641 const SDLoc &dl, SelectionDAG &DAG,
642 SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
643 SDValue ThisVal, bool isCmseNSCall) const;
644
645 void initializeSplitCSR(MachineBasicBlock *Entry) const override;
646 void insertCopiesSplitCSR(
647 MachineBasicBlock *Entry,
648 const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;
649
650 bool splitValueIntoRegisterParts(
651 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
652 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
653 const override;
654
655 SDValue joinRegisterPartsIntoValue(
656 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
657 unsigned NumParts, MVT PartVT, EVT ValueVT,
658 std::optional<CallingConv::ID> CC) const override;
659
660 SDValue
661 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
662 const SmallVectorImpl<ISD::InputArg> &Ins,
663 const SDLoc &dl, SelectionDAG &DAG,
664 SmallVectorImpl<SDValue> &InVals) const override;
665
666 int StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, const SDLoc &dl,
667 SDValue &Chain, const Value *OrigArg,
668 unsigned InRegsParamRecordIdx, int ArgOffset,
669 unsigned ArgSize) const;
670
671 void VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
672 const SDLoc &dl, SDValue &Chain,
673 unsigned ArgOffset, unsigned TotalArgRegsSaveSize,
674 bool ForceMutable = false) const;
675
676 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
677 SmallVectorImpl<SDValue> &InVals) const override;
678
679 /// HandleByVal - Target-specific cleanup for ByVal support.
680 void HandleByVal(CCState *, unsigned &, Align) const override;
681
682 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
683 /// for tail call optimization. Targets which want to do tail call
684 /// optimization should implement this function.
685 bool IsEligibleForTailCallOptimization(
686 TargetLowering::CallLoweringInfo &CLI, CCState &CCInfo,
687 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const;
688
689 bool CanLowerReturn(CallingConv::ID CallConv,
690 MachineFunction &MF, bool isVarArg,
691 const SmallVectorImpl<ISD::OutputArg> &Outs,
692 LLVMContext &Context, const Type *RetTy) const override;
693
694 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
695 const SmallVectorImpl<ISD::OutputArg> &Outs,
696 const SmallVectorImpl<SDValue> &OutVals,
697 const SDLoc &dl, SelectionDAG &DAG) const override;
698
699 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
700
701 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
702
703 bool shouldConsiderGEPOffsetSplit() const override { return true; }
704
705 bool isUnsupportedFloatingType(EVT VT) const;
706
707 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
708
709 SDValue getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal, SDValue TrueVal,
710 SDValue ARMcc, SDValue Flags, SelectionDAG &DAG) const;
711 SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
712 SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const;
713 SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
714 const SDLoc &dl, bool Signaling = false) const;
715
716 SDValue OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const;
717
718 void SetupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
719 MachineBasicBlock *DispatchBB, int FI) const;
720
721 void EmitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *MBB) const;
722
723 MachineBasicBlock *EmitStructByval(MachineInstr &MI,
724 MachineBasicBlock *MBB) const;
725
726 MachineBasicBlock *EmitLowered__chkstk(MachineInstr &MI,
727 MachineBasicBlock *MBB) const;
728 MachineBasicBlock *EmitLowered__dbzchk(MachineInstr &MI,
729 MachineBasicBlock *MBB) const;
730 void addMVEVectorTypes(bool HasMVEFP);
731 void addAllExtLoads(const MVT From, const MVT To, LegalizeAction Action);
732 void setAllExpand(MVT VT);
733 };
734
735 enum VMOVModImmType {
736 VMOVModImm,
737 VMVNModImm,
738 MVEVMVNModImm,
739 OtherModImm
740 };
741
742 namespace ARM {
743
744 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
745 const TargetLibraryInfo *libInfo,
746 const LibcallLoweringInfo *libcallLowering);
747
748 } // end namespace ARM
749
750} // end namespace llvm
751
752#endif // LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
753