LLVM 23.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::CTTZ_ELTS:
52 assert(N->getOperand(0).getValueType() == N->getOperand(1).getValueType() &&
53 "Expected the general-predicate and mask to have matching types");
54 break;
55 case AArch64ISD::SADDWT:
56 case AArch64ISD::SADDWB:
57 case AArch64ISD::UADDWT:
58 case AArch64ISD::UADDWB: {
59 EVT VT = N->getValueType(0);
60 EVT Op0VT = N->getOperand(0).getValueType();
61 EVT Op1VT = N->getOperand(1).getValueType();
62 assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
63 VT.isInteger() && Op0VT.isInteger() && Op1VT.isInteger() &&
64 "Expected integer vectors!");
65 assert(VT == Op0VT &&
66 "Expected result and first input to have the same type!");
67 assert(Op0VT.getSizeInBits() == Op1VT.getSizeInBits() &&
68 "Expected vectors of equal size!");
69 assert(Op0VT.getVectorElementCount() * 2 == Op1VT.getVectorElementCount() &&
70 "Expected result vector and first input vector to have half the "
71 "lanes of the second input vector!");
72 break;
73 }
74 case AArch64ISD::SUNPKLO:
75 case AArch64ISD::SUNPKHI:
76 case AArch64ISD::UUNPKLO:
77 case AArch64ISD::UUNPKHI: {
78 EVT VT = N->getValueType(0);
79 EVT OpVT = N->getOperand(0).getValueType();
80 assert(OpVT.isVector() && VT.isVector() && OpVT.isInteger() &&
81 VT.isInteger() && "Expected integer vectors!");
82 assert(OpVT.getSizeInBits() == VT.getSizeInBits() &&
83 "Expected vectors of equal size!");
85 "Expected result vector with half the lanes of its input!");
86 break;
87 }
88 case AArch64ISD::TRN1:
89 case AArch64ISD::TRN2:
90 case AArch64ISD::UZP1:
91 case AArch64ISD::UZP2:
92 case AArch64ISD::ZIP1:
93 case AArch64ISD::ZIP2: {
94 EVT VT = N->getValueType(0);
95 EVT Op0VT = N->getOperand(0).getValueType();
96 EVT Op1VT = N->getOperand(1).getValueType();
97 assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
98 "Expected vectors!");
99 assert(VT == Op0VT && VT == Op1VT && "Expected matching vectors!");
100 break;
101 }
102 case AArch64ISD::RSHRNB_I: {
103 EVT VT = N->getValueType(0);
104 EVT Op0VT = N->getOperand(0).getValueType();
105 assert(VT.isVector() && VT.isInteger() &&
106 "Expected integer vector result type!");
107 assert(Op0VT.isVector() && Op0VT.isInteger() &&
108 "Expected first operand to be an integer vector!");
109 assert(VT.getSizeInBits() == Op0VT.getSizeInBits() &&
110 "Expected vectors of equal size!");
112 "Expected input vector with half the lanes of its result!");
113 assert(isa<ConstantSDNode>(N->getOperand(1)) &&
114 "Expected second operand to be a constant!");
115 break;
116 }
117 }
118#endif
119}
120
122 const SDLoc &DL, SDValue Chain,
123 SDValue Dst, SDValue SrcOrValue,
124 SDValue Size, Align DstAlign,
125 Align SrcAlign, bool isVolatile,
126 MachinePointerInfo DstPtrInfo,
127 MachinePointerInfo SrcPtrInfo) const {
128
129 // Get the constant size of the copy/set.
131 if (auto *C = dyn_cast<ConstantSDNode>(Size))
132 MemSize = LocationSize::precise(C->getZExtValue());
133
134 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
135 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
136
138
139 auto Vol =
141 auto DstFlags = MachineMemOperand::MOStore | Vol;
142 auto *DstOp =
143 MF.getMachineMemOperand(DstPtrInfo, DstFlags, MemSize, DstAlign);
144
145 if (IsSet) {
146 // Extend value to i64, if required.
147 if (SrcOrValue.getValueType() != MVT::i64)
148 SrcOrValue = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, SrcOrValue);
149 SDValue Ops[] = {Dst, Size, SrcOrValue, Chain};
150 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::Other};
151 MachineSDNode *Node = DAG.getMachineNode(Opcode, DL, ResultTys, Ops);
152 DAG.setNodeMemRefs(Node, {DstOp});
153 return SDValue(Node, 2);
154 } else {
155 SDValue Ops[] = {Dst, SrcOrValue, Size, Chain};
156 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::i64, MVT::Other};
157 MachineSDNode *Node = DAG.getMachineNode(Opcode, DL, ResultTys, Ops);
158
159 auto SrcFlags = MachineMemOperand::MOLoad | Vol;
160 auto *SrcOp =
161 MF.getMachineMemOperand(SrcPtrInfo, SrcFlags, MemSize, SrcAlign);
163 return SDValue(Node, 3);
164 }
165}
166
168 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op0, SDValue Op1,
169 SDValue Size, RTLIB::Libcall LC) const {
170 const AArch64Subtarget &STI =
172 const AArch64TargetLowering *TLI = STI.getTargetLowering();
174 Args.emplace_back(Op0, PointerType::getUnqual(*DAG.getContext()));
175
176 bool UsesResult = false;
177 RTLIB::Libcall NewLC;
178 switch (LC) {
179 case RTLIB::MEMCPY: {
180 NewLC = RTLIB::SC_MEMCPY;
181 Args.emplace_back(Op1, PointerType::getUnqual(*DAG.getContext()));
182 break;
183 }
184 case RTLIB::MEMMOVE: {
185 NewLC = RTLIB::SC_MEMMOVE;
186 Args.emplace_back(Op1, PointerType::getUnqual(*DAG.getContext()));
187 break;
188 }
189 case RTLIB::MEMSET: {
190 NewLC = RTLIB::SC_MEMSET;
191 Args.emplace_back(DAG.getZExtOrTrunc(Op1, DL, MVT::i32),
193 break;
194 }
195 case RTLIB::MEMCHR: {
196 UsesResult = true;
197 NewLC = RTLIB::SC_MEMCHR;
198 Args.emplace_back(DAG.getZExtOrTrunc(Op1, DL, MVT::i32),
200 break;
201 }
202 default:
203 return SDValue();
204 }
205
206 RTLIB::LibcallImpl NewLCImpl = DAG.getLibcalls().getLibcallImpl(NewLC);
207 if (NewLCImpl == RTLIB::Unsupported)
208 return SDValue();
209
210 EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
211 SDValue Symbol = DAG.getExternalSymbol(NewLCImpl, PointerVT);
212 Args.emplace_back(Size, DAG.getDataLayout().getIntPtrType(*DAG.getContext()));
213
217 DAG.getLibcalls().getLibcallImplCallingConv(NewLCImpl), RetTy, Symbol,
218 std::move(Args));
219
220 auto [Result, ChainOut] = TLI->LowerCallTo(CLI);
221 return UsesResult ? DAG.getMergeValues({Result, ChainOut}, DL) : ChainOut;
222}
223
225 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
226 SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile,
227 bool AlwaysInline, MachinePointerInfo DstPtrInfo,
228 MachinePointerInfo SrcPtrInfo) const {
229 const AArch64Subtarget &STI =
231
232 if (UseMOPS && STI.hasMOPS())
233 return EmitMOPS(AArch64::MOPSMemoryCopyPseudo, DAG, DL, Chain, Dst, Src,
234 Size, DstAlign, SrcAlign, isVolatile, DstPtrInfo,
235 SrcPtrInfo);
236
238 SMEAttrs Attrs = AFI->getSMEFnAttrs();
239 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody())
240 return EmitStreamingCompatibleMemLibCall(DAG, DL, Chain, Dst, Src, Size,
241 RTLIB::MEMCPY);
242 return SDValue();
243}
244
246 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
247 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
248 MachinePointerInfo DstPtrInfo) const {
249 const AArch64Subtarget &STI =
251
252 if (UseMOPS && STI.hasMOPS())
253 return EmitMOPS(AArch64::MOPSMemorySetPseudo, DAG, dl, Chain, Dst, Src,
254 Size, Alignment, Alignment, isVolatile, DstPtrInfo,
256
258 SMEAttrs Attrs = AFI->getSMEFnAttrs();
259 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody())
260 return EmitStreamingCompatibleMemLibCall(DAG, dl, Chain, Dst, Src, Size,
261 RTLIB::MEMSET);
262 return SDValue();
263}
264
266 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
267 SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile,
268 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
269 const AArch64Subtarget &STI =
271
272 if (UseMOPS && STI.hasMOPS())
273 return EmitMOPS(AArch64::MOPSMemoryMovePseudo, DAG, dl, Chain, Dst, Src,
274 Size, DstAlign, SrcAlign, isVolatile, DstPtrInfo,
275 SrcPtrInfo);
276
278 SMEAttrs Attrs = AFI->getSMEFnAttrs();
279 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody())
280 return EmitStreamingCompatibleMemLibCall(DAG, dl, Chain, Dst, Src, Size,
281 RTLIB::MEMMOVE);
282 return SDValue();
283}
284
286 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Src,
287 SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const {
289 SMEAttrs Attrs = AFI->getSMEFnAttrs();
290 if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody()) {
292 DAG, dl, Chain, Src, Char, Length, RTLIB::MEMCHR);
293 return std::make_pair(Result.getValue(0), Result.getValue(1));
294 }
295 return std::make_pair(SDValue(), SDValue());
296}
297
298static const int kSetTagLoopThreshold = 176;
299
301 SDValue Chain, SDValue Ptr, uint64_t ObjSize,
302 const MachineMemOperand *BaseMemOperand,
303 bool ZeroData) {
305 unsigned ObjSizeScaled = ObjSize / 16;
306
307 SDValue TagSrc = Ptr;
308 if (Ptr.getOpcode() == ISD::FrameIndex) {
309 int FI = cast<FrameIndexSDNode>(Ptr)->getIndex();
310 Ptr = DAG.getTargetFrameIndex(FI, MVT::i64);
311 // A frame index operand may end up as [SP + offset] => it is fine to use SP
312 // register as the tag source.
313 TagSrc = DAG.getRegister(AArch64::SP, MVT::i64);
314 }
315
316 const unsigned OpCode1 = ZeroData ? AArch64ISD::STZG : AArch64ISD::STG;
317 const unsigned OpCode2 = ZeroData ? AArch64ISD::STZ2G : AArch64ISD::ST2G;
318
319 SmallVector<SDValue, 8> OutChains;
320 unsigned OffsetScaled = 0;
321 while (OffsetScaled < ObjSizeScaled) {
322 if (ObjSizeScaled - OffsetScaled >= 2) {
323 SDValue AddrNode = DAG.getMemBasePlusOffset(
324 Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
326 OpCode2, dl, DAG.getVTList(MVT::Other),
327 {Chain, TagSrc, AddrNode},
328 MVT::v4i64,
329 MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16 * 2));
330 OffsetScaled += 2;
331 OutChains.push_back(St);
332 continue;
333 }
334
335 if (ObjSizeScaled - OffsetScaled > 0) {
336 SDValue AddrNode = DAG.getMemBasePlusOffset(
337 Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
339 OpCode1, dl, DAG.getVTList(MVT::Other),
340 {Chain, TagSrc, AddrNode},
341 MVT::v2i64,
342 MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16));
343 OffsetScaled += 1;
344 OutChains.push_back(St);
345 }
346 }
347
348 SDValue Res = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
349 return Res;
350}
351
353 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Addr,
354 SDValue Size, MachinePointerInfo DstPtrInfo, bool ZeroData) const {
355 uint64_t ObjSize = Size->getAsZExtVal();
356 assert(ObjSize % 16 == 0);
357
359 MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand(
360 DstPtrInfo, MachineMemOperand::MOStore, ObjSize, Align(16));
361
362 bool UseSetTagRangeLoop =
363 kSetTagLoopThreshold >= 0 && (int)ObjSize >= kSetTagLoopThreshold;
364 if (!UseSetTagRangeLoop)
365 return EmitUnrolledSetTag(DAG, dl, Chain, Addr, ObjSize, BaseMemOperand,
366 ZeroData);
367
368 const EVT ResTys[] = {MVT::i64, MVT::i64, MVT::Other};
369
370 unsigned Opcode;
371 if (Addr.getOpcode() == ISD::FrameIndex) {
372 int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
373 Addr = DAG.getTargetFrameIndex(FI, MVT::i64);
374 Opcode = ZeroData ? AArch64::STZGloop : AArch64::STGloop;
375 } else {
376 Opcode = ZeroData ? AArch64::STZGloop_wback : AArch64::STGloop_wback;
377 }
378 SDValue Ops[] = {DAG.getTargetConstant(ObjSize, dl, MVT::i64), Addr, Chain};
379 SDNode *St = DAG.getMachineNode(Opcode, dl, ResTys, Ops);
380
381 DAG.setNodeMemRefs(cast<MachineSDNode>(St), {BaseMemOperand});
382 return SDValue(St, 2);
383}
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...
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 EmitMOPS(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue SrcOrValue, SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const
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
SDValue EmitTargetCodeForMemmove(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, 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 DstAlign, Align SrcAlign, bool isVolatile, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const override
Emit target-specific code that performs a memcpy.
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.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
static LocationSize precise(uint64_t Value)
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
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)
const LibcallLoweringInfo & getLibcalls() const
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:309
@ 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:857
@ 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.
@ Length
Definition DWP.cpp:558
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:373
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
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)