LLVM 22.0.0git
AArch64SelectionDAGInfo.cpp
Go to the documentation of this file.
1//===-- AArch64SelectionDAGInfo.cpp - AArch64 SelectionDAG Info -----------===//
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 implements the AArch64SelectionDAGInfo class.
10//
11//===----------------------------------------------------------------------===//
12
15
16#define GET_SDNODE_DESC
17#include "AArch64GenSDNodeInfo.inc"
18#undef GET_SDNODE_DESC
19
20using namespace llvm;
21
22#define DEBUG_TYPE "aarch64-selectiondag-info"
23
24static cl::opt<bool>
25 LowerToSMERoutines("aarch64-lower-to-sme-routines", cl::Hidden,
26 cl::desc("Enable AArch64 SME memory operations "
27 "to lower to librt functions"),
28 cl::init(true));
29
30static cl::opt<bool> UseMOPS("aarch64-use-mops", cl::Hidden,
31 cl::desc("Enable AArch64 MOPS instructions "
32 "for memcpy/memset/memmove"),
33 cl::init(true));
34
37
39 const SDNode *N) const {
40 switch (N->getOpcode()) {
41 case AArch64ISD::WrapperLarge:
42 // operand #0 must have type i32, but has type i64
43 return;
44 }
45
47
48#ifndef NDEBUG
49 // Some additional checks not yet implemented by verifyTargetNode.
50 switch (N->getOpcode()) {
51 case AArch64ISD::SADDWT:
52 case AArch64ISD::SADDWB:
53 case AArch64ISD::UADDWT:
54 case AArch64ISD::UADDWB: {
55 EVT VT = N->getValueType(0);
56 EVT Op0VT = N->getOperand(0).getValueType();
57 EVT Op1VT = N->getOperand(1).getValueType();
58 assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
59 VT.isInteger() && Op0VT.isInteger() && Op1VT.isInteger() &&
60 "Expected integer vectors!");
61 assert(VT == Op0VT &&
62 "Expected result and first input to have the same type!");
63 assert(Op0VT.getSizeInBits() == Op1VT.getSizeInBits() &&
64 "Expected vectors of equal size!");
65 assert(Op0VT.getVectorElementCount() * 2 == Op1VT.getVectorElementCount() &&
66 "Expected result vector and first input vector to have half the "
67 "lanes of the second input vector!");
68 break;
69 }
70 case AArch64ISD::SUNPKLO:
71 case AArch64ISD::SUNPKHI:
72 case AArch64ISD::UUNPKLO:
73 case AArch64ISD::UUNPKHI: {
74 EVT VT = N->getValueType(0);
75 EVT OpVT = N->getOperand(0).getValueType();
76 assert(OpVT.isVector() && VT.isVector() && OpVT.isInteger() &&
77 VT.isInteger() && "Expected integer vectors!");
78 assert(OpVT.getSizeInBits() == VT.getSizeInBits() &&
79 "Expected vectors of equal size!");
81 "Expected result vector with half the lanes of its input!");
82 break;
83 }
84 case AArch64ISD::TRN1:
85 case AArch64ISD::TRN2:
86 case AArch64ISD::UZP1:
87 case AArch64ISD::UZP2:
88 case AArch64ISD::ZIP1:
89 case AArch64ISD::ZIP2: {
90 EVT VT = N->getValueType(0);
91 EVT Op0VT = N->getOperand(0).getValueType();
92 EVT Op1VT = N->getOperand(1).getValueType();
93 assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
94 "Expected vectors!");
95 assert(VT == Op0VT && VT == Op1VT && "Expected matching vectors!");
96 break;
97 }
98 case AArch64ISD::RSHRNB_I: {
99 EVT VT = N->getValueType(0);
100 EVT Op0VT = N->getOperand(0).getValueType();
101 assert(VT.isVector() && VT.isInteger() &&
102 "Expected integer vector result type!");
103 assert(Op0VT.isVector() && Op0VT.isInteger() &&
104 "Expected first operand to be an integer vector!");
105 assert(VT.getSizeInBits() == Op0VT.getSizeInBits() &&
106 "Expected vectors of equal size!");
108 "Expected input vector with half the lanes of its result!");
109 assert(isa<ConstantSDNode>(N->getOperand(1)) &&
110 "Expected second operand to be a constant!");
111 break;
112 }
113 }
114#endif
115}
116
118 const SDLoc &DL, SDValue Chain,
119 SDValue Dst, SDValue SrcOrValue,
120 SDValue Size, Align Alignment,
121 bool isVolatile,
122 MachinePointerInfo DstPtrInfo,
123 MachinePointerInfo SrcPtrInfo) const {
124
125 // Get the constant size of the copy/set.
126 uint64_t ConstSize = 0;
127 if (auto *C = dyn_cast<ConstantSDNode>(Size))
128 ConstSize = C->getZExtValue();
129
130 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
131 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
132
134
135 auto Vol =
137 auto DstFlags = MachineMemOperand::MOStore | Vol;
138 auto *DstOp =
139 MF.getMachineMemOperand(DstPtrInfo, DstFlags, ConstSize, Alignment);
140
141 if (IsSet) {
142 // Extend value to i64, if required.
143 if (SrcOrValue.getValueType() != MVT::i64)
144 SrcOrValue = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, SrcOrValue);
145 SDValue Ops[] = {Dst, Size, SrcOrValue, Chain};
146 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::Other};
147 MachineSDNode *Node = DAG.getMachineNode(Opcode, DL, ResultTys, Ops);
148 DAG.setNodeMemRefs(Node, {DstOp});
149 return SDValue(Node, 2);
150 } else {
151 SDValue Ops[] = {Dst, SrcOrValue, Size, Chain};
152 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::i64, MVT::Other};
153 MachineSDNode *Node = DAG.getMachineNode(Opcode, DL, ResultTys, Ops);
154
155 auto SrcFlags = MachineMemOperand::MOLoad | Vol;
156 auto *SrcOp =
157 MF.getMachineMemOperand(SrcPtrInfo, SrcFlags, ConstSize, Alignment);
159 return SDValue(Node, 3);
160 }
161}
162
164 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op0, SDValue Op1,
165 SDValue Size, RTLIB::Libcall LC) const {
166 const AArch64Subtarget &STI =
168 const AArch64TargetLowering *TLI = STI.getTargetLowering();
170 Args.emplace_back(Op0, PointerType::getUnqual(*DAG.getContext()));
171
172 bool UsesResult = false;
173 RTLIB::Libcall NewLC;
174 switch (LC) {
175 case RTLIB::MEMCPY: {
176 NewLC = RTLIB::SC_MEMCPY;
177 Args.emplace_back(Op1, PointerType::getUnqual(*DAG.getContext()));
178 break;
179 }
180 case RTLIB::MEMMOVE: {
181 NewLC = RTLIB::SC_MEMMOVE;
182 Args.emplace_back(Op1, PointerType::getUnqual(*DAG.getContext()));
183 break;
184 }
185 case RTLIB::MEMSET: {
186 NewLC = RTLIB::SC_MEMSET;
187 Args.emplace_back(DAG.getZExtOrTrunc(Op1, DL, MVT::i32),
189 break;
190 }
191 case RTLIB::MEMCHR: {
192 UsesResult = true;
193 NewLC = RTLIB::SC_MEMCHR;
194 Args.emplace_back(DAG.getZExtOrTrunc(Op1, DL, MVT::i32),
196 break;
197 }
198 default:
199 return SDValue();
200 }
201
202 EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
203 SDValue Symbol = DAG.getExternalSymbol(TLI->getLibcallName(NewLC), PointerVT);
204 Args.emplace_back(Size, DAG.getDataLayout().getIntPtrType(*DAG.getContext()));
205
209 TLI->getLibcallCallingConv(NewLC), RetTy, Symbol, std::move(Args));
210
211 auto [Result, ChainOut] = TLI->LowerCallTo(CLI);
212 return UsesResult ? DAG.getMergeValues({Result, ChainOut}, DL) : ChainOut;
213}
214
216 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
217 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
218 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
219 const AArch64Subtarget &STI =
221
222 if (UseMOPS && STI.hasMOPS())
223 return EmitMOPS(AArch64::MOPSMemoryCopyPseudo, DAG, DL, Chain, Dst, Src,
224 Size, Alignment, isVolatile, DstPtrInfo, SrcPtrInfo);
225
227 SMEAttrs Attrs = AFI->getSMEFnAttrs();
228 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody())
229 return EmitStreamingCompatibleMemLibCall(DAG, DL, Chain, Dst, Src, Size,
230 RTLIB::MEMCPY);
231 return SDValue();
232}
233
235 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
236 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
237 MachinePointerInfo DstPtrInfo) const {
238 const AArch64Subtarget &STI =
240
241 if (UseMOPS && STI.hasMOPS())
242 return EmitMOPS(AArch64::MOPSMemorySetPseudo, DAG, dl, Chain, Dst, Src,
243 Size, Alignment, isVolatile, DstPtrInfo,
245
247 SMEAttrs Attrs = AFI->getSMEFnAttrs();
248 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody())
249 return EmitStreamingCompatibleMemLibCall(DAG, dl, Chain, Dst, Src, Size,
250 RTLIB::MEMSET);
251 return SDValue();
252}
253
255 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
256 SDValue Size, Align Alignment, bool isVolatile,
257 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
258 const AArch64Subtarget &STI =
260
261 if (UseMOPS && STI.hasMOPS())
262 return EmitMOPS(AArch64::MOPSMemoryMovePseudo, DAG, dl, Chain, Dst, Src,
263 Size, Alignment, isVolatile, DstPtrInfo, SrcPtrInfo);
264
266 SMEAttrs Attrs = AFI->getSMEFnAttrs();
267 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody())
268 return EmitStreamingCompatibleMemLibCall(DAG, dl, Chain, Dst, Src, Size,
269 RTLIB::MEMMOVE);
270 return SDValue();
271}
272
274 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Src,
275 SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const {
277 SMEAttrs Attrs = AFI->getSMEFnAttrs();
278 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody()) {
280 DAG, dl, Chain, Src, Char, Length, RTLIB::MEMCHR);
281 return std::make_pair(Result.getValue(0), Result.getValue(1));
282 }
283 return std::make_pair(SDValue(), SDValue());
284}
285
286static const int kSetTagLoopThreshold = 176;
287
289 SDValue Chain, SDValue Ptr, uint64_t ObjSize,
290 const MachineMemOperand *BaseMemOperand,
291 bool ZeroData) {
293 unsigned ObjSizeScaled = ObjSize / 16;
294
295 SDValue TagSrc = Ptr;
296 if (Ptr.getOpcode() == ISD::FrameIndex) {
297 int FI = cast<FrameIndexSDNode>(Ptr)->getIndex();
298 Ptr = DAG.getTargetFrameIndex(FI, MVT::i64);
299 // A frame index operand may end up as [SP + offset] => it is fine to use SP
300 // register as the tag source.
301 TagSrc = DAG.getRegister(AArch64::SP, MVT::i64);
302 }
303
304 const unsigned OpCode1 = ZeroData ? AArch64ISD::STZG : AArch64ISD::STG;
305 const unsigned OpCode2 = ZeroData ? AArch64ISD::STZ2G : AArch64ISD::ST2G;
306
307 SmallVector<SDValue, 8> OutChains;
308 unsigned OffsetScaled = 0;
309 while (OffsetScaled < ObjSizeScaled) {
310 if (ObjSizeScaled - OffsetScaled >= 2) {
311 SDValue AddrNode = DAG.getMemBasePlusOffset(
312 Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
314 OpCode2, dl, DAG.getVTList(MVT::Other),
315 {Chain, TagSrc, AddrNode},
316 MVT::v4i64,
317 MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16 * 2));
318 OffsetScaled += 2;
319 OutChains.push_back(St);
320 continue;
321 }
322
323 if (ObjSizeScaled - OffsetScaled > 0) {
324 SDValue AddrNode = DAG.getMemBasePlusOffset(
325 Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
327 OpCode1, dl, DAG.getVTList(MVT::Other),
328 {Chain, TagSrc, AddrNode},
329 MVT::v2i64,
330 MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16));
331 OffsetScaled += 1;
332 OutChains.push_back(St);
333 }
334 }
335
336 SDValue Res = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
337 return Res;
338}
339
341 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Addr,
342 SDValue Size, MachinePointerInfo DstPtrInfo, bool ZeroData) const {
343 uint64_t ObjSize = Size->getAsZExtVal();
344 assert(ObjSize % 16 == 0);
345
347 MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand(
348 DstPtrInfo, MachineMemOperand::MOStore, ObjSize, Align(16));
349
350 bool UseSetTagRangeLoop =
351 kSetTagLoopThreshold >= 0 && (int)ObjSize >= kSetTagLoopThreshold;
352 if (!UseSetTagRangeLoop)
353 return EmitUnrolledSetTag(DAG, dl, Chain, Addr, ObjSize, BaseMemOperand,
354 ZeroData);
355
356 const EVT ResTys[] = {MVT::i64, MVT::i64, MVT::Other};
357
358 unsigned Opcode;
359 if (Addr.getOpcode() == ISD::FrameIndex) {
360 int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
361 Addr = DAG.getTargetFrameIndex(FI, MVT::i64);
362 Opcode = ZeroData ? AArch64::STZGloop : AArch64::STGloop;
363 } else {
364 Opcode = ZeroData ? AArch64::STZGloop_wback : AArch64::STGloop_wback;
365 }
366 SDValue Ops[] = {DAG.getTargetConstant(ObjSize, dl, MVT::i64), Addr, Chain};
367 SDNode *St = DAG.getMachineNode(Opcode, dl, ResTys, Ops);
368
369 DAG.setNodeMemRefs(cast<MachineSDNode>(St), {BaseMemOperand});
370 return SDValue(St, 2);
371}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Ptr, uint64_t ObjSize, const MachineMemOperand *BaseMemOperand, bool ZeroData)
static cl::opt< bool > UseMOPS("aarch64-use-mops", cl::Hidden, cl::desc("Enable AArch64 MOPS instructions " "for memcpy/memset/memmove"), cl::init(true))
static cl::opt< bool > LowerToSMERoutines("aarch64-lower-to-sme-routines", cl::Hidden, cl::desc("Enable AArch64 SME memory operations " "to lower to librt functions"), cl::init(true))
static const int kSetTagLoopThreshold
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
SDValue EmitMOPS(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue SrcOrValue, SDValue Size, Align Alignment, bool isVolatile, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const
SDValue EmitTargetCodeForMemmove(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVolatile, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memmove.
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memcpy.
void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override
Checks that the given target-specific node is valid. Aborts if it is not.
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo) const override
Emit target-specific code that performs a memset.
SDValue EmitStreamingCompatibleMemLibCall(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op0, SDValue Op1, SDValue Size, RTLIB::Libcall LC) const
SDValue EmitTargetCodeForSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, MachinePointerInfo DstPtrInfo, bool ZeroData) const override
std::pair< SDValue, SDValue > EmitTargetCodeForMemchr(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Src, SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memchr, in cases where that is faster than a libcall.
const AArch64TargetLowering * getTargetLowering() const override
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
An SDNode that represents everything that will be needed to construct a MachineInstr.
Class to represent pointers.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
SelectionDAGGenTargetInfo(const SDNodeInfo &GenNodeInfo)
void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override
Checks that the given target-specific node is valid. Aborts if it is not.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVMContext * getContext() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::vector< ArgListEntry > ArgListTy
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:296
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:847
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Length
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
ElementCount getVectorElementCount() const
Definition ValueTypes.h:350
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:373
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:168
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:152
This class contains a discriminated union of information about pointers in memory operands,...
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setChain(SDValue InChain)