LLVM 23.0.0git
RISCVInterleavedAccess.cpp
Go to the documentation of this file.
1//===-- RISCVInterleavedAccess.cpp - RISC-V Interleaved Access Transform --===//
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// Functions and callbacks related to the InterleavedAccessPass.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCV.h"
14#include "RISCVISelLowering.h"
15#include "RISCVSubtarget.h"
19#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/IntrinsicsRISCV.h"
22#include "llvm/IR/Module.h"
24
25using namespace llvm;
26
28 VectorType *VTy, unsigned Factor, Align Alignment, unsigned AddrSpace,
29 const DataLayout &DL) const {
30 EVT VT = getValueType(DL, VTy);
31 // Don't lower vlseg/vsseg for vector types that can't be split.
32 if (!isTypeLegal(VT))
33 return false;
34
36 !allowsMemoryAccessForAlignment(VTy->getContext(), DL, VT, AddrSpace,
37 Alignment))
38 return false;
39
40 MVT ContainerVT = VT.getSimpleVT();
41
42 if (auto *FVTy = dyn_cast<FixedVectorType>(VTy)) {
43 if (!Subtarget.useRVVForFixedLengthVectors())
44 return false;
45 // Sometimes the interleaved access pass picks up splats as interleaves of
46 // one element. Don't lower these.
47 if (FVTy->getNumElements() < 2)
48 return false;
49
51 }
52
53 // Need to make sure that EMUL * NFIELDS ≤ 8
54 auto [LMUL, Fractional] = RISCVVType::decodeVLMUL(getLMUL(ContainerVT));
55 if (Fractional)
56 return true;
57 return Factor * LMUL <= 8;
58}
59
61 Intrinsic::riscv_seg2_load_mask, Intrinsic::riscv_seg3_load_mask,
62 Intrinsic::riscv_seg4_load_mask, Intrinsic::riscv_seg5_load_mask,
63 Intrinsic::riscv_seg6_load_mask, Intrinsic::riscv_seg7_load_mask,
64 Intrinsic::riscv_seg8_load_mask};
65
67 Intrinsic::riscv_sseg2_load_mask, Intrinsic::riscv_sseg3_load_mask,
68 Intrinsic::riscv_sseg4_load_mask, Intrinsic::riscv_sseg5_load_mask,
69 Intrinsic::riscv_sseg6_load_mask, Intrinsic::riscv_sseg7_load_mask,
70 Intrinsic::riscv_sseg8_load_mask};
71
73 Intrinsic::riscv_vlsseg2_mask, Intrinsic::riscv_vlsseg3_mask,
74 Intrinsic::riscv_vlsseg4_mask, Intrinsic::riscv_vlsseg5_mask,
75 Intrinsic::riscv_vlsseg6_mask, Intrinsic::riscv_vlsseg7_mask,
76 Intrinsic::riscv_vlsseg8_mask};
77
79 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
80 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
81 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
82 Intrinsic::riscv_vlseg8_mask};
83
85 Intrinsic::riscv_seg2_store_mask, Intrinsic::riscv_seg3_store_mask,
86 Intrinsic::riscv_seg4_store_mask, Intrinsic::riscv_seg5_store_mask,
87 Intrinsic::riscv_seg6_store_mask, Intrinsic::riscv_seg7_store_mask,
88 Intrinsic::riscv_seg8_store_mask};
89
91 Intrinsic::riscv_sseg2_store_mask, Intrinsic::riscv_sseg3_store_mask,
92 Intrinsic::riscv_sseg4_store_mask, Intrinsic::riscv_sseg5_store_mask,
93 Intrinsic::riscv_sseg6_store_mask, Intrinsic::riscv_sseg7_store_mask,
94 Intrinsic::riscv_sseg8_store_mask};
95
97 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
98 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
99 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
100 Intrinsic::riscv_vsseg8_mask};
101
102static bool isMultipleOfN(const Value *V, const DataLayout &DL, unsigned N) {
103 assert(N);
104 if (N == 1)
105 return true;
106
107 using namespace PatternMatch;
108 // Right now we're only recognizing the simplest pattern.
109 uint64_t C;
112 C && C % N == 0)
113 return true;
114
115 if (isPowerOf2_32(N)) {
117 return KB.countMinTrailingZeros() >= Log2_32(N);
118 }
119
120 return false;
121}
122
123/// Do the common operand retrieval and validition required by the
124/// routines below.
125static bool getMemOperands(unsigned Factor, VectorType *VTy, Type *XLenTy,
126 Instruction *I, Value *&Ptr, Value *&Mask,
127 Value *&VL, Align &Alignment) {
128
129 IRBuilder<> Builder(I);
130 const DataLayout &DL = I->getDataLayout();
131 ElementCount EC = VTy->getElementCount();
132 if (auto *LI = dyn_cast<LoadInst>(I)) {
133 assert(LI->isSimple());
134 Ptr = LI->getPointerOperand();
135 Alignment = LI->getAlign();
136 assert(!Mask && "Unexpected mask on a load");
137 Mask = Builder.getAllOnesMask(EC);
138 VL = isa<FixedVectorType>(VTy) ? Builder.CreateElementCount(XLenTy, EC)
140 return true;
141 }
142 if (auto *SI = dyn_cast<StoreInst>(I)) {
143 assert(SI->isSimple());
144 Ptr = SI->getPointerOperand();
145 Alignment = SI->getAlign();
146 assert(!Mask && "Unexpected mask on a store");
147 Mask = Builder.getAllOnesMask(EC);
148 VL = isa<FixedVectorType>(VTy) ? Builder.CreateElementCount(XLenTy, EC)
150 return true;
151 }
152
153 auto *II = cast<IntrinsicInst>(I);
154 switch (II->getIntrinsicID()) {
155 default:
156 llvm_unreachable("Unsupported intrinsic type");
157 case Intrinsic::vp_load:
158 case Intrinsic::vp_store: {
159 auto *VPLdSt = cast<VPIntrinsic>(I);
160 Ptr = VPLdSt->getMemoryPointerParam();
161 Alignment = VPLdSt->getPointerAlignment().value_or(
162 DL.getABITypeAlign(VTy->getElementType()));
163
164 assert(Mask && "vp.load and vp.store needs a mask!");
165
166 Value *WideEVL = VPLdSt->getVectorLengthParam();
167 // Conservatively check if EVL is a multiple of factor, otherwise some
168 // (trailing) elements might be lost after the transformation.
169 if (!isMultipleOfN(WideEVL, I->getDataLayout(), Factor))
170 return false;
171
172 auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
173 VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
174 return true;
175 }
176 case Intrinsic::masked_load: {
177 Ptr = II->getOperand(0);
178 Alignment = II->getParamAlign(0).valueOrOne();
179
180 if (!isa<UndefValue>(II->getOperand(2)))
181 return false;
182
183 assert(Mask && "masked.load needs a mask!");
184
185 VL = isa<FixedVectorType>(VTy)
186 ? Builder.CreateElementCount(XLenTy, VTy->getElementCount())
188 return true;
189 }
190 case Intrinsic::masked_store: {
191 Ptr = II->getOperand(1);
192 Alignment = II->getParamAlign(1).valueOrOne();
193
194 assert(Mask && "masked.store needs a mask!");
195
196 VL = isa<FixedVectorType>(VTy)
197 ? Builder.CreateElementCount(XLenTy, VTy->getElementCount())
199 return true;
200 }
201 }
202}
203
204/// Lower an interleaved load into a vlsegN intrinsic.
205///
206/// E.g. Lower an interleaved load (Factor = 2):
207/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr
208/// %v0 = shuffle %wide.vec, undef, <0, 2, 4, 6> ; Extract even elements
209/// %v1 = shuffle %wide.vec, undef, <1, 3, 5, 7> ; Extract odd elements
210///
211/// Into:
212/// %ld2 = { <4 x i32>, <4 x i32> } call llvm.riscv.seg2.load.v4i32.p0.i64(
213/// %ptr, i64 4)
214/// %vec0 = extractelement { <4 x i32>, <4 x i32> } %ld2, i32 0
215/// %vec1 = extractelement { <4 x i32>, <4 x i32> } %ld2, i32 1
217 Instruction *Load, Value *Mask, ArrayRef<ShuffleVectorInst *> Shuffles,
218 ArrayRef<unsigned> Indices, unsigned Factor, const APInt &GapMask) const {
219 assert(Indices.size() == Shuffles.size());
220 assert(GapMask.getBitWidth() == Factor);
221
222 // We only support cases where the skipped fields are the trailing ones.
223 if (!GapMask.isMask())
224 return false;
225 IRBuilder<> Builder(Load);
226
227 unsigned MaskFactor = GapMask.popcount();
228 const DataLayout &DL = Load->getDataLayout();
229 auto *VTy = cast<FixedVectorType>(Shuffles[0]->getType());
230 auto *XLenTy = Builder.getIntNTy(Subtarget.getXLen());
231
232 Value *Ptr, *VL;
233 Align Alignment;
234 if (!getMemOperands(MaskFactor, VTy, XLenTy, Load, Ptr, Mask, VL, Alignment))
235 return false;
236
237 Type *PtrTy = Ptr->getType();
238 unsigned AS = PtrTy->getPointerAddressSpace();
239 if (!isLegalInterleavedAccessType(VTy, MaskFactor, Alignment, AS, DL))
240 return false;
241
242 CallInst *SegLoad = nullptr;
243 if (MaskFactor < Factor && MaskFactor != 1) {
244 // Lower to strided segmented load.
245 unsigned ScalarSizeInBytes = DL.getTypeStoreSize(VTy->getElementType());
246 Value *Stride = ConstantInt::get(XLenTy, Factor * ScalarSizeInBytes);
247 SegLoad = Builder.CreateIntrinsic(FixedVlssegIntrIds[MaskFactor - 2],
248 {VTy, PtrTy, XLenTy, XLenTy},
249 {Ptr, Stride, Mask, VL});
250 } else {
251 // Lower to normal segmented load.
252 SegLoad = Builder.CreateIntrinsic(FixedVlsegIntrIds[Factor - 2],
253 {VTy, PtrTy, XLenTy}, {Ptr, Mask, VL});
254 }
255
256 for (unsigned i = 0; i < Shuffles.size(); i++) {
257 unsigned FactorIdx = Indices[i];
258 if (FactorIdx >= MaskFactor) {
259 // Replace masked-off factors (that are still extracted) with poison.
260 Shuffles[i]->replaceAllUsesWith(PoisonValue::get(VTy));
261 } else {
262 Value *SubVec = Builder.CreateExtractValue(SegLoad, FactorIdx);
263 Shuffles[i]->replaceAllUsesWith(SubVec);
264 }
265 }
266
267 return true;
268}
269
270/// Lower an interleaved store into a vssegN intrinsic.
271///
272/// E.g. Lower an interleaved store (Factor = 3):
273/// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
274/// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
275/// store <12 x i32> %i.vec, <12 x i32>* %ptr
276///
277/// Into:
278/// %sub.v0 = shuffle <8 x i32> %v0, <8 x i32> v1, <0, 1, 2, 3>
279/// %sub.v1 = shuffle <8 x i32> %v0, <8 x i32> v1, <4, 5, 6, 7>
280/// %sub.v2 = shuffle <8 x i32> %v0, <8 x i32> v1, <8, 9, 10, 11>
281/// call void llvm.riscv.seg3.store.v4i32.p0.i64(%sub.v0, %sub.v1, %sub.v2,
282/// %ptr, i32 4)
283///
284/// Note that the new shufflevectors will be removed and we'll only generate one
285/// vsseg3 instruction in CodeGen.
287 Value *LaneMask,
289 unsigned Factor,
290 const APInt &GapMask) const {
291 assert(GapMask.getBitWidth() == Factor);
292
293 // We only support cases where the skipped fields are the trailing ones.
294 // TODO: Lower to strided store if there is only a single active field.
295 unsigned MaskFactor = GapMask.popcount();
296 if (MaskFactor < 2 || !GapMask.isMask())
297 return false;
298
299 IRBuilder<> Builder(Store);
300 const DataLayout &DL = Store->getDataLayout();
301 auto Mask = SVI->getShuffleMask();
302 auto *ShuffleVTy = cast<FixedVectorType>(SVI->getType());
303 // Given SVI : <n*factor x ty>, then VTy : <n x ty>
304 auto *VTy = FixedVectorType::get(ShuffleVTy->getElementType(),
305 ShuffleVTy->getNumElements() / Factor);
306 auto *XLenTy = Builder.getIntNTy(Subtarget.getXLen());
307
308 Value *Ptr, *VL;
309 Align Alignment;
310 if (!getMemOperands(MaskFactor, VTy, XLenTy, Store, Ptr, LaneMask, VL,
311 Alignment))
312 return false;
313
314 Type *PtrTy = Ptr->getType();
315 unsigned AS = PtrTy->getPointerAddressSpace();
316 if (!isLegalInterleavedAccessType(VTy, MaskFactor, Alignment, AS, DL))
317 return false;
318
319 Function *SegStoreFunc;
320 if (MaskFactor < Factor)
321 // Strided segmented store.
323 Store->getModule(), FixedVsssegIntrIds[MaskFactor - 2],
324 {VTy, PtrTy, XLenTy, XLenTy});
325 else
326 // Normal segmented store.
328 Store->getModule(), FixedVssegIntrIds[Factor - 2],
329 {VTy, PtrTy, XLenTy});
330
332 SmallVector<int, 16> NewShuffleMask;
333
334 for (unsigned i = 0; i < MaskFactor; i++) {
335 // Collect shuffle mask for this lane.
336 for (unsigned j = 0; j < VTy->getNumElements(); j++)
337 NewShuffleMask.push_back(Mask[i + Factor * j]);
338
339 Value *Shuffle = Builder.CreateShuffleVector(
340 SVI->getOperand(0), SVI->getOperand(1), NewShuffleMask);
341 Ops.push_back(Shuffle);
342
343 NewShuffleMask.clear();
344 }
345 Ops.push_back(Ptr);
346 if (MaskFactor < Factor) {
347 // Insert the stride argument.
348 unsigned ScalarSizeInBytes = DL.getTypeStoreSize(VTy->getElementType());
349 Ops.push_back(ConstantInt::get(XLenTy, Factor * ScalarSizeInBytes));
350 }
351 Ops.append({LaneMask, VL});
352 Builder.CreateCall(SegStoreFunc, Ops);
353
354 return true;
355}
356
358 Instruction *Load, Value *Mask, IntrinsicInst *DI,
359 const APInt &GapMask) const {
360 const unsigned Factor = getDeinterleaveIntrinsicFactor(DI->getIntrinsicID());
361 assert(GapMask.getBitWidth() == Factor);
362 if (Factor > 8)
363 return false;
364
365 // We only support cases where the skipped fields are the trailing ones.
366 if (!GapMask.isMask())
367 return false;
368 IRBuilder<> Builder(Load);
369
371
372 unsigned MaskFactor = GapMask.getActiveBits();
373 // For MaskFactor of 1, we still want to lower it with segmented load
374 // (of the original Factor), because the sole field extraction will eventually
375 // turn it into a strided load.
376 bool UseStridedSeg = MaskFactor < Factor && MaskFactor > 1;
377 const DataLayout &DL = Load->getDataLayout();
378 auto *XLenTy = Builder.getIntNTy(Subtarget.getXLen());
379
380 Value *Ptr, *VL;
381 Align Alignment;
382 if (!getMemOperands(Factor, ResVTy, XLenTy, Load, Ptr, Mask, VL, Alignment))
383 return false;
384
385 Type *PtrTy = Ptr->getType();
386 unsigned AS = PtrTy->getPointerAddressSpace();
387 if (!isLegalInterleavedAccessType(ResVTy, Factor, Alignment, AS, DL))
388 return false;
389
390 unsigned ElementSizeInBytes = DL.getTypeStoreSize(ResVTy->getElementType());
391 Value *Return;
392 if (isa<FixedVectorType>(ResVTy)) {
393 Value *SegLoad;
394 if (UseStridedSeg) {
395 // Lower to strided segmented load.
396 Value *Stride = ConstantInt::get(XLenTy, Factor * ElementSizeInBytes);
397 SegLoad = Builder.CreateIntrinsic(FixedVlssegIntrIds[MaskFactor - 2],
398 {ResVTy, PtrTy, XLenTy, XLenTy},
399 {Ptr, Stride, Mask, VL});
400 } else {
401 SegLoad =
402 Builder.CreateIntrinsic(FixedVlsegIntrIds[Factor - 2],
403 {ResVTy, PtrTy, XLenTy}, {Ptr, Mask, VL});
404 }
405
406 if (MaskFactor != Factor) {
407 // Replace masked-off factors with poisons.
408 SmallVector<Type *, 8> AggrTypes{Factor, ResVTy};
409 Return = PoisonValue::get(StructType::get(Load->getContext(), AggrTypes));
410 for (unsigned I = 0; I < MaskFactor; ++I) {
411 Value *SubVec = Builder.CreateExtractValue(SegLoad, I);
412 Return = Builder.CreateInsertValue(Return, SubVec, I);
413 }
414 } else {
415 Return = SegLoad;
416 }
417 } else {
418 unsigned SEW = DL.getTypeSizeInBits(ResVTy->getElementType());
419 unsigned NumElts = ResVTy->getElementCount().getKnownMinValue();
420 Type *VecTupTy = TargetExtType::get(
421 Load->getContext(), "riscv.vector.tuple",
422 ScalableVectorType::get(Builder.getInt8Ty(), NumElts * SEW / 8),
423 UseStridedSeg ? MaskFactor : Factor);
424 Function *SegLoadFunc;
425 if (UseStridedSeg) {
426 // Lower to strided segmented load.
428 Load->getModule(), ScalableVlssegIntrIds[MaskFactor - 2],
429 {VecTupTy, PtrTy, XLenTy, Mask->getType()});
430 } else {
432 Load->getModule(), ScalableVlsegIntrIds[Factor - 2],
433 {VecTupTy, PtrTy, Mask->getType(), VL->getType()});
434 }
435
436 SmallVector<Value *, 8> Operands = {
437 PoisonValue::get(VecTupTy),
438 Ptr,
439 Mask,
440 VL,
441 ConstantInt::get(XLenTy,
443 ConstantInt::get(XLenTy, Log2_64(SEW))};
444 if (UseStridedSeg) {
445 Value *Stride = ConstantInt::get(XLenTy, Factor * ElementSizeInBytes);
446 Operands.insert(std::next(Operands.begin(), 2), Stride);
447 }
448
449 CallInst *Vlseg = Builder.CreateCall(SegLoadFunc, Operands);
450
451 SmallVector<Type *, 8> AggrTypes{Factor, ResVTy};
452 Return = PoisonValue::get(StructType::get(Load->getContext(), AggrTypes));
453 for (unsigned i = 0; i < MaskFactor; ++i) {
454 Value *VecExtract = Builder.CreateIntrinsic(
455 Intrinsic::riscv_tuple_extract, {ResVTy, VecTupTy},
456 {Vlseg, Builder.getInt32(i)});
457 Return = Builder.CreateInsertValue(Return, VecExtract, i);
458 }
459 }
460
461 DI->replaceAllUsesWith(Return);
462 return true;
463}
464
466 Instruction *Store, Value *Mask, ArrayRef<Value *> InterleaveValues) const {
467 unsigned Factor = InterleaveValues.size();
468 if (Factor > 8)
469 return false;
470
471 IRBuilder<> Builder(Store);
472
473 auto *InVTy = cast<VectorType>(InterleaveValues[0]->getType());
474 const DataLayout &DL = Store->getDataLayout();
475 Type *XLenTy = Builder.getIntNTy(Subtarget.getXLen());
476
477 Value *Ptr, *VL;
478 Align Alignment;
479 if (!getMemOperands(Factor, InVTy, XLenTy, Store, Ptr, Mask, VL, Alignment))
480 return false;
481 Type *PtrTy = Ptr->getType();
482 unsigned AS = Ptr->getType()->getPointerAddressSpace();
483 if (!isLegalInterleavedAccessType(InVTy, Factor, Alignment, AS, DL))
484 return false;
485
486 if (isa<FixedVectorType>(InVTy)) {
488 Store->getModule(), FixedVssegIntrIds[Factor - 2],
489 {InVTy, PtrTy, XLenTy});
490 SmallVector<Value *, 10> Ops(InterleaveValues);
491 Ops.append({Ptr, Mask, VL});
492 Builder.CreateCall(VssegNFunc, Ops);
493 return true;
494 }
495 unsigned SEW = DL.getTypeSizeInBits(InVTy->getElementType());
496 unsigned NumElts = InVTy->getElementCount().getKnownMinValue();
497 Type *VecTupTy = TargetExtType::get(
498 Store->getContext(), "riscv.vector.tuple",
499 ScalableVectorType::get(Builder.getInt8Ty(), NumElts * SEW / 8), Factor);
500
501 Value *StoredVal = PoisonValue::get(VecTupTy);
502 for (unsigned i = 0; i < Factor; ++i)
503 StoredVal = Builder.CreateIntrinsic(
504 Intrinsic::riscv_tuple_insert, {VecTupTy, InVTy},
505 {StoredVal, InterleaveValues[i], Builder.getInt32(i)});
506
508 Store->getModule(), ScalableVssegIntrIds[Factor - 2],
509 {VecTupTy, PtrTy, Mask->getType(), VL->getType()});
510
511 Value *Operands[] = {StoredVal, Ptr, Mask, VL,
512 ConstantInt::get(XLenTy, Log2_64(SEW))};
513 Builder.CreateCall(VssegNFunc, Operands);
514 return true;
515}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
static const Intrinsic::ID FixedVlsegIntrIds[]
static bool isMultipleOfN(const Value *V, const DataLayout &DL, unsigned N)
static const Intrinsic::ID ScalableVlsegIntrIds[]
static const Intrinsic::ID ScalableVssegIntrIds[]
static const Intrinsic::ID FixedVlssegIntrIds[]
static bool getMemOperands(unsigned Factor, VectorType *VTy, Type *XLenTy, Instruction *I, Value *&Ptr, Value *&Mask, Value *&VL, Align &Alignment)
Do the common operand retrieval and validition required by the routines below.
static const Intrinsic::ID FixedVsssegIntrIds[]
static const Intrinsic::ID FixedVssegIntrIds[]
static const Intrinsic::ID ScalableVlssegIntrIds[]
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
Class for arbitrary precision integers.
Definition APInt.h:78
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1693
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1535
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1511
bool isMask(unsigned numBits) const
Definition APInt.h:489
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:873
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2858
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Machine Value Type.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
bool lowerInterleavedStore(Instruction *Store, Value *Mask, ShuffleVectorInst *SVI, unsigned Factor, const APInt &GapMask) const override
Lower an interleaved store into a vssegN intrinsic.
MVT getContainerForFixedLengthVector(MVT VT) const
bool lowerDeinterleaveIntrinsicToLoad(Instruction *Load, Value *Mask, IntrinsicInst *DI, const APInt &GapMask) const override
Lower a deinterleave intrinsic to a target specific load intrinsic.
bool lowerInterleavedLoad(Instruction *Load, Value *Mask, ArrayRef< ShuffleVectorInst * > Shuffles, ArrayRef< unsigned > Indices, unsigned Factor, const APInt &GapMask) const override
Lower an interleaved load into a vlsegN intrinsic.
bool lowerInterleaveIntrinsicToStore(Instruction *Store, Value *Mask, ArrayRef< Value * > InterleaveValues) const override
Lower an interleave intrinsic to a target specific store intrinsic.
bool isLegalElementTypeForRVV(EVT ScalarTy) const
bool isLegalInterleavedAccessType(VectorType *VTy, unsigned Factor, Align Alignment, unsigned AddrSpace, const DataLayout &) const
Returns whether or not generating a interleaved load/store intrinsic for this type will be legal.
static RISCVVType::VLMUL getLMUL(MVT VT)
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
Definition Type.cpp:895
This instruction constructs a fixed permutation of two input vectors.
VectorType * getType() const
Overload to return most specific vector type.
static LLVM_ABI void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:483
static LLVM_ABI TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
Definition Type.cpp:978
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:317
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:337
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI unsigned getDeinterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.deinterleaveN intrinsics.
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
LLVM_ABI VectorType * getDeinterleavedVectorType(IntrinsicInst *DI)
Given a deinterleaveN intrinsic, return the (narrow) vector type of each factor.
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
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:324
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:331
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
Definition KnownBits.h:256