LLVM 24.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
26
28 const SDNode *N) const {
29 switch (N->getOpcode()) {
30 case AArch64ISD::WrapperLarge:
31 // operand #0 must have type i32, but has type i64
32 return;
33 }
34
36
37#ifndef NDEBUG
38 // Some additional checks not yet implemented by verifyTargetNode.
39 switch (N->getOpcode()) {
40 case AArch64ISD::CTTZ_ELTS:
41 case AArch64ISD::CTTZ_ELTS_ZERO_POISON:
42 assert(N->getOperand(0).getValueType() == N->getOperand(1).getValueType() &&
43 "Expected the general-predicate and mask to have matching types");
44 break;
45 case AArch64ISD::SUNPKLO:
46 case AArch64ISD::SUNPKHI:
47 case AArch64ISD::UUNPKLO:
48 case AArch64ISD::UUNPKHI: {
49 EVT VT = N->getValueType(0);
50 EVT OpVT = N->getOperand(0).getValueType();
51 assert(OpVT.isVector() && VT.isVector() && OpVT.isInteger() &&
52 VT.isInteger() && "Expected integer vectors!");
53 assert(OpVT.getSizeInBits() == VT.getSizeInBits() &&
54 "Expected vectors of equal size!");
56 "Expected result vector with half the lanes of its input!");
57 break;
58 }
59 case AArch64ISD::TRN1:
60 case AArch64ISD::TRN2:
61 case AArch64ISD::UZP1:
62 case AArch64ISD::UZP2:
63 case AArch64ISD::ZIP1:
64 case AArch64ISD::ZIP2: {
65 EVT VT = N->getValueType(0);
66 EVT Op0VT = N->getOperand(0).getValueType();
67 EVT Op1VT = N->getOperand(1).getValueType();
68 assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
69 "Expected vectors!");
70 assert(VT == Op0VT && VT == Op1VT && "Expected matching vectors!");
71 break;
72 }
73 case AArch64ISD::RSHRNB_I: {
74 EVT VT = N->getValueType(0);
75 EVT Op0VT = N->getOperand(0).getValueType();
76 assert(VT.isVector() && VT.isInteger() &&
77 "Expected integer vector result type!");
78 assert(Op0VT.isVector() && Op0VT.isInteger() &&
79 "Expected first operand to be an integer vector!");
80 assert(VT.getSizeInBits() == Op0VT.getSizeInBits() &&
81 "Expected vectors of equal size!");
83 "Expected input vector with half the lanes of its result!");
84 assert(isa<ConstantSDNode>(N->getOperand(1)) &&
85 "Expected second operand to be a constant!");
86 break;
87 }
88 }
89#endif
90}
91
93 const SDLoc &DL, SDValue Chain,
94 SDValue Dst, SDValue SrcOrValue,
95 SDValue Size, Align DstAlign,
96 Align SrcAlign, bool isVolatile,
97 MachinePointerInfo DstPtrInfo,
98 MachinePointerInfo SrcPtrInfo) const {
99
100 // Get the constant size of the copy/set.
102 if (auto *C = dyn_cast<ConstantSDNode>(Size))
103 MemSize = LocationSize::precise(C->getZExtValue());
104
105 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
106 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
107
109
110 auto Vol =
112 auto DstFlags = MachineMemOperand::MOStore | Vol;
113 auto *DstOp =
114 MF.getMachineMemOperand(DstPtrInfo, DstFlags, MemSize, DstAlign);
115
116 if (IsSet) {
117 // Extend value to i64, if required.
118 if (SrcOrValue.getValueType() != MVT::i64)
119 SrcOrValue = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, SrcOrValue);
120 SDValue Ops[] = {Dst, Size, SrcOrValue, Chain};
121 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::Other};
122 MachineSDNode *Node = DAG.getMachineNode(Opcode, DL, ResultTys, Ops);
123 DAG.setNodeMemRefs(Node, {DstOp});
124 return SDValue(Node, 2);
125 } else {
126 SDValue Ops[] = {Dst, SrcOrValue, Size, Chain};
127 const EVT ResultTys[] = {MVT::i64, MVT::i64, MVT::i64, MVT::Other};
128 MachineSDNode *Node = DAG.getMachineNode(Opcode, DL, ResultTys, Ops);
129
130 auto SrcFlags = MachineMemOperand::MOLoad | Vol;
131 auto *SrcOp =
132 MF.getMachineMemOperand(SrcPtrInfo, SrcFlags, MemSize, SrcAlign);
134 return SDValue(Node, 3);
135 }
136}
137
139 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op0, SDValue Op1,
140 SDValue Size, RTLIB::Libcall LC) const {
141 const AArch64Subtarget &STI =
143 const AArch64TargetLowering *TLI = STI.getTargetLowering();
145 Args.emplace_back(Op0, PointerType::getUnqual(*DAG.getContext()));
146
147 bool UsesResult = false;
148 RTLIB::Libcall NewLC;
149 switch (LC) {
150 case RTLIB::MEMCPY: {
151 NewLC = RTLIB::SC_MEMCPY;
152 Args.emplace_back(Op1, PointerType::getUnqual(*DAG.getContext()));
153 break;
154 }
155 case RTLIB::MEMMOVE: {
156 NewLC = RTLIB::SC_MEMMOVE;
157 Args.emplace_back(Op1, PointerType::getUnqual(*DAG.getContext()));
158 break;
159 }
160 case RTLIB::MEMSET: {
161 NewLC = RTLIB::SC_MEMSET;
162 Args.emplace_back(DAG.getZExtOrTrunc(Op1, DL, MVT::i32),
164 break;
165 }
166 case RTLIB::MEMCHR: {
167 UsesResult = true;
168 NewLC = RTLIB::SC_MEMCHR;
169 Args.emplace_back(DAG.getZExtOrTrunc(Op1, DL, MVT::i32),
171 break;
172 }
173 default:
174 return SDValue();
175 }
176
177 RTLIB::LibcallImpl NewLCImpl = DAG.getLibcalls().getLibcallImpl(NewLC);
178 if (NewLCImpl == RTLIB::Unsupported)
179 return SDValue();
180
181 EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
182 SDValue Symbol = DAG.getExternalSymbol(NewLCImpl, PointerVT);
183 Args.emplace_back(Size, DAG.getDataLayout().getIntPtrType(*DAG.getContext()));
184
188 DAG.getLibcalls().getLibcallImplCallingConv(NewLCImpl), RetTy, Symbol,
189 std::move(Args));
190
191 auto [Result, ChainOut] = TLI->LowerCallTo(CLI);
192 return UsesResult ? DAG.getMergeValues({Result, ChainOut}, DL) : ChainOut;
193}
194
196 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
197 SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile,
198 bool AlwaysInline, MachinePointerInfo DstPtrInfo,
199 MachinePointerInfo SrcPtrInfo) const {
200 const AArch64Subtarget &STI =
202
203 if (STI.getCLOpts().use_mops && STI.hasMOPS())
204 return EmitMOPS(AArch64::MOPSMemoryCopyPseudo, DAG, DL, Chain, Dst, Src,
205 Size, DstAlign, SrcAlign, isVolatile, DstPtrInfo,
206 SrcPtrInfo);
207
209 SMEAttrs Attrs = AFI->getSMEFnAttrs();
210 if (STI.getCLOpts().lower_to_sme_routines &&
211 !Attrs.hasNonStreamingInterfaceAndBody())
212 return EmitStreamingCompatibleMemLibCall(DAG, DL, Chain, Dst, Src, Size,
213 RTLIB::MEMCPY);
214 return SDValue();
215}
216
218 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
219 SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
220 MachinePointerInfo DstPtrInfo) const {
221 const AArch64Subtarget &STI =
223
224 if (STI.getCLOpts().use_mops && STI.hasMOPS())
225 return EmitMOPS(AArch64::MOPSMemorySetPseudo, DAG, dl, Chain, Dst, Src,
226 Size, Alignment, Alignment, isVolatile, DstPtrInfo,
228
230 SMEAttrs Attrs = AFI->getSMEFnAttrs();
231 if (STI.getCLOpts().lower_to_sme_routines &&
232 !Attrs.hasNonStreamingInterfaceAndBody())
233 return EmitStreamingCompatibleMemLibCall(DAG, dl, Chain, Dst, Src, Size,
234 RTLIB::MEMSET);
235 return SDValue();
236}
237
239 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
240 SDValue Size, Align DstAlign, Align SrcAlign, bool isVolatile,
241 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
242 const AArch64Subtarget &STI =
244
245 if (STI.getCLOpts().use_mops && STI.hasMOPS())
246 return EmitMOPS(AArch64::MOPSMemoryMovePseudo, DAG, dl, Chain, Dst, Src,
247 Size, DstAlign, SrcAlign, isVolatile, DstPtrInfo,
248 SrcPtrInfo);
249
251 SMEAttrs Attrs = AFI->getSMEFnAttrs();
252 if (STI.getCLOpts().lower_to_sme_routines &&
253 !Attrs.hasNonStreamingInterfaceAndBody())
254 return EmitStreamingCompatibleMemLibCall(DAG, dl, Chain, Dst, Src, Size,
255 RTLIB::MEMMOVE);
256 return SDValue();
257}
258
260 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Src,
261 SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const {
263 SMEAttrs Attrs = AFI->getSMEFnAttrs();
264 if (DAG.getSubtarget<AArch64Subtarget>().getCLOpts().lower_to_sme_routines &&
265 !Attrs.hasNonStreamingInterfaceAndBody()) {
267 DAG, dl, Chain, Src, Char, Length, RTLIB::MEMCHR);
268 return std::make_pair(Result.getValue(0), Result.getValue(1));
269 }
270 return std::make_pair(SDValue(), SDValue());
271}
272
273static const int kSetTagLoopThreshold = 176;
274
276 SDValue Chain, SDValue Ptr, uint64_t ObjSize,
277 const MachineMemOperand *BaseMemOperand,
278 bool ZeroData) {
280 unsigned ObjSizeScaled = ObjSize / 16;
281
282 SDValue TagSrc = Ptr;
283 if (Ptr.getOpcode() == ISD::FrameIndex) {
284 int FI = cast<FrameIndexSDNode>(Ptr)->getIndex();
285 Ptr = DAG.getTargetFrameIndex(FI, MVT::i64);
286 // A frame index operand may end up as [SP + offset] => it is fine to use SP
287 // register as the tag source.
288 TagSrc = DAG.getRegister(AArch64::SP, MVT::i64);
289 }
290
291 const unsigned OpCode1 = ZeroData ? AArch64ISD::STZG : AArch64ISD::STG;
292 const unsigned OpCode2 = ZeroData ? AArch64ISD::STZ2G : AArch64ISD::ST2G;
293
294 SmallVector<SDValue, 8> OutChains;
295 unsigned OffsetScaled = 0;
296 while (OffsetScaled < ObjSizeScaled) {
297 if (ObjSizeScaled - OffsetScaled >= 2) {
298 SDValue AddrNode = DAG.getMemBasePlusOffset(
299 Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
301 OpCode2, dl, DAG.getVTList(MVT::Other),
302 {Chain, TagSrc, AddrNode},
303 MVT::v4i64,
304 MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16 * 2));
305 OffsetScaled += 2;
306 OutChains.push_back(St);
307 continue;
308 }
309
310 if (ObjSizeScaled - OffsetScaled > 0) {
311 SDValue AddrNode = DAG.getMemBasePlusOffset(
312 Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
314 OpCode1, dl, DAG.getVTList(MVT::Other),
315 {Chain, TagSrc, AddrNode},
316 MVT::v2i64,
317 MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16));
318 OffsetScaled += 1;
319 OutChains.push_back(St);
320 }
321 }
322
323 SDValue Res = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
324 return Res;
325}
326
328 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Addr,
329 SDValue Size, MachinePointerInfo DstPtrInfo, bool ZeroData) const {
330 uint64_t ObjSize = Size->getAsZExtVal();
331 assert(ObjSize % 16 == 0);
332
334 MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand(
335 DstPtrInfo, MachineMemOperand::MOStore, ObjSize, Align(16));
336
337 bool UseSetTagRangeLoop =
338 kSetTagLoopThreshold >= 0 && (int)ObjSize >= kSetTagLoopThreshold;
339 if (!UseSetTagRangeLoop)
340 return EmitUnrolledSetTag(DAG, dl, Chain, Addr, ObjSize, BaseMemOperand,
341 ZeroData);
342
343 const EVT ResTys[] = {MVT::i64, MVT::i64, MVT::Other};
344
345 unsigned Opcode;
346 if (Addr.getOpcode() == ISD::FrameIndex) {
347 int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
348 Addr = DAG.getTargetFrameIndex(FI, MVT::i64);
349 Opcode = ZeroData ? AArch64::STZGloop : AArch64::STGloop;
350 } else {
351 Opcode = ZeroData ? AArch64::STZGloop_wback : AArch64::STGloop_wback;
352 }
353 SDValue Ops[] = {DAG.getTargetConstant(ObjSize, dl, MVT::i64), Addr, Chain};
354 SDNode *St = DAG.getMachineNode(Opcode, dl, ResTys, Ops);
355
356 DAG.setNodeMemRefs(cast<MachineSDNode>(St), {BaseMemOperand});
357 return SDValue(St, 2);
358}
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 const int kSetTagLoopThreshold
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 AArch64Options & getCLOpts() const
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
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...
const TargetSubtargetInfo & getSubtarget() const
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:339
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:871
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
This is an optimization pass for GlobalISel generic memory operations.
@ Length
Definition DWP.cpp:577
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)