LLVM 24.0.0git
VectorCombine.cpp
Go to the documentation of this file.
1//===------- VectorCombine.cpp - Optimize partial vector operations -------===//
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 pass optimizes scalar/vector interactions using target cost models. The
10// transforms implemented here may not fit in traditional loop-based or SLP
11// vectorization passes.
12//
13//===----------------------------------------------------------------------===//
14
16#include "VectorizeOptions.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/ScopeExit.h"
21#include "llvm/ADT/Statistic.h"
26#include "llvm/Analysis/Loads.h"
31#include "llvm/IR/Dominators.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/IRBuilder.h"
41#include <numeric>
42#include <optional>
43#include <queue>
44#include <set>
45
46#define DEBUG_TYPE "vector-combine"
48
49using namespace llvm;
50using namespace llvm::PatternMatch;
51
52STATISTIC(NumVecLoad, "Number of vector loads formed");
53STATISTIC(NumVecCmp, "Number of vector compares formed");
54STATISTIC(NumVecBO, "Number of vector binops formed");
55STATISTIC(NumVecCmpBO, "Number of vector compare + binop formed");
56STATISTIC(NumShufOfBitcast, "Number of shuffles moved after bitcast");
57STATISTIC(NumScalarOps, "Number of scalar unary + binary ops formed");
58STATISTIC(NumScalarCmp, "Number of scalar compares formed");
59STATISTIC(NumScalarIntrinsic, "Number of scalar intrinsic calls formed");
60
61static const unsigned InvalidIndex = std::numeric_limits<unsigned>::max();
62
63namespace {
64class VectorCombine {
65public:
66 VectorCombine(const VectorizeOptions &Opts, Function &F,
67 const TargetTransformInfo &TTI, const DominatorTree &DT,
69 TTI::TargetCostKind CostKind, bool TryEarlyFoldsOnly)
70 : Opts(Opts), F(F),
71 Builder(*F.getParent(), InstSimplifyFolder(*DL),
73 // Automatically add newly created instructions
74 // into the deferred queue.
75 Worklist.add(I);
76 })),
77 TTI(TTI), DT(DT), AA(AA), DL(DL), CostKind(CostKind),
78 SQ(*DL, /*TLI=*/nullptr, &DT, &AC),
79 TryEarlyFoldsOnly(TryEarlyFoldsOnly) {}
80
81 bool run();
82
83private:
84 const VectorizeOptions &Opts;
85 Function &F;
86 IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> Builder;
87 const TargetTransformInfo &TTI;
88 const DominatorTree &DT;
89 AAResults &AA;
90 const DataLayout *DL;
91 TTI::TargetCostKind CostKind;
92 const SimplifyQuery SQ;
93
94 /// If true, only perform beneficial early IR transforms. Do not introduce new
95 /// vector operations.
96 bool TryEarlyFoldsOnly;
97
98 InstructionWorklist Worklist;
99
100 /// Next instruction to iterate. It will be updated when it is erased by
101 /// RecursivelyDeleteTriviallyDeadInstructions.
102 Instruction *NextInst;
103
104 // TODO: Direct calls from the top-level "run" loop use a plain "Instruction"
105 // parameter. That should be updated to specific sub-classes because the
106 // run loop was changed to dispatch on opcode.
107 bool vectorizeLoadInsert(Instruction &I);
108 bool widenSubvectorLoad(Instruction &I);
109 ExtractElementInst *getShuffleExtract(ExtractElementInst *Ext0,
110 ExtractElementInst *Ext1,
111 unsigned PreferredExtractIndex) const;
112 bool isExtractExtractCheap(ExtractElementInst *Ext0, ExtractElementInst *Ext1,
113 const Instruction &I,
114 ExtractElementInst *&ConvertToShuffle,
115 unsigned PreferredExtractIndex);
116 Value *foldExtExtCmp(Value *V0, Value *V1, Value *ExtIndex, Instruction &I);
117 Value *foldExtExtBinop(Value *V0, Value *V1, Value *ExtIndex, Instruction &I);
118 bool foldExtractExtract(Instruction &I);
119 bool foldInsExtFNeg(Instruction &I);
120 bool foldInsExtBinop(Instruction &I);
121 bool foldInsExtVectorToShuffle(Instruction &I);
122 bool foldInsertScalarPartsToShuffle(Instruction &I);
123 bool foldBitOpOfCastops(Instruction &I);
124 bool foldBitOpOfCastConstant(Instruction &I);
125 bool foldBitcastShuffle(Instruction &I);
126 bool scalarizeOpOrCmp(Instruction &I);
127 bool foldExtractedCmps(Instruction &I);
128 bool foldSelectsFromBitcast(Instruction &I);
129 bool foldBinopOfReductions(Instruction &I);
130 bool foldInsertElementsToStores(Instruction &I);
131 bool scalarizeLoad(Instruction &I);
132 bool scalarizeLoadExtract(LoadInst *LI, VectorType *VecTy, Value *Ptr);
133 bool scalarizeLoadBitcast(LoadInst *LI, VectorType *VecTy, Value *Ptr);
134 bool scalarizeExtExtract(Instruction &I);
135 bool foldConcatOfBoolMasks(Instruction &I);
136 bool foldPermuteOfBinops(Instruction &I);
137 bool foldShuffleOfBinops(Instruction &I);
138 bool foldShuffleOfSelects(Instruction &I);
139 bool foldShuffleOfCastops(Instruction &I);
140 bool foldShuffleOfShuffles(Instruction &I);
141 bool foldShuffleOfAdjacentLoads(Instruction &I);
142 bool foldPermuteOfIntrinsic(Instruction &I);
143 bool foldShufflesOfLengthChangingShuffles(Instruction &I);
144 bool foldShuffleOfIntrinsics(Instruction &I);
145 bool foldShuffleToIdentity(Instruction &I);
146 bool foldShuffleFromReductions(Instruction &I);
147 bool foldShuffleChainsToReduce(Instruction &I);
148 bool foldCastFromReductions(Instruction &I);
149 bool foldSignBitReductionCmp(Instruction &I);
150 bool foldReductionZeroTest(Instruction &I);
151 bool foldICmpEqZeroVectorReduce(Instruction &I);
152 bool foldEquivalentReductionCmp(Instruction &I);
153 bool foldReduceAddCmpZero(Instruction &I);
154 bool foldSelectShuffle(Instruction &I, bool FromReduction = false);
155 bool foldInterleaveIntrinsics(Instruction &I);
156 bool foldDeinterleaveIntrinsics(Instruction &I);
157 bool foldBitcastOfVPLoad(Instruction &I);
158 bool foldBitOrderReverseAndSwap(Instruction &I);
159 bool shrinkType(Instruction &I);
160 bool shrinkLoadForShuffles(Instruction &I);
161 bool shrinkPhiOfShuffles(Instruction &I);
162 bool foldInterleaveOfDeinterleaveChains(Instruction &I);
163
164 void replaceValue(Instruction &Old, Value &New, bool Erase = true) {
165 LLVM_DEBUG(dbgs() << "VC: Replacing: " << Old << '\n');
166 LLVM_DEBUG(dbgs() << " With: " << New << '\n');
167 Old.replaceAllUsesWith(&New);
168 if (auto *NewI = dyn_cast<Instruction>(&New)) {
169 New.takeName(&Old);
170 Worklist.pushUsersToWorkList(*NewI);
171 Worklist.pushValue(NewI);
172 }
173 if (Erase && isInstructionTriviallyDead(&Old)) {
174 eraseInstruction(Old);
175 } else {
176 Worklist.push(&Old);
177 }
178 }
179
180 void eraseInstruction(Instruction &I) {
181 LLVM_DEBUG(dbgs() << "VC: Erasing: " << I << '\n');
182 SmallVector<Value *> Ops(I.operands());
183 Worklist.remove(&I);
184 I.eraseFromParent();
185
186 // Push remaining users of the operands and then the operand itself - allows
187 // further folds that were hindered by OneUse limits.
188 SmallPtrSet<Value *, 4> Visited;
189 for (Value *Op : Ops) {
190 if (!Visited.contains(Op)) {
191 if (auto *OpI = dyn_cast<Instruction>(Op)) {
193 OpI, nullptr, nullptr, [&](Value *V) {
194 if (auto *I = dyn_cast<Instruction>(V)) {
195 LLVM_DEBUG(dbgs() << "VC: Erased: " << *I << '\n');
196 Worklist.remove(I);
197 if (I == NextInst)
198 NextInst = NextInst->getNextNode();
199 Visited.insert(I);
200 }
201 }))
202 continue;
203 Worklist.pushUsersToWorkList(*OpI);
204 Worklist.pushValue(OpI);
205 }
206 }
207 }
208 }
209};
210} // namespace
211
212/// Return the source operand of a potentially bitcasted value. If there is no
213/// bitcast, return the input value itself.
215 while (auto *BitCast = dyn_cast<BitCastInst>(V))
216 V = BitCast->getOperand(0);
217 return V;
218}
219
220/// Helper to peek through bitcasts to the same value.
221static bool isEquivBitcast(Value *X, Value *Y) {
222 return X->getType() == Y->getType() &&
224}
225
227 // Do not widen load if atomic/volatile or under asan/hwasan/memtag/tsan.
228 // The widened load may load data from dirty regions or create data races
229 // non-existent in the source.
230 if (!Load || !Load->isSimple() || !Load->hasOneUse() ||
231 Load->getFunction()->hasFnAttribute(Attribute::SanitizeMemTag) ||
233 return false;
234
235 // We are potentially transforming byte-sized (8-bit) memory accesses, so make
236 // sure we have all of our type-based constraints in place for this target.
237 Type *ScalarTy = Load->getType()->getScalarType();
238 uint64_t ScalarSize = ScalarTy->getPrimitiveSizeInBits();
239 unsigned MinVectorSize = TTI.getMinVectorRegisterBitWidth();
240 if (!ScalarSize || !MinVectorSize || MinVectorSize % ScalarSize != 0 ||
241 ScalarSize % 8 != 0)
242 return false;
243
244 return true;
245}
246
247bool VectorCombine::vectorizeLoadInsert(Instruction &I) {
248 // Match insert into fixed vector of scalar value.
249 // TODO: Handle non-zero insert index.
250 Value *Scalar;
251 if (!match(&I,
253 return false;
254
255 // Optionally match an extract from another vector.
256 Value *X;
257 bool HasExtract = match(Scalar, m_ExtractElt(m_Value(X), m_ZeroInt()));
258 if (!HasExtract)
259 X = Scalar;
260
261 auto *Load = dyn_cast<LoadInst>(X);
262 if (!canWidenLoad(Load, TTI))
263 return false;
264
265 Type *ScalarTy = Scalar->getType();
266 uint64_t ScalarSize = ScalarTy->getPrimitiveSizeInBits();
267 unsigned MinVectorSize = TTI.getMinVectorRegisterBitWidth();
268
269 // Check safety of replacing the scalar load with a larger vector load.
270 // We use minimal alignment (maximum flexibility) because we only care about
271 // the dereferenceable region. When calculating cost and creating a new op,
272 // we may use a larger value based on alignment attributes.
273 Value *SrcPtr = Load->getPointerOperand()->stripPointerCasts();
274 assert(isa<PointerType>(SrcPtr->getType()) && "Expected a pointer type");
275
276 unsigned MinVecNumElts = MinVectorSize / ScalarSize;
277 auto *MinVecTy = VectorType::get(ScalarTy, MinVecNumElts, false);
278 unsigned OffsetEltIndex = 0;
279 Align Alignment = Load->getAlign();
280 // Ignore frees because the existing load proves that the object has not been
281 // freed. Allocations cannot shrink, so this is sufficient.
282 if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1),
284 /*IgnoreFree=*/true)) {
285 // It is not safe to load directly from the pointer, but we can still peek
286 // through gep offsets and check if it safe to load from a base address with
287 // updated alignment. If it is, we can shuffle the element(s) into place
288 // after loading.
289 unsigned OffsetBitWidth = DL->getIndexTypeSizeInBits(SrcPtr->getType());
290 APInt Offset(OffsetBitWidth, 0);
292
293 // We want to shuffle the result down from a high element of a vector, so
294 // the offset must be positive.
295 if (Offset.isNegative())
296 return false;
297
298 // The offset must be a multiple of the scalar element to shuffle cleanly
299 // in the element's size.
300 uint64_t ScalarSizeInBytes = ScalarSize / 8;
301 if (Offset.urem(ScalarSizeInBytes) != 0)
302 return false;
303
304 // If we load MinVecNumElts, will our target element still be loaded?
305 APInt OffsetEltIndexAP = Offset.udiv(ScalarSizeInBytes);
306 if (OffsetEltIndexAP.uge(MinVecNumElts))
307 return false;
308 OffsetEltIndex = OffsetEltIndexAP.getZExtValue();
309
310 if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1),
312 /*IgnoreFree=*/true))
313 return false;
314
315 // Update alignment with offset value. Note that the offset could be negated
316 // to more accurately represent "(new) SrcPtr - Offset = (old) SrcPtr", but
317 // negation does not change the result of the alignment calculation.
318 Alignment = commonAlignment(Alignment, Offset.getZExtValue());
319 }
320
321 // Original pattern: insertelt undef, load [free casts of] PtrOp, 0
322 // Use the greater of the alignment on the load or its source pointer.
323 Alignment = std::max(SrcPtr->getPointerAlignment(*DL), Alignment);
324 Type *LoadTy = Load->getType();
325 unsigned AS = Load->getPointerAddressSpace();
326 InstructionCost OldCost =
327 TTI.getMemoryOpCost(Instruction::Load, LoadTy, Alignment, AS, CostKind);
328 APInt DemandedElts = APInt::getOneBitSet(MinVecNumElts, 0);
329 OldCost +=
330 TTI.getScalarizationOverhead(MinVecTy, DemandedElts,
331 /* Insert */ true, HasExtract, CostKind);
332
333 // New pattern: load VecPtr
334 InstructionCost NewCost =
335 TTI.getMemoryOpCost(Instruction::Load, MinVecTy, Alignment, AS, CostKind);
336 // Optionally, we are shuffling the loaded vector element(s) into place.
337 // For the mask set everything but element 0 to undef to prevent poison from
338 // propagating from the extra loaded memory. This will also optionally
339 // shrink/grow the vector from the loaded size to the output size.
340 // We assume this operation has no cost in codegen if there was no offset.
341 // Note that we could use freeze to avoid poison problems, but then we might
342 // still need a shuffle to change the vector size.
343 auto *Ty = cast<FixedVectorType>(I.getType());
344 unsigned OutputNumElts = Ty->getNumElements();
345 SmallVector<int, 16> Mask(OutputNumElts, PoisonMaskElem);
346 assert(OffsetEltIndex < MinVecNumElts && "Address offset too big");
347 Mask[0] = OffsetEltIndex;
348 if (OffsetEltIndex)
349 NewCost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, Ty, MinVecTy,
350 CostKind, Mask);
351
352 // We can aggressively convert to the vector form because the backend can
353 // invert this transform if it does not result in a performance win.
354 if (OldCost < NewCost || !NewCost.isValid())
355 return false;
356
357 // It is safe and potentially profitable to load a vector directly:
358 // inselt undef, load Scalar, 0 --> load VecPtr
359 Builder.SetInsertPoint(Load);
360 Value *CastedPtr =
361 Builder.CreatePointerBitCastOrAddrSpaceCast(SrcPtr, Builder.getPtrTy(AS));
362 Value *VecLd = Builder.CreateAlignedLoad(MinVecTy, CastedPtr, Alignment);
363 VecLd = Builder.CreateShuffleVector(VecLd, Mask);
364
365 replaceValue(I, *VecLd);
366 ++NumVecLoad;
367 return true;
368}
369
370/// If we are loading a vector and then inserting it into a larger vector with
371/// undefined elements, try to load the larger vector and eliminate the insert.
372/// This removes a shuffle in IR and may allow combining of other loaded values.
373bool VectorCombine::widenSubvectorLoad(Instruction &I) {
374 // Match subvector insert of fixed vector.
375 auto *Shuf = cast<ShuffleVectorInst>(&I);
376 if (!Shuf->isIdentityWithPadding())
377 return false;
378
379 // Allow a non-canonical shuffle mask that is choosing elements from op1.
380 unsigned NumOpElts =
381 cast<FixedVectorType>(Shuf->getOperand(0)->getType())->getNumElements();
382 unsigned OpIndex = any_of(Shuf->getShuffleMask(), [&NumOpElts](int M) {
383 return M >= (int)(NumOpElts);
384 });
385
386 auto *Load = dyn_cast<LoadInst>(Shuf->getOperand(OpIndex));
387 if (!canWidenLoad(Load, TTI))
388 return false;
389
390 // We use minimal alignment (maximum flexibility) because we only care about
391 // the dereferenceable region. When calculating cost and creating a new op,
392 // we may use a larger value based on alignment attributes.
393 auto *Ty = cast<FixedVectorType>(I.getType());
394 Value *SrcPtr = Load->getPointerOperand()->stripPointerCasts();
395 assert(isa<PointerType>(SrcPtr->getType()) && "Expected a pointer type");
396 Align Alignment = Load->getAlign();
397 // Ignore frees because the existing load proves that the object has not been
398 // freed. Allocations cannot shrink, so this is sufficient.
399 if (!isSafeToLoadUnconditionally(SrcPtr, Ty, Align(1),
401 /*IgnoreFree=*/true))
402 return false;
403
404 Alignment = std::max(SrcPtr->getPointerAlignment(*DL), Alignment);
405 Type *LoadTy = Load->getType();
406 unsigned AS = Load->getPointerAddressSpace();
407
408 // Original pattern: insert_subvector (load PtrOp)
409 // This conservatively assumes that the cost of a subvector insert into an
410 // undef value is 0. We could add that cost if the cost model accurately
411 // reflects the real cost of that operation.
412 InstructionCost OldCost =
413 TTI.getMemoryOpCost(Instruction::Load, LoadTy, Alignment, AS, CostKind);
414
415 // New pattern: load PtrOp
416 InstructionCost NewCost =
417 TTI.getMemoryOpCost(Instruction::Load, Ty, Alignment, AS, CostKind);
418
419 // We can aggressively convert to the vector form because the backend can
420 // invert this transform if it does not result in a performance win.
421 if (OldCost < NewCost || !NewCost.isValid())
422 return false;
423
424 Builder.SetInsertPoint(Load);
425 Value *CastedPtr =
426 Builder.CreatePointerBitCastOrAddrSpaceCast(SrcPtr, Builder.getPtrTy(AS));
427 Value *VecLd = Builder.CreateAlignedLoad(Ty, CastedPtr, Alignment);
428 replaceValue(I, *VecLd);
429 ++NumVecLoad;
430 return true;
431}
432
433/// Determine which, if any, of the inputs should be replaced by a shuffle
434/// followed by extract from a different index.
435ExtractElementInst *VectorCombine::getShuffleExtract(
436 ExtractElementInst *Ext0, ExtractElementInst *Ext1,
437 unsigned PreferredExtractIndex = InvalidIndex) const {
438 auto *Index0C = dyn_cast<ConstantInt>(Ext0->getIndexOperand());
439 auto *Index1C = dyn_cast<ConstantInt>(Ext1->getIndexOperand());
440 assert(Index0C && Index1C && "Expected constant extract indexes");
441
442 unsigned Index0 = Index0C->getZExtValue();
443 unsigned Index1 = Index1C->getZExtValue();
444
445 // If the extract indexes are identical, no shuffle is needed.
446 if (Index0 == Index1)
447 return nullptr;
448
449 Type *VecTy = Ext0->getVectorOperand()->getType();
450 assert(VecTy == Ext1->getVectorOperand()->getType() && "Need matching types");
451 InstructionCost Cost0 =
452 TTI.getVectorInstrCost(*Ext0, VecTy, CostKind, Index0);
453 InstructionCost Cost1 =
454 TTI.getVectorInstrCost(*Ext1, VecTy, CostKind, Index1);
455
456 // If both costs are invalid no shuffle is needed
457 if (!Cost0.isValid() && !Cost1.isValid())
458 return nullptr;
459
460 // We are extracting from 2 different indexes, so one operand must be shuffled
461 // before performing a vector operation and/or extract. The more expensive
462 // extract will be replaced by a shuffle.
463 if (Cost0 > Cost1)
464 return Ext0;
465 if (Cost1 > Cost0)
466 return Ext1;
467
468 // If the costs are equal and there is a preferred extract index, shuffle the
469 // opposite operand.
470 if (PreferredExtractIndex == Index0)
471 return Ext1;
472 if (PreferredExtractIndex == Index1)
473 return Ext0;
474
475 // Otherwise, replace the extract with the higher index.
476 return Index0 > Index1 ? Ext0 : Ext1;
477}
478
479/// Compare the relative costs of 2 extracts followed by scalar operation vs.
480/// vector operation(s) followed by extract. Return true if the existing
481/// instructions are cheaper than a vector alternative. Otherwise, return false
482/// and if one of the extracts should be transformed to a shufflevector, set
483/// \p ConvertToShuffle to that extract instruction.
484bool VectorCombine::isExtractExtractCheap(ExtractElementInst *Ext0,
485 ExtractElementInst *Ext1,
486 const Instruction &I,
487 ExtractElementInst *&ConvertToShuffle,
488 unsigned PreferredExtractIndex) {
489 auto *Ext0IndexC = dyn_cast<ConstantInt>(Ext0->getIndexOperand());
490 auto *Ext1IndexC = dyn_cast<ConstantInt>(Ext1->getIndexOperand());
491 assert(Ext0IndexC && Ext1IndexC && "Expected constant extract indexes");
492
493 unsigned Opcode = I.getOpcode();
494 Value *Ext0Src = Ext0->getVectorOperand();
495 Value *Ext1Src = Ext1->getVectorOperand();
496 Type *ScalarTy = Ext0->getType();
497 auto *VecTy = cast<VectorType>(Ext0Src->getType());
498 InstructionCost ScalarOpCost, VectorOpCost;
499
500 // Get cost estimates for scalar and vector versions of the operation.
501 bool IsBinOp = Instruction::isBinaryOp(Opcode);
502 if (IsBinOp) {
503 ScalarOpCost = TTI.getArithmeticInstrCost(Opcode, ScalarTy, CostKind);
504 VectorOpCost = TTI.getArithmeticInstrCost(Opcode, VecTy, CostKind);
505 } else {
506 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
507 "Expected a compare");
508 CmpInst::Predicate Pred = cast<CmpInst>(I).getPredicate();
509 ScalarOpCost = TTI.getCmpSelInstrCost(
510 Opcode, ScalarTy, CmpInst::makeCmpResultType(ScalarTy), Pred, CostKind);
511 VectorOpCost = TTI.getCmpSelInstrCost(
512 Opcode, VecTy, CmpInst::makeCmpResultType(VecTy), Pred, CostKind);
513 }
514
515 // Get cost estimates for the extract elements. These costs will factor into
516 // both sequences.
517 unsigned Ext0Index = Ext0IndexC->getZExtValue();
518 unsigned Ext1Index = Ext1IndexC->getZExtValue();
519
520 InstructionCost Extract0Cost =
521 TTI.getVectorInstrCost(*Ext0, VecTy, CostKind, Ext0Index);
522 InstructionCost Extract1Cost =
523 TTI.getVectorInstrCost(*Ext1, VecTy, CostKind, Ext1Index);
524
525 // A more expensive extract will always be replaced by a splat shuffle.
526 // For example, if Ext0 is more expensive:
527 // opcode (extelt V0, Ext0), (ext V1, Ext1) -->
528 // extelt (opcode (splat V0, Ext0), V1), Ext1
529 // TODO: Evaluate whether that always results in lowest cost. Alternatively,
530 // check the cost of creating a broadcast shuffle and shuffling both
531 // operands to element 0.
532 unsigned BestExtIndex = Extract0Cost > Extract1Cost ? Ext0Index : Ext1Index;
533 unsigned BestInsIndex = Extract0Cost > Extract1Cost ? Ext1Index : Ext0Index;
534 InstructionCost CheapExtractCost = std::min(Extract0Cost, Extract1Cost);
535
536 // Extra uses of the extracts mean that we include those costs in the
537 // vector total because those instructions will not be eliminated.
538 InstructionCost OldCost, NewCost;
539 if (Ext0Src == Ext1Src && Ext0Index == Ext1Index) {
540 // Handle a special case. If the 2 extracts are identical, adjust the
541 // formulas to account for that. The extra use charge allows for either the
542 // CSE'd pattern or an unoptimized form with identical values:
543 // opcode (extelt V, C), (extelt V, C) --> extelt (opcode V, V), C
544 bool HasUseTax = Ext0 == Ext1 ? !Ext0->hasNUses(2)
545 : !Ext0->hasOneUse() || !Ext1->hasOneUse();
546 OldCost = CheapExtractCost + ScalarOpCost;
547 NewCost = VectorOpCost + CheapExtractCost + HasUseTax * CheapExtractCost;
548 } else {
549 // Handle the general case. Each extract is actually a different value:
550 // opcode (extelt V0, C0), (extelt V1, C1) --> extelt (opcode V0, V1), C
551 OldCost = Extract0Cost + Extract1Cost + ScalarOpCost;
552 NewCost = VectorOpCost + CheapExtractCost +
553 !Ext0->hasOneUse() * Extract0Cost +
554 !Ext1->hasOneUse() * Extract1Cost;
555 }
556
557 ConvertToShuffle = getShuffleExtract(Ext0, Ext1, PreferredExtractIndex);
558 if (ConvertToShuffle) {
559 if (IsBinOp && Opts.disable_binop_extract_shuffle)
560 return true;
561
562 // If we are extracting from 2 different indexes, then one operand must be
563 // shuffled before performing the vector operation. The shuffle mask is
564 // poison except for 1 lane that is being translated to the remaining
565 // extraction lane. Therefore, it is a splat shuffle. Ex:
566 // ShufMask = { poison, poison, 0, poison }
567 // TODO: The cost model has an option for a "broadcast" shuffle
568 // (splat-from-element-0), but no option for a more general splat.
569 if (auto *FixedVecTy = dyn_cast<FixedVectorType>(VecTy)) {
570 SmallVector<int> ShuffleMask(FixedVecTy->getNumElements(),
572 ShuffleMask[BestInsIndex] = BestExtIndex;
574 VecTy, VecTy, CostKind, ShuffleMask, 0,
575 nullptr, {ConvertToShuffle});
576 } else {
578 VecTy, VecTy, CostKind, {}, 0, nullptr,
579 {ConvertToShuffle});
580 }
581 }
582
583 LLVM_DEBUG(dbgs() << "Found a binop of extractions: " << I << "\n OldCost: "
584 << OldCost << " vs NewCost: " << NewCost << "\n");
585
586 // Aggressively form a vector op if the cost is equal because the transform
587 // may enable further optimization.
588 // Codegen can reverse this transform (scalarize) if it was not profitable.
589 return OldCost < NewCost;
590}
591
592/// Create a shuffle that translates (shifts) 1 element from the input vector
593/// to a new element location.
594static Value *createShiftShuffle(Value *Vec, unsigned OldIndex,
595 unsigned NewIndex, IRBuilderBase &Builder) {
596 // The shuffle mask is poison except for 1 lane that is being translated
597 // to the new element index. Example for OldIndex == 2 and NewIndex == 0:
598 // ShufMask = { 2, poison, poison, poison }
599 auto *VecTy = cast<FixedVectorType>(Vec->getType());
600 SmallVector<int, 32> ShufMask(VecTy->getNumElements(), PoisonMaskElem);
601 ShufMask[NewIndex] = OldIndex;
602 return Builder.CreateShuffleVector(Vec, ShufMask, "shift");
603}
604
605/// Given an extract element instruction with constant index operand, shuffle
606/// the source vector (shift the scalar element) to a NewIndex for extraction.
607/// Return null if the input can be constant folded, so that we are not creating
608/// unnecessary instructions.
609static Value *translateExtract(ExtractElementInst *ExtElt, unsigned NewIndex,
610 IRBuilderBase &Builder) {
611 // Shufflevectors can only be created for fixed-width vectors.
612 Value *X = ExtElt->getVectorOperand();
613 if (!isa<FixedVectorType>(X->getType()))
614 return nullptr;
615
616 // If the extract can be constant-folded, this code is unsimplified. Defer
617 // to other passes to handle that.
618 Value *C = ExtElt->getIndexOperand();
619 assert(isa<ConstantInt>(C) && "Expected a constant index operand");
620 if (isa<Constant>(X))
621 return nullptr;
622
623 Value *Shuf = createShiftShuffle(X, cast<ConstantInt>(C)->getZExtValue(),
624 NewIndex, Builder);
625 return Shuf;
626}
627
628/// Try to reduce extract element costs by converting scalar compares to vector
629/// compares followed by extract.
630/// cmp (ext0 V0, ExtIndex), (ext1 V1, ExtIndex)
631Value *VectorCombine::foldExtExtCmp(Value *V0, Value *V1, Value *ExtIndex,
632 Instruction &I) {
633 assert(isa<CmpInst>(&I) && "Expected a compare");
634
635 // cmp Pred (extelt V0, ExtIndex), (extelt V1, ExtIndex)
636 // --> extelt (cmp Pred V0, V1), ExtIndex
637 ++NumVecCmp;
638 CmpInst::Predicate Pred = cast<CmpInst>(&I)->getPredicate();
639 Value *VecCmp = Builder.CreateCmp(Pred, V0, V1);
640 return Builder.CreateExtractElement(VecCmp, ExtIndex, "foldExtExtCmp");
641}
642
643/// Try to reduce extract element costs by converting scalar binops to vector
644/// binops followed by extract.
645/// bo (ext0 V0, ExtIndex), (ext1 V1, ExtIndex)
646Value *VectorCombine::foldExtExtBinop(Value *V0, Value *V1, Value *ExtIndex,
647 Instruction &I) {
648 assert(isa<BinaryOperator>(&I) && "Expected a binary operator");
649
650 // bo (extelt V0, ExtIndex), (extelt V1, ExtIndex)
651 // --> extelt (bo V0, V1), ExtIndex
652 ++NumVecBO;
653 Value *VecBO = Builder.CreateBinOp(cast<BinaryOperator>(&I)->getOpcode(), V0,
654 V1, "foldExtExtBinop");
655
656 // All IR flags are safe to back-propagate because any potential poison
657 // created in unused vector elements is discarded by the extract.
658 if (auto *VecBOInst = dyn_cast<Instruction>(VecBO))
659 VecBOInst->copyIRFlags(&I);
660
661 return Builder.CreateExtractElement(VecBO, ExtIndex, "foldExtExtBinop");
662}
663
664/// Match an instruction with extracted vector operands.
665bool VectorCombine::foldExtractExtract(Instruction &I) {
666 // It is not safe to transform things like div, urem, etc. because we may
667 // create undefined behavior when executing those on unknown vector elements.
669 return false;
670
671 Instruction *I0, *I1;
672 CmpPredicate Pred = CmpInst::BAD_ICMP_PREDICATE;
673 if (!match(&I, m_Cmp(Pred, m_Instruction(I0), m_Instruction(I1))) &&
675 return false;
676
677 Value *V0, *V1;
678 uint64_t C0, C1;
679 if (!match(I0, m_ExtractElt(m_Value(V0), m_ConstantInt(C0))) ||
681 V0->getType() != V1->getType())
682 return false;
683
684 // For fixed-width vectors, reject out-of-bounds extract indexes
685 if (auto *FixedVecTy = dyn_cast<FixedVectorType>(V0->getType())) {
686 unsigned NumElts = FixedVecTy->getNumElements();
687 if (C0 >= NumElts || C1 >= NumElts)
688 return false;
689 }
690
691 // If the scalar value 'I' is going to be re-inserted into a vector, then try
692 // to create an extract to that same element. The extract/insert can be
693 // reduced to a "select shuffle".
694 // TODO: If we add a larger pattern match that starts from an insert, this
695 // probably becomes unnecessary.
696 auto *Ext0 = cast<ExtractElementInst>(I0);
697 auto *Ext1 = cast<ExtractElementInst>(I1);
698 uint64_t InsertIndex = InvalidIndex;
699 if (I.hasOneUse())
700 match(I.user_back(),
701 m_InsertElt(m_Value(), m_Value(), m_ConstantInt(InsertIndex)));
702
703 ExtractElementInst *ExtractToChange;
704 if (isExtractExtractCheap(Ext0, Ext1, I, ExtractToChange, InsertIndex))
705 return false;
706
707 Value *ExtOp0 = Ext0->getVectorOperand();
708 Value *ExtOp1 = Ext1->getVectorOperand();
709
710 if (ExtractToChange) {
711 unsigned CheapExtractIdx = ExtractToChange == Ext0 ? C1 : C0;
712 Value *NewExtOp =
713 translateExtract(ExtractToChange, CheapExtractIdx, Builder);
714 if (!NewExtOp)
715 return false;
716 if (ExtractToChange == Ext0)
717 ExtOp0 = NewExtOp;
718 else
719 ExtOp1 = NewExtOp;
720 }
721
722 Value *ExtIndex = ExtractToChange == Ext0 ? Ext1->getIndexOperand()
723 : Ext0->getIndexOperand();
725 ? foldExtExtCmp(ExtOp0, ExtOp1, ExtIndex, I)
726 : foldExtExtBinop(ExtOp0, ExtOp1, ExtIndex, I);
727 replaceValue(I, *NewExt);
728 return true;
729}
730
731/// Try to replace an extract + scalar fneg + insert with a vector fneg +
732/// shuffle.
733bool VectorCombine::foldInsExtFNeg(Instruction &I) {
734 // Match an insert (op (extract)) pattern.
735 Value *DstVec;
736 uint64_t ExtIdx, InsIdx;
737 Instruction *FNeg;
738 if (!match(&I, m_InsertElt(m_Value(DstVec), m_OneUse(m_Instruction(FNeg)),
739 m_ConstantInt(InsIdx))))
740 return false;
741
742 // Note: This handles the canonical fneg instruction and "fsub -0.0, X".
743 Value *SrcVec;
744 Instruction *Extract;
745 // TODO: Confirm whether m_FNegOrFSubNegZero is correct.
747 m_Instruction(Extract),
748 m_ExtractElt(m_Value(SrcVec), m_ConstantInt(ExtIdx))))))
749 return false;
750
751 auto *DstVecTy = cast<FixedVectorType>(DstVec->getType());
752 auto *DstVecScalarTy = DstVecTy->getScalarType();
753 auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcVec->getType());
754 if (!SrcVecTy || DstVecScalarTy != SrcVecTy->getScalarType())
755 return false;
756
757 // Ignore if insert/extract index is out of bounds or destination vector has
758 // one element
759 unsigned NumDstElts = DstVecTy->getNumElements();
760 unsigned NumSrcElts = SrcVecTy->getNumElements();
761 if (ExtIdx > NumSrcElts || InsIdx >= NumDstElts || NumDstElts == 1)
762 return false;
763
764 // We are inserting the negated element into the same lane that we extracted
765 // from. This is equivalent to a select-shuffle that chooses all but the
766 // negated element from the destination vector.
767 SmallVector<int> Mask(NumDstElts);
768 std::iota(Mask.begin(), Mask.end(), 0);
769 Mask[InsIdx] = (ExtIdx % NumDstElts) + NumDstElts;
770 InstructionCost OldCost =
771 TTI.getArithmeticInstrCost(Instruction::FNeg, DstVecScalarTy, CostKind) +
772 TTI.getVectorInstrCost(I, DstVecTy, CostKind, InsIdx);
773
774 // If the extract has one use, it will be eliminated, so count it in the
775 // original cost. If it has more than one use, ignore the cost because it will
776 // be the same before/after.
777 if (Extract->hasOneUse())
778 OldCost += TTI.getVectorInstrCost(*Extract, SrcVecTy, CostKind, ExtIdx);
779
780 InstructionCost NewCost =
781 TTI.getArithmeticInstrCost(Instruction::FNeg, SrcVecTy, CostKind) +
783 DstVecTy, CostKind, Mask);
784
785 bool NeedLenChg = SrcVecTy->getNumElements() != NumDstElts;
786 // If the lengths of the two vectors are not equal,
787 // we need to add a length-change vector. Add this cost.
788 SmallVector<int> SrcMask;
789 if (NeedLenChg) {
790 SrcMask.assign(NumDstElts, PoisonMaskElem);
791 SrcMask[ExtIdx % NumDstElts] = ExtIdx;
793 DstVecTy, SrcVecTy, CostKind, SrcMask);
794 }
795
796 LLVM_DEBUG(dbgs() << "Found an insertion of (extract)fneg : " << I
797 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
798 << "\n");
799 if (NewCost > OldCost)
800 return false;
801
802 Value *NewShuf, *LenChgShuf = nullptr;
803 // insertelt DstVec, (fneg (extractelt SrcVec, Index)), Index
804 Value *VecFNeg = Builder.CreateFNegFMF(SrcVec, FNeg);
805 if (NeedLenChg) {
806 // shuffle DstVec, (shuffle (fneg SrcVec), poison, SrcMask), Mask
807 LenChgShuf = Builder.CreateShuffleVector(VecFNeg, SrcMask);
808 NewShuf = Builder.CreateShuffleVector(DstVec, LenChgShuf, Mask);
809 } else {
810 // shuffle DstVec, (fneg SrcVec), Mask
811 NewShuf = Builder.CreateShuffleVector(DstVec, VecFNeg, Mask);
812 }
813
814 replaceValue(I, *NewShuf);
815 return true;
816}
817
818/// Try to fold insert(binop(x,y),binop(a,b),idx)
819/// --> binop(insert(x,a,idx),insert(y,b,idx))
820bool VectorCombine::foldInsExtBinop(Instruction &I) {
821 BinaryOperator *VecBinOp, *SclBinOp;
823 if (!match(&I,
824 m_InsertElt(m_OneUse(m_BinOp(VecBinOp)),
825 m_OneUse(m_BinOp(SclBinOp)), m_ConstantInt(Index))))
826 return false;
827
828 // TODO: Add support for addlike etc.
829 Instruction::BinaryOps BinOpcode = VecBinOp->getOpcode();
830 if (BinOpcode != SclBinOp->getOpcode())
831 return false;
832
833 auto *ResultTy = dyn_cast<FixedVectorType>(I.getType());
834 if (!ResultTy)
835 return false;
836
837 // TODO: Attempt to detect m_ExtractElt for scalar operands and convert to
838 // shuffle?
839
840 InstructionCost OldCost = TTI.getInstructionCost(&I, CostKind) +
841 TTI.getInstructionCost(VecBinOp, CostKind) +
842 TTI.getInstructionCost(SclBinOp, CostKind);
843 InstructionCost NewCost =
844 TTI.getArithmeticInstrCost(BinOpcode, ResultTy, CostKind) +
845 TTI.getVectorInstrCost(Instruction::InsertElement, ResultTy, CostKind,
846 Index, VecBinOp->getOperand(0),
847 SclBinOp->getOperand(0)) +
848 TTI.getVectorInstrCost(Instruction::InsertElement, ResultTy, CostKind,
849 Index, VecBinOp->getOperand(1),
850 SclBinOp->getOperand(1));
851
852 LLVM_DEBUG(dbgs() << "Found an insertion of two binops: " << I
853 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
854 << "\n");
855 if (NewCost > OldCost)
856 return false;
857
858 Value *NewIns0 = Builder.CreateInsertElement(VecBinOp->getOperand(0),
859 SclBinOp->getOperand(0), Index);
860 Value *NewIns1 = Builder.CreateInsertElement(VecBinOp->getOperand(1),
861 SclBinOp->getOperand(1), Index);
862 Value *NewBO = Builder.CreateBinOp(BinOpcode, NewIns0, NewIns1);
863
864 // Intersect flags from the old binops.
865 if (auto *NewInst = dyn_cast<Instruction>(NewBO)) {
866 NewInst->copyIRFlags(VecBinOp);
867 NewInst->andIRFlags(SclBinOp);
868 }
869
870 replaceValue(I, *NewBO);
871 return true;
872}
873
874/// Match: bitop(castop(x), castop(y)) -> castop(bitop(x, y))
875/// Supports: bitcast, trunc, sext, zext
876bool VectorCombine::foldBitOpOfCastops(Instruction &I) {
877 // Check if this is a bitwise logic operation
878 auto *BinOp = dyn_cast<BinaryOperator>(&I);
879 if (!BinOp || !BinOp->isBitwiseLogicOp())
880 return false;
881
882 // Get the cast instructions
883 auto *LHSCast = dyn_cast<CastInst>(BinOp->getOperand(0));
884 auto *RHSCast = dyn_cast<CastInst>(BinOp->getOperand(1));
885 if (!LHSCast || !RHSCast) {
886 LLVM_DEBUG(dbgs() << " One or both operands are not cast instructions\n");
887 return false;
888 }
889
890 // Both casts must be the same type
891 Instruction::CastOps CastOpcode = LHSCast->getOpcode();
892 if (CastOpcode != RHSCast->getOpcode())
893 return false;
894
895 // Only handle supported cast operations
896 switch (CastOpcode) {
897 case Instruction::BitCast:
898 case Instruction::Trunc:
899 case Instruction::SExt:
900 case Instruction::ZExt:
901 break;
902 default:
903 return false;
904 }
905
906 Value *LHSSrc = LHSCast->getOperand(0);
907 Value *RHSSrc = RHSCast->getOperand(0);
908
909 // Source types must match
910 if (LHSSrc->getType() != RHSSrc->getType())
911 return false;
912
913 auto *SrcTy = LHSSrc->getType();
914 auto *DstTy = I.getType();
915 // Bitcasts can handle scalar/vector mixes, such as i16 -> <16 x i1>.
916 // Other casts only handle vector types with integer elements.
917 if (CastOpcode != Instruction::BitCast &&
918 (!isa<FixedVectorType>(SrcTy) || !isa<FixedVectorType>(DstTy)))
919 return false;
920
921 // Only integer scalar/vector values are legal for bitwise logic operations.
922 if (!SrcTy->getScalarType()->isIntegerTy() ||
923 !DstTy->getScalarType()->isIntegerTy())
924 return false;
925
926 // Cost Check :
927 // OldCost = bitlogic + 2*casts
928 // NewCost = bitlogic + cast
929
930 // Calculate specific costs for each cast with instruction context
932 CastOpcode, DstTy, SrcTy, TTI::CastContextHint::None, CostKind, LHSCast);
934 CastOpcode, DstTy, SrcTy, TTI::CastContextHint::None, CostKind, RHSCast);
935
936 InstructionCost OldCost =
937 TTI.getArithmeticInstrCost(BinOp->getOpcode(), DstTy, CostKind) +
938 LHSCastCost + RHSCastCost;
939
940 // For new cost, we can't provide an instruction (it doesn't exist yet)
941 InstructionCost GenericCastCost = TTI.getCastInstrCost(
942 CastOpcode, DstTy, SrcTy, TTI::CastContextHint::None, CostKind);
943
944 InstructionCost NewCost =
945 TTI.getArithmeticInstrCost(BinOp->getOpcode(), SrcTy, CostKind) +
946 GenericCastCost;
947
948 // Account for multi-use casts using specific costs
949 if (!LHSCast->hasOneUse())
950 NewCost += LHSCastCost;
951 if (!RHSCast->hasOneUse())
952 NewCost += RHSCastCost;
953
954 LLVM_DEBUG(dbgs() << "foldBitOpOfCastops: OldCost=" << OldCost
955 << " NewCost=" << NewCost << "\n");
956
957 if (NewCost > OldCost)
958 return false;
959
960 // Create the operation on the source type
961 Value *NewOp = Builder.CreateBinOp(BinOp->getOpcode(), LHSSrc, RHSSrc,
962 BinOp->getName() + ".inner");
963 if (auto *NewBinOp = dyn_cast<BinaryOperator>(NewOp))
964 NewBinOp->copyIRFlags(BinOp);
965
966 // Create the cast operation directly to ensure we get a new instruction
967 Instruction *NewCast = CastInst::Create(CastOpcode, NewOp, I.getType());
968
969 // Preserve cast instruction flags
970 NewCast->copyIRFlags(LHSCast);
971 NewCast->andIRFlags(RHSCast);
972
973 // Insert the new instruction
974 Value *Result = Builder.Insert(NewCast);
975
976 replaceValue(I, *Result);
977 return true;
978}
979
980/// Match:
981// bitop(castop(x), C) ->
982// bitop(castop(x), castop(InvC)) ->
983// castop(bitop(x, InvC))
984// Supports: bitcast
985bool VectorCombine::foldBitOpOfCastConstant(Instruction &I) {
987 Constant *C;
988
989 // Check if this is a bitwise logic operation
991 return false;
992
993 // Get the cast instructions
994 auto *LHSCast = dyn_cast<CastInst>(LHS);
995 if (!LHSCast)
996 return false;
997
998 Instruction::CastOps CastOpcode = LHSCast->getOpcode();
999
1000 // Only handle supported cast operations
1001 switch (CastOpcode) {
1002 case Instruction::BitCast:
1003 case Instruction::ZExt:
1004 case Instruction::SExt:
1005 case Instruction::Trunc:
1006 break;
1007 default:
1008 return false;
1009 }
1010
1011 Value *LHSSrc = LHSCast->getOperand(0);
1012
1013 auto *SrcTy = LHSSrc->getType();
1014 auto *DstTy = I.getType();
1015 // Bitcasts can handle scalar/vector mixes, such as i16 -> <16 x i1>.
1016 // Other casts only handle vector types with integer elements.
1017 if (CastOpcode != Instruction::BitCast &&
1018 (!isa<FixedVectorType>(SrcTy) || !isa<FixedVectorType>(DstTy)))
1019 return false;
1020
1021 // Only integer scalar/vector values are legal for bitwise logic operations.
1022 if (!SrcTy->getScalarType()->isIntegerTy() ||
1023 !DstTy->getScalarType()->isIntegerTy())
1024 return false;
1025
1026 // Find the constant InvC, such that castop(InvC) equals to C.
1027 PreservedCastFlags RHSFlags;
1028 Constant *InvC = getLosslessInvCast(C, SrcTy, CastOpcode, *DL, &RHSFlags);
1029 if (!InvC)
1030 return false;
1031
1032 // Cost Check :
1033 // OldCost = bitlogic + cast
1034 // NewCost = bitlogic + cast
1035
1036 // Calculate specific costs for each cast with instruction context
1037 InstructionCost LHSCastCost = TTI.getCastInstrCost(
1038 CastOpcode, DstTy, SrcTy, TTI::CastContextHint::None, CostKind, LHSCast);
1039
1040 InstructionCost OldCost =
1041 TTI.getArithmeticInstrCost(I.getOpcode(), DstTy, CostKind) + LHSCastCost;
1042
1043 // For new cost, we can't provide an instruction (it doesn't exist yet)
1044 InstructionCost GenericCastCost = TTI.getCastInstrCost(
1045 CastOpcode, DstTy, SrcTy, TTI::CastContextHint::None, CostKind);
1046
1047 InstructionCost NewCost =
1048 TTI.getArithmeticInstrCost(I.getOpcode(), SrcTy, CostKind) +
1049 GenericCastCost;
1050
1051 // Account for multi-use casts using specific costs
1052 if (!LHSCast->hasOneUse())
1053 NewCost += LHSCastCost;
1054
1055 LLVM_DEBUG(dbgs() << "foldBitOpOfCastConstant: OldCost=" << OldCost
1056 << " NewCost=" << NewCost << "\n");
1057
1058 if (NewCost > OldCost)
1059 return false;
1060
1061 // Create the operation on the source type
1062 Value *NewOp = Builder.CreateBinOp((Instruction::BinaryOps)I.getOpcode(),
1063 LHSSrc, InvC, I.getName() + ".inner");
1064 if (auto *NewBinOp = dyn_cast<BinaryOperator>(NewOp))
1065 NewBinOp->copyIRFlags(&I);
1066
1067 // Create the cast operation directly to ensure we get a new instruction
1068 Instruction *NewCast = CastInst::Create(CastOpcode, NewOp, I.getType());
1069
1070 // Preserve cast instruction flags
1071 if (RHSFlags.NNeg)
1072 NewCast->setNonNeg();
1073 if (RHSFlags.NUW)
1074 NewCast->setHasNoUnsignedWrap();
1075 if (RHSFlags.NSW)
1076 NewCast->setHasNoSignedWrap();
1077
1078 NewCast->andIRFlags(LHSCast);
1079
1080 // Insert the new instruction
1081 Value *Result = Builder.Insert(NewCast);
1082
1083 replaceValue(I, *Result);
1084 return true;
1085}
1086
1087/// If this is a bitcast of a shuffle, try to bitcast the source vector to the
1088/// destination type followed by shuffle. This can enable further transforms by
1089/// moving bitcasts or shuffles together.
1090bool VectorCombine::foldBitcastShuffle(Instruction &I) {
1091 Value *V0, *V1;
1092 ArrayRef<int> Mask;
1093 if (!match(&I, m_BitCast(m_OneUse(
1094 m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(Mask))))))
1095 return false;
1096
1097 // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for
1098 // scalable type is unknown; Second, we cannot reason if the narrowed shuffle
1099 // mask for scalable type is a splat or not.
1100 // 2) Disallow non-vector casts.
1101 // TODO: We could allow any shuffle.
1102 auto *DestTy = dyn_cast<FixedVectorType>(I.getType());
1103 auto *SrcTy = dyn_cast<FixedVectorType>(V0->getType());
1104 if (!DestTy || !SrcTy)
1105 return false;
1106
1107 unsigned DestEltSize = DestTy->getScalarSizeInBits();
1108 unsigned SrcEltSize = SrcTy->getScalarSizeInBits();
1109 if (SrcTy->getPrimitiveSizeInBits() % DestEltSize != 0)
1110 return false;
1111
1112 bool IsUnary = isa<UndefValue>(V1);
1113
1114 // For binary shuffles, only fold bitcast(shuffle(X,Y))
1115 // if it won't increase the number of bitcasts.
1116 if (!IsUnary) {
1119 if (!(BCTy0 && BCTy0->getElementType() == DestTy->getElementType()) &&
1120 !(BCTy1 && BCTy1->getElementType() == DestTy->getElementType()))
1121 return false;
1122 }
1123
1124 SmallVector<int, 16> NewMask;
1125 if (DestEltSize <= SrcEltSize) {
1126 // The bitcast is from wide to narrow/equal elements. The shuffle mask can
1127 // always be expanded to the equivalent form choosing narrower elements.
1128 if (SrcEltSize % DestEltSize != 0)
1129 return false;
1130 unsigned ScaleFactor = SrcEltSize / DestEltSize;
1131 narrowShuffleMaskElts(ScaleFactor, Mask, NewMask);
1132 } else {
1133 // The bitcast is from narrow elements to wide elements. The shuffle mask
1134 // must choose consecutive elements to allow casting first.
1135 if (DestEltSize % SrcEltSize != 0)
1136 return false;
1137 unsigned ScaleFactor = DestEltSize / SrcEltSize;
1138 if (!widenShuffleMaskElts(ScaleFactor, Mask, NewMask))
1139 return false;
1140 }
1141
1142 // Bitcast the shuffle src - keep its original width but using the destination
1143 // scalar type.
1144 unsigned NumSrcElts = SrcTy->getPrimitiveSizeInBits() / DestEltSize;
1145 auto *NewShuffleTy =
1146 FixedVectorType::get(DestTy->getScalarType(), NumSrcElts);
1147 auto *OldShuffleTy =
1148 FixedVectorType::get(SrcTy->getScalarType(), Mask.size());
1149 unsigned NumOps = IsUnary ? 1 : 2;
1150
1151 // The new shuffle must not cost more than the old shuffle.
1155
1156 InstructionCost NewCost =
1157 TTI.getShuffleCost(SK, DestTy, NewShuffleTy, CostKind, NewMask) +
1158 (NumOps * TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy,
1159 TargetTransformInfo::CastContextHint::None,
1160 CostKind));
1161 InstructionCost OldCost =
1162 TTI.getShuffleCost(SK, OldShuffleTy, SrcTy, CostKind, Mask) +
1163 TTI.getCastInstrCost(Instruction::BitCast, DestTy, OldShuffleTy,
1164 TargetTransformInfo::CastContextHint::None,
1165 CostKind);
1166
1167 LLVM_DEBUG(dbgs() << "Found a bitcasted shuffle: " << I << "\n OldCost: "
1168 << OldCost << " vs NewCost: " << NewCost << "\n");
1169
1170 if (NewCost > OldCost || !NewCost.isValid())
1171 return false;
1172
1173 // bitcast (shuf V0, V1, MaskC) --> shuf (bitcast V0), (bitcast V1), MaskC'
1174 ++NumShufOfBitcast;
1175 Value *CastV0 = Builder.CreateBitCast(peekThroughBitcasts(V0), NewShuffleTy);
1176 Value *CastV1 = Builder.CreateBitCast(peekThroughBitcasts(V1), NewShuffleTy);
1177 Value *Shuf = Builder.CreateShuffleVector(CastV0, CastV1, NewMask);
1178 replaceValue(I, *Shuf);
1179 return true;
1180}
1181
1182/// Match a vector op/compare/intrinsic with at least one
1183/// inserted scalar operand and convert to scalar op/cmp/intrinsic followed
1184/// by insertelement.
1185bool VectorCombine::scalarizeOpOrCmp(Instruction &I) {
1186 auto *UO = dyn_cast<UnaryOperator>(&I);
1187 auto *BO = dyn_cast<BinaryOperator>(&I);
1188 auto *CI = dyn_cast<CmpInst>(&I);
1189 auto *II = dyn_cast<IntrinsicInst>(&I);
1190 if (!UO && !BO && !CI && !II)
1191 return false;
1192
1193 // TODO: Allow intrinsics with different argument types
1194 if (II) {
1195 if (!isTriviallyVectorizable(II->getIntrinsicID()))
1196 return false;
1197 for (auto [Idx, Arg] : enumerate(II->args()))
1198 if (Arg->getType() != II->getType() &&
1199 !isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Idx, &TTI))
1200 return false;
1201 }
1202
1203 // Do not convert the vector condition of a vector select into a scalar
1204 // condition. That may cause problems for codegen because of differences in
1205 // boolean formats and register-file transfers.
1206 // TODO: Can we account for that in the cost model?
1207 if (CI)
1208 for (User *U : I.users())
1209 if (match(U, m_Select(m_Specific(&I), m_Value(), m_Value())))
1210 return false;
1211
1212 // Match constant vectors or scalars being inserted into constant vectors:
1213 // vec_op [VecC0 | (inselt VecC0, V0, Index)], ...
1214 SmallVector<Value *> VecCs, ScalarOps;
1215 std::optional<uint64_t> Index;
1216
1217 auto Ops = II ? II->args() : I.operands();
1218 for (auto [OpNum, Op] : enumerate(Ops)) {
1219 Constant *VecC;
1220 Value *V;
1221 uint64_t InsIdx = 0;
1222 if (match(Op.get(), m_InsertElt(m_Constant(VecC), m_Value(V),
1223 m_ConstantInt(InsIdx)))) {
1224 // Bail if any inserts are out of bounds.
1225 VectorType *OpTy = cast<VectorType>(Op->getType());
1226 if (OpTy->getElementCount().getKnownMinValue() <= InsIdx)
1227 return false;
1228 // All inserts must have the same index.
1229 // TODO: Deal with mismatched index constants and variable indexes?
1230 if (!Index)
1231 Index = InsIdx;
1232 else if (InsIdx != *Index)
1233 return false;
1234 VecCs.push_back(VecC);
1235 ScalarOps.push_back(V);
1236 } else if (II && isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(),
1237 OpNum, &TTI)) {
1238 VecCs.push_back(Op.get());
1239 ScalarOps.push_back(Op.get());
1240 } else if (match(Op.get(), m_Constant(VecC))) {
1241 VecCs.push_back(VecC);
1242 ScalarOps.push_back(nullptr);
1243 } else {
1244 return false;
1245 }
1246 }
1247
1248 // Bail if all operands are constant.
1249 if (!Index.has_value())
1250 return false;
1251
1252 VectorType *VecTy = cast<VectorType>(I.getType());
1253 Type *ScalarTy = VecTy->getScalarType();
1254 assert(VecTy->isVectorTy() &&
1255 (ScalarTy->isIntegerTy() || ScalarTy->isFloatingPointTy() ||
1256 ScalarTy->isPointerTy()) &&
1257 "Unexpected types for insert element into binop or cmp");
1258
1259 unsigned Opcode = I.getOpcode();
1260 InstructionCost ScalarOpCost, VectorOpCost;
1261 if (CI) {
1262 CmpInst::Predicate Pred = CI->getPredicate();
1263 ScalarOpCost = TTI.getCmpSelInstrCost(
1264 Opcode, ScalarTy, CmpInst::makeCmpResultType(ScalarTy), Pred, CostKind);
1265 VectorOpCost = TTI.getCmpSelInstrCost(
1266 Opcode, VecTy, CmpInst::makeCmpResultType(VecTy), Pred, CostKind);
1267 } else if (UO || BO) {
1268 ScalarOpCost = TTI.getArithmeticInstrCost(Opcode, ScalarTy, CostKind);
1269 VectorOpCost = TTI.getArithmeticInstrCost(Opcode, VecTy, CostKind);
1270 } else {
1271 IntrinsicCostAttributes ScalarICA(
1272 II->getIntrinsicID(), ScalarTy,
1273 SmallVector<Type *>(II->arg_size(), ScalarTy));
1274 ScalarOpCost = TTI.getIntrinsicInstrCost(ScalarICA, CostKind);
1275 IntrinsicCostAttributes VectorICA(
1276 II->getIntrinsicID(), VecTy,
1277 SmallVector<Type *>(II->arg_size(), VecTy));
1278 VectorOpCost = TTI.getIntrinsicInstrCost(VectorICA, CostKind);
1279 }
1280
1281 // Fold the vector constants in the original vectors into a new base vector to
1282 // get more accurate cost modelling.
1283 Value *NewVecC = nullptr;
1284 if (CI)
1285 NewVecC = simplifyCmpInst(CI->getPredicate(), VecCs[0], VecCs[1], SQ);
1286 else if (UO)
1287 NewVecC =
1288 simplifyUnOp(UO->getOpcode(), VecCs[0], UO->getFastMathFlags(), SQ);
1289 else if (BO)
1290 NewVecC = simplifyBinOp(BO->getOpcode(), VecCs[0], VecCs[1], SQ);
1291 else if (II)
1292 NewVecC = simplifyCall(II, II->getCalledOperand(), VecCs, SQ);
1293
1294 if (!NewVecC)
1295 return false;
1296
1297 // Get cost estimate for the insert element. This cost will factor into
1298 // both sequences.
1299 InstructionCost OldCost = VectorOpCost;
1300 InstructionCost NewCost =
1301 ScalarOpCost + TTI.getVectorInstrCost(Instruction::InsertElement, VecTy,
1302 CostKind, *Index, NewVecC);
1303
1304 for (auto [Idx, Op, VecC, Scalar] : enumerate(Ops, VecCs, ScalarOps)) {
1305 if (!Scalar || (II && isVectorIntrinsicWithScalarOpAtArg(
1306 II->getIntrinsicID(), Idx, &TTI)))
1307 continue;
1309 Instruction::InsertElement, VecTy, CostKind, *Index, VecC, Scalar);
1310 OldCost += InsertCost;
1311 NewCost += !Op->hasOneUse() * InsertCost;
1312 }
1313
1314 // We want to scalarize unless the vector variant actually has lower cost.
1315 if (OldCost < NewCost || !NewCost.isValid())
1316 return false;
1317
1318 // vec_op (inselt VecC0, V0, Index), (inselt VecC1, V1, Index) -->
1319 // inselt NewVecC, (scalar_op V0, V1), Index
1320 if (CI)
1321 ++NumScalarCmp;
1322 else if (UO || BO)
1323 ++NumScalarOps;
1324 else
1325 ++NumScalarIntrinsic;
1326
1327 // For constant cases, extract the scalar element, this should constant fold.
1328 for (auto [OpIdx, Scalar, VecC] : enumerate(ScalarOps, VecCs))
1329 if (!Scalar)
1330 ScalarOps[OpIdx] = ConstantExpr::getExtractElement(
1331 cast<Constant>(VecC), Builder.getInt64(*Index));
1332
1333 Value *Scalar;
1334 // We need to pass the flags during the creation of instructions. Constant
1335 // folding might remove the instructions, so post setting the flags might
1336 // pollute the later instructions.
1337 if (CI) {
1338 if (FPMathOperator *FPMO = dyn_cast<FPMathOperator>(&I)) {
1339 Scalar = Builder.CreateFCmpFMF(CI->getPredicate(), ScalarOps[0],
1340 ScalarOps[1], FPMO->getFastMathFlags(),
1341 CI->getName() + ".scalar");
1342 } else {
1343 Scalar = Builder.CreateICmp(CI->getPredicate(), ScalarOps[0],
1344 ScalarOps[1], CI->getName() + ".scalar");
1345 }
1346 } else if (UO) {
1347 Scalar = Builder.CreateUnOpFMF(UO->getOpcode(), ScalarOps[0], UO,
1348 UO->getName() + ".scalar");
1349 } else if (BO) {
1350 if (OverflowingBinaryOperator *OBO =
1352 Scalar = Builder.CreateNoWrapBinOp(
1353 BO->getOpcode(), ScalarOps[0], ScalarOps[1], OBO->hasNoUnsignedWrap(),
1354 OBO->hasNoSignedWrap(), BO->getName() + ".scalar");
1355 } else if (PossiblyDisjointInst *PDI = dyn_cast<PossiblyDisjointInst>(&I)) {
1356 Scalar = Builder.CreateOr(ScalarOps[0], ScalarOps[1],
1357 BO->getName() + ".scalar", PDI->isDisjoint());
1358 } else if (PossiblyExactOperator *PEO =
1360 Scalar =
1361 Builder.CreateExactBinOp(BO->getOpcode(), ScalarOps[0], ScalarOps[1],
1362 PEO->isExact(), BO->getName() + ".scalar");
1363 } else if (FPMathOperator *FPMO = dyn_cast<FPMathOperator>(&I)) {
1364 Scalar = Builder.CreateBinOpFMF(BO->getOpcode(), ScalarOps[0],
1365 ScalarOps[1], FPMO->getFastMathFlags(),
1366 BO->getName() + ".scalar");
1367 } else {
1368 Scalar = Builder.CreateBinOp(BO->getOpcode(), ScalarOps[0], ScalarOps[1],
1369 BO->getName() + ".scalar");
1370 }
1371 } else {
1372 FastMathFlags FMF;
1373 if (auto *FPMO = dyn_cast<FPMathOperator>(&I))
1374 FMF = FPMO->getFastMathFlags();
1375 Scalar = Builder.CreateIntrinsic(ScalarTy, II->getIntrinsicID(), ScalarOps,
1376 FMF, II->getName() + ".scalar");
1377 }
1378
1379 Value *Insert = Builder.CreateInsertElement(NewVecC, Scalar, *Index);
1380 replaceValue(I, *Insert);
1381 return true;
1382}
1383
1384/// Try to combine a scalar binop + 2 scalar compares of extracted elements of
1385/// a vector into vector operations followed by extract. Note: The SLP pass
1386/// may miss this pattern because of implementation problems.
1387bool VectorCombine::foldExtractedCmps(Instruction &I) {
1388 auto *BI = dyn_cast<BinaryOperator>(&I);
1389
1390 // We are looking for a scalar binop of booleans.
1391 // binop i1 (cmp Pred I0, C0), (cmp Pred I1, C1)
1392 if (!BI || !I.getType()->isIntegerTy(1))
1393 return false;
1394
1395 // The compare predicates should match, and each compare should have a
1396 // constant operand.
1397 Value *B0 = I.getOperand(0), *B1 = I.getOperand(1);
1398 Instruction *I0, *I1;
1399 Constant *C0, *C1;
1400 CmpPredicate P0, P1;
1401 if (!match(B0, m_Cmp(P0, m_Instruction(I0), m_Constant(C0))) ||
1402 !match(B1, m_Cmp(P1, m_Instruction(I1), m_Constant(C1))))
1403 return false;
1404
1405 auto MatchingPred = CmpPredicate::getMatching(P0, P1);
1406 if (!MatchingPred)
1407 return false;
1408
1409 // The compare operands must be extracts of the same vector with constant
1410 // extract indexes.
1411 Value *X;
1412 uint64_t Index0, Index1;
1413 if (!match(I0, m_ExtractElt(m_Value(X), m_ConstantInt(Index0))) ||
1414 !match(I1, m_ExtractElt(m_Specific(X), m_ConstantInt(Index1))))
1415 return false;
1416
1417 auto *Ext0 = cast<ExtractElementInst>(I0);
1418 auto *Ext1 = cast<ExtractElementInst>(I1);
1419 ExtractElementInst *ConvertToShuf = getShuffleExtract(Ext0, Ext1, CostKind);
1420 if (!ConvertToShuf)
1421 return false;
1422 assert((ConvertToShuf == Ext0 || ConvertToShuf == Ext1) &&
1423 "Unknown ExtractElementInst");
1424
1425 // The original scalar pattern is:
1426 // binop i1 (cmp Pred (ext X, Index0), C0), (cmp Pred (ext X, Index1), C1)
1427 CmpInst::Predicate Pred = *MatchingPred;
1428 unsigned CmpOpcode =
1429 CmpInst::isFPPredicate(Pred) ? Instruction::FCmp : Instruction::ICmp;
1430 auto *VecTy = dyn_cast<FixedVectorType>(X->getType());
1431 if (!VecTy)
1432 return false;
1433
1434 if (Index0 >= VecTy->getNumElements() || Index1 >= VecTy->getNumElements())
1435 return false;
1436
1437 InstructionCost Ext0Cost =
1438 TTI.getVectorInstrCost(*Ext0, VecTy, CostKind, Index0);
1439 InstructionCost Ext1Cost =
1440 TTI.getVectorInstrCost(*Ext1, VecTy, CostKind, Index1);
1442 CmpOpcode, I0->getType(), CmpInst::makeCmpResultType(I0->getType()), Pred,
1443 CostKind);
1444
1445 InstructionCost OldCost =
1446 Ext0Cost + Ext1Cost + CmpCost * 2 +
1447 TTI.getArithmeticInstrCost(I.getOpcode(), I.getType(), CostKind);
1448
1449 // The proposed vector pattern is:
1450 // vcmp = cmp Pred X, VecC
1451 // ext (binop vNi1 vcmp, (shuffle vcmp, Index1)), Index0
1452 int CheapIndex = ConvertToShuf == Ext0 ? Index1 : Index0;
1453 int ExpensiveIndex = ConvertToShuf == Ext0 ? Index0 : Index1;
1456 CmpOpcode, VecTy, CmpInst::makeCmpResultType(VecTy), Pred, CostKind);
1457 SmallVector<int, 32> ShufMask(VecTy->getNumElements(), PoisonMaskElem);
1458 ShufMask[CheapIndex] = ExpensiveIndex;
1460 CmpTy, CostKind, ShufMask);
1461 NewCost += TTI.getArithmeticInstrCost(I.getOpcode(), CmpTy, CostKind);
1462 NewCost += TTI.getVectorInstrCost(*Ext0, CmpTy, CostKind, CheapIndex);
1463 NewCost += Ext0->hasOneUse() ? 0 : Ext0Cost;
1464 NewCost += Ext1->hasOneUse() ? 0 : Ext1Cost;
1465
1466 // Aggressively form vector ops if the cost is equal because the transform
1467 // may enable further optimization.
1468 // Codegen can reverse this transform (scalarize) if it was not profitable.
1469 if (OldCost < NewCost || !NewCost.isValid())
1470 return false;
1471
1472 // Create a vector constant from the 2 scalar constants.
1473 SmallVector<Constant *, 32> CmpC(VecTy->getNumElements(),
1474 PoisonValue::get(VecTy->getElementType()));
1475 CmpC[Index0] = C0;
1476 CmpC[Index1] = C1;
1477 Value *VCmp = Builder.CreateCmp(Pred, X, ConstantVector::get(CmpC));
1478 Value *Shuf = createShiftShuffle(VCmp, ExpensiveIndex, CheapIndex, Builder);
1479 Value *LHS = ConvertToShuf == Ext0 ? Shuf : VCmp;
1480 Value *RHS = ConvertToShuf == Ext0 ? VCmp : Shuf;
1481 Value *VecLogic = Builder.CreateBinOp(BI->getOpcode(), LHS, RHS);
1482 Value *NewExt = Builder.CreateExtractElement(VecLogic, CheapIndex);
1483 replaceValue(I, *NewExt);
1484 ++NumVecCmpBO;
1485 return true;
1486}
1487
1488/// Try to fold scalar selects that select between extracted elements and zero
1489/// into extracting from a vector select. This is rooted at the bitcast.
1490///
1491/// This pattern arises when a vector is bitcast to a smaller element type,
1492/// elements are extracted, and then conditionally selected with zero:
1493///
1494/// %bc = bitcast <4 x i32> %src to <16 x i8>
1495/// %e0 = extractelement <16 x i8> %bc, i32 0
1496/// %s0 = select i1 %cond, i8 %e0, i8 0
1497/// %e1 = extractelement <16 x i8> %bc, i32 1
1498/// %s1 = select i1 %cond, i8 %e1, i8 0
1499/// ...
1500///
1501/// Transforms to:
1502/// %sel = select i1 %cond, <4 x i32> %src, <4 x i32> zeroinitializer
1503/// %bc = bitcast <4 x i32> %sel to <16 x i8>
1504/// %e0 = extractelement <16 x i8> %bc, i32 0
1505/// %e1 = extractelement <16 x i8> %bc, i32 1
1506/// ...
1507///
1508/// This is profitable because vector select on wider types produces fewer
1509/// select/cndmask instructions than scalar selects on each element.
1510bool VectorCombine::foldSelectsFromBitcast(Instruction &I) {
1511 auto *BC = dyn_cast<BitCastInst>(&I);
1512 if (!BC)
1513 return false;
1514
1515 FixedVectorType *SrcVecTy = dyn_cast<FixedVectorType>(BC->getSrcTy());
1516 FixedVectorType *DstVecTy = dyn_cast<FixedVectorType>(BC->getDestTy());
1517 if (!SrcVecTy || !DstVecTy)
1518 return false;
1519
1520 // Source must be 32-bit or 64-bit elements, destination must be smaller
1521 // integer elements. Zero in all these types is all-bits-zero.
1522 Type *SrcEltTy = SrcVecTy->getElementType();
1523 Type *DstEltTy = DstVecTy->getElementType();
1524 unsigned SrcEltBits = SrcEltTy->getPrimitiveSizeInBits();
1525 unsigned DstEltBits = DstEltTy->getPrimitiveSizeInBits();
1526
1527 if (SrcEltBits != 32 && SrcEltBits != 64)
1528 return false;
1529
1530 if (!DstEltTy->isIntegerTy() || DstEltBits >= SrcEltBits)
1531 return false;
1532
1533 // Check profitability using TTI before collecting users.
1534 Type *CondTy = CmpInst::makeCmpResultType(DstEltTy);
1535 Type *VecCondTy = CmpInst::makeCmpResultType(SrcVecTy);
1536
1537 InstructionCost ScalarSelCost =
1538 TTI.getCmpSelInstrCost(Instruction::Select, DstEltTy, CondTy,
1539 CmpInst::BAD_ICMP_PREDICATE, CostKind);
1540 InstructionCost VecSelCost =
1541 TTI.getCmpSelInstrCost(Instruction::Select, SrcVecTy, VecCondTy,
1542 CmpInst::BAD_ICMP_PREDICATE, CostKind);
1543
1544 // We need at least this many selects for vectorization to be profitable.
1545 // VecSelCost < ScalarSelCost * NumSelects => NumSelects > VecSelCost /
1546 // ScalarSelCost
1547 if (!ScalarSelCost.isValid() || ScalarSelCost == 0)
1548 return false;
1549
1550 unsigned MinSelects = (VecSelCost.getValue() / ScalarSelCost.getValue()) + 1;
1551
1552 // Quick check: if bitcast doesn't have enough users, bail early.
1553 if (!BC->hasNUsesOrMore(MinSelects))
1554 return false;
1555
1556 // Collect all select users that match the pattern, grouped by condition.
1557 // Pattern: select i1 %cond, (extractelement %bc, idx), 0
1558 DenseMap<Value *, SmallVector<SelectInst *, 8>> CondToSelects;
1559
1560 for (User *U : BC->users()) {
1561 auto *Ext = dyn_cast<ExtractElementInst>(U);
1562 if (!Ext)
1563 continue;
1564
1565 for (User *ExtUser : Ext->users()) {
1566 Value *Cond;
1567 // Match: select i1 %cond, %ext, 0
1568 if (match(ExtUser, m_Select(m_Value(Cond), m_Specific(Ext), m_Zero())) &&
1569 Cond->getType()->isIntegerTy(1))
1570 CondToSelects[Cond].push_back(cast<SelectInst>(ExtUser));
1571 }
1572 }
1573
1574 if (CondToSelects.empty())
1575 return false;
1576
1577 bool MadeChange = false;
1578 Value *SrcVec = BC->getOperand(0);
1579
1580 // Process each group of selects with the same condition.
1581 for (auto [Cond, Selects] : CondToSelects) {
1582 // Only profitable if vector select cost < total scalar select cost.
1583 if (Selects.size() < MinSelects) {
1584 LLVM_DEBUG(dbgs() << "VectorCombine: foldSelectsFromBitcast not "
1585 << "profitable (VecCost=" << VecSelCost
1586 << ", ScalarCost=" << ScalarSelCost
1587 << ", NumSelects=" << Selects.size() << ")\n");
1588 continue;
1589 }
1590
1591 // Create the vector select and bitcast once for this condition.
1592 auto InsertPt = std::next(BC->getIterator());
1593
1594 if (auto *CondInst = dyn_cast<Instruction>(Cond))
1595 if (DT.dominates(BC, CondInst))
1596 InsertPt = std::next(CondInst->getIterator());
1597
1598 Builder.SetInsertPoint(InsertPt);
1599 Value *VecSel =
1600 Builder.CreateSelect(Cond, SrcVec, Constant::getNullValue(SrcVecTy));
1601 Value *NewBC = Builder.CreateBitCast(VecSel, DstVecTy);
1602
1603 // Replace each scalar select with an extract from the new bitcast.
1604 for (SelectInst *Sel : Selects) {
1605 auto *Ext = cast<ExtractElementInst>(Sel->getTrueValue());
1606 Value *Idx = Ext->getIndexOperand();
1607
1608 Builder.SetInsertPoint(Sel);
1609 Value *NewExt = Builder.CreateExtractElement(NewBC, Idx);
1610 replaceValue(*Sel, *NewExt);
1611 MadeChange = true;
1612 }
1613
1614 LLVM_DEBUG(dbgs() << "VectorCombine: folded " << Selects.size()
1615 << " selects into vector select\n");
1616 }
1617
1618 return MadeChange;
1619}
1620
1622 TTI::TargetCostKind CostKind,
1623 const TargetTransformInfo &TTI,
1624 InstructionCost &CostBeforeReduction,
1625 InstructionCost &CostAfterReduction) {
1626 Instruction *Op0, *Op1;
1627 auto *RedOp = dyn_cast<Instruction>(II.getOperand(0));
1628 auto *VecRedTy = cast<VectorType>(II.getOperand(0)->getType());
1629 unsigned ReductionOpc =
1630 getArithmeticReductionInstruction(II.getIntrinsicID());
1631 if (RedOp && match(RedOp, m_ZExtOrSExt(m_Value()))) {
1632 bool IsUnsigned = isa<ZExtInst>(RedOp);
1633 auto *ExtType = cast<VectorType>(RedOp->getOperand(0)->getType());
1634
1635 CostBeforeReduction =
1636 TTI.getCastInstrCost(RedOp->getOpcode(), VecRedTy, ExtType,
1637 TTI::CastContextHint::None, CostKind, RedOp);
1638 CostAfterReduction =
1639 TTI.getExtendedReductionCost(ReductionOpc, IsUnsigned, II.getType(),
1640 ExtType, FastMathFlags(), CostKind);
1641 return;
1642 }
1643 if (RedOp && II.getIntrinsicID() == Intrinsic::vector_reduce_add &&
1644 match(RedOp,
1646 match(Op0, m_ZExtOrSExt(m_Value())) &&
1647 Op0->getOpcode() == Op1->getOpcode() &&
1648 Op0->getOperand(0)->getType() == Op1->getOperand(0)->getType() &&
1649 (Op0->getOpcode() == RedOp->getOpcode() || Op0 == Op1)) {
1650 // Matched reduce.add(ext(mul(ext(A), ext(B)))
1651 bool IsUnsigned = isa<ZExtInst>(Op0);
1652 auto *ExtType = cast<VectorType>(Op0->getOperand(0)->getType());
1653 VectorType *MulType = VectorType::get(Op0->getType(), VecRedTy);
1654
1655 InstructionCost ExtCost =
1656 TTI.getCastInstrCost(Op0->getOpcode(), MulType, ExtType,
1657 TTI::CastContextHint::None, CostKind, Op0);
1658 InstructionCost MulCost =
1659 TTI.getArithmeticInstrCost(Instruction::Mul, MulType, CostKind);
1660 InstructionCost Ext2Cost =
1661 TTI.getCastInstrCost(RedOp->getOpcode(), VecRedTy, MulType,
1662 TTI::CastContextHint::None, CostKind, RedOp);
1663
1664 CostBeforeReduction = ExtCost * 2 + MulCost + Ext2Cost;
1665 CostAfterReduction = TTI.getMulAccReductionCost(
1666 IsUnsigned, ReductionOpc, II.getType(), ExtType, CostKind);
1667 return;
1668 }
1669 CostAfterReduction = TTI.getArithmeticReductionCost(ReductionOpc, VecRedTy,
1670 std::nullopt, CostKind);
1671}
1672
1673bool VectorCombine::foldBinopOfReductions(Instruction &I) {
1674 Instruction::BinaryOps BinOpOpc = cast<BinaryOperator>(&I)->getOpcode();
1675 Intrinsic::ID ReductionIID = getReductionForBinop(BinOpOpc);
1676 if (BinOpOpc == Instruction::Sub)
1677 ReductionIID = Intrinsic::vector_reduce_add;
1678 if (ReductionIID == Intrinsic::not_intrinsic)
1679 return false;
1680 // FP reductions have a start-value operand that this fold doesn't handle.
1681 if (ReductionIID == Intrinsic::vector_reduce_fadd ||
1682 ReductionIID == Intrinsic::vector_reduce_fmul)
1683 return false;
1684
1685 auto checkIntrinsicAndGetItsArgument = [](Value *V,
1686 Intrinsic::ID IID) -> Value * {
1687 auto *II = dyn_cast<IntrinsicInst>(V);
1688 if (!II)
1689 return nullptr;
1690 if (II->getIntrinsicID() == IID && II->hasOneUse())
1691 return II->getArgOperand(0);
1692 return nullptr;
1693 };
1694
1695 Value *V0 = checkIntrinsicAndGetItsArgument(I.getOperand(0), ReductionIID);
1696 if (!V0)
1697 return false;
1698 Value *V1 = checkIntrinsicAndGetItsArgument(I.getOperand(1), ReductionIID);
1699 if (!V1)
1700 return false;
1701
1702 auto *VTy = cast<VectorType>(V0->getType());
1703 if (V1->getType() != VTy)
1704 return false;
1705 const auto &II0 = *cast<IntrinsicInst>(I.getOperand(0));
1706 const auto &II1 = *cast<IntrinsicInst>(I.getOperand(1));
1707 unsigned ReductionOpc =
1708 getArithmeticReductionInstruction(II0.getIntrinsicID());
1709
1710 InstructionCost OldCost = 0;
1711 InstructionCost NewCost = 0;
1712 InstructionCost CostOfRedOperand0 = 0;
1713 InstructionCost CostOfRed0 = 0;
1714 InstructionCost CostOfRedOperand1 = 0;
1715 InstructionCost CostOfRed1 = 0;
1716 analyzeCostOfVecReduction(II0, CostKind, TTI, CostOfRedOperand0, CostOfRed0);
1717 analyzeCostOfVecReduction(II1, CostKind, TTI, CostOfRedOperand1, CostOfRed1);
1718 OldCost = CostOfRed0 + CostOfRed1 + TTI.getInstructionCost(&I, CostKind);
1719 NewCost =
1720 CostOfRedOperand0 + CostOfRedOperand1 +
1721 TTI.getArithmeticInstrCost(BinOpOpc, VTy, CostKind) +
1722 TTI.getArithmeticReductionCost(ReductionOpc, VTy, std::nullopt, CostKind);
1723 if (NewCost >= OldCost || !NewCost.isValid())
1724 return false;
1725
1726 LLVM_DEBUG(dbgs() << "Found two mergeable reductions: " << I
1727 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
1728 << "\n");
1729 Value *VectorBO;
1730 if (BinOpOpc == Instruction::Or)
1731 VectorBO = Builder.CreateOr(V0, V1, "",
1732 cast<PossiblyDisjointInst>(I).isDisjoint());
1733 else
1734 VectorBO = Builder.CreateBinOp(BinOpOpc, V0, V1);
1735
1736 Value *Rdx = Builder.CreateIntrinsic(ReductionIID, {VTy}, {VectorBO});
1737 replaceValue(I, *Rdx);
1738 return true;
1739}
1740
1741// Check if memory is modified, freed, or synchronized between two instrs in
1742// the same BB.
1743static bool isMemModifiedBetween(const VectorizeOptions &Opts,
1746 const MemoryLocation &Loc, AAResults &AA) {
1747 unsigned NumScanned = 0;
1748 if (std::any_of(Begin, End, [&](const Instruction &Instr) {
1749 return isModSet(AA.getModRefInfo(&Instr, Loc)) ||
1750 ++NumScanned > Opts.vector_combine_max_scan_instrs;
1751 }))
1752 return true;
1753
1754 // willNotFreeBetween expects instructions rather than iterators. An empty
1755 // range cannot free or synchronize, so avoid dereferencing its end.
1756 return Begin != End && !willNotFreeBetween(&*Begin, &*End);
1757}
1758
1759namespace {
1760/// Helper class to indicate whether a vector index can be safely scalarized and
1761/// if a freeze needs to be inserted.
1762class ScalarizationResult {
1763 enum class StatusTy { Unsafe, Safe, SafeWithFreeze };
1764
1765 StatusTy Status;
1766 Value *ToFreeze;
1767
1768 ScalarizationResult(StatusTy Status, Value *ToFreeze = nullptr)
1769 : Status(Status), ToFreeze(ToFreeze) {}
1770
1771public:
1772 ScalarizationResult(const ScalarizationResult &Other) = default;
1773 ~ScalarizationResult() {
1774 assert(!ToFreeze && "freeze() not called with ToFreeze being set");
1775 }
1776
1777 static ScalarizationResult unsafe() { return {StatusTy::Unsafe}; }
1778 static ScalarizationResult safe() { return {StatusTy::Safe}; }
1779 static ScalarizationResult safeWithFreeze(Value *ToFreeze) {
1780 return {StatusTy::SafeWithFreeze, ToFreeze};
1781 }
1782
1783 /// Returns true if the index can be scalarize without requiring a freeze.
1784 bool isSafe() const { return Status == StatusTy::Safe; }
1785 /// Returns true if the index cannot be scalarized.
1786 bool isUnsafe() const { return Status == StatusTy::Unsafe; }
1787 /// Returns true if the index can be scalarize, but requires inserting a
1788 /// freeze.
1789 bool isSafeWithFreeze() const { return Status == StatusTy::SafeWithFreeze; }
1790
1791 /// Reset the state of Unsafe and clear ToFreze if set.
1792 void discard() {
1793 ToFreeze = nullptr;
1794 Status = StatusTy::Unsafe;
1795 }
1796
1797 /// Freeze the ToFreeze and update the use in \p User to use it.
1798 void freeze(IRBuilderBase &Builder, Instruction &UserI) {
1799 assert(isSafeWithFreeze() &&
1800 "should only be used when freezing is required");
1801 assert(is_contained(ToFreeze->users(), &UserI) &&
1802 "UserI must be a user of ToFreeze");
1803 IRBuilder<>::InsertPointGuard Guard(Builder);
1804 Builder.SetInsertPoint(cast<Instruction>(&UserI));
1805 Value *Frozen =
1806 Builder.CreateFreeze(ToFreeze, ToFreeze->getName() + ".frozen");
1807 for (Use &U : make_early_inc_range((UserI.operands())))
1808 if (U.get() == ToFreeze)
1809 U.set(Frozen);
1810
1811 ToFreeze = nullptr;
1812 }
1813};
1814} // namespace
1815
1816/// Check if it is legal to scalarize a memory access to \p VecTy at index \p
1817/// Idx. \p Idx must access a valid vector element.
1818static ScalarizationResult canScalarizeAccess(VectorType *VecTy, Value *Idx,
1819 const SimplifyQuery &SQ) {
1820 // We do checks for both fixed vector types and scalable vector types.
1821 // This is the number of elements of fixed vector types,
1822 // or the minimum number of elements of scalable vector types.
1823 uint64_t NumElements = VecTy->getElementCount().getKnownMinValue();
1824 unsigned IntWidth = Idx->getType()->getScalarSizeInBits();
1825
1826 if (auto *C = dyn_cast<ConstantInt>(Idx)) {
1827 if (C->getValue().ult(NumElements))
1828 return ScalarizationResult::safe();
1829 return ScalarizationResult::unsafe();
1830 }
1831
1832 // Always unsafe if the index type can't handle all inbound values.
1833 if (!llvm::isUIntN(IntWidth, NumElements))
1834 return ScalarizationResult::unsafe();
1835
1836 APInt Zero(IntWidth, 0);
1837 APInt MaxElts(IntWidth, NumElements);
1838 ConstantRange ValidIndices(Zero, MaxElts);
1839 ConstantRange IdxRange(IntWidth, true);
1840
1841 if (isGuaranteedNotToBePoison(Idx, SQ.AC, SQ.CtxI, SQ.DT)) {
1842 if (ValidIndices.contains(
1843 computeConstantRange(Idx, /*ForSigned=*/false, SQ)))
1844 return ScalarizationResult::safe();
1845 return ScalarizationResult::unsafe();
1846 }
1847
1848 // If the index may be poison, check if we can insert a freeze before the
1849 // range of the index is restricted.
1850 Value *IdxBase;
1851 ConstantInt *CI;
1852 if (match(Idx, m_And(m_Value(IdxBase), m_ConstantInt(CI)))) {
1853 IdxRange = IdxRange.binaryAnd(CI->getValue());
1854 } else if (match(Idx, m_URem(m_Value(IdxBase), m_ConstantInt(CI)))) {
1855 IdxRange = IdxRange.urem(CI->getValue());
1856 }
1857
1858 if (ValidIndices.contains(IdxRange))
1859 return ScalarizationResult::safeWithFreeze(IdxBase);
1860 return ScalarizationResult::unsafe();
1861}
1862
1863/// Return the GEP index type if the unsigned vector index \p Idx can be
1864/// represented by an inbounds GEP. A null result means that the maximum byte
1865/// offset cannot be represented by the pointer's signed GEP index type.
1866///
1867/// unsigned lane range
1868/// |
1869/// v
1870/// MaxByteOffset = MaxLane * element store size
1871/// |
1872/// +-- unavailable or outside signed GEP range --> reject
1873/// |
1874/// v
1875/// valid range --> use the pointer's GEP index type
1877 Type *PtrTy,
1878 const DataLayout &DL) {
1879 auto *GEPIndexTy = cast<IntegerType>(DL.getIndexType(PtrTy));
1880 unsigned GEPBits = GEPIndexTy->getBitWidth();
1881 uint64_t NumElements = VecTy->getElementCount().getKnownMinValue();
1882
1883 uint64_t MaxLane = NumElements - 1;
1884 if (auto *C = dyn_cast<ConstantInt>(Idx)) {
1885 if (C->getValue().uge(NumElements))
1886 return nullptr;
1887 MaxLane = C->getZExtValue();
1888 }
1889
1890 Type *ElemTy = VecTy->getElementType();
1891 if (!DL.typeSizeEqualsStoreSize(ElemTy))
1892 return nullptr;
1893
1894 TypeSize ElemStride = DL.getTypeStoreSize(ElemTy);
1895 if (ElemStride.isScalable())
1896 return nullptr;
1897
1898 // Compare both values in a common width:
1899 //
1900 // MaxLane (uint64_t) * ElemStride (uint64_t) signed_max(GEPBits)
1901 // | |
1902 // v v
1903 // ByteOffset (up to 128 bits) sext to WideBits
1904 // \ /
1905 // +------------ ugt ------------+
1906 // |
1907 // greater -> reject
1908 //
1909 // WideBits = max(GEPBits, 128) prevents the multiplication from wrapping
1910 // and preserves the GEP limit during the comparison.
1911 unsigned WideBits = std::max(GEPBits, 128u);
1912 APInt MaxLaneValue(WideBits, MaxLane);
1913 APInt ByteOffset = MaxLaneValue;
1914 ByteOffset *= APInt(WideBits, ElemStride.getFixedValue());
1915 APInt MaxGEPOffset = APInt::getSignedMaxValue(GEPBits).sext(WideBits);
1916 // Reject offsets outside the GEP's positive signed range. Compare as
1917 // unsigned because the full 128-bit product may set its sign bit.
1918 if (ByteOffset.ugt(MaxGEPOffset))
1919 return nullptr;
1920
1921 return GEPIndexTy;
1922}
1923
1924/// Materialize an index for a scalarized GEP after profitability is known.
1925/// Vector element indices are unsigned, but GEP sign-extends narrow integer
1926/// indices. Widen a narrow index explicitly so its unsigned value is retained.
1928 IRBuilderBase &Builder) {
1929 unsigned SrcBits = Idx->getType()->getIntegerBitWidth();
1930 unsigned DstBits = GEPIndexTy->getBitWidth();
1931 if (SrcBits >= DstBits)
1932 return Idx;
1933
1934 return Builder.CreateZExt(Idx, GEPIndexTy, Idx->getName() + ".gepidx");
1935}
1936
1937/// The memory operation on a vector of \p ScalarType had alignment of
1938/// \p VectorAlignment. Compute the maximal, but conservatively correct,
1939/// alignment that will be valid for the memory operation on a single scalar
1940/// element of the same type with index \p Idx.
1942 Type *ScalarType, Value *Idx,
1943 const DataLayout &DL) {
1944 if (auto *C = dyn_cast<ConstantInt>(Idx))
1945 return commonAlignment(VectorAlignment,
1946 C->getZExtValue() * DL.getTypeStoreSize(ScalarType));
1947 return commonAlignment(VectorAlignment, DL.getTypeStoreSize(ScalarType));
1948}
1949
1950/// Fold a vector store fed by a single-use insertelement chain into scalar
1951/// stores.
1952///
1953/// Before:
1954///
1955/// %p --> vector load --> insert %x, lane 1 --> insert %y, lane 3
1956/// |
1957/// v
1958/// vector store to %p
1959///
1960/// Vector lanes: [ 0 ] [ 1 ] [ 2 ] [ 3 ]
1961/// Stored value: [ old | x | old | y ] (one vector store)
1962///
1963/// After:
1964///
1965/// +--> GEP(%p, lane 1) --> store %x
1966/// %p -------------+
1967/// +--> GEP(%p, lane 3) --> store %y
1968///
1969/// Vector lanes: [ 0 ] [ 1 ] [ 2 ] [ 3 ]
1970/// Scalar stores: x y
1971/// store@1 store@3
1972///
1973/// Step 1. Gate:
1974/// target supports vector-element GEP addressing
1975///
1976/// Step 2. Trace:
1977/// vector store <-- insertelement <-- ... <-- insertelement <-- load
1978///
1979/// Steps 3-5. Validate:
1980/// reject unprofitable full overwrites; require simple accesses, a
1981/// common address/block, no memory write in between, and scalarizable
1982/// indices.
1983bool VectorCombine::foldInsertElementsToStores(Instruction &I) {
1984 // Step 1: The target must support addressing a vector element with a GEP.
1986 return false;
1987
1988 auto *SI = cast<StoreInst>(&I);
1989 if (!SI->isSimple() || !isa<VectorType>(SI->getValueOperand()->getType()))
1990 return false;
1991
1992 // Step 2: Collect a single-use insertelement chain, starting at the vector
1993 // store and walking back to the candidate load.
1994 Value *Source = SI->getValueOperand();
1995 SmallVector<std::pair<Value *, Value *>, 4> InsertElements;
1996 Value *Base = Source;
1997 while (auto *Insert = dyn_cast<InsertElementInst>(Base)) {
1998 if (!Insert->hasOneUse())
1999 break;
2000 Value *InsertVal = Insert->getOperand(1);
2001 Value *Idx = Insert->getOperand(2);
2002 InsertElements.push_back({InsertVal, Idx});
2003 Base = Insert->getOperand(0);
2004 }
2005
2006 if (InsertElements.empty())
2007 return false;
2008
2009 // The backwards walk collected the inserts in reverse program order. Restore
2010 // it now so later scalar stores preserve writes to duplicate/equal indices.
2011 std::reverse(InsertElements.begin(), InsertElements.end());
2012 auto *Load = dyn_cast<LoadInst>(Base);
2013 if (!Load)
2014 return false;
2015 auto *VecTy = cast<VectorType>(SI->getValueOperand()->getType());
2016
2017 // Step 3: Avoid replacing a complete overwrite with scalar stores when every
2018 // lane receives the same value; keeping the vector operation is preferable.
2019 if (auto *FVT = dyn_cast<FixedVectorType>(VecTy)) {
2020 if (InsertElements.size() == FVT->getNumElements()) {
2021 Value *FirstVal = InsertElements.front().first;
2022 if (all_of(InsertElements,
2023 [FirstVal](const auto &Elt) { return Elt.first == FirstVal; }))
2024 return false;
2025 }
2026 }
2027 Value *SrcAddr = Load->getPointerOperand()->stripPointerCasts();
2028 // Step 4: Establish the load/store update is legal: both accesses are simple,
2029 // have the same base address and block, have scalar elements whose type size
2030 // equals their store size, and no intervening operation modifies the updated
2031 // memory.
2032 if (!Load->isSimple() || Load->getParent() != SI->getParent() ||
2033 !DL->typeSizeEqualsStoreSize(Load->getType()->getScalarType()) ||
2034 SrcAddr != SI->getPointerOperand()->stripPointerCasts())
2035 return false;
2036
2037 if (isMemModifiedBetween(Opts, Load->getIterator(), SI->getIterator(),
2038 MemoryLocation::get(SI), AA))
2039 return false;
2040
2041 // Step 5: Validate every index before changing IR. A safe-with-freeze result
2042 // is recorded by ScalarizationResult, so discard it until profitability is
2043 // known; otherwise a rejected candidate could leave a freeze behind.
2044 for (auto [InsertVal, Idx] : InsertElements) {
2045 auto ScalarizableIdx =
2046 canScalarizeAccess(VecTy, Idx, SQ.getWithInstruction(&I));
2047 if (ScalarizableIdx.isUnsafe())
2048 return false;
2049
2050 auto GEPIndex =
2051 getScalarizedGEPIndexInfo(VecTy, Idx, SI->getPointerOperandType(), *DL);
2052 if (!GEPIndex) {
2053 ScalarizableIdx.discard();
2054 return false;
2055 }
2056
2057 // We are only checking legality here. Do not mutate IR before the
2058 // profitability check, but also do not leave a pending ToFreeze behind.
2059 ScalarizableIdx.discard();
2060 }
2061
2063 Instruction::Store, SI->getValueOperand()->getType(), SI->getAlign(),
2064 SI->getPointerAddressSpace(), CostKind);
2065
2066 if (Load->hasOneUse())
2067 OldCost += TTI.getMemoryOpCost(Instruction::Load, Load->getType(),
2068 Load->getAlign(),
2069 Load->getPointerAddressSpace(), CostKind);
2070
2071 for (auto [InsertVal, Idx] : InsertElements) {
2072 int Index = -1;
2073 if (auto *CIdx = dyn_cast<ConstantInt>(Idx))
2074 Index = CIdx->getZExtValue();
2075
2076 OldCost += TTI.getVectorInstrCost(Instruction::InsertElement, VecTy,
2077 CostKind, Index);
2078 }
2079
2080 InstructionCost NewCost = 0;
2081 // This transform replaces insertelement operations on a single vector with
2082 // GEPs and scalar stores, so assume constant-index GEP offsets stay within
2083 // addressing-mode ranges that getGEPCost considers TCC_Free. Cost only GEPs
2084 // with dynamic indices.
2085 for (auto [InsertVal, Idx] : InsertElements) {
2086 if (isa<ConstantInt>(Idx))
2087 continue;
2088 const Value *GEPIndices[] = {ConstantInt::get(Idx->getType(), 0), Idx};
2089 NewCost += TTI.getGEPCost(VecTy, SI->getPointerOperand(), GEPIndices,
2090 CostKind, InsertVal->getType());
2091 }
2092
2093 for (auto [InsertVal, Idx] : InsertElements) {
2094 Align ScalarOpAlignment = computeAlignmentAfterScalarization(
2095 std::max(SI->getAlign(), Load->getAlign()), InsertVal->getType(), Idx,
2096 *DL);
2097
2098 NewCost += TTI.getMemoryOpCost(Instruction::Store, InsertVal->getType(),
2099 ScalarOpAlignment,
2100 SI->getPointerAddressSpace(), CostKind);
2101 }
2102
2103 LLVM_DEBUG(dbgs() << "Found an insert-elements vector store scalarization "
2104 "candidate: "
2105 << I << "\n"
2106 << " NumInserts: " << InsertElements.size() << "\n"
2107 << " OldCost: " << OldCost << " vs NewCost: " << NewCost
2108 << "\n");
2109
2110 if (OldCost <= NewCost)
2111 return false;
2112
2113 for (auto [InsertVal, Idx] : InsertElements) {
2114 auto ScalarizableIdx =
2115 canScalarizeAccess(VecTy, Idx, SQ.getWithInstruction(&I));
2116 assert(!ScalarizableIdx.isUnsafe() && "already checked above");
2117
2118 if (ScalarizableIdx.isSafeWithFreeze())
2119 ScalarizableIdx.freeze(Builder, *cast<Instruction>(Idx));
2120 }
2121
2122 Worklist.push(Load);
2123 StoreInst *LastStore = nullptr;
2124 for (auto [InsertVal, Idx] : InsertElements) {
2125 auto ScalarizableIdx =
2126 canScalarizeAccess(VecTy, Idx, SQ.getWithInstruction(&I));
2127 if (ScalarizableIdx.isUnsafe())
2128 return false;
2129
2130 IntegerType *GEPIndexTy =
2131 getScalarizedGEPIndexInfo(VecTy, Idx, SI->getPointerOperandType(), *DL);
2132
2133 Value *GEPIdx = materializeScalarizedGEPIndex(Idx, GEPIndexTy, Builder);
2134 Value *GEP = Builder.CreateInBoundsGEP(
2135 SI->getValueOperand()->getType(), SI->getPointerOperand(),
2136 {ConstantInt::get(GEPIdx->getType(), 0), GEPIdx});
2137
2138 LastStore = Builder.CreateStore(InsertVal, GEP);
2139 LastStore->copyMetadata(*SI);
2140
2141 // The new GEP may change the pointer operand, so !invariant.group cannot
2142 // be transferred to the scalar store.
2143 LastStore->setMetadata(LLVMContext::MD_invariant_group, nullptr);
2144 Align ScalarOpAlignment = computeAlignmentAfterScalarization(
2145 std::max(SI->getAlign(), Load->getAlign()), InsertVal->getType(), Idx,
2146 *DL);
2147 LastStore->setAlignment(ScalarOpAlignment);
2148 }
2149
2150 replaceValue(I, *LastStore);
2152 return true;
2153}
2154
2155/// Try to scalarize vector loads feeding extractelement or bitcast
2156/// instructions.
2157bool VectorCombine::scalarizeLoad(Instruction &I) {
2158 Value *Ptr;
2159 if (!match(&I, m_Load(m_Value(Ptr))))
2160 return false;
2161
2162 auto *LI = cast<LoadInst>(&I);
2163 auto *VecTy = cast<VectorType>(LI->getType());
2164
2165 // The isSimple() check could be isUnordered(), but for now we cowardly
2166 // refuse to handle even unordered atomics.
2167 if (!LI->isSimple() || !DL->typeSizeEqualsStoreSize(VecTy->getScalarType()))
2168 return false;
2169
2170 bool AllExtracts = true;
2171 bool AllBitcasts = true;
2172 Instruction *LastCheckedInst = LI;
2173 unsigned NumInstChecked = 0;
2174
2175 // Check what type of users we have (must either all be extracts or
2176 // bitcasts) and ensure no memory modifications between the load and
2177 // its users.
2178 for (User *U : LI->users()) {
2179 auto *UI = dyn_cast<Instruction>(U);
2180 if (!UI || UI->getParent() != LI->getParent())
2181 return false;
2182
2183 // If any user is waiting to be erased, then bail out as this will
2184 // distort the cost calculation and possibly lead to infinite loops.
2185 if (UI->use_empty())
2186 return false;
2187
2188 if (!isa<ExtractElementInst>(UI))
2189 AllExtracts = false;
2190 if (!isa<BitCastInst>(UI))
2191 AllBitcasts = false;
2192
2193 // Check if any instruction between the load and the user may modify memory.
2194 if (LastCheckedInst->comesBefore(UI)) {
2195 for (Instruction &I :
2196 make_range(std::next(LI->getIterator()), UI->getIterator())) {
2197 // Bail out if we reached the check limit or the instruction may write
2198 // to memory.
2199 if (NumInstChecked == Opts.vector_combine_max_scan_instrs ||
2200 I.mayWriteToMemory())
2201 return false;
2202 NumInstChecked++;
2203 }
2204 LastCheckedInst = UI;
2205 }
2206 }
2207
2208 if (AllExtracts)
2209 return scalarizeLoadExtract(LI, VecTy, Ptr);
2210 if (AllBitcasts)
2211 return scalarizeLoadBitcast(LI, VecTy, Ptr);
2212 return false;
2213}
2214
2215/// Try to scalarize vector loads feeding extractelement instructions.
2216bool VectorCombine::scalarizeLoadExtract(LoadInst *LI, VectorType *VecTy,
2217 Value *Ptr) {
2219 return false;
2220
2221 DenseMap<ExtractElementInst *, ScalarizationResult> NeedFreeze;
2222 DenseMap<ExtractElementInst *, IntegerType *> GEPIndexInfos;
2223 llvm::scope_exit FailureGuard([&]() {
2224 // If the transform is aborted, discard the ScalarizationResults.
2225 for (auto &Pair : NeedFreeze)
2226 Pair.second.discard();
2227 });
2228
2229 InstructionCost OriginalCost =
2230 TTI.getMemoryOpCost(Instruction::Load, VecTy, LI->getAlign(),
2231 LI->getPointerAddressSpace(), CostKind);
2232 InstructionCost ScalarizedCost = 0;
2233
2234 for (User *U : LI->users()) {
2235 auto *UI = cast<ExtractElementInst>(U);
2236
2237 auto ScalarIdx = canScalarizeAccess(VecTy, UI->getIndexOperand(),
2238 SQ.getWithInstruction(LI));
2239 if (ScalarIdx.isUnsafe())
2240 return false;
2241
2242 IntegerType *GEPIndex = getScalarizedGEPIndexInfo(
2243 VecTy, UI->getIndexOperand(), LI->getPointerOperandType(), *DL);
2244 if (!GEPIndex) {
2245 ScalarIdx.discard();
2246 return false;
2247 }
2248
2249 GEPIndexInfos.try_emplace(UI, GEPIndex);
2250
2251 if (ScalarIdx.isSafeWithFreeze()) {
2252 NeedFreeze.try_emplace(UI, ScalarIdx);
2253 ScalarIdx.discard();
2254 }
2255
2256 auto *Index = dyn_cast<ConstantInt>(UI->getIndexOperand());
2257 OriginalCost +=
2258 TTI.getVectorInstrCost(Instruction::ExtractElement, VecTy, CostKind,
2259 Index ? Index->getZExtValue() : -1);
2260 ScalarizedCost +=
2261 TTI.getMemoryOpCost(Instruction::Load, VecTy->getElementType(),
2262 Align(1), LI->getPointerAddressSpace(), CostKind);
2263 ScalarizedCost += TTI.getAddressComputationCost(LI->getPointerOperandType(),
2264 nullptr, nullptr, CostKind);
2265 if (!Index && UI->getIndexOperand()->getType()->getIntegerBitWidth() <
2266 GEPIndex->getBitWidth())
2267 ScalarizedCost += TTI.getCastInstrCost(
2268 Instruction::ZExt, GEPIndex, UI->getIndexOperand()->getType(),
2269 TTI::CastContextHint::None, CostKind);
2270 }
2271
2272 LLVM_DEBUG(dbgs() << "Found all extractions of a vector load: " << *LI
2273 << "\n LoadExtractCost: " << OriginalCost
2274 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2275
2276 if (ScalarizedCost > OriginalCost)
2277 return false;
2278 if (ScalarizedCost == OriginalCost && !LI->hasOneUse())
2279 return false;
2280
2281 // Ensure we add the load back to the worklist BEFORE its users so they can
2282 // erased in the correct order.
2283 Worklist.push(LI);
2284
2285 Type *ElemType = VecTy->getElementType();
2286
2287 // Replace extracts with narrow scalar loads.
2288 for (User *U : LI->users()) {
2289 auto *EI = cast<ExtractElementInst>(U);
2290 Value *Idx = EI->getIndexOperand();
2291
2292 // Insert 'freeze' for poison indexes.
2293 if (auto It = NeedFreeze.find(EI); It != NeedFreeze.end())
2294 It->second.freeze(Builder, *cast<Instruction>(Idx));
2295
2296 Builder.SetInsertPoint(EI);
2297 auto It = GEPIndexInfos.find(EI);
2298 assert(It != GEPIndexInfos.end() &&
2299 "Missing scalarized GEP index information");
2300 Value *GEPIdx = materializeScalarizedGEPIndex(Idx, It->second, Builder);
2301 Value *GEP = Builder.CreateInBoundsGEP(
2302 VecTy, Ptr, {ConstantInt::get(GEPIdx->getType(), 0), GEPIdx});
2303 auto *NewLoad = cast<LoadInst>(
2304 Builder.CreateLoad(ElemType, GEP, EI->getName() + ".scalar"));
2305
2306 Align ScalarOpAlignment =
2307 computeAlignmentAfterScalarization(LI->getAlign(), ElemType, Idx, *DL);
2308 NewLoad->setAlignment(ScalarOpAlignment);
2309
2310 if (auto *ConstIdx = dyn_cast<ConstantInt>(Idx)) {
2311 size_t Offset = ConstIdx->getZExtValue() * DL->getTypeStoreSize(ElemType);
2312 AAMDNodes OldAAMD = LI->getAAMetadata();
2313 NewLoad->setAAMetadata(OldAAMD.adjustForAccess(Offset, ElemType, *DL));
2314 }
2315
2316 replaceValue(*EI, *NewLoad, false);
2317 }
2318
2319 FailureGuard.release();
2320 return true;
2321}
2322
2323/// Try to scalarize vector loads feeding bitcast instructions.
2324bool VectorCombine::scalarizeLoadBitcast(LoadInst *LI, VectorType *VecTy,
2325 Value *Ptr) {
2326 InstructionCost OriginalCost =
2327 TTI.getMemoryOpCost(Instruction::Load, VecTy, LI->getAlign(),
2328 LI->getPointerAddressSpace(), CostKind);
2329
2330 if (!isa<FixedVectorType>(VecTy))
2331 return false;
2332
2333 Type *TargetScalarType = nullptr;
2334 unsigned VecBitWidth = DL->getTypeSizeInBits(VecTy);
2335
2336 for (User *U : LI->users()) {
2337 auto *BC = cast<BitCastInst>(U);
2338
2339 Type *DestTy = BC->getDestTy();
2340 if (!DestTy->isIntegerTy() && !DestTy->isFloatingPointTy())
2341 return false;
2342
2343 unsigned DestBitWidth = DL->getTypeSizeInBits(DestTy);
2344 if (DestBitWidth != VecBitWidth)
2345 return false;
2346
2347 // All bitcasts must target the same scalar type.
2348 if (!TargetScalarType)
2349 TargetScalarType = DestTy;
2350 else if (TargetScalarType != DestTy)
2351 return false;
2352
2353 OriginalCost +=
2354 TTI.getCastInstrCost(Instruction::BitCast, TargetScalarType, VecTy,
2355 TTI.getCastContextHint(BC), CostKind, BC);
2356 }
2357
2358 if (!TargetScalarType)
2359 return false;
2360
2361 assert(!LI->user_empty() && "Unexpected load without bitcast users");
2362 InstructionCost ScalarizedCost =
2363 TTI.getMemoryOpCost(Instruction::Load, TargetScalarType, LI->getAlign(),
2364 LI->getPointerAddressSpace(), CostKind);
2365
2366 LLVM_DEBUG(dbgs() << "Found vector load feeding only bitcasts: " << *LI
2367 << "\n OriginalCost: " << OriginalCost
2368 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2369
2370 if (ScalarizedCost >= OriginalCost)
2371 return false;
2372
2373 // Ensure we add the load back to the worklist BEFORE its users so they can
2374 // erased in the correct order.
2375 Worklist.push(LI);
2376
2377 Builder.SetInsertPoint(LI);
2378 auto *ScalarLoad =
2379 Builder.CreateLoad(TargetScalarType, Ptr, LI->getName() + ".scalar");
2380 ScalarLoad->setAlignment(LI->getAlign());
2381 ScalarLoad->copyMetadata(*LI);
2382
2383 // Replace all bitcast users with the scalar load.
2384 for (User *U : LI->users()) {
2385 auto *BC = cast<BitCastInst>(U);
2386 replaceValue(*BC, *ScalarLoad, false);
2387 }
2388
2389 return true;
2390}
2391
2392bool VectorCombine::scalarizeExtExtract(Instruction &I) {
2394 return false;
2395 auto *Ext = dyn_cast<ZExtInst>(&I);
2396 if (!Ext)
2397 return false;
2398
2399 // Try to convert a vector zext feeding only extracts to a set of scalar
2400 // (Src << ExtIdx *Size) & (Size -1)
2401 // if profitable .
2402 auto *SrcTy = dyn_cast<FixedVectorType>(Ext->getOperand(0)->getType());
2403 if (!SrcTy)
2404 return false;
2405 auto *DstTy = cast<FixedVectorType>(Ext->getType());
2406
2407 Type *ScalarDstTy = DstTy->getElementType();
2408 if (DL->getTypeSizeInBits(SrcTy) != DL->getTypeSizeInBits(ScalarDstTy))
2409 return false;
2410
2411 InstructionCost VectorCost =
2412 TTI.getCastInstrCost(Instruction::ZExt, DstTy, SrcTy,
2413 TTI::CastContextHint::None, CostKind, Ext);
2414 unsigned ExtCnt = 0;
2415 bool ExtLane0 = false;
2416 for (User *U : Ext->users()) {
2417 uint64_t Idx;
2418 if (!match(U, m_ExtractElt(m_Value(), m_ConstantInt(Idx))))
2419 return false;
2420 // An out-of-bounds extractelement produces poison; bail out rather
2421 // than computing a shift amount that overflows the packed type.
2422 if (Idx >= SrcTy->getNumElements())
2423 return false;
2424 if (cast<Instruction>(U)->use_empty())
2425 continue;
2426 ExtCnt += 1;
2427 ExtLane0 |= !Idx;
2428 VectorCost += TTI.getVectorInstrCost(Instruction::ExtractElement, DstTy,
2429 CostKind, Idx, U);
2430 }
2431
2432 InstructionCost ScalarCost =
2433 ExtCnt * TTI.getArithmeticInstrCost(
2434 Instruction::And, ScalarDstTy, CostKind,
2437 (ExtCnt - ExtLane0) *
2439 Instruction::LShr, ScalarDstTy, CostKind,
2442 if (ScalarCost > VectorCost)
2443 return false;
2444
2445 Value *ScalarV = Ext->getOperand(0);
2446 if (!isGuaranteedNotToBePoison(ScalarV, SQ.AC, dyn_cast<Instruction>(ScalarV),
2447 SQ.DT)) {
2448 // Check wether all lanes are extracted, all extracts trigger UB
2449 // on poison, and the last extract (and hence all previous ones)
2450 // are guaranteed to execute if Ext executes. If so, we do not
2451 // need to insert a freeze.
2452 SmallDenseSet<ConstantInt *, 8> ExtractedLanes;
2453 bool AllExtractsTriggerUB = true;
2454 ExtractElementInst *LastExtract = nullptr;
2455 BasicBlock *ExtBB = Ext->getParent();
2456 for (User *U : Ext->users()) {
2457 auto *Extract = cast<ExtractElementInst>(U);
2458 if (Extract->getParent() != ExtBB || !programUndefinedIfPoison(Extract)) {
2459 AllExtractsTriggerUB = false;
2460 break;
2461 }
2462 ExtractedLanes.insert(cast<ConstantInt>(Extract->getIndexOperand()));
2463 if (!LastExtract || LastExtract->comesBefore(Extract))
2464 LastExtract = Extract;
2465 }
2466 if (ExtractedLanes.size() != DstTy->getNumElements() ||
2467 !AllExtractsTriggerUB ||
2469 LastExtract->getIterator()))
2470 ScalarV = Builder.CreateFreeze(ScalarV);
2471 }
2472 ScalarV = Builder.CreateBitCast(
2473 ScalarV,
2474 IntegerType::get(SrcTy->getContext(), DL->getTypeSizeInBits(SrcTy)));
2475 uint64_t SrcEltSizeInBits = DL->getTypeSizeInBits(SrcTy->getElementType());
2476 uint64_t TotalBits = DL->getTypeSizeInBits(SrcTy);
2477 APInt EltBitMask = APInt::getLowBitsSet(TotalBits, SrcEltSizeInBits);
2478 Type *PackedTy = IntegerType::get(SrcTy->getContext(), TotalBits);
2479 Value *Mask = ConstantInt::get(PackedTy, EltBitMask);
2480 for (User *U : Ext->users()) {
2481 auto *Extract = cast<ExtractElementInst>(U);
2482 uint64_t Idx =
2483 cast<ConstantInt>(Extract->getIndexOperand())->getZExtValue();
2484 uint64_t ShiftAmt =
2485 DL->isBigEndian()
2486 ? (TotalBits - SrcEltSizeInBits - Idx * SrcEltSizeInBits)
2487 : (Idx * SrcEltSizeInBits);
2488 Value *LShr = Builder.CreateLShr(ScalarV, ShiftAmt);
2489 Value *And = Builder.CreateAnd(LShr, Mask);
2490 U->replaceAllUsesWith(And);
2491 }
2492 return true;
2493}
2494
2495/// Try to fold "(or (zext (bitcast X)), (shl (zext (bitcast Y)), C))"
2496/// to "(bitcast (concat X, Y))"
2497/// where X/Y are bitcasted from i1 mask vectors.
2498bool VectorCombine::foldConcatOfBoolMasks(Instruction &I) {
2499 Type *Ty = I.getType();
2500 if (!Ty->isIntegerTy())
2501 return false;
2502
2503 // TODO: Add big endian test coverage
2504 if (DL->isBigEndian())
2505 return false;
2506
2507 // Restrict to disjoint cases so the mask vectors aren't overlapping.
2508 Instruction *X, *Y;
2510 return false;
2511
2512 // Allow both sources to contain shl, to handle more generic pattern:
2513 // "(or (shl (zext (bitcast X)), C1), (shl (zext (bitcast Y)), C2))"
2514 Value *SrcX;
2515 uint64_t ShAmtX = 0;
2516 if (!match(X, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcX)))))) &&
2517 !match(X, m_OneUse(
2519 m_ConstantInt(ShAmtX)))))
2520 return false;
2521
2522 Value *SrcY;
2523 uint64_t ShAmtY = 0;
2524 if (!match(Y, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcY)))))) &&
2525 !match(Y, m_OneUse(
2527 m_ConstantInt(ShAmtY)))))
2528 return false;
2529
2530 // Canonicalize larger shift to the RHS.
2531 if (ShAmtX > ShAmtY) {
2532 std::swap(X, Y);
2533 std::swap(SrcX, SrcY);
2534 std::swap(ShAmtX, ShAmtY);
2535 }
2536
2537 // Ensure both sources are matching vXi1 bool mask types, and that the shift
2538 // difference is the mask width so they can be easily concatenated together.
2539 uint64_t ShAmtDiff = ShAmtY - ShAmtX;
2540 unsigned NumSHL = (ShAmtX > 0) + (ShAmtY > 0);
2541 unsigned BitWidth = Ty->getPrimitiveSizeInBits();
2542 auto *MaskTy = dyn_cast<FixedVectorType>(SrcX->getType());
2543 if (!MaskTy || SrcX->getType() != SrcY->getType() ||
2544 !MaskTy->getElementType()->isIntegerTy(1) ||
2545 MaskTy->getNumElements() != ShAmtDiff ||
2546 MaskTy->getNumElements() > (BitWidth / 2))
2547 return false;
2548
2549 auto *ConcatTy = FixedVectorType::getDoubleElementsVectorType(MaskTy);
2550 auto *ConcatIntTy =
2551 Type::getIntNTy(Ty->getContext(), ConcatTy->getNumElements());
2552 auto *MaskIntTy = Type::getIntNTy(Ty->getContext(), ShAmtDiff);
2553
2554 SmallVector<int, 32> ConcatMask(ConcatTy->getNumElements());
2555 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
2556
2557 // TODO: Is it worth supporting multi use cases?
2558 InstructionCost OldCost = 0;
2559 OldCost += TTI.getArithmeticInstrCost(Instruction::Or, Ty, CostKind);
2560 OldCost +=
2561 NumSHL * TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2562 OldCost += 2 * TTI.getCastInstrCost(Instruction::ZExt, Ty, MaskIntTy,
2563 TTI::CastContextHint::None, CostKind);
2564 OldCost += 2 * TTI.getCastInstrCost(Instruction::BitCast, MaskIntTy, MaskTy,
2565 TTI::CastContextHint::None, CostKind);
2566
2567 InstructionCost NewCost = 0;
2569 MaskTy, CostKind, ConcatMask);
2570 NewCost += TTI.getCastInstrCost(Instruction::BitCast, ConcatIntTy, ConcatTy,
2571 TTI::CastContextHint::None, CostKind);
2572 if (Ty != ConcatIntTy)
2573 NewCost += TTI.getCastInstrCost(Instruction::ZExt, Ty, ConcatIntTy,
2574 TTI::CastContextHint::None, CostKind);
2575 if (ShAmtX > 0)
2576 NewCost += TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2577
2578 LLVM_DEBUG(dbgs() << "Found a concatenation of bitcasted bool masks: " << I
2579 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2580 << "\n");
2581
2582 if (NewCost > OldCost)
2583 return false;
2584
2585 // Build bool mask concatenation, bitcast back to scalar integer, and perform
2586 // any residual zero-extension or shifting.
2587 Value *Concat = Builder.CreateShuffleVector(SrcX, SrcY, ConcatMask);
2588
2589 Value *Result = Builder.CreateBitCast(Concat, ConcatIntTy);
2590
2591 if (Ty != ConcatIntTy) {
2592 Result = Builder.CreateZExt(Result, Ty);
2593 }
2594
2595 if (ShAmtX > 0) {
2596 Result = Builder.CreateShl(Result, ShAmtX);
2597 }
2598
2599 replaceValue(I, *Result);
2600 return true;
2601}
2602
2603/// Try to convert "shuffle (binop (shuffle, shuffle)), undef"
2604/// --> "binop (shuffle), (shuffle)".
2605bool VectorCombine::foldPermuteOfBinops(Instruction &I) {
2606 BinaryOperator *BinOp;
2607 ArrayRef<int> OuterMask;
2608 if (!match(&I, m_Shuffle(m_BinOp(BinOp), m_Undef(), m_Mask(OuterMask))))
2609 return false;
2610
2611 // Don't introduce poison into div/rem.
2612 if (BinOp->isIntDivRem() && llvm::is_contained(OuterMask, PoisonMaskElem))
2613 return false;
2614
2615 Value *Op00, *Op01, *Op10, *Op11;
2616 ArrayRef<int> Mask0, Mask1;
2617 bool Match0 = match(BinOp->getOperand(0),
2618 m_Shuffle(m_Value(Op00), m_Value(Op01), m_Mask(Mask0)));
2619 bool Match1 = match(BinOp->getOperand(1),
2620 m_Shuffle(m_Value(Op10), m_Value(Op11), m_Mask(Mask1)));
2621 if (!Match0 && !Match1)
2622 return false;
2623
2624 Op00 = Match0 ? Op00 : BinOp->getOperand(0);
2625 Op01 = Match0 ? Op01 : BinOp->getOperand(0);
2626 Op10 = Match1 ? Op10 : BinOp->getOperand(1);
2627 Op11 = Match1 ? Op11 : BinOp->getOperand(1);
2628
2629 Instruction::BinaryOps Opcode = BinOp->getOpcode();
2630 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2631 auto *BinOpTy = dyn_cast<FixedVectorType>(BinOp->getType());
2632 auto *Op0Ty = dyn_cast<FixedVectorType>(Op00->getType());
2633 auto *Op1Ty = dyn_cast<FixedVectorType>(Op10->getType());
2634 if (!ShuffleDstTy || !BinOpTy || !Op0Ty || !Op1Ty)
2635 return false;
2636
2637 unsigned NumSrcElts = BinOpTy->getNumElements();
2638
2639 // Don't accept shuffles that reference the second operand in
2640 // div/rem or if its an undef arg.
2641 if ((BinOp->isIntDivRem() || !isa<PoisonValue>(I.getOperand(1))) &&
2642 any_of(OuterMask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
2643 return false;
2644
2645 // Merge outer / inner (or identity if no match) shuffles.
2646 SmallVector<int> NewMask0, NewMask1;
2647 for (int M : OuterMask) {
2648 if (M < 0 || M >= (int)NumSrcElts) {
2649 NewMask0.push_back(PoisonMaskElem);
2650 NewMask1.push_back(PoisonMaskElem);
2651 } else {
2652 NewMask0.push_back(Match0 ? Mask0[M] : M);
2653 NewMask1.push_back(Match1 ? Mask1[M] : M);
2654 }
2655 }
2656
2657 unsigned NumOpElts = Op0Ty->getNumElements();
2658 bool IsIdentity0 = ShuffleDstTy == Op0Ty &&
2659 all_of(NewMask0, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2660 ShuffleVectorInst::isIdentityMask(NewMask0, NumOpElts);
2661 bool IsIdentity1 = ShuffleDstTy == Op1Ty &&
2662 all_of(NewMask1, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2663 ShuffleVectorInst::isIdentityMask(NewMask1, NumOpElts);
2664
2665 InstructionCost NewCost = 0;
2666 // Try to merge shuffles across the binop if the new shuffles are not costly.
2667 InstructionCost BinOpCost =
2668 TTI.getArithmeticInstrCost(Opcode, BinOpTy, CostKind);
2669 InstructionCost OldCost =
2671 ShuffleDstTy, BinOpTy, CostKind, OuterMask,
2672 0, nullptr, {BinOp}, &I);
2673 if (!BinOp->hasOneUse())
2674 NewCost += BinOpCost;
2675
2676 if (Match0) {
2678 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op0Ty, CostKind, Mask0,
2679 0, nullptr, {Op00, Op01}, cast<Instruction>(BinOp->getOperand(0)));
2680 OldCost += Shuf0Cost;
2681 if (!BinOp->hasOneUse() || !BinOp->getOperand(0)->hasOneUse())
2682 NewCost += Shuf0Cost;
2683 }
2684 if (Match1) {
2686 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op1Ty, CostKind, Mask1,
2687 0, nullptr, {Op10, Op11}, cast<Instruction>(BinOp->getOperand(1)));
2688 OldCost += Shuf1Cost;
2689 if (!BinOp->hasOneUse() || !BinOp->getOperand(1)->hasOneUse())
2690 NewCost += Shuf1Cost;
2691 }
2692
2693 NewCost += TTI.getArithmeticInstrCost(Opcode, ShuffleDstTy, CostKind);
2694
2695 if (!IsIdentity0)
2696 NewCost +=
2698 Op0Ty, CostKind, NewMask0, 0, nullptr, {Op00, Op01});
2699 if (!IsIdentity1)
2700 NewCost +=
2702 Op1Ty, CostKind, NewMask1, 0, nullptr, {Op10, Op11});
2703
2704 LLVM_DEBUG(dbgs() << "Found a shuffle feeding a shuffled binop: " << I
2705 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2706 << "\n");
2707
2708 // If costs are equal, still fold as we reduce instruction count.
2709 if (NewCost > OldCost)
2710 return false;
2711
2712 Value *LHS =
2713 IsIdentity0 ? Op00 : Builder.CreateShuffleVector(Op00, Op01, NewMask0);
2714 Value *RHS =
2715 IsIdentity1 ? Op10 : Builder.CreateShuffleVector(Op10, Op11, NewMask1);
2716 Value *NewBO = Builder.CreateBinOp(Opcode, LHS, RHS);
2717
2718 // Intersect flags from the old binops.
2719 if (auto *NewInst = dyn_cast<Instruction>(NewBO))
2720 NewInst->copyIRFlags(BinOp);
2721
2722 replaceValue(I, *NewBO);
2723 return true;
2724}
2725
2726/// Try to convert "shuffle (binop), (binop)" into "binop (shuffle), (shuffle)".
2727/// Try to convert "shuffle (cmpop), (cmpop)" into "cmpop (shuffle), (shuffle)".
2728bool VectorCombine::foldShuffleOfBinops(Instruction &I) {
2729 ArrayRef<int> OldMask;
2730 Instruction *LHS, *RHS;
2732 m_Mask(OldMask))))
2733 return false;
2734
2735 // TODO: Add support for addlike etc.
2736 if (LHS->getOpcode() != RHS->getOpcode())
2737 return false;
2738
2739 Value *X, *Y, *Z, *W;
2740 bool IsCommutative = false;
2741 CmpPredicate PredLHS = CmpInst::BAD_ICMP_PREDICATE;
2742 CmpPredicate PredRHS = CmpInst::BAD_ICMP_PREDICATE;
2743 if (match(LHS, m_BinOp(m_Value(X), m_Value(Y))) &&
2744 match(RHS, m_BinOp(m_Value(Z), m_Value(W)))) {
2745 auto *BO = cast<BinaryOperator>(LHS);
2746 // Don't introduce poison into div/rem.
2747 if (llvm::is_contained(OldMask, PoisonMaskElem) && BO->isIntDivRem())
2748 return false;
2749 IsCommutative = BinaryOperator::isCommutative(BO->getOpcode());
2750 } else if (match(LHS, m_Cmp(PredLHS, m_Value(X), m_Value(Y))) &&
2751 match(RHS, m_Cmp(PredRHS, m_Value(Z), m_Value(W))) &&
2752 (CmpInst::Predicate)PredLHS == (CmpInst::Predicate)PredRHS) {
2753 IsCommutative = cast<CmpInst>(LHS)->isCommutative();
2754 } else
2755 return false;
2756
2757 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2758 auto *BinResTy = dyn_cast<FixedVectorType>(LHS->getType());
2759 auto *BinOpTy = dyn_cast<FixedVectorType>(X->getType());
2760 if (!ShuffleDstTy || !BinResTy || !BinOpTy || X->getType() != Z->getType())
2761 return false;
2762
2763 bool SameBinOp = LHS == RHS;
2764 unsigned NumSrcElts = BinOpTy->getNumElements();
2765
2766 // If we have something like "add X, Y" and "add Z, X", swap ops to match.
2767 if (IsCommutative && X != Z && Y != W && (X == W || Y == Z))
2768 std::swap(X, Y);
2769
2770 auto ConvertToUnary = [NumSrcElts](int &M) {
2771 if (M >= (int)NumSrcElts)
2772 M -= NumSrcElts;
2773 };
2774
2775 SmallVector<int> NewMask0(OldMask);
2777 TTI::OperandValueInfo Op0Info = TTI.commonOperandInfo(X, Z);
2778 if (X == Z) {
2779 llvm::for_each(NewMask0, ConvertToUnary);
2781 Z = PoisonValue::get(BinOpTy);
2782 }
2783
2784 SmallVector<int> NewMask1(OldMask);
2786 TTI::OperandValueInfo Op1Info = TTI.commonOperandInfo(Y, W);
2787 if (Y == W) {
2788 llvm::for_each(NewMask1, ConvertToUnary);
2790 W = PoisonValue::get(BinOpTy);
2791 }
2792
2793 // Try to replace a binop with a shuffle if the shuffle is not costly.
2794 // When SameBinOp, only count the binop cost once.
2795 InstructionCost LHSCost = TTI.getInstructionCost(LHS, CostKind);
2796 InstructionCost RHSCost = TTI.getInstructionCost(RHS, CostKind);
2797
2798 InstructionCost OldCost = LHSCost;
2799 if (!SameBinOp) {
2800 OldCost += RHSCost;
2801 }
2803 ShuffleDstTy, BinResTy, CostKind, OldMask, 0,
2804 nullptr, {LHS, RHS}, &I);
2805
2806 // Handle shuffle(binop(shuffle(x),y),binop(z,shuffle(w))) style patterns
2807 // where one use shuffles have gotten split across the binop/cmp. These
2808 // often allow a major reduction in total cost that wouldn't happen as
2809 // individual folds.
2810 auto MergeInner = [&](Value *&Op, int Offset, MutableArrayRef<int> Mask,
2811 TTI::TargetCostKind CostKind,
2812 Instruction *BinOp) -> bool {
2813 Value *InnerOp;
2814 ArrayRef<int> InnerMask;
2815 if (match(Op, m_OneUse(m_Shuffle(m_Value(InnerOp), m_Undef(),
2816 m_Mask(InnerMask)))) &&
2817 InnerOp->getType() == Op->getType() &&
2818 all_of(InnerMask,
2819 [NumSrcElts](int M) { return M < (int)NumSrcElts; })) {
2820 for (int &M : Mask)
2821 if (Offset <= M && M < (int)(Offset + NumSrcElts)) {
2822 M = InnerMask[M - Offset];
2823 M = 0 <= M ? M + Offset : M;
2824 }
2825 // Op is only removed if the binop using it is removed too.
2826 bool Removed = BinOp->hasOneUser();
2827 if (Removed)
2828 OldCost += TTI.getInstructionCost(cast<Instruction>(Op), CostKind);
2829 Op = InnerOp;
2830 return Removed;
2831 }
2832 return false;
2833 };
2834 bool ReducedInstCount = false;
2835 ReducedInstCount |= MergeInner(X, 0, NewMask0, CostKind, LHS);
2836 ReducedInstCount |= MergeInner(Y, 0, NewMask1, CostKind, LHS);
2837 ReducedInstCount |= MergeInner(Z, NumSrcElts, NewMask0, CostKind, RHS);
2838 ReducedInstCount |= MergeInner(W, NumSrcElts, NewMask1, CostKind, RHS);
2839 bool SingleSrcBinOp = (X == Y) && (Z == W) && (NewMask0 == NewMask1);
2840 // SingleSrcBinOp only reduces instruction count if we also eliminate the
2841 // original binop(s). If binops have multiple uses, they won't be eliminated.
2842 ReducedInstCount |= SingleSrcBinOp && LHS->hasOneUser() && RHS->hasOneUser();
2843
2844 // For concat shuffles of i1 vectors where both binops are one-use, the
2845 // transform keeps the same instruction count but canonicalises to a single
2846 // wider binop, enabling downstream folds (e.g. NOT(XOR(concat(a,b),
2847 // concat(c,d))) -> XNOR(concat(a,b),concat(c,d)) on AVX-512 mask regs).
2848 // Restrict to BinaryOperator (not CmpInst) since narrow comparisons may
2849 // be cheaper than wide ones on some targets (e.g. AVX-512 vpcmpeq).
2850 ReducedInstCount |= cast<ShuffleVectorInst>(&I)->isConcat() &&
2851 I.getType()->getScalarType()->isIntegerTy(1) &&
2853 RHS->hasOneUser();
2854
2855 auto *ShuffleCmpTy =
2856 FixedVectorType::get(BinOpTy->getElementType(), ShuffleDstTy);
2858 SK0, ShuffleCmpTy, BinOpTy, CostKind, NewMask0, 0, nullptr, {X, Z});
2859 if (!SingleSrcBinOp)
2860 NewCost += TTI.getShuffleCost(SK1, ShuffleCmpTy, BinOpTy, CostKind,
2861 NewMask1, 0, nullptr, {Y, W});
2862
2863 if (PredLHS == CmpInst::BAD_ICMP_PREDICATE) {
2864 NewCost += TTI.getArithmeticInstrCost(LHS->getOpcode(), ShuffleDstTy,
2865 CostKind, Op0Info, Op1Info);
2866 } else {
2867 NewCost +=
2868 TTI.getCmpSelInstrCost(LHS->getOpcode(), ShuffleCmpTy, ShuffleDstTy,
2869 PredLHS, CostKind, Op0Info, Op1Info);
2870 }
2871 // If LHS/RHS have other uses, we need to account for the cost of keeping
2872 // the original instructions. When SameBinOp, only add the cost once.
2873 if (!LHS->hasOneUser())
2874 NewCost += LHSCost;
2875 if (!SameBinOp && !RHS->hasOneUser())
2876 NewCost += RHSCost;
2877
2878 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two binops: " << I
2879 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2880 << "\n");
2881
2882 // If either shuffle will constant fold away, then fold for the same cost as
2883 // we will reduce the instruction count.
2884 ReducedInstCount |= (isa<Constant>(X) && isa<Constant>(Z)) ||
2885 (isa<Constant>(Y) && isa<Constant>(W));
2886 if (ReducedInstCount ? (NewCost > OldCost) : (NewCost >= OldCost))
2887 return false;
2888
2889 Value *Shuf0 = Builder.CreateShuffleVector(X, Z, NewMask0);
2890 Value *Shuf1 =
2891 SingleSrcBinOp ? Shuf0 : Builder.CreateShuffleVector(Y, W, NewMask1);
2892 Value *NewBO = PredLHS == CmpInst::BAD_ICMP_PREDICATE
2893 ? Builder.CreateBinOp(
2894 cast<BinaryOperator>(LHS)->getOpcode(), Shuf0, Shuf1)
2895 : Builder.CreateCmp(PredLHS, Shuf0, Shuf1);
2896
2897 // Intersect flags from the old binops.
2898 if (auto *NewInst = dyn_cast<Instruction>(NewBO)) {
2899 NewInst->copyIRFlags(LHS);
2900 NewInst->andIRFlags(RHS);
2901 }
2902
2903 replaceValue(I, *NewBO);
2904 return true;
2905}
2906
2907/// Try to convert,
2908/// (shuffle(select(c1,t1,f1)), (select(c2,t2,f2)), m) into
2909/// (select (shuffle c1,c2,m), (shuffle t1,t2,m), (shuffle f1,f2,m))
2910bool VectorCombine::foldShuffleOfSelects(Instruction &I) {
2911 ArrayRef<int> Mask;
2912 Value *C1, *T1, *F1, *C2, *T2, *F2;
2914 m_Select(m_Value(C2), m_Value(T2), m_Value(F2)),
2915 m_Mask(Mask))))
2916 return false;
2917
2918 auto *Sel1 = cast<Instruction>(I.getOperand(0));
2919 auto *Sel2 = cast<Instruction>(I.getOperand(1));
2920
2921 auto *C1VecTy = dyn_cast<FixedVectorType>(C1->getType());
2922 auto *C2VecTy = dyn_cast<FixedVectorType>(C2->getType());
2923 if (!C1VecTy || !C2VecTy || C1VecTy != C2VecTy)
2924 return false;
2925
2926 auto *SI0FOp = dyn_cast<FPMathOperator>(I.getOperand(0));
2927 auto *SI1FOp = dyn_cast<FPMathOperator>(I.getOperand(1));
2928 // SelectInsts must have the same FMF.
2929 if (((SI0FOp == nullptr) != (SI1FOp == nullptr)) ||
2930 ((SI0FOp != nullptr) &&
2931 (SI0FOp->getFastMathFlags() != SI1FOp->getFastMathFlags())))
2932 return false;
2933
2934 auto *SrcVecTy = cast<FixedVectorType>(T1->getType());
2935 auto *DstVecTy = cast<FixedVectorType>(I.getType());
2937 auto SelOp = Instruction::Select;
2938
2940 SelOp, SrcVecTy, C1VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2942 SelOp, SrcVecTy, C2VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2943
2944 InstructionCost OldCost =
2945 CostSel1 + CostSel2 +
2946 TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0, nullptr,
2947 {I.getOperand(0), I.getOperand(1)}, &I);
2948
2950 SK, FixedVectorType::get(C1VecTy->getScalarType(), Mask.size()), C1VecTy,
2951 CostKind, Mask, 0, nullptr, {C1, C2});
2952 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0,
2953 nullptr, {T1, T2});
2954 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0,
2955 nullptr, {F1, F2});
2956 auto *C1C2ShuffledVecTy = FixedVectorType::get(
2957 Type::getInt1Ty(I.getContext()), DstVecTy->getNumElements());
2958 NewCost += TTI.getCmpSelInstrCost(SelOp, DstVecTy, C1C2ShuffledVecTy,
2959 CmpInst::BAD_ICMP_PREDICATE, CostKind);
2960
2961 if (!Sel1->hasOneUse())
2962 NewCost += CostSel1;
2963 if (!Sel2->hasOneUse())
2964 NewCost += CostSel2;
2965
2966 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two selects: " << I
2967 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2968 << "\n");
2969 if (NewCost > OldCost)
2970 return false;
2971
2972 Value *ShuffleCmp = Builder.CreateShuffleVector(C1, C2, Mask);
2973 Value *ShuffleTrue = Builder.CreateShuffleVector(T1, T2, Mask);
2974 Value *ShuffleFalse = Builder.CreateShuffleVector(F1, F2, Mask);
2975 Value *NewSel;
2976 // We presuppose that the SelectInsts have the same FMF.
2977 if (SI0FOp)
2978 NewSel = Builder.CreateSelectFMF(ShuffleCmp, ShuffleTrue, ShuffleFalse,
2979 SI0FOp->getFastMathFlags());
2980 else
2981 NewSel = Builder.CreateSelect(ShuffleCmp, ShuffleTrue, ShuffleFalse);
2982
2983 replaceValue(I, *NewSel);
2984 return true;
2985}
2986
2987/// Try to convert "shuffle (castop), (castop)" with a shared castop operand
2988/// into "castop (shuffle)".
2989bool VectorCombine::foldShuffleOfCastops(Instruction &I) {
2990 Value *V0, *V1;
2991 ArrayRef<int> OldMask;
2992 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
2993 return false;
2994
2995 // Check whether this is a binary shuffle.
2996 bool IsBinaryShuffle = !isa<UndefValue>(V1);
2997
2998 auto *C0 = dyn_cast<CastInst>(V0);
2999 auto *C1 = dyn_cast<CastInst>(V1);
3000 if (!C0 || (IsBinaryShuffle && !C1))
3001 return false;
3002
3003 Instruction::CastOps Opcode = C0->getOpcode();
3004
3005 // If this is allowed, foldShuffleOfCastops can get stuck in a loop
3006 // with foldBitcastOfShuffle. Reject in favor of foldBitcastOfShuffle.
3007 if (!IsBinaryShuffle && Opcode == Instruction::BitCast)
3008 return false;
3009
3010 if (IsBinaryShuffle) {
3011 if (C0->getSrcTy() != C1->getSrcTy())
3012 return false;
3013 // Handle shuffle(zext_nneg(x), sext(y)) -> sext(shuffle(x,y)) folds.
3014 if (Opcode != C1->getOpcode()) {
3016 Opcode = Instruction::SExt;
3017 else
3018 return false;
3019 }
3020 }
3021
3022 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3023 auto *CastDstTy = dyn_cast<FixedVectorType>(C0->getDestTy());
3024 auto *CastSrcTy = dyn_cast<FixedVectorType>(C0->getSrcTy());
3025 if (!ShuffleDstTy || !CastDstTy || !CastSrcTy)
3026 return false;
3027
3028 unsigned NumSrcElts = CastSrcTy->getNumElements();
3029 unsigned NumDstElts = CastDstTy->getNumElements();
3030 assert((NumDstElts == NumSrcElts || Opcode == Instruction::BitCast) &&
3031 "Only bitcasts expected to alter src/dst element counts");
3032
3033 // Check for bitcasting of unscalable vector types.
3034 // e.g. <32 x i40> -> <40 x i32>
3035 if (NumDstElts != NumSrcElts && (NumSrcElts % NumDstElts) != 0 &&
3036 (NumDstElts % NumSrcElts) != 0)
3037 return false;
3038
3039 SmallVector<int, 16> NewMask;
3040 if (NumSrcElts >= NumDstElts) {
3041 // The bitcast is from wide to narrow/equal elements. The shuffle mask can
3042 // always be expanded to the equivalent form choosing narrower elements.
3043 assert(NumSrcElts % NumDstElts == 0 && "Unexpected shuffle mask");
3044 unsigned ScaleFactor = NumSrcElts / NumDstElts;
3045 narrowShuffleMaskElts(ScaleFactor, OldMask, NewMask);
3046 } else {
3047 // The bitcast is from narrow elements to wide elements. The shuffle mask
3048 // must choose consecutive elements to allow casting first.
3049 assert(NumDstElts % NumSrcElts == 0 && "Unexpected shuffle mask");
3050 unsigned ScaleFactor = NumDstElts / NumSrcElts;
3051 if (!widenShuffleMaskElts(ScaleFactor, OldMask, NewMask))
3052 return false;
3053 }
3054
3055 auto *NewShuffleDstTy =
3056 FixedVectorType::get(CastSrcTy->getScalarType(), NewMask.size());
3057
3058 // Try to replace a castop with a shuffle if the shuffle is not costly.
3059 InstructionCost CostC0 =
3060 TTI.getCastInstrCost(C0->getOpcode(), CastDstTy, CastSrcTy,
3061 TTI::CastContextHint::None, CostKind, C0);
3062
3064 if (IsBinaryShuffle)
3066 else
3068
3069 InstructionCost OldCost = CostC0;
3070 OldCost += TTI.getShuffleCost(ShuffleKind, ShuffleDstTy, CastDstTy, CostKind,
3071 OldMask, 0, nullptr, {}, &I);
3072
3073 InstructionCost NewCost = TTI.getShuffleCost(ShuffleKind, NewShuffleDstTy,
3074 CastSrcTy, CostKind, NewMask);
3075 NewCost += TTI.getCastInstrCost(Opcode, ShuffleDstTy, NewShuffleDstTy,
3076 TTI::CastContextHint::None, CostKind);
3077 if (!C0->hasOneUse())
3078 NewCost += CostC0;
3079 if (IsBinaryShuffle) {
3080 InstructionCost CostC1 =
3081 TTI.getCastInstrCost(C1->getOpcode(), CastDstTy, CastSrcTy,
3082 TTI::CastContextHint::None, CostKind, C1);
3083 OldCost += CostC1;
3084 if (!C1->hasOneUse())
3085 NewCost += CostC1;
3086 }
3087
3088 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two casts: " << I
3089 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3090 << "\n");
3091 if (NewCost > OldCost)
3092 return false;
3093
3094 Value *Shuf;
3095 if (IsBinaryShuffle)
3096 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), C1->getOperand(0),
3097 NewMask);
3098 else
3099 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), NewMask);
3100
3101 Value *Cast = Builder.CreateCast(Opcode, Shuf, ShuffleDstTy);
3102
3103 // Intersect flags from the old casts.
3104 if (auto *NewInst = dyn_cast<Instruction>(Cast)) {
3105 NewInst->copyIRFlags(C0);
3106 if (IsBinaryShuffle)
3107 NewInst->andIRFlags(C1);
3108 }
3109
3110 replaceValue(I, *Cast);
3111 return true;
3112}
3113
3114/// Try to convert any of:
3115/// "shuffle (shuffle x, y), (shuffle y, x)"
3116/// "shuffle (shuffle x, undef), (shuffle y, undef)"
3117/// "shuffle (shuffle x, undef), y"
3118/// "shuffle x, (shuffle y, undef)"
3119/// into "shuffle x, y".
3120bool VectorCombine::foldShuffleOfShuffles(Instruction &I) {
3121 ArrayRef<int> OuterMask;
3122 Value *OuterV0, *OuterV1;
3123 if (!match(&I,
3124 m_Shuffle(m_Value(OuterV0), m_Value(OuterV1), m_Mask(OuterMask))))
3125 return false;
3126
3127 ArrayRef<int> InnerMask0, InnerMask1;
3128 Value *X0, *X1, *Y0, *Y1;
3129 bool Match0 =
3130 match(OuterV0, m_Shuffle(m_Value(X0), m_Value(Y0), m_Mask(InnerMask0)));
3131 bool Match1 =
3132 match(OuterV1, m_Shuffle(m_Value(X1), m_Value(Y1), m_Mask(InnerMask1)));
3133 if (!Match0 && !Match1)
3134 return false;
3135
3136 // If the outer shuffle is a permute, then create a fake inner all-poison
3137 // shuffle. This is easier than accounting for length-changing shuffles below.
3138 SmallVector<int, 16> PoisonMask1;
3139 if (!Match1 && isa<PoisonValue>(OuterV1)) {
3140 X1 = X0;
3141 Y1 = Y0;
3142 PoisonMask1.append(InnerMask0.size(), PoisonMaskElem);
3143 InnerMask1 = PoisonMask1;
3144 Match1 = true; // fake match
3145 }
3146
3147 X0 = Match0 ? X0 : OuterV0;
3148 Y0 = Match0 ? Y0 : OuterV0;
3149 X1 = Match1 ? X1 : OuterV1;
3150 Y1 = Match1 ? Y1 : OuterV1;
3151 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3152 auto *ShuffleSrcTy = dyn_cast<FixedVectorType>(X0->getType());
3153 auto *ShuffleImmTy = dyn_cast<FixedVectorType>(OuterV0->getType());
3154 if (!ShuffleDstTy || !ShuffleSrcTy || !ShuffleImmTy ||
3155 X0->getType() != X1->getType())
3156 return false;
3157
3158 unsigned NumSrcElts = ShuffleSrcTy->getNumElements();
3159 unsigned NumImmElts = ShuffleImmTy->getNumElements();
3160
3161 // Attempt to merge shuffles, matching upto 2 source operands.
3162 // Replace index to a poison arg with PoisonMaskElem.
3163 // Bail if either inner masks reference an undef arg.
3164 SmallVector<int, 16> NewMask(OuterMask);
3165 Value *NewX = nullptr, *NewY = nullptr;
3166 for (int &M : NewMask) {
3167 Value *Src = nullptr;
3168 if (0 <= M && M < (int)NumImmElts) {
3169 Src = OuterV0;
3170 if (Match0) {
3171 M = InnerMask0[M];
3172 Src = M >= (int)NumSrcElts ? Y0 : X0;
3173 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3174 }
3175 } else if (M >= (int)NumImmElts) {
3176 Src = OuterV1;
3177 M -= NumImmElts;
3178 if (Match1) {
3179 M = InnerMask1[M];
3180 Src = M >= (int)NumSrcElts ? Y1 : X1;
3181 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3182 }
3183 }
3184 if (Src && M != PoisonMaskElem) {
3185 assert(0 <= M && M < (int)NumSrcElts && "Unexpected shuffle mask index");
3186 if (isa<UndefValue>(Src)) {
3187 // We've referenced an undef element - if its poison, update the shuffle
3188 // mask, else bail.
3189 if (!isa<PoisonValue>(Src))
3190 return false;
3191 M = PoisonMaskElem;
3192 continue;
3193 }
3194 if (!NewX || NewX == Src) {
3195 NewX = Src;
3196 continue;
3197 }
3198 if (!NewY || NewY == Src) {
3199 M += NumSrcElts;
3200 NewY = Src;
3201 continue;
3202 }
3203 return false;
3204 }
3205 }
3206
3207 if (!NewX) {
3208 replaceValue(I, *PoisonValue::get(ShuffleDstTy));
3209 return true;
3210 }
3211
3212 if (!NewY)
3213 NewY = PoisonValue::get(ShuffleSrcTy);
3214
3215 // Have we folded to an Identity shuffle?
3216 if (ShuffleVectorInst::isIdentityMask(NewMask, NumSrcElts)) {
3217 replaceValue(I, *NewX);
3218 return true;
3219 }
3220
3221 // Try to merge the shuffles if the new shuffle is not costly.
3222 InstructionCost InnerCost0 = 0;
3223 if (Match0)
3224 InnerCost0 = TTI.getInstructionCost(cast<User>(OuterV0), CostKind);
3225
3226 InstructionCost InnerCost1 = 0;
3227 if (Match1)
3228 InnerCost1 = TTI.getInstructionCost(cast<User>(OuterV1), CostKind);
3229
3230 InstructionCost OuterCost = TTI.getInstructionCost(&I, CostKind);
3231
3232 InstructionCost OldCost = InnerCost0 + InnerCost1 + OuterCost;
3233
3234 bool IsUnary = all_of(NewMask, [&](int M) { return M < (int)NumSrcElts; });
3238 InstructionCost NewCost =
3239 TTI.getShuffleCost(SK, ShuffleDstTy, ShuffleSrcTy, CostKind, NewMask, 0,
3240 nullptr, {NewX, NewY});
3241 if (!OuterV0->hasOneUse())
3242 NewCost += InnerCost0;
3243 if (!OuterV1->hasOneUse())
3244 NewCost += InnerCost1;
3245
3246 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two shuffles: " << I
3247 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3248 << "\n");
3249 if (NewCost > OldCost)
3250 return false;
3251
3252 Value *Shuf = Builder.CreateShuffleVector(NewX, NewY, NewMask);
3253 replaceValue(I, *Shuf);
3254 return true;
3255}
3256
3257/// Try to convert a chain of length-preserving shuffles that are fed by
3258/// length-changing shuffles from the same source, e.g. a chain of length 3:
3259///
3260/// "shuffle (shuffle (shuffle x, (shuffle y, undef)),
3261/// (shuffle y, undef)),
3262// (shuffle y, undef)"
3263///
3264/// into a single shuffle fed by a length-changing shuffle:
3265///
3266/// "shuffle x, (shuffle y, undef)"
3267///
3268/// Such chains arise e.g. from folding extract/insert sequences.
3269bool VectorCombine::foldShufflesOfLengthChangingShuffles(Instruction &I) {
3270 FixedVectorType *TrunkType = dyn_cast<FixedVectorType>(I.getType());
3271 if (!TrunkType)
3272 return false;
3273
3274 unsigned ChainLength = 0;
3275 SmallVector<int> Mask;
3276 SmallVector<int> YMask;
3277 InstructionCost OldCost = 0;
3278 InstructionCost NewCost = 0;
3279 Value *Trunk = &I;
3280 unsigned NumTrunkElts = TrunkType->getNumElements();
3281 Value *Y = nullptr;
3282
3283 for (;;) {
3284 // Match the current trunk against (commutations of) the pattern
3285 // "shuffle trunk', (shuffle y, undef)"
3286 ArrayRef<int> OuterMask;
3287 Value *OuterV0, *OuterV1;
3288 if (ChainLength != 0 && !Trunk->hasOneUse())
3289 break;
3290 if (!match(Trunk, m_Shuffle(m_Value(OuterV0), m_Value(OuterV1),
3291 m_Mask(OuterMask))))
3292 break;
3293 if (OuterV0->getType() != TrunkType) {
3294 // This shuffle is not length-preserving, so it cannot be part of the
3295 // chain.
3296 break;
3297 }
3298
3299 ArrayRef<int> InnerMask0, InnerMask1;
3300 Value *A0, *A1, *B0, *B1;
3301 bool Match0 =
3302 match(OuterV0, m_Shuffle(m_Value(A0), m_Value(B0), m_Mask(InnerMask0)));
3303 bool Match1 =
3304 match(OuterV1, m_Shuffle(m_Value(A1), m_Value(B1), m_Mask(InnerMask1)));
3305 bool Match0Leaf = Match0 && A0->getType() != I.getType();
3306 bool Match1Leaf = Match1 && A1->getType() != I.getType();
3307 if (Match0Leaf == Match1Leaf) {
3308 // Only handle the case of exactly one leaf in each step. The "two leaves"
3309 // case is handled by foldShuffleOfShuffles.
3310 break;
3311 }
3312
3313 SmallVector<int> CommutedOuterMask;
3314 if (Match0Leaf) {
3315 std::swap(OuterV0, OuterV1);
3316 std::swap(InnerMask0, InnerMask1);
3317 std::swap(A0, A1);
3318 std::swap(B0, B1);
3319 llvm::append_range(CommutedOuterMask, OuterMask);
3320 for (int &M : CommutedOuterMask) {
3321 if (M == PoisonMaskElem)
3322 continue;
3323 if (M < (int)NumTrunkElts)
3324 M += NumTrunkElts;
3325 else
3326 M -= NumTrunkElts;
3327 }
3328 OuterMask = CommutedOuterMask;
3329 }
3330 if (!OuterV1->hasOneUse())
3331 break;
3332
3333 if (!isa<UndefValue>(A1)) {
3334 if (!Y)
3335 Y = A1;
3336 else if (Y != A1)
3337 break;
3338 }
3339 if (!isa<UndefValue>(B1)) {
3340 if (!Y)
3341 Y = B1;
3342 else if (Y != B1)
3343 break;
3344 }
3345
3346 auto *YType = cast<FixedVectorType>(A1->getType());
3347 int NumLeafElts = YType->getNumElements();
3348 SmallVector<int> LocalYMask(InnerMask1);
3349 for (int &M : LocalYMask) {
3350 if (M >= NumLeafElts)
3351 M -= NumLeafElts;
3352 }
3353
3354 InstructionCost LocalOldCost =
3355 TTI.getInstructionCost(cast<User>(Trunk), CostKind) +
3356 TTI.getInstructionCost(cast<User>(OuterV1), CostKind);
3357
3358 // Handle the initial (start of chain) case.
3359 if (!ChainLength) {
3360 Mask.assign(OuterMask);
3361 YMask.assign(LocalYMask);
3362 OldCost = NewCost = LocalOldCost;
3363 Trunk = OuterV0;
3364 ChainLength++;
3365 continue;
3366 }
3367
3368 // For the non-root case, first attempt to combine masks.
3369 SmallVector<int> NewYMask(YMask);
3370 bool Valid = true;
3371 for (auto [CombinedM, LeafM] : llvm::zip(NewYMask, LocalYMask)) {
3372 if (LeafM == -1 || CombinedM == LeafM)
3373 continue;
3374 if (CombinedM == -1) {
3375 CombinedM = LeafM;
3376 } else {
3377 Valid = false;
3378 break;
3379 }
3380 }
3381 if (!Valid)
3382 break;
3383
3384 SmallVector<int> NewMask;
3385 NewMask.reserve(NumTrunkElts);
3386 for (int M : Mask) {
3387 if (M < 0 || M >= static_cast<int>(NumTrunkElts))
3388 NewMask.push_back(M);
3389 else
3390 NewMask.push_back(OuterMask[M]);
3391 }
3392
3393 // Break the chain if adding this new step complicates the shuffles such
3394 // that it would increase the new cost by more than the old cost of this
3395 // step.
3396 InstructionCost LocalNewCost =
3398 YType, CostKind, NewYMask) +
3400 TrunkType, CostKind, NewMask);
3401
3402 if (LocalNewCost >= NewCost && LocalOldCost < LocalNewCost - NewCost)
3403 break;
3404
3405 LLVM_DEBUG({
3406 if (ChainLength == 1) {
3407 dbgs() << "Found chain of shuffles fed by length-changing shuffles: "
3408 << I << '\n';
3409 }
3410 dbgs() << " next chain link: " << *Trunk << '\n'
3411 << " old cost: " << (OldCost + LocalOldCost)
3412 << " new cost: " << LocalNewCost << '\n';
3413 });
3414
3415 Mask = NewMask;
3416 YMask = NewYMask;
3417 OldCost += LocalOldCost;
3418 NewCost = LocalNewCost;
3419 Trunk = OuterV0;
3420 ChainLength++;
3421 }
3422 if (ChainLength <= 1)
3423 return false;
3424
3425 // Bail out if all leaves were poison.
3426 if (!Y)
3427 return false;
3428
3429 if (llvm::all_of(Mask, [&](int M) {
3430 return M < 0 || M >= static_cast<int>(NumTrunkElts);
3431 })) {
3432 // Produce a canonical simplified form if all elements are sourced from Y.
3433 for (int &M : Mask) {
3434 if (M >= static_cast<int>(NumTrunkElts))
3435 M = YMask[M - NumTrunkElts];
3436 }
3437 Value *Root =
3438 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), Mask);
3439 replaceValue(I, *Root);
3440 return true;
3441 }
3442
3443 Value *Leaf =
3444 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), YMask);
3445 Value *Root = Builder.CreateShuffleVector(Trunk, Leaf, Mask);
3446 replaceValue(I, *Root);
3447 return true;
3448}
3449
3450/// Try to convert
3451/// "shuffle (intrinsic), (intrinsic)" into "intrinsic (shuffle), (shuffle)".
3452bool VectorCombine::foldShuffleOfIntrinsics(Instruction &I) {
3453 Value *V0, *V1;
3454 ArrayRef<int> OldMask;
3455 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
3456 return false;
3457
3458 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3459 auto *II1 = dyn_cast<IntrinsicInst>(V1);
3460 if (!II0 || !II1)
3461 return false;
3462
3463 Intrinsic::ID IID = II0->getIntrinsicID();
3464 if (IID != II1->getIntrinsicID())
3465 return false;
3466 InstructionCost CostII0 =
3467 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3468 InstructionCost CostII1 =
3469 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II1), CostKind);
3470
3471 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3472 auto *II0Ty = dyn_cast<FixedVectorType>(II0->getType());
3473 if (!ShuffleDstTy || !II0Ty)
3474 return false;
3475
3476 if (!isTriviallyVectorizable(IID))
3477 return false;
3478
3479 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3480 Value *Arg0 = II0->getArgOperand(Idx);
3481 Value *Arg1 = II1->getArgOperand(Idx);
3482 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3483 // Scalar operands must be identical.
3484 if (Arg0 != Arg1)
3485 return false;
3486 } else if (Arg0->getType() != Arg1->getType()) {
3487 // The corresponding vector operands are shuffled together, so they must
3488 // share the same type. For intrinsics overloaded on their operand type
3489 // (e.g. llvm.fptosi.sat), two calls can produce the same result type
3490 // from different operand types; shuffling those would be invalid.
3491 return false;
3492 }
3493 }
3494
3495 InstructionCost OldCost =
3496 CostII0 + CostII1 +
3498 II0Ty, CostKind, OldMask, 0, nullptr, {II0, II1}, &I);
3499
3500 SmallVector<Type *> NewArgsTy;
3501 InstructionCost NewCost = 0;
3502 SmallDenseSet<std::pair<Value *, Value *>> SeenOperandPairs;
3503 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3504 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3505 NewArgsTy.push_back(II0->getArgOperand(Idx)->getType());
3506 } else {
3507 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(Idx)->getType());
3508 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3509 ShuffleDstTy->getNumElements());
3510 NewArgsTy.push_back(ArgTy);
3511 std::pair<Value *, Value *> OperandPair =
3512 std::make_pair(II0->getArgOperand(Idx), II1->getArgOperand(Idx));
3513 if (!SeenOperandPairs.insert(OperandPair).second) {
3514 // We've already computed the cost for this operand pair.
3515 continue;
3516 }
3517 NewCost += TTI.getShuffleCost(
3518 TargetTransformInfo::SK_PermuteTwoSrc, ArgTy, VecTy, CostKind,
3519 OldMask, 0, nullptr,
3520 {II0->getArgOperand(Idx), II1->getArgOperand(Idx)});
3521 }
3522 }
3523 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3524
3525 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3526 if (!II0->hasOneUse())
3527 NewCost += CostII0;
3528 if (II1 != II0 && !II1->hasOneUse())
3529 NewCost += CostII1;
3530
3531 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two intrinsics: " << I
3532 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3533 << "\n");
3534
3535 if (NewCost > OldCost)
3536 return false;
3537
3538 SmallVector<Value *> NewArgs;
3539 SmallDenseMap<std::pair<Value *, Value *>, Value *> ShuffleCache;
3540 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3541 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3542 NewArgs.push_back(II0->getArgOperand(Idx));
3543 } else {
3544 std::pair<Value *, Value *> OperandPair =
3545 std::make_pair(II0->getArgOperand(Idx), II1->getArgOperand(Idx));
3546 auto It = ShuffleCache.find(OperandPair);
3547 if (It != ShuffleCache.end()) {
3548 // Reuse previously created shuffle for this operand pair.
3549 NewArgs.push_back(It->second);
3550 continue;
3551 }
3552 Value *Shuf = Builder.CreateShuffleVector(
3553 II0->getArgOperand(Idx), II1->getArgOperand(Idx), OldMask);
3554 ShuffleCache[OperandPair] = Shuf;
3555 NewArgs.push_back(Shuf);
3556 }
3557 }
3558 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3559
3560 // Intersect flags from the old intrinsics.
3561 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic)) {
3562 NewInst->copyIRFlags(II0);
3563 NewInst->andIRFlags(II1);
3564 }
3565
3566 replaceValue(I, *NewIntrinsic);
3567 return true;
3568}
3569
3570/// Try to convert
3571/// "shuffle (intrinsic), (poison/undef)" into "intrinsic (shuffle)".
3572bool VectorCombine::foldPermuteOfIntrinsic(Instruction &I) {
3573 Value *V0;
3574 ArrayRef<int> Mask;
3575 if (!match(&I, m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask))))
3576 return false;
3577
3578 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3579 if (!II0)
3580 return false;
3581
3582 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3583 auto *IntrinsicSrcTy = dyn_cast<FixedVectorType>(II0->getType());
3584 if (!ShuffleDstTy || !IntrinsicSrcTy)
3585 return false;
3586
3587 // Validate it's a pure permute, mask should only reference the first vector
3588 unsigned NumSrcElts = IntrinsicSrcTy->getNumElements();
3589 if (any_of(Mask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
3590 return false;
3591
3592 Intrinsic::ID IID = II0->getIntrinsicID();
3593 if (!isTriviallyVectorizable(IID))
3594 return false;
3595
3596 // Cost analysis
3598 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3599 InstructionCost OldCost =
3602 IntrinsicSrcTy, CostKind, Mask, 0, nullptr, {V0}, &I);
3603
3604 SmallVector<Type *> NewArgsTy;
3605 InstructionCost NewCost = 0;
3606 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3608 NewArgsTy.push_back(II0->getArgOperand(I)->getType());
3609 } else {
3610 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(I)->getType());
3611 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3612 ShuffleDstTy->getNumElements());
3613 NewArgsTy.push_back(ArgTy);
3615 ArgTy, VecTy, CostKind, Mask, 0, nullptr,
3616 {II0->getArgOperand(I)});
3617 }
3618 }
3619 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3620 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3621
3622 // If the intrinsic has multiple uses, we need to account for the cost of
3623 // keeping the original intrinsic around.
3624 if (!II0->hasOneUse())
3625 NewCost += IntrinsicCost;
3626
3627 LLVM_DEBUG(dbgs() << "Found a permute of intrinsic: " << I << "\n OldCost: "
3628 << OldCost << " vs NewCost: " << NewCost << "\n");
3629
3630 if (NewCost > OldCost)
3631 return false;
3632
3633 // Transform
3634 SmallVector<Value *> NewArgs;
3635 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3637 NewArgs.push_back(II0->getArgOperand(I));
3638 } else {
3639 Value *Shuf = Builder.CreateShuffleVector(II0->getArgOperand(I), Mask);
3640 NewArgs.push_back(Shuf);
3641 }
3642 }
3643
3644 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3645
3646 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic))
3647 NewInst->copyIRFlags(II0);
3648
3649 replaceValue(I, *NewIntrinsic);
3650 return true;
3651}
3652
3653using InstLane = std::pair<Value *, int>;
3654
3656 while (auto *SV = dyn_cast<ShuffleVectorInst>(V)) {
3657 unsigned NumElts =
3658 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
3659 int M = SV->getMaskValue(Lane);
3660 if (M < 0)
3661 return {nullptr, PoisonMaskElem};
3662 if (static_cast<unsigned>(M) < NumElts) {
3663 V = SV->getOperand(0);
3664 Lane = M;
3665 } else {
3666 V = SV->getOperand(1);
3667 Lane = M - NumElts;
3668 }
3669 }
3670 return InstLane{V, Lane};
3671}
3672
3676 for (InstLane IL : Item) {
3677 auto [U, Lane] = IL;
3678 InstLane OpLane =
3679 U ? lookThroughShuffles(cast<Instruction>(U)->getOperand(Op), Lane)
3680 : InstLane{nullptr, PoisonMaskElem};
3681 NItem.emplace_back(OpLane);
3682 }
3683 return NItem;
3684}
3685
3686/// Detect concat of multiple values into a vector
3688 const TargetTransformInfo &TTI) {
3689 auto *Ty = cast<FixedVectorType>(Item.front().first->getType());
3690 unsigned NumElts = Ty->getNumElements();
3691 if (Item.size() == NumElts || NumElts == 1 || Item.size() % NumElts != 0)
3692 return false;
3693
3694 // Check that the concat is free, usually meaning that the type will be split
3695 // during legalization.
3696 SmallVector<int, 16> ConcatMask(NumElts * 2);
3697 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
3698 if (TTI.getShuffleCost(TTI::SK_PermuteTwoSrc,
3699 FixedVectorType::get(Ty->getScalarType(), NumElts * 2),
3700 Ty, CostKind, ConcatMask) != 0)
3701 return false;
3702
3703 unsigned NumSlices = Item.size() / NumElts;
3704 // Currently we generate a tree of shuffles for the concats, which limits us
3705 // to a power2.
3706 if (!isPowerOf2_32(NumSlices))
3707 return false;
3708 for (unsigned Slice = 0; Slice < NumSlices; ++Slice) {
3709 Value *SliceV = Item[Slice * NumElts].first;
3710 if (!SliceV || SliceV->getType() != Ty)
3711 return false;
3712 for (unsigned Elt = 0; Elt < NumElts; ++Elt) {
3713 auto [V, Lane] = Item[Slice * NumElts + Elt];
3714 if (Lane != static_cast<int>(Elt) || SliceV != V)
3715 return false;
3716 }
3717 }
3718 return true;
3719}
3720
3721static Value *
3723 const DenseSet<std::pair<Value *, Use *>> &IdentityLeafs,
3724 const DenseSet<std::pair<Value *, Use *>> &SplatLeafs,
3725 const DenseSet<std::pair<Value *, Use *>> &ConcatLeafs,
3726 IRBuilderBase &Builder, InstructionWorklist &WorkList,
3727 const TargetTransformInfo *TTI) {
3728 auto [FrontV, FrontLane] = Item.front();
3729
3730 if (IdentityLeafs.contains(std::make_pair(FrontV, From))) {
3731 return FrontV;
3732 }
3733 if (SplatLeafs.contains(std::make_pair(FrontV, From))) {
3734 SmallVector<int, 16> Mask(Item.size(), FrontLane);
3735 return Builder.CreateShuffleVector(FrontV, Mask);
3736 }
3737 if (ConcatLeafs.contains(std::make_pair(FrontV, From))) {
3738 unsigned NumElts =
3739 cast<FixedVectorType>(FrontV->getType())->getNumElements();
3740 SmallVector<Value *> Values(Item.size() / NumElts, nullptr);
3741 for (unsigned S = 0; S < Values.size(); ++S)
3742 Values[S] = Item[S * NumElts].first;
3743
3744 while (Values.size() > 1) {
3745 NumElts *= 2;
3746 SmallVector<int, 16> Mask(NumElts, 0);
3747 std::iota(Mask.begin(), Mask.end(), 0);
3748 SmallVector<Value *> NewValues(Values.size() / 2, nullptr);
3749 for (unsigned S = 0; S < NewValues.size(); ++S)
3750 NewValues[S] =
3751 Builder.CreateShuffleVector(Values[S * 2], Values[S * 2 + 1], Mask);
3752 Values = NewValues;
3753 }
3754 return Values[0];
3755 }
3756
3757 auto *I = cast<Instruction>(FrontV);
3758
3759 // Handle vector bitcasts that change element count. We cannot use
3760 // generateInstLaneVectorFromOperand for these because the lane indices
3761 // don't map 1:1 through the bitcast.
3762 if (auto *BitCast = dyn_cast<BitCastInst>(I)) {
3763 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3764 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3765 if (BCDstTy && BCSrcTy &&
3766 BCDstTy->getElementCount() != BCSrcTy->getElementCount()) {
3767 unsigned DstElts = BCDstTy->getNumElements();
3768 unsigned SrcElts = BCSrcTy->getNumElements();
3769 SmallVector<InstLane> NewItem;
3770 if (DstElts > SrcElts) {
3771 // Widening: compress operand Item.
3772 unsigned R = DstElts / SrcElts;
3773 if (Item.size() % R != 0)
3774 return nullptr;
3775 for (unsigned Idx = 0, E = Item.size(); Idx < E; Idx += R) {
3776 auto [V, Lane] = Item[Idx];
3777 if (!V) {
3778 NewItem.push_back({nullptr, PoisonMaskElem});
3779 continue;
3780 }
3781 NewItem.push_back(
3782 lookThroughShuffles(cast<Operator>(V)->getOperand(0), Lane / R));
3783 }
3784 } else {
3785 // Narrowing: expand operand Item.
3786 unsigned R = SrcElts / DstElts;
3787 for (auto [V, Lane] : Item) {
3788 if (!V) {
3789 NewItem.append(R, {nullptr, PoisonMaskElem});
3790 continue;
3791 }
3792 Value *Op = cast<Operator>(V)->getOperand(0);
3793 for (unsigned J = 0; J < R; ++J)
3794 NewItem.push_back(lookThroughShuffles(Op, Lane * R + J));
3795 }
3796 }
3797 Value *Op = generateNewInstTree(NewItem, &BitCast->getOperandUse(0),
3798 IdentityLeafs, SplatLeafs, ConcatLeafs,
3799 Builder, WorkList, TTI);
3800 return Builder.CreateBitCast(
3801 Op, FixedVectorType::get(BCDstTy->getScalarType(), Item.size()));
3802 }
3803 }
3804 auto *II = dyn_cast<IntrinsicInst>(I);
3805 unsigned NumOps = I->getNumOperands() - (II ? 1 : 0);
3807 for (unsigned Idx = 0; Idx < NumOps; Idx++) {
3808 if (II &&
3809 isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Idx, TTI)) {
3810 Ops[Idx] = II->getOperand(Idx);
3811 continue;
3812 }
3813 Ops[Idx] = generateNewInstTree(
3814 generateInstLaneVectorFromOperand(Item, Idx), &I->getOperandUse(Idx),
3815 IdentityLeafs, SplatLeafs, ConcatLeafs, Builder, WorkList, TTI);
3816 // Don't re-queue the operand of a bitcast we just regenerated. Doing so
3817 // lets foldBitcastShuffle sink the bitcast back into a shuffle(bitcast),
3818 // which foldShuffleToIdentity then re-matches as the same superfluous
3819 // identity - an infinite loop between the two folds.
3820 // TODO: we should fix algorithms in foldBitcastShuffle and
3821 // foldShuffleToIdentity instead of workaround the problem in worklist.
3822 if (isa<BitCastInst>(I) && isa<Instruction>(Ops[Idx]))
3823 WorkList.remove(cast<Instruction>(Ops[Idx]));
3824 }
3825
3826 SmallVector<Value *, 8> ValueList;
3827 for (const auto &Lane : Item)
3828 if (Lane.first)
3829 ValueList.push_back(Lane.first);
3830
3831 Type *DstTy =
3832 FixedVectorType::get(I->getType()->getScalarType(), Item.size());
3833 if (auto *BI = dyn_cast<BinaryOperator>(I)) {
3834 auto *Value = Builder.CreateBinOp((Instruction::BinaryOps)BI->getOpcode(),
3835 Ops[0], Ops[1]);
3836 propagateIRFlags(Value, ValueList);
3837 return Value;
3838 }
3839 if (auto *CI = dyn_cast<CmpInst>(I)) {
3840 auto *Value = Builder.CreateCmp(CI->getPredicate(), Ops[0], Ops[1]);
3841 propagateIRFlags(Value, ValueList);
3842 return Value;
3843 }
3844 if (auto *SI = dyn_cast<SelectInst>(I)) {
3845 auto *Value = Builder.CreateSelect(Ops[0], Ops[1], Ops[2], "", SI);
3846 propagateIRFlags(Value, ValueList);
3847 return Value;
3848 }
3849 if (auto *CI = dyn_cast<CastInst>(I)) {
3850 auto *Value = Builder.CreateCast(CI->getOpcode(), Ops[0], DstTy);
3851 propagateIRFlags(Value, ValueList);
3852 return Value;
3853 }
3854 if (II) {
3855 auto *Value = Builder.CreateIntrinsic(DstTy, II->getIntrinsicID(), Ops);
3856 propagateIRFlags(Value, ValueList);
3857 return Value;
3858 }
3859 assert(isa<UnaryInstruction>(I) && "Unexpected instruction type in Generate");
3860 auto *Value =
3861 Builder.CreateUnOp((Instruction::UnaryOps)I->getOpcode(), Ops[0]);
3862 propagateIRFlags(Value, ValueList);
3863 return Value;
3864}
3865
3866// Starting from a shuffle, look up through operands tracking the shuffled index
3867// of each lane. If we can simplify away the shuffles to identities then
3868// do so.
3869bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
3870 auto *Ty = dyn_cast<FixedVectorType>(I.getType());
3871 if (!Ty || I.use_empty())
3872 return false;
3873
3874 SmallVector<InstLane> Start(Ty->getNumElements());
3875 for (unsigned M = 0, E = Ty->getNumElements(); M < E; ++M)
3876 Start[M] = lookThroughShuffles(&I, M);
3877
3879 Candidates.push_back(std::make_pair(Start, &*I.use_begin()));
3880 DenseSet<std::pair<Value *, Use *>> IdentityLeafs, SplatLeafs, ConcatLeafs;
3881 unsigned NumVisited = 0;
3882 bool TraversedElCountChangingBitcast = false;
3883
3884 while (!Candidates.empty()) {
3885 if (++NumVisited > Opts.vector_combine_max_scan_instrs)
3886 return false;
3887
3888 auto ItemFrom = Candidates.pop_back_val();
3889 auto Item = ItemFrom.first;
3890 auto From = ItemFrom.second;
3891 auto [FrontV, FrontLane] = Item.front();
3892
3893 // If we found an undef first lane then bail out to keep things simple.
3894 if (!FrontV)
3895 return false;
3896
3897 // Look for an identity value.
3898 if (FrontLane == 0 &&
3899 cast<FixedVectorType>(FrontV->getType())->getNumElements() ==
3900 Item.size() &&
3901 all_of(drop_begin(enumerate(Item)), [Item](const auto &E) {
3902 Value *FrontV = Item.front().first;
3903 return !E.value().first || (isEquivBitcast(E.value().first, FrontV) &&
3904 E.value().second == (int)E.index());
3905 })) {
3906 IdentityLeafs.insert(std::make_pair(FrontV, From));
3907 continue;
3908 }
3909 // Look for constants, for the moment only supporting constant splats.
3910 if (auto *C = dyn_cast<Constant>(FrontV);
3911 C && C->getSplatValue() &&
3912 all_of(drop_begin(Item), [Item](InstLane &IL) {
3913 Value *FrontV = Item.front().first;
3914 Value *V = IL.first;
3915 return !V || (isa<Constant>(V) &&
3916 cast<Constant>(V)->getSplatValue() ==
3917 cast<Constant>(FrontV)->getSplatValue());
3918 })) {
3919 SplatLeafs.insert(std::make_pair(FrontV, From));
3920 continue;
3921 }
3922 // Look for a splat value.
3923 if (all_of(drop_begin(Item), [Item](InstLane &IL) {
3924 auto [FrontV, FrontLane] = Item.front();
3925 auto [V, Lane] = IL;
3926 return !V || (V == FrontV && Lane == FrontLane);
3927 })) {
3928 SplatLeafs.insert(std::make_pair(FrontV, From));
3929 continue;
3930 }
3931
3932 // We need each element to be the same type of value, and check that each
3933 // element has a single use.
3934 auto CheckLaneIsEquivalentToFirst = [Item](InstLane IL) {
3935 Value *FrontV = Item.front().first;
3936 if (!IL.first)
3937 return true;
3938 Value *V = IL.first;
3939 if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUser())
3940 return false;
3941 if (V->getValueID() != FrontV->getValueID())
3942 return false;
3943 if (auto *CI = dyn_cast<CmpInst>(V))
3944 if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
3945 return false;
3946 if (auto *CI = dyn_cast<CastInst>(V))
3947 if (CI->getSrcTy()->getScalarType() !=
3948 cast<CastInst>(FrontV)->getSrcTy()->getScalarType())
3949 return false;
3950 if (auto *SI = dyn_cast<SelectInst>(V))
3951 if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
3952 SI->getOperand(0)->getType() !=
3953 cast<SelectInst>(FrontV)->getOperand(0)->getType())
3954 return false;
3956 return false;
3957 auto *II = dyn_cast<IntrinsicInst>(V);
3958 return !II || (isa<IntrinsicInst>(FrontV) &&
3959 II->getIntrinsicID() ==
3960 cast<IntrinsicInst>(FrontV)->getIntrinsicID() &&
3961 !II->hasOperandBundles());
3962 };
3963 if (all_of(drop_begin(Item), CheckLaneIsEquivalentToFirst)) {
3964 // Check the operator is one that we support.
3965 if (isa<BinaryOperator, CmpInst>(FrontV)) {
3966 // We exclude div/rem in case they hit UB from poison lanes.
3967 if (auto *BO = dyn_cast<BinaryOperator>(FrontV);
3968 BO && BO->isIntDivRem())
3969 return false;
3971 &cast<Instruction>(FrontV)->getOperandUse(0));
3973 &cast<Instruction>(FrontV)->getOperandUse(1));
3974 continue;
3975 } else if (isa<UnaryOperator, TruncInst, ZExtInst, SExtInst, FPToSIInst,
3976 FPToUIInst, SIToFPInst, UIToFPInst>(FrontV)) {
3978 &cast<Instruction>(FrontV)->getOperandUse(0));
3979 continue;
3980 } else if (auto *BitCast = dyn_cast<BitCastInst>(FrontV)) {
3981 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3982 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3983 if (BCDstTy && BCSrcTy) {
3984 ElementCount DstEC = BCDstTy->getElementCount();
3985 ElementCount SrcEC = BCSrcTy->getElementCount();
3986 if (DstEC == SrcEC) {
3987 // Same element count - simple pass-through.
3989 &BitCast->getOperandUse(0));
3990 continue;
3991 }
3992 unsigned DstElts = DstEC.getFixedValue();
3993 unsigned SrcElts = SrcEC.getFixedValue();
3994 if (DstElts > SrcElts && DstElts % SrcElts == 0) {
3995 // Widening bitcast (e.g. <2 x i32> -> <4 x i16>). Compress
3996 // consecutive groups of R destination lanes into one source
3997 // lane.
3998 unsigned R = DstElts / SrcElts;
4000 bool Valid = Item.size() % R == 0;
4001 for (unsigned Idx = 0, E = Item.size(); Valid && Idx < E;
4002 Idx += R) {
4003 auto [V0, L0] = Item[Idx];
4004 if (!V0) {
4005 if (any_of(ArrayRef(Item).slice(Idx + 1, R - 1),
4006 [](InstLane IL) { return IL.first != nullptr; })) {
4007 Valid = false;
4008 break;
4009 }
4010 NItem.push_back({nullptr, PoisonMaskElem});
4011 continue;
4012 }
4013 if (L0 % R != 0) {
4014 Valid = false;
4015 break;
4016 }
4017 for (unsigned J = 1; J < R; ++J) {
4018 auto [VJ, LJ] = Item[Idx + J];
4019 if (!VJ || VJ != V0 || LJ != L0 + (int)J) {
4020 Valid = false;
4021 break;
4022 }
4023 }
4024 if (!Valid)
4025 break;
4027 cast<Operator>(V0)->getOperand(0), L0 / R));
4028 }
4029 if (Valid) {
4030 TraversedElCountChangingBitcast = true;
4031 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
4032 continue;
4033 }
4034 } else if (SrcElts > DstElts && SrcElts % DstElts == 0) {
4035 // Narrowing bitcast (e.g. <4 x i16> -> <2 x i32>). Expand
4036 // each destination lane into R source lanes.
4037 unsigned R = SrcElts / DstElts;
4039 for (auto [V, Lane] : Item) {
4040 if (!V) {
4041 NItem.append(R, {nullptr, PoisonMaskElem});
4042 continue;
4043 }
4044 Value *Op = cast<Operator>(V)->getOperand(0);
4045 for (unsigned J = 0; J < R; ++J)
4046 NItem.push_back(lookThroughShuffles(Op, Lane * R + J));
4047 }
4048 TraversedElCountChangingBitcast = true;
4049 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
4050 continue;
4051 }
4052 }
4053 } else if (auto *Sel = dyn_cast<SelectInst>(FrontV)) {
4055 &Sel->getOperandUse(0));
4057 &Sel->getOperandUse(1));
4059 &Sel->getOperandUse(2));
4060 continue;
4061 } else if (auto *II = dyn_cast<IntrinsicInst>(FrontV);
4062 II && isTriviallyVectorizable(II->getIntrinsicID()) &&
4063 !II->hasOperandBundles()) {
4064 for (unsigned Op = 0, E = II->getNumOperands() - 1; Op < E; Op++) {
4065 if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Op,
4066 &TTI)) {
4067 if (!all_of(drop_begin(Item), [Item, Op](InstLane &IL) {
4068 Value *FrontV = Item.front().first;
4069 Value *V = IL.first;
4070 return !V || (cast<Instruction>(V)->getOperand(Op) ==
4071 cast<Instruction>(FrontV)->getOperand(Op));
4072 }))
4073 return false;
4074 continue;
4075 }
4076 Candidates.emplace_back(
4078 &cast<Instruction>(FrontV)->getOperandUse(Op));
4079 }
4080 continue;
4081 }
4082 }
4083
4084 if (isFreeConcat(Item, CostKind, TTI)) {
4085 ConcatLeafs.insert(std::make_pair(FrontV, From));
4086 continue;
4087 }
4088
4089 return false;
4090 }
4091
4092 if (NumVisited <= 1)
4093 return false;
4094
4095 // If the only non-leaf node traversed was a single bitcast that changes
4096 // element count, the fold would just commute the bitcast and shuffle.
4097 // foldBitcastShuffle does the reverse transform, causing an infinite loop.
4098 if (NumVisited == 2 && TraversedElCountChangingBitcast)
4099 return false;
4100
4101 LLVM_DEBUG(dbgs() << "Found a superfluous identity shuffle: " << I << "\n");
4102
4103 // If we got this far, we know the shuffles are superfluous and can be
4104 // removed. Scan through again and generate the new tree of instructions.
4105 Builder.SetInsertPoint(&I);
4106 Value *V =
4107 generateNewInstTree(Start, &*I.use_begin(), IdentityLeafs, SplatLeafs,
4108 ConcatLeafs, Builder, Worklist, &TTI);
4109 replaceValue(I, *V);
4110 return true;
4111}
4112
4113/// Given a commutative reduction, the order of the input lanes does not alter
4114/// the results. We can use this to remove certain shuffles feeding the
4115/// reduction, removing the need to shuffle at all.
4116bool VectorCombine::foldShuffleFromReductions(Instruction &I) {
4117 auto *II = dyn_cast<IntrinsicInst>(&I);
4118 if (!II)
4119 return false;
4120 switch (II->getIntrinsicID()) {
4121 case Intrinsic::vector_reduce_add:
4122 case Intrinsic::vector_reduce_mul:
4123 case Intrinsic::vector_reduce_and:
4124 case Intrinsic::vector_reduce_or:
4125 case Intrinsic::vector_reduce_xor:
4126 case Intrinsic::vector_reduce_smin:
4127 case Intrinsic::vector_reduce_smax:
4128 case Intrinsic::vector_reduce_umin:
4129 case Intrinsic::vector_reduce_umax:
4130 break;
4131 default:
4132 return false;
4133 }
4134
4135 // Find all the inputs when looking through operations that do not alter the
4136 // lane order (binops, for example). Currently we look for a single shuffle,
4137 // and can ignore splat values.
4138 std::queue<Value *> Worklist;
4139 SmallPtrSet<Value *, 4> Visited;
4140 ShuffleVectorInst *Shuffle = nullptr;
4141 if (auto *Op = dyn_cast<Instruction>(I.getOperand(0)))
4142 Worklist.push(Op);
4143
4144 while (!Worklist.empty()) {
4145 Value *CV = Worklist.front();
4146 Worklist.pop();
4147 if (Visited.contains(CV))
4148 continue;
4149
4150 // Splats don't change the order, so can be safely ignored.
4151 if (isSplatValue(CV))
4152 continue;
4153
4154 Visited.insert(CV);
4155
4156 if (auto *CI = dyn_cast<Instruction>(CV)) {
4157 if (CI->isBinaryOp()) {
4158 for (auto *Op : CI->operand_values())
4159 Worklist.push(Op);
4160 continue;
4161 } else if (auto *SV = dyn_cast<ShuffleVectorInst>(CI)) {
4162 if (Shuffle && Shuffle != SV)
4163 return false;
4164 Shuffle = SV;
4165 continue;
4166 }
4167 }
4168
4169 // Anything else is currently an unknown node.
4170 return false;
4171 }
4172
4173 if (!Shuffle)
4174 return false;
4175
4176 // Check all uses of the binary ops and shuffles are also included in the
4177 // lane-invariant operations (Visited should be the list of lanewise
4178 // instructions, including the shuffle that we found).
4179 for (auto *V : Visited)
4180 for (auto *U : V->users())
4181 if (!Visited.contains(U) && U != &I)
4182 return false;
4183
4184 FixedVectorType *VecType =
4185 dyn_cast<FixedVectorType>(II->getOperand(0)->getType());
4186 if (!VecType)
4187 return false;
4188 FixedVectorType *ShuffleInputType =
4190 if (!ShuffleInputType)
4191 return false;
4192 unsigned NumInputElts = ShuffleInputType->getNumElements();
4193
4194 // Find the mask from sorting the lanes into order. This is most likely to
4195 // become a identity or concat mask. Undef elements are pushed to the end.
4196 SmallVector<int> ConcatMask;
4197 Shuffle->getShuffleMask(ConcatMask);
4198 sort(ConcatMask, [](int X, int Y) { return (unsigned)X < (unsigned)Y; });
4199 bool UsesSecondVec =
4200 any_of(ConcatMask, [&](int M) { return M >= (int)NumInputElts; });
4201
4203 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4204 ShuffleInputType, CostKind, Shuffle->getShuffleMask());
4206 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4207 ShuffleInputType, CostKind, ConcatMask);
4208
4209 LLVM_DEBUG(dbgs() << "Found a reduction feeding from a shuffle: " << *Shuffle
4210 << "\n");
4211 LLVM_DEBUG(dbgs() << " OldCost: " << OldCost << " vs NewCost: " << NewCost
4212 << "\n");
4213 bool MadeChanges = false;
4214 if (NewCost < OldCost) {
4215 Builder.SetInsertPoint(Shuffle);
4216 Value *NewShuffle = Builder.CreateShuffleVector(
4217 Shuffle->getOperand(0), Shuffle->getOperand(1), ConcatMask);
4218 LLVM_DEBUG(dbgs() << "Created new shuffle: " << *NewShuffle << "\n");
4219 replaceValue(*Shuffle, *NewShuffle);
4220 return true;
4221 }
4222
4223 // See if we can re-use foldSelectShuffle, getting it to reduce the size of
4224 // the shuffle into a nicer order, as it can ignore the order of the shuffles.
4225 MadeChanges |= foldSelectShuffle(*Shuffle, true);
4226 return MadeChanges;
4227}
4228
4229/// Try to fold a chain of shuffles and ops feeding extractelement(..., 0)
4230/// into llvm.vector.reduce.*, by tracking which lanes contribute to the
4231/// extracted lane and reducing the widest vector whose lanes each contribute
4232/// once.
4233///
4234/// For example:
4235///
4236/// %lo = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 0, i32 1>
4237/// %hi = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 2, i32 3>
4238/// %s = add <2 x i32> %lo, %hi
4239/// %sh = shufflevector <2 x i32> %s, poison, <2 x i32> <i32 1, i32 poison>
4240/// %r = add <2 x i32> %s, %sh
4241/// %e = extractelement <2 x i32> %r, i64 0
4242///
4243/// transforms to:
4244///
4245/// %e = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
4246bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
4247 Value *VecOpEE;
4248 if (!match(&I, m_ExtractElt(m_Value(VecOpEE), m_Zero())))
4249 return false;
4250
4251 auto *FVT = dyn_cast<FixedVectorType>(VecOpEE->getType());
4252 if (!FVT)
4253 return false;
4254
4255 if (FVT->getNumElements() < 2)
4256 return false;
4257
4258 std::optional<Instruction::BinaryOps> CommonBinOp;
4259 std::optional<Intrinsic::ID> CommonCallOp;
4260
4261 if (auto *BO = dyn_cast<BinaryOperator>(VecOpEE)) {
4262 if (!getReductionForBinop(BO->getOpcode()))
4263 return false;
4264 CommonBinOp = BO->getOpcode();
4265 } else if (auto *MMI = dyn_cast<MinMaxIntrinsic>(VecOpEE)) {
4266 CommonCallOp = MMI->getIntrinsicID();
4267 } else {
4268 return false;
4269 }
4270
4271 // For floating-point reductions, track FMF intersection across all binops.
4272 FastMathFlags CommonFMF;
4273 bool IsFloatReduction = false;
4274
4275 // A chain node is one we walk through, either a matching-opcode binop/min-max
4276 // or a single-source shuffle. Anything else is a leaf source.
4277 auto IsChainNode = [&](Value *V) {
4278 if (auto *BO = dyn_cast<BinaryOperator>(V))
4279 return CommonBinOp && BO->getOpcode() == *CommonBinOp;
4280 if (auto *MMI = dyn_cast<MinMaxIntrinsic>(V))
4281 return CommonCallOp && MMI->getIntrinsicID() == *CommonCallOp;
4282 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V))
4283 return isa<PoisonValue>(SVI->getOperand(1));
4284 return false;
4285 };
4286
4287 // Collect the chain, building Nodes in postorder. Bail if the chain is empty
4288 // or exceeds MaxChainNodes.
4289 constexpr unsigned MaxChainNodes = 32;
4290 SmallSetVector<Value *, 16> Nodes;
4291 SmallSetVector<Value *, 4> Sources;
4292 unsigned NumVisited = 0;
4293 auto AddSource = [&](Value *V) {
4294 if (!isa<FixedVectorType>(V->getType()))
4295 return false;
4296 Sources.insert(V);
4297 return true;
4298 };
4299 auto Walk = [&](Value *V, auto &&Walk) -> bool {
4300 if (Nodes.contains(V) || Sources.contains(V))
4301 return true;
4302 if (++NumVisited > MaxChainNodes)
4303 return false;
4304 if (!IsChainNode(V))
4305 return AddSource(V);
4306 // Chain shuffles always have poison as op1, so only op0 matters.
4307 auto *U = cast<Instruction>(V);
4308 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4309 for (unsigned I = 0; I != NumOps; ++I)
4310 if (!Walk(U->getOperand(I), Walk))
4311 return false;
4312 if (isa<ShuffleVectorInst>(U) || Nodes.contains(U->getOperand(0)) ||
4313 Nodes.contains(U->getOperand(1))) {
4314 Nodes.insert(V);
4315 return true;
4316 }
4317 // Both operands are leaves so treat this binop as a source rather than
4318 // walking into it.
4319 return AddSource(V);
4320 };
4321 if (!Walk(VecOpEE, Walk) || Nodes.empty())
4322 return false;
4323
4324 bool IsIdempotent =
4325 CommonCallOp || (CommonBinOp && Instruction::isIdempotent(*CommonBinOp));
4326
4327 // For FP reductions, require reassoc on every binop and collect FMF.
4328 for (Value *V : Nodes) {
4329 auto *BinOp = dyn_cast<BinaryOperator>(V);
4330 if (!BinOp || !BinOp->getType()->isFPOrFPVectorTy())
4331 continue;
4332 if (!BinOp->hasAllowReassoc())
4333 return false;
4334 if (!IsFloatReduction) {
4335 CommonFMF = BinOp->getFastMathFlags();
4336 IsFloatReduction = true;
4337 } else {
4338 CommonFMF &= BinOp->getFastMathFlags();
4339 }
4340 }
4341
4342 // Top-down demanded elements. For each chain value, track which lanes feed
4343 // the extracted lane 0 and which feed it more than once. Reverse postorder
4344 // visits every use before its value. A binop forwards its demand to both
4345 // operands and a shuffle follows its mask back to the source lane.
4346 struct Demand {
4347 APInt Lanes;
4348 APInt Duplicates;
4349 };
4350 DenseMap<Value *, Demand> Demands;
4351 auto DemandOf = [&](Value *V) -> Demand & {
4352 unsigned N = cast<FixedVectorType>(V->getType())->getNumElements();
4353 Demand &D = Demands[V];
4354 if (D.Lanes.getBitWidth() != N)
4355 D.Lanes = D.Duplicates = APInt::getZero(N);
4356 return D;
4357 };
4358 DemandOf(VecOpEE).Lanes.setBit(0);
4359 for (Value *V : reverse(Nodes)) {
4360 Demand DV = Demands.lookup(V);
4361 if (DV.Lanes.isZero())
4362 continue;
4363 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V)) {
4364 ArrayRef<int> Mask = SVI->getShuffleMask();
4365 Demand &DS = DemandOf(SVI->getOperand(0));
4366 for (unsigned I = 0, E = Mask.size(); I != E; ++I) {
4367 // Skip lanes that are undemanded or map to poison.
4368 if (!DV.Lanes[I] || Mask[I] < 0 ||
4369 (unsigned)Mask[I] >= DS.Lanes.getBitWidth())
4370 continue;
4371 if (DS.Lanes[Mask[I]] || DV.Duplicates[I])
4372 DS.Duplicates.setBit(Mask[I]);
4373 DS.Lanes.setBit(Mask[I]);
4374 }
4375 } else {
4376 auto *U = cast<User>(V);
4377 for (Value *Op : {U->getOperand(0), U->getOperand(1)}) {
4378 Demand &DOp = DemandOf(Op);
4379 // Lanes demanded through more than one path accumulate in Duplicates.
4380 DOp.Duplicates |= DV.Duplicates | (DOp.Lanes & DV.Lanes);
4381 DOp.Lanes |= DV.Lanes;
4382 }
4383 }
4384 }
4385
4386 // Reducing V replaces the entire chain, so every contribution to the result
4387 // must flow through V. Reject if anything above V reads outside the chain.
4388 auto CoversChain = [&](Value *V) {
4389 SmallVector<Value *, 8> Worklist(1, VecOpEE);
4390 SmallPtrSet<Value *, 8> Seen;
4391 Seen.insert(VecOpEE);
4392 while (!Worklist.empty()) {
4393 auto *U = cast<Instruction>(Worklist.pop_back_val());
4394 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4395 for (unsigned I = 0; I != NumOps; ++I) {
4396 Value *Op = U->getOperand(I);
4397 if (Op == V || !Seen.insert(Op).second)
4398 continue;
4399 if (!Nodes.contains(Op))
4400 return false;
4401 Worklist.push_back(Op);
4402 }
4403 }
4404 return true;
4405 };
4406
4407 // Reduce a single cleanly demanded source if there is one, otherwise the
4408 // deepest intermediate that covers the chain.
4409 struct ReductionCut {
4410 Value *Src;
4411 APInt Elts;
4412 };
4413 std::optional<ReductionCut> Cut;
4414 for (Value *S : Sources) {
4415 auto It = Demands.find(S);
4416 if (It == Demands.end() || It->second.Lanes.isZero())
4417 continue;
4418 if (!IsIdempotent && !It->second.Duplicates.isZero()) {
4419 Cut.reset();
4420 break;
4421 }
4422 if (!Cut) {
4423 Cut = ReductionCut{S, It->second.Lanes};
4424 continue;
4425 }
4426 if (!isEquivBitcast(Cut->Src, S)) {
4427 Cut.reset();
4428 break;
4429 }
4430 if (!IsIdempotent && !(Cut->Elts & It->second.Lanes).isZero()) {
4431 Cut.reset();
4432 break;
4433 }
4434 Cut->Elts |= It->second.Lanes;
4435 }
4436 if (!Cut) {
4437 for (Value *V : Nodes) {
4439 continue;
4440 auto It = Demands.find(V);
4441 if (It == Demands.end() || !It->second.Lanes.isAllOnes())
4442 continue;
4443 if (!IsIdempotent && !It->second.Duplicates.isZero())
4444 continue;
4445 if (!CoversChain(V))
4446 continue;
4447 Cut = ReductionCut{V, It->second.Lanes};
4448 break;
4449 }
4450 }
4451 // Reducing one lane is just an extract and can refold forever.
4452 if (!Cut || Cut->Elts.popcount() < 2)
4453 return false;
4454
4455 Intrinsic::ID ReducedOp =
4456 (CommonCallOp ? getMinMaxReductionIntrinsicID(*CommonCallOp)
4457 : getReductionForBinop(*CommonBinOp));
4458 if (!ReducedOp)
4459 return false;
4460
4461 InstructionCost OrigCost = 0;
4462 for (Value *V : Nodes)
4463 OrigCost += TTI.getInstructionCost(cast<Instruction>(V), CostKind);
4464
4465 auto *SrcVT = cast<FixedVectorType>(Cut->Src->getType());
4466 bool IsPartialReduction = !Cut->Elts.isAllOnes();
4467 FixedVectorType *ReduceVecTy =
4468 IsPartialReduction
4469 ? FixedVectorType::get(FVT->getElementType(), Cut->Elts.popcount())
4470 : SrcVT;
4471
4472 SmallVector<int> ExtractMask;
4473 InstructionCost NewCost = 0;
4474 if (IsPartialReduction) {
4475 for (unsigned I = 0, E = Cut->Elts.getBitWidth(); I != E; ++I)
4476 if (Cut->Elts[I])
4477 ExtractMask.push_back(I);
4478 unsigned SubIdx = 0, SubLen;
4479 auto SK = Cut->Elts.isShiftedMask(SubIdx, SubLen)
4482 NewCost += TTI.getShuffleCost(SK, ReduceVecTy, SrcVT, CostKind, ExtractMask,
4483 SubIdx, ReduceVecTy);
4484 }
4485
4486 IntrinsicCostAttributes ICA(
4487 ReducedOp, ReduceVecTy->getElementType(),
4488 IsFloatReduction
4489 ? SmallVector<Type *, 2>{ReduceVecTy->getElementType(), ReduceVecTy}
4490 : SmallVector<Type *, 2>{ReduceVecTy},
4491 IsFloatReduction ? CommonFMF : FastMathFlags());
4492 NewCost += TTI.getIntrinsicInstrCost(ICA, CostKind);
4493
4494 LLVM_DEBUG(dbgs() << "Found reduction shuffle chain: " << I << "\n OldCost : "
4495 << OrigCost << " vs NewCost: " << NewCost << "\n");
4496
4497 if (!OrigCost.isValid() || !NewCost.isValid())
4498 return false;
4499
4500 if (VecOpEE->hasOneUse() ? (NewCost > OrigCost) : (NewCost >= OrigCost))
4501 return false;
4502
4503 Value *ReduceInput = Cut->Src;
4504 if (IsPartialReduction)
4505 ReduceInput = Builder.CreateShuffleVector(Cut->Src, ExtractMask);
4506
4507 Value *ReducedResult;
4508 if (IsFloatReduction) {
4510 *CommonBinOp, ReduceVecTy->getElementType(), /*AllowRHSConstant=*/false,
4511 CommonFMF.noSignedZeros());
4512 ReducedResult = Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy},
4513 {Identity, ReduceInput}, CommonFMF);
4514 } else {
4515 ReducedResult =
4516 Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy}, {ReduceInput});
4517 }
4518 replaceValue(I, *ReducedResult);
4519
4520 return true;
4521}
4522
4523/// Determine if its more efficient to fold:
4524/// reduce(trunc(x)) -> trunc(reduce(x)).
4525/// reduce(sext(x)) -> sext(reduce(x)).
4526/// reduce(zext(x)) -> zext(reduce(x)).
4527bool VectorCombine::foldCastFromReductions(Instruction &I) {
4528 auto *II = dyn_cast<IntrinsicInst>(&I);
4529 if (!II)
4530 return false;
4531
4532 bool TruncOnly = false;
4533 Intrinsic::ID IID = II->getIntrinsicID();
4534 switch (IID) {
4535 case Intrinsic::vector_reduce_add:
4536 case Intrinsic::vector_reduce_mul:
4537 TruncOnly = true;
4538 break;
4539 case Intrinsic::vector_reduce_and:
4540 case Intrinsic::vector_reduce_or:
4541 case Intrinsic::vector_reduce_xor:
4542 break;
4543 default:
4544 return false;
4545 }
4546
4547 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
4548 Value *ReductionSrc = I.getOperand(0);
4549
4550 Value *Src;
4551 if (!match(ReductionSrc, m_OneUse(m_Trunc(m_Value(Src)))) &&
4552 (TruncOnly || !match(ReductionSrc, m_OneUse(m_ZExtOrSExt(m_Value(Src))))))
4553 return false;
4554
4555 auto CastOpc =
4556 (Instruction::CastOps)cast<Instruction>(ReductionSrc)->getOpcode();
4557
4558 auto *SrcTy = cast<VectorType>(Src->getType());
4559 auto *ReductionSrcTy = cast<VectorType>(ReductionSrc->getType());
4560 Type *ResultTy = I.getType();
4561
4563 ReductionOpc, ReductionSrcTy, std::nullopt, CostKind);
4564 OldCost += TTI.getCastInstrCost(CastOpc, ReductionSrcTy, SrcTy,
4566 cast<CastInst>(ReductionSrc));
4567 InstructionCost NewCost =
4568 TTI.getArithmeticReductionCost(ReductionOpc, SrcTy, std::nullopt,
4569 CostKind) +
4570 TTI.getCastInstrCost(CastOpc, ResultTy, ReductionSrcTy->getScalarType(),
4571 TTI::CastContextHint::None, CostKind);
4572
4573 if (OldCost <= NewCost || !NewCost.isValid())
4574 return false;
4575
4576 Value *NewReduction = Builder.CreateIntrinsic(SrcTy->getScalarType(),
4577 II->getIntrinsicID(), {Src});
4578 Value *NewCast = Builder.CreateCast(CastOpc, NewReduction, ResultTy);
4579 replaceValue(I, *NewCast);
4580 return true;
4581}
4582
4583/// Fold:
4584/// icmp pred (reduce.{add,or,and,umax,umin}(signbit_extract(x))), C
4585/// into:
4586/// icmp sgt/slt (reduce.{or,umax,and,umin}(x)), -1/0
4587///
4588/// Sign-bit reductions produce values with known semantics:
4589/// - reduce.{or,umax}: 0 if no element is negative, 1 if any is
4590/// - reduce.{and,umin}: 1 if all elements are negative, 0 if any isn't
4591/// - reduce.add: count of negative elements (0 to NumElts)
4592///
4593/// Both lshr and ashr are supported:
4594/// - lshr produces 0 or 1, so reduce.add range is [0, N]
4595/// - ashr produces 0 or -1, so reduce.add range is [-N, 0]
4596///
4597/// The fold generalizes to multiple source vectors combined with the same
4598/// operation as the reduction. For example:
4599/// reduce.or(or(shr A, shr B)) conceptually extends the vector
4600/// For reduce.add, this changes the count to M*N where M is the number of
4601/// source vectors.
4602///
4603/// We transform to a direct sign check on the original vector using
4604/// reduce.{or,umax} or reduce.{and,umin}.
4605///
4606/// In spirit, it's similar to foldSignBitCheck in InstCombine.
4607bool VectorCombine::foldSignBitReductionCmp(Instruction &I) {
4608 CmpPredicate Pred;
4609 IntrinsicInst *ReduceOp;
4610 const APInt *CmpVal;
4611 if (!match(&I,
4612 m_ICmp(Pred, m_OneUse(m_AnyIntrinsic(ReduceOp)), m_APInt(CmpVal))))
4613 return false;
4614
4615 Intrinsic::ID OrigIID = ReduceOp->getIntrinsicID();
4616 switch (OrigIID) {
4617 case Intrinsic::vector_reduce_or:
4618 case Intrinsic::vector_reduce_umax:
4619 case Intrinsic::vector_reduce_and:
4620 case Intrinsic::vector_reduce_umin:
4621 case Intrinsic::vector_reduce_add:
4622 break;
4623 default:
4624 return false;
4625 }
4626
4627 Value *ReductionSrc = ReduceOp->getArgOperand(0);
4628 auto *VecTy = dyn_cast<FixedVectorType>(ReductionSrc->getType());
4629 if (!VecTy)
4630 return false;
4631
4632 unsigned BitWidth = VecTy->getScalarSizeInBits();
4633 if (BitWidth == 1)
4634 return false;
4635
4636 unsigned NumElts = VecTy->getNumElements();
4637
4638 // Determine the expected tree opcode for multi-vector patterns.
4639 // The tree opcode must match the reduction's underlying operation.
4640 //
4641 // TODO: for pairs of equivalent operators, we should match both,
4642 // not only the most common.
4643 Instruction::BinaryOps TreeOpcode;
4644 switch (OrigIID) {
4645 case Intrinsic::vector_reduce_or:
4646 case Intrinsic::vector_reduce_umax:
4647 TreeOpcode = Instruction::Or;
4648 break;
4649 case Intrinsic::vector_reduce_and:
4650 case Intrinsic::vector_reduce_umin:
4651 TreeOpcode = Instruction::And;
4652 break;
4653 case Intrinsic::vector_reduce_add:
4654 TreeOpcode = Instruction::Add;
4655 break;
4656 default:
4657 llvm_unreachable("Unexpected intrinsic");
4658 }
4659
4660 // Collect sign-bit extraction leaves from an associative tree of TreeOpcode.
4661 // The tree conceptually extends the vector being reduced.
4662 SmallVector<Value *, 8> Worklist;
4663 SmallVector<Value *, 8> Sources; // Original vectors (X in shr X, BW-1)
4664 Worklist.push_back(ReductionSrc);
4665 std::optional<bool> IsAShr;
4666 constexpr unsigned MaxSources = 8;
4667
4668 // Calculate old cost: all shifts + tree ops + reduction
4669 InstructionCost OldCost = TTI.getInstructionCost(ReduceOp, CostKind);
4670
4671 while (!Worklist.empty() && Worklist.size() <= MaxSources &&
4672 Sources.size() <= MaxSources) {
4673 Value *V = Worklist.pop_back_val();
4674
4675 // Try to match sign-bit extraction: shr X, (bitwidth-1)
4676 Value *X;
4678 auto *Shr = cast<Instruction>(V);
4679
4680 // All shifts must be the same type (all lshr or all ashr)
4681 bool ThisIsAShr = Shr->getOpcode() == Instruction::AShr;
4682 if (!IsAShr)
4683 IsAShr = ThisIsAShr;
4684 else if (*IsAShr != ThisIsAShr)
4685 return false;
4686
4687 Sources.push_back(X);
4688
4689 // As part of the fold, we remove all of the shifts, so we need to keep
4690 // track of their costs.
4691 OldCost += TTI.getInstructionCost(Shr, CostKind);
4692
4693 continue;
4694 }
4695
4696 // Try to extend through a tree node of the expected opcode
4697 Value *A, *B;
4698 if (!match(V, m_OneUse(m_BinOp(TreeOpcode, m_Value(A), m_Value(B)))))
4699 return false;
4700
4701 // We are potentially replacing these operations as well, so we add them
4702 // to the costs.
4703 OldCost += TTI.getInstructionCost(cast<Instruction>(V), CostKind);
4704
4705 Worklist.push_back(A);
4706 Worklist.push_back(B);
4707 }
4708
4709 // Must have at least one source and not exceed limit
4710 if (Sources.empty() || Sources.size() > MaxSources ||
4711 Worklist.size() > MaxSources || !IsAShr)
4712 return false;
4713
4714 unsigned NumSources = Sources.size();
4715
4716 // For reduce.add, the total count must fit as a signed integer.
4717 // Range is [0, M*N] for lshr or [-M*N, 0] for ashr.
4718 if (OrigIID == Intrinsic::vector_reduce_add &&
4719 !isIntN(BitWidth, NumSources * NumElts))
4720 return false;
4721
4722 // Compute the boundary value when all elements are negative:
4723 // - Per-element contribution: 1 for lshr, -1 for ashr
4724 // - For add: M*N (total elements across all sources); for others: just 1
4725 unsigned Count =
4726 (OrigIID == Intrinsic::vector_reduce_add) ? NumSources * NumElts : 1;
4727 APInt NegativeVal(CmpVal->getBitWidth(), Count);
4728 if (*IsAShr)
4729 NegativeVal.negate();
4730
4731 // Range is [min(0, AllNegVal), max(0, AllNegVal)]
4732 APInt Zero = APInt::getZero(CmpVal->getBitWidth());
4733 APInt RangeLow = APIntOps::smin(Zero, NegativeVal);
4734 APInt RangeHigh = APIntOps::smax(Zero, NegativeVal);
4735
4736 // Determine comparison semantics:
4737 // - IsEq: true for equality test, false for inequality
4738 // - TestsNegative: true if testing against AllNegVal, false for zero
4739 //
4740 // In addition to EQ/NE against 0 or AllNegVal, we support inequalities
4741 // that fold to boundary tests given the narrow value range:
4742 // < RangeHigh -> != RangeHigh
4743 // > RangeHigh-1 -> == RangeHigh
4744 // > RangeLow -> != RangeLow
4745 // < RangeLow+1 -> == RangeLow
4746 //
4747 // For inequalities, we work with signed predicates only. Unsigned predicates
4748 // are canonicalized to signed when the range is non-negative (where they are
4749 // equivalent). When the range includes negative values, unsigned predicates
4750 // would have different semantics due to wrap-around, so we reject them.
4751 if (!ICmpInst::isEquality(Pred) && !ICmpInst::isSigned(Pred)) {
4752 if (RangeLow.isNegative())
4753 return false;
4755 }
4756
4757 bool IsEq;
4758 bool TestsNegative;
4760 if (CmpVal->isZero()) {
4761 TestsNegative = false;
4762 } else if (*CmpVal == NegativeVal) {
4763 TestsNegative = true;
4764 } else {
4765 return false;
4766 }
4767 IsEq = Pred == ICmpInst::ICMP_EQ;
4768 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeHigh) {
4769 IsEq = false;
4770 TestsNegative = (RangeHigh == NegativeVal);
4771 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeHigh - 1) {
4772 IsEq = true;
4773 TestsNegative = (RangeHigh == NegativeVal);
4774 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeLow) {
4775 IsEq = false;
4776 TestsNegative = (RangeLow == NegativeVal);
4777 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeLow + 1) {
4778 IsEq = true;
4779 TestsNegative = (RangeLow == NegativeVal);
4780 } else {
4781 return false;
4782 }
4783
4784 // For this fold we support four types of checks:
4785 //
4786 // 1. All lanes are negative - AllNeg
4787 // 2. All lanes are non-negative - AllNonNeg
4788 // 3. At least one negative lane - AnyNeg
4789 // 4. At least one non-negative lane - AnyNonNeg
4790 //
4791 // For each case, we can generate the following code:
4792 //
4793 // 1. AllNeg - reduce.and/umin(X) < 0
4794 // 2. AllNonNeg - reduce.or/umax(X) > -1
4795 // 3. AnyNeg - reduce.or/umax(X) < 0
4796 // 4. AnyNonNeg - reduce.and/umin(X) > -1
4797 //
4798 // The table below shows the aggregation of all supported cases
4799 // using these four cases.
4800 //
4801 // Reduction | == 0 | != 0 | == MAX | != MAX
4802 // ------------+-----------+-----------+-----------+-----------
4803 // or/umax | AllNonNeg | AnyNeg | AnyNeg | AllNonNeg
4804 // and/umin | AnyNonNeg | AllNeg | AllNeg | AnyNonNeg
4805 // add | AllNonNeg | AnyNeg | AllNeg | AnyNonNeg
4806 //
4807 // NOTE: MAX = 1 for or/and/umax/umin, and the vector size N for add
4808 //
4809 // For easier codegen and check inversion, we use the following encoding:
4810 //
4811 // 1. Bit-3 === requires or/umax (1) or and/umin (0) check
4812 // 2. Bit-2 === checks < 0 (1) or > -1 (0)
4813 // 3. Bit-1 === universal (1) or existential (0) check
4814 //
4815 // AnyNeg = 0b110: uses or/umax, checks negative, any-check
4816 // AllNonNeg = 0b101: uses or/umax, checks non-neg, all-check
4817 // AnyNonNeg = 0b000: uses and/umin, checks non-neg, any-check
4818 // AllNeg = 0b011: uses and/umin, checks negative, all-check
4819 //
4820 // XOR with 0b011 inverts the check (swaps all/any and neg/non-neg).
4821 //
4822 enum CheckKind : unsigned {
4823 AnyNonNeg = 0b000,
4824 AllNeg = 0b011,
4825 AllNonNeg = 0b101,
4826 AnyNeg = 0b110,
4827 };
4828 // Return true if we fold this check into or/umax and false for and/umin
4829 auto RequiresOr = [](CheckKind C) -> bool { return C & 0b100; };
4830 // Return true if we should check if result is negative and false otherwise
4831 auto IsNegativeCheck = [](CheckKind C) -> bool { return C & 0b010; };
4832 // Logically invert the check
4833 auto Invert = [](CheckKind C) { return CheckKind(C ^ 0b011); };
4834
4835 CheckKind Base;
4836 switch (OrigIID) {
4837 case Intrinsic::vector_reduce_or:
4838 case Intrinsic::vector_reduce_umax:
4839 Base = TestsNegative ? AnyNeg : AllNonNeg;
4840 break;
4841 case Intrinsic::vector_reduce_and:
4842 case Intrinsic::vector_reduce_umin:
4843 Base = TestsNegative ? AllNeg : AnyNonNeg;
4844 break;
4845 case Intrinsic::vector_reduce_add:
4846 Base = TestsNegative ? AllNeg : AllNonNeg;
4847 break;
4848 default:
4849 llvm_unreachable("Unexpected intrinsic");
4850 }
4851
4852 CheckKind Check = IsEq ? Base : Invert(Base);
4853
4854 auto PickCheaper = [&](Intrinsic::ID Arith, Intrinsic::ID MinMax) {
4855 InstructionCost ArithCost =
4857 VecTy, std::nullopt, CostKind);
4858 InstructionCost MinMaxCost =
4860 FastMathFlags(), CostKind);
4861 return ArithCost <= MinMaxCost ? std::make_pair(Arith, ArithCost)
4862 : std::make_pair(MinMax, MinMaxCost);
4863 };
4864
4865 // Choose output reduction based on encoding's MSB
4866 auto [NewIID, NewCost] = RequiresOr(Check)
4867 ? PickCheaper(Intrinsic::vector_reduce_or,
4868 Intrinsic::vector_reduce_umax)
4869 : PickCheaper(Intrinsic::vector_reduce_and,
4870 Intrinsic::vector_reduce_umin);
4871
4872 // Add cost of combining multiple sources with or/and
4873 if (NumSources > 1) {
4874 unsigned CombineOpc =
4875 RequiresOr(Check) ? Instruction::Or : Instruction::And;
4876 NewCost += TTI.getArithmeticInstrCost(CombineOpc, VecTy, CostKind) *
4877 (NumSources - 1);
4878 }
4879
4880 LLVM_DEBUG(dbgs() << "Found sign-bit reduction cmp: " << I << "\n OldCost: "
4881 << OldCost << " vs NewCost: " << NewCost << "\n");
4882
4883 if (NewCost > OldCost)
4884 return false;
4885
4886 // Generate the combined input and reduction
4887 Builder.SetInsertPoint(&I);
4888 Type *ScalarTy = VecTy->getScalarType();
4889
4890 Value *Input;
4891 if (NumSources == 1) {
4892 Input = Sources[0];
4893 } else {
4894 // Combine sources with or/and based on check type
4895 Input = RequiresOr(Check) ? Builder.CreateOr(Sources)
4896 : Builder.CreateAnd(Sources);
4897 }
4898
4899 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, NewIID, {Input});
4900 Value *NewCmp = IsNegativeCheck(Check) ? Builder.CreateIsNeg(NewReduce)
4901 : Builder.CreateIsNotNeg(NewReduce);
4902 replaceValue(I, *NewCmp);
4903 return true;
4904}
4905
4906/// Fold a zero test of reduce.or or reduce.umax into a boolean reduction.
4907///
4908/// Vectorization may produce IR that compares the result of a scalar reduction
4909/// with zero. Depending on the target, lowering a reduction and a scalar
4910/// comparison separately can cost more than reducing lane-wise comparison
4911/// results. This fold creates the latter form only when it is not costlier.
4912///
4913/// Before:
4914/// %r = call iT @llvm.vector.reduce.or.vNiT(<N x iT> %x)
4915/// %cmp = icmp ne iT %r, 0
4916///
4917/// After:
4918/// %lane.cmp = icmp ne <N x iT> %x, zeroinitializer
4919/// %cmp = call i1 @llvm.vector.reduce.or.vNi1(<N x i1> %lane.cmp)
4920///
4921/// `reduce.or` and `reduce.umax` are non-zero when at least one lane is
4922/// non-zero. Therefore, `icmp ne` uses the existential `reduce.or` test.
4923/// Conversely, `icmp eq` must check that every lane is zero, so it uses the
4924/// universal `reduce.and` test.
4925///
4926/// Before:
4927/// %r = call iT @llvm.vector.reduce.umax.vNiT(<N x iT> %x)
4928/// %cmp = icmp eq iT %r, 0
4929///
4930/// After:
4931/// %lane.cmp = icmp eq <N x iT> %x, zeroinitializer
4932/// %cmp = call i1 @llvm.vector.reduce.and.vNi1(<N x i1> %lane.cmp)
4933bool VectorCombine::foldReductionZeroTest(Instruction &I) {
4934 CmpPredicate Pred;
4935 Value *Op;
4936
4937 if (!match(&I, m_c_ICmp(Pred, m_Value(Op), m_Zero())) ||
4939 return false;
4940
4941 auto *II = dyn_cast<IntrinsicInst>(Op);
4942 if (!II || !II->hasOneUse())
4943 return false;
4944
4945 auto ReduceID = II->getIntrinsicID();
4946 if (ReduceID != Intrinsic::vector_reduce_or &&
4947 ReduceID != Intrinsic::vector_reduce_umax)
4948 return false;
4949
4950 Value *Vec = II->getArgOperand(0);
4951 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
4952 if (!VecTy || !VecTy->getElementType()->isIntegerTy())
4953 return false;
4954
4955 // Map the scalar zero test to an any-lane or all-lane boolean reduction.
4956 Intrinsic::ID NewIID = (Pred == ICmpInst::ICMP_NE)
4957 ? Intrinsic::vector_reduce_or
4958 : Intrinsic::vector_reduce_and;
4959
4960 // This is not an unconditional canonicalization: compare the cost of the
4961 // original scalar reduction and compare with the vector compare and i1
4962 // reduction replacement for both reduce.or and reduce.umax.
4963 InstructionCost OldCost = TTI.getInstructionCost(II, CostKind) +
4964 TTI.getInstructionCost(&I, CostKind);
4965
4966 auto *CmpTy = cast<VectorType>(CmpInst::makeCmpResultType(VecTy));
4967 InstructionCost NewCost =
4968 TTI.getCmpSelInstrCost(Instruction::ICmp, VecTy, CmpTy, Pred, CostKind);
4970 getArithmeticReductionInstruction(NewIID), CmpTy, std::nullopt, CostKind);
4971
4972 LLVM_DEBUG(dbgs() << "Found a reduction zero test: " << I << "\n OldCost: "
4973 << OldCost << " vs NewCost: " << NewCost << "\n");
4974
4975 if (!OldCost.isValid() || !NewCost.isValid() || NewCost > OldCost)
4976 return false;
4977
4978 Builder.SetInsertPoint(&I);
4979 Value *NewCmp = Builder.CreateICmp(Pred, Vec, Constant::getNullValue(VecTy));
4980 Value *NewReduce = Builder.CreateIntrinsic(NewIID, {CmpTy}, {NewCmp});
4981 replaceValue(I, *NewReduce);
4982 return true;
4983}
4984
4985/// vector.reduce.OP f(X_i) == 0 -> vector.reduce.OP X_i == 0
4986///
4987/// We can prove it for cases when:
4988///
4989/// 1. OP X_i == 0 <=> \forall i \in [1, N] X_i == 0
4990/// 1'. OP X_i == 0 <=> \exists j \in [1, N] X_j == 0
4991/// 2. f(x) == 0 <=> x == 0
4992///
4993/// From 1 and 2 (or 1' and 2), we can infer that
4994///
4995/// OP f(X_i) == 0 <=> OP X_i == 0.
4996///
4997/// (1)
4998/// OP f(X_i) == 0 <=> \forall i \in [1, N] f(X_i) == 0
4999/// (2)
5000/// <=> \forall i \in [1, N] X_i == 0
5001/// (1)
5002/// <=> OP(X_i) == 0
5003///
5004/// For some of the OP's and f's, we need to have domain constraints on X
5005/// to ensure properties 1 (or 1') and 2.
5006bool VectorCombine::foldICmpEqZeroVectorReduce(Instruction &I) {
5007 CmpPredicate Pred;
5008 Value *Op;
5009 if (!match(&I, m_ICmp(Pred, m_Value(Op), m_Zero())) ||
5011 return false;
5012
5013 auto *II = dyn_cast<IntrinsicInst>(Op);
5014 if (!II)
5015 return false;
5016
5017 switch (II->getIntrinsicID()) {
5018 case Intrinsic::vector_reduce_add:
5019 case Intrinsic::vector_reduce_or:
5020 case Intrinsic::vector_reduce_umin:
5021 case Intrinsic::vector_reduce_umax:
5022 case Intrinsic::vector_reduce_smin:
5023 case Intrinsic::vector_reduce_smax:
5024 break;
5025 default:
5026 return false;
5027 }
5028
5029 Value *InnerOp = II->getArgOperand(0);
5030
5031 // TODO: fixed vector type might be too restrictive
5032 if (!II->hasOneUse() || !isa<FixedVectorType>(InnerOp->getType()))
5033 return false;
5034
5035 Value *X = nullptr;
5036
5037 // Check for zero-preserving operations where f(x) = 0 <=> x = 0
5038 //
5039 // 1. f(x) = shl nuw x, y for arbitrary y
5040 // 2. f(x) = mul nuw x, c for defined c != 0
5041 // 3. f(x) = zext x
5042 // 4. f(x) = sext x
5043 // 5. f(x) = neg x
5044 //
5045 if (!(match(InnerOp, m_NUWShl(m_Value(X), m_Value())) || // Case 1
5046 match(InnerOp, m_NUWMul(m_Value(X), m_NonZeroInt())) || // Case 2
5047 match(InnerOp, m_ZExt(m_Value(X))) || // Case 3
5048 match(InnerOp, m_SExt(m_Value(X))) || // Case 4
5049 match(InnerOp, m_Neg(m_Value(X))) // Case 5
5050 ))
5051 return false;
5052
5053 SimplifyQuery S = SQ.getWithInstruction(&I);
5054 auto *XTy = cast<FixedVectorType>(X->getType());
5055
5056 // Check for domain constraints for all supported reductions.
5057 //
5058 // a. OR X_i - has property 1 for every X
5059 // b. UMAX X_i - has property 1 for every X
5060 // c. UMIN X_i - has property 1' for every X
5061 // d. SMAX X_i - has property 1 for X >= 0
5062 // e. SMIN X_i - has property 1' for X >= 0
5063 // f. ADD X_i - has property 1 for X >= 0 && ADD X_i doesn't sign wrap
5064 //
5065 // In order for the proof to work, we need 1 (or 1') to be true for both
5066 // OP f(X_i) and OP X_i and that's why below we check constraints twice.
5067 //
5068 // NOTE: ADD X_i holds property 1 for a mirror case as well, i.e. when
5069 // X <= 0 && ADD X_i doesn't sign wrap. However, due to the nature
5070 // of known bits, we can't reasonably hold knowledge of "either 0
5071 // or negative".
5072 switch (II->getIntrinsicID()) {
5073 case Intrinsic::vector_reduce_add: {
5074 // We need to check that both X_i and f(X_i) have enough leading
5075 // zeros to not overflow.
5076 KnownBits KnownX = computeKnownBits(X, S);
5077 KnownBits KnownFX = computeKnownBits(InnerOp, S);
5078 unsigned NumElems = XTy->getNumElements();
5079 // Adding N elements loses at most ceil(log2(N)) leading bits.
5080 unsigned LostBits = Log2_32_Ceil(NumElems);
5081 unsigned LeadingZerosX = KnownX.countMinLeadingZeros();
5082 unsigned LeadingZerosFX = KnownFX.countMinLeadingZeros();
5083 // Need at least one leading zero left after summation to ensure no overflow
5084 if (LeadingZerosX <= LostBits || LeadingZerosFX <= LostBits)
5085 return false;
5086
5087 // We are not checking whether X or f(X) are positive explicitly because
5088 // we implicitly checked for it when we checked if both cases have enough
5089 // leading zeros to not wrap addition.
5090 break;
5091 }
5092 case Intrinsic::vector_reduce_smin:
5093 case Intrinsic::vector_reduce_smax:
5094 // Check whether X >= 0 and f(X) >= 0
5095 if (!isKnownNonNegative(InnerOp, S) || !isKnownNonNegative(X, S))
5096 return false;
5097
5098 break;
5099 default:
5100 break;
5101 };
5102
5103 LLVM_DEBUG(dbgs() << "Found a reduction to 0 comparison with removable op: "
5104 << *II << "\n");
5105
5106 // For zext/sext, check if the transform is profitable using cost model.
5107 // For other operations (shl, mul, neg), we're removing an instruction
5108 // while keeping the same reduction type, so it's always profitable.
5109 if (isa<ZExtInst>(InnerOp) || isa<SExtInst>(InnerOp)) {
5110 auto *FXTy = cast<FixedVectorType>(InnerOp->getType());
5111 Intrinsic::ID IID = II->getIntrinsicID();
5112
5114 cast<CastInst>(InnerOp)->getOpcode(), FXTy, XTy,
5115 TTI::CastContextHint::None, CostKind, cast<CastInst>(InnerOp));
5116
5117 InstructionCost OldReduceCost, NewReduceCost;
5118 switch (IID) {
5119 case Intrinsic::vector_reduce_add:
5120 case Intrinsic::vector_reduce_or:
5121 OldReduceCost = TTI.getArithmeticReductionCost(
5122 getArithmeticReductionInstruction(IID), FXTy, std::nullopt, CostKind);
5123 NewReduceCost = TTI.getArithmeticReductionCost(
5124 getArithmeticReductionInstruction(IID), XTy, std::nullopt, CostKind);
5125 break;
5126 case Intrinsic::vector_reduce_umin:
5127 case Intrinsic::vector_reduce_umax:
5128 case Intrinsic::vector_reduce_smin:
5129 case Intrinsic::vector_reduce_smax:
5130 OldReduceCost = TTI.getMinMaxReductionCost(
5131 getMinMaxReductionIntrinsicOp(IID), FXTy, FastMathFlags(), CostKind);
5132 NewReduceCost = TTI.getMinMaxReductionCost(
5133 getMinMaxReductionIntrinsicOp(IID), XTy, FastMathFlags(), CostKind);
5134 break;
5135 default:
5136 llvm_unreachable("Unexpected reduction");
5137 }
5138
5139 InstructionCost OldCost = OldReduceCost + ExtCost;
5140 InstructionCost NewCost =
5141 NewReduceCost + (InnerOp->hasOneUse() ? 0 : ExtCost);
5142
5143 LLVM_DEBUG(dbgs() << "Found a removable extension before reduction: "
5144 << *InnerOp << "\n OldCost: " << OldCost
5145 << " vs NewCost: " << NewCost << "\n");
5146
5147 // We consider transformation to still be potentially beneficial even
5148 // when the costs are the same because we might remove a use from f(X)
5149 // and unlock other optimizations. Equal costs would just mean that we
5150 // didn't make it worse in the worst case.
5151 if (NewCost > OldCost)
5152 return false;
5153 }
5154
5155 // Since we support zext and sext as f, we might change the scalar type
5156 // of the intrinsic.
5157 Type *Ty = XTy->getScalarType();
5158 Value *NewReduce = Builder.CreateIntrinsic(Ty, II->getIntrinsicID(), {X});
5159 Value *NewCmp =
5160 Builder.CreateICmp(Pred, NewReduce, ConstantInt::getNullValue(Ty));
5161 replaceValue(I, *NewCmp);
5162 return true;
5163}
5164
5165/// Fold comparisons of reduce.or/reduce.and with reduce.umax/reduce.umin
5166/// based on cost, preserving the comparison semantics.
5167///
5168/// We use two fundamental properties for each pair:
5169///
5170/// 1. or(X) == 0 <=> umax(X) == 0
5171/// 2. or(X) == 1 <=> umax(X) == 1
5172/// 3. sign(or(X)) == sign(umax(X))
5173///
5174/// 1. and(X) == -1 <=> umin(X) == -1
5175/// 2. and(X) == -2 <=> umin(X) == -2
5176/// 3. sign(and(X)) == sign(umin(X))
5177///
5178/// From these we can infer the following transformations:
5179/// a. or(X) ==/!= 0 <-> umax(X) ==/!= 0
5180/// b. or(X) s< 0 <-> umax(X) s< 0
5181/// c. or(X) s> -1 <-> umax(X) s> -1
5182/// d. or(X) s< 1 <-> umax(X) s< 1
5183/// e. or(X) ==/!= 1 <-> umax(X) ==/!= 1
5184/// f. or(X) s< 2 <-> umax(X) s< 2
5185/// g. and(X) ==/!= -1 <-> umin(X) ==/!= -1
5186/// h. and(X) s< 0 <-> umin(X) s< 0
5187/// i. and(X) s> -1 <-> umin(X) s> -1
5188/// j. and(X) s> -2 <-> umin(X) s> -2
5189/// k. and(X) ==/!= -2 <-> umin(X) ==/!= -2
5190/// l. and(X) s> -3 <-> umin(X) s> -3
5191///
5192bool VectorCombine::foldEquivalentReductionCmp(Instruction &I) {
5193 CmpPredicate Pred;
5194 Value *ReduceOp;
5195 const APInt *CmpVal;
5196 if (!match(&I, m_ICmp(Pred, m_Value(ReduceOp), m_APInt(CmpVal))))
5197 return false;
5198
5199 auto *II = dyn_cast<IntrinsicInst>(ReduceOp);
5200 if (!II || !II->hasOneUse())
5201 return false;
5202
5203 const auto IsValidOrUmaxCmp = [&]() {
5204 // or === umax for i1
5205 if (CmpVal->getBitWidth() == 1)
5206 return true;
5207
5208 // Cases a and e
5209 bool IsEquality =
5210 (CmpVal->isZero() || CmpVal->isOne()) && ICmpInst::isEquality(Pred);
5211 // Case c
5212 bool IsPositive = CmpVal->isAllOnes() && Pred == ICmpInst::ICMP_SGT;
5213 // Cases b, d, and f
5214 bool IsNegative = (CmpVal->isZero() || CmpVal->isOne() || *CmpVal == 2) &&
5215 Pred == ICmpInst::ICMP_SLT;
5216 return IsEquality || IsPositive || IsNegative;
5217 };
5218
5219 const auto IsValidAndUminCmp = [&]() {
5220 // and === umin for i1
5221 if (CmpVal->getBitWidth() == 1)
5222 return true;
5223
5224 const auto LeadingOnes = CmpVal->countl_one();
5225
5226 // Cases g and k
5227 bool IsEquality =
5228 (CmpVal->isAllOnes() || LeadingOnes + 1 == CmpVal->getBitWidth()) &&
5230 // Case h
5231 bool IsNegative = CmpVal->isZero() && Pred == ICmpInst::ICMP_SLT;
5232 // Cases i, j, and l
5233 bool IsPositive =
5234 // if the number has at least N - 2 leading ones
5235 // and the two LSBs are:
5236 // - 1 x 1 -> -1
5237 // - 1 x 0 -> -2
5238 // - 0 x 1 -> -3
5239 LeadingOnes + 2 >= CmpVal->getBitWidth() &&
5240 ((*CmpVal)[0] || (*CmpVal)[1]) && Pred == ICmpInst::ICMP_SGT;
5241 return IsEquality || IsNegative || IsPositive;
5242 };
5243
5244 Intrinsic::ID OriginalIID = II->getIntrinsicID();
5245 Intrinsic::ID AlternativeIID;
5246
5247 // Check if this is a valid comparison pattern and determine the alternate
5248 // reduction intrinsic.
5249 switch (OriginalIID) {
5250 case Intrinsic::vector_reduce_or:
5251 if (!IsValidOrUmaxCmp())
5252 return false;
5253 AlternativeIID = Intrinsic::vector_reduce_umax;
5254 break;
5255 case Intrinsic::vector_reduce_umax:
5256 if (!IsValidOrUmaxCmp())
5257 return false;
5258 AlternativeIID = Intrinsic::vector_reduce_or;
5259 break;
5260 case Intrinsic::vector_reduce_and:
5261 if (!IsValidAndUminCmp())
5262 return false;
5263 AlternativeIID = Intrinsic::vector_reduce_umin;
5264 break;
5265 case Intrinsic::vector_reduce_umin:
5266 if (!IsValidAndUminCmp())
5267 return false;
5268 AlternativeIID = Intrinsic::vector_reduce_and;
5269 break;
5270 default:
5271 return false;
5272 }
5273
5274 Value *X = II->getArgOperand(0);
5275 auto *VecTy = dyn_cast<FixedVectorType>(X->getType());
5276 if (!VecTy)
5277 return false;
5278
5279 const auto GetReductionCost = [&](Intrinsic::ID IID) -> InstructionCost {
5280 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
5281 if (ReductionOpc != Instruction::ICmp)
5282 return TTI.getArithmeticReductionCost(ReductionOpc, VecTy, std::nullopt,
5283 CostKind);
5285 FastMathFlags(), CostKind);
5286 };
5287
5288 InstructionCost OrigCost = GetReductionCost(OriginalIID);
5289 InstructionCost AltCost = GetReductionCost(AlternativeIID);
5290
5291 LLVM_DEBUG(dbgs() << "Found equivalent reduction cmp: " << I
5292 << "\n OrigCost: " << OrigCost
5293 << " vs AltCost: " << AltCost << "\n");
5294
5295 if (AltCost >= OrigCost)
5296 return false;
5297
5298 Builder.SetInsertPoint(&I);
5299 Type *ScalarTy = VecTy->getScalarType();
5300 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, AlternativeIID, {X});
5301 Value *NewCmp =
5302 Builder.CreateICmp(Pred, NewReduce, ConstantInt::get(ScalarTy, *CmpVal));
5303
5304 replaceValue(I, *NewCmp);
5305 return true;
5306}
5307
5308/// Used by foldReduceAddCmpZero to check if we can prove that a value is
5309/// non-positive.
5310/// KnownBits cannot see sext <? x i1> as non-positive: each top bit equals a
5311/// single unknown input bit, which a per-bit lattice cannot track. The fold's
5312/// target shape is popcount-style sums of <N x i1> valid/invalid masks (e.g.
5313/// ray-intersection hits) tested for any-hit.
5314/// Previous attempts to approximate the known bits of such expressions were
5315/// using a fully recursive value tracking approach to infer a constant range
5316/// but ultimately turned to be too expensive in compile time.
5317static bool isKnownNonPositive(const Value *V, const SimplifyQuery &SQ,
5318 unsigned Depth = 0) {
5319 constexpr unsigned MaxLocalDepth = 2;
5320 if (Depth > MaxLocalDepth)
5321 return false;
5322
5323 auto NumSignBits = [&](const Value *X) {
5324 return ComputeNumSignBits(X, SQ.DL, SQ.AC, SQ.CtxI, SQ.DT);
5325 };
5326 if (NumSignBits(V) == V->getType()->getScalarSizeInBits())
5327 return true;
5328
5329 Value *A, *B;
5330 if (match(V, m_Add(m_Value(A), m_Value(B))))
5331 return NumSignBits(A) >= 2 && NumSignBits(B) >= 2 &&
5332 isKnownNonPositive(A, SQ, Depth + 1) &&
5333 isKnownNonPositive(B, SQ, Depth + 1);
5334
5335 return computeKnownBits(V, SQ).isNonPositive();
5336}
5337
5338/// Fold (icmp pred (reduce.add X), 0) to (icmp pred' (reduce.or X), 0) when X
5339/// has lanes known to all be non-negative or all non-positive, so that
5340/// sum == 0 iff every lane is 0. Falls back to reduce.umax if reduce.or is
5341/// more expensive on the target.
5342bool VectorCombine::foldReduceAddCmpZero(Instruction &I) {
5343 CmpPredicate Pred;
5344 Value *Vec;
5345 if (!match(&I, m_ICmp(Pred,
5347 m_Value(Vec))),
5348 m_Zero())))
5349 return false;
5350
5351 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
5352 if (!VecTy || VecTy->getNumElements() < 2)
5353 return false;
5354
5355 SimplifyQuery Q = SQ.getWithInstruction(&I);
5356 bool IsNonNegative = isKnownNonNegative(Vec, Q);
5357 bool IsNonPositive = !IsNonNegative && isKnownNonPositive(Vec, Q);
5358 if (!IsNonNegative && !IsNonPositive)
5359 return false;
5360
5361 // Summing NumElts lanes can consume up to log2(NumElts) sign bits. Require
5362 // strictly more headroom than that so the sum cannot wrap to zero.
5363 unsigned NumElts = VecTy->getNumElements();
5364 unsigned NumSignBits = ComputeNumSignBits(Vec, *DL, SQ.AC, &I, &DT);
5365 if (Log2_32(NumElts) >= NumSignBits)
5366 return false;
5367
5368 ICmpInst::Predicate NewPred;
5369 switch (Pred) {
5370 case ICmpInst::ICMP_EQ:
5371 case ICmpInst::ICMP_ULE:
5372 case ICmpInst::ICMP_SLE:
5373 case ICmpInst::ICMP_SGE:
5374 NewPred = ICmpInst::ICMP_EQ;
5375 break;
5376 case ICmpInst::ICMP_NE:
5377 case ICmpInst::ICMP_UGT:
5378 case ICmpInst::ICMP_SGT:
5379 case ICmpInst::ICMP_SLT:
5380 NewPred = ICmpInst::ICMP_NE;
5381 break;
5382 default:
5383 return false;
5384 }
5385
5386 // SGT and SLE on a non-positive tree, and SLT and SGE on a non-negative
5387 // tree, are tautologies (always true or always false). Leave those to
5388 // InstCombine rather than mapping them here. Remaining signed inequalities
5389 // also need one extra sign bit so the sum cannot flip sign.
5390 if (!IsNonNegative &&
5391 (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE))
5392 return false;
5393 if (!IsNonPositive &&
5394 (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE))
5395 return false;
5396 if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE ||
5397 Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) &&
5398 Log2_32(NumElts) >= NumSignBits - 1)
5399 return false;
5400
5402 Instruction::Add, VecTy, std::nullopt, CostKind);
5404 Instruction::Or, VecTy, std::nullopt, CostKind);
5406 Intrinsic::umax, VecTy, FastMathFlags(), CostKind);
5407 if (!OrCost.isValid() && !UmaxCost.isValid())
5408 return false;
5409 bool UseOr = OrCost.isValid() && (!UmaxCost.isValid() || OrCost <= UmaxCost);
5410 InstructionCost AltCost = UseOr ? OrCost : UmaxCost;
5411 if (AltCost > OrigCost)
5412 return false;
5413
5414 Builder.SetInsertPoint(&I);
5415 Value *NewReduce = UseOr ? Builder.CreateOrReduce(Vec)
5416 : Builder.CreateIntrinsic(
5417 Intrinsic::vector_reduce_umax, {VecTy}, {Vec});
5418 Value *NewCmp = Builder.CreateICmp(
5419 NewPred, NewReduce, ConstantInt::getNullValue(VecTy->getScalarType()));
5420 replaceValue(I, *NewCmp);
5421 return true;
5422}
5423
5424/// Returns true if this ShuffleVectorInst eventually feeds into a
5425/// vector reduction intrinsic (e.g., vector_reduce_add) by only following
5426/// chains of shuffles and binary operators (in any combination/order).
5427/// The search does not go deeper than the given Depth.
5429 constexpr unsigned MaxVisited = 32;
5432 bool FoundReduction = false;
5433
5434 WorkList.push_back(SVI);
5435 while (!WorkList.empty()) {
5436 Instruction *I = WorkList.pop_back_val();
5437 for (User *U : I->users()) {
5438 auto *UI = cast<Instruction>(U);
5439 if (!UI || !Visited.insert(UI).second)
5440 continue;
5441 if (Visited.size() > MaxVisited)
5442 return false;
5443 if (auto *II = dyn_cast<IntrinsicInst>(UI)) {
5444 // More than one reduction reached
5445 if (FoundReduction)
5446 return false;
5447 switch (II->getIntrinsicID()) {
5448 case Intrinsic::vector_reduce_add:
5449 case Intrinsic::vector_reduce_mul:
5450 case Intrinsic::vector_reduce_and:
5451 case Intrinsic::vector_reduce_or:
5452 case Intrinsic::vector_reduce_xor:
5453 case Intrinsic::vector_reduce_smin:
5454 case Intrinsic::vector_reduce_smax:
5455 case Intrinsic::vector_reduce_umin:
5456 case Intrinsic::vector_reduce_umax:
5457 FoundReduction = true;
5458 continue;
5459 default:
5460 return false;
5461 }
5462 }
5463
5465 return false;
5466
5467 WorkList.emplace_back(UI);
5468 }
5469 }
5470 return FoundReduction;
5471}
5472
5473/// This method looks for groups of shuffles acting on binops, of the form:
5474/// %x = shuffle ...
5475/// %y = shuffle ...
5476/// %a = binop %x, %y
5477/// %b = binop %x, %y
5478/// shuffle %a, %b, selectmask
5479/// We may, especially if the shuffle is wider than legal, be able to convert
5480/// the shuffle to a form where only parts of a and b need to be computed. On
5481/// architectures with no obvious "select" shuffle, this can reduce the total
5482/// number of operations if the target reports them as cheaper.
5483bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
5484 auto *SVI = cast<ShuffleVectorInst>(&I);
5485 auto *VT = cast<FixedVectorType>(I.getType());
5486 auto *Op0 = dyn_cast<Instruction>(SVI->getOperand(0));
5487 auto *Op1 = dyn_cast<Instruction>(SVI->getOperand(1));
5488 if (!Op0 || !Op1 || Op0 == Op1 || !Op0->isBinaryOp() || !Op1->isBinaryOp() ||
5489 VT != Op0->getType())
5490 return false;
5491
5492 auto *SVI0A = dyn_cast<Instruction>(Op0->getOperand(0));
5493 auto *SVI0B = dyn_cast<Instruction>(Op0->getOperand(1));
5494 auto *SVI1A = dyn_cast<Instruction>(Op1->getOperand(0));
5495 auto *SVI1B = dyn_cast<Instruction>(Op1->getOperand(1));
5496 SmallPtrSet<Instruction *, 4> InputShuffles({SVI0A, SVI0B, SVI1A, SVI1B});
5497 auto checkSVNonOpUses = [&](Instruction *I) {
5498 if (!I || I->getOperand(0)->getType() != VT)
5499 return true;
5500 return any_of(I->users(), [&](User *U) {
5501 return U != Op0 && U != Op1 &&
5502 !(isa<ShuffleVectorInst>(U) &&
5503 (InputShuffles.contains(cast<Instruction>(U)) ||
5504 isInstructionTriviallyDead(cast<Instruction>(U))));
5505 });
5506 };
5507 if (checkSVNonOpUses(SVI0A) || checkSVNonOpUses(SVI0B) ||
5508 checkSVNonOpUses(SVI1A) || checkSVNonOpUses(SVI1B))
5509 return false;
5510
5511 // Collect all the uses that are shuffles that we can transform together. We
5512 // may not have a single shuffle, but a group that can all be transformed
5513 // together profitably.
5515 auto collectShuffles = [&](Instruction *I) {
5516 for (auto *U : I->users()) {
5518 if (!SV || SV->getType() != VT)
5519 return false;
5520 if ((SV->getOperand(0) != Op0 && SV->getOperand(0) != Op1) ||
5521 (SV->getOperand(1) != Op0 && SV->getOperand(1) != Op1))
5522 return false;
5523 if (!llvm::is_contained(Shuffles, SV))
5524 Shuffles.push_back(SV);
5525 }
5526 return true;
5527 };
5528 if (!collectShuffles(Op0) || !collectShuffles(Op1))
5529 return false;
5530 // From a reduction, we need to be processing a single shuffle, otherwise the
5531 // other uses will not be lane-invariant.
5532 if (FromReduction && Shuffles.size() > 1)
5533 return false;
5534
5535 // Add any shuffle uses for the shuffles we have found, to include them in our
5536 // cost calculations.
5537 if (!FromReduction) {
5538 for (size_t Idx = 0, E = Shuffles.size(); Idx != E; ++Idx) {
5539 for (auto *U : Shuffles[Idx]->users()) {
5540 ShuffleVectorInst *SSV = dyn_cast<ShuffleVectorInst>(U);
5541 if (SSV && isa<UndefValue>(SSV->getOperand(1)) && SSV->getType() == VT)
5542 Shuffles.push_back(SSV);
5543 }
5544 }
5545 }
5546
5547 // For each of the output shuffles, we try to sort all the first vector
5548 // elements to the beginning, followed by the second array elements at the
5549 // end. If the binops are legalized to smaller vectors, this may reduce total
5550 // number of binops. We compute the ReconstructMask mask needed to convert
5551 // back to the original lane order.
5553 SmallVector<SmallVector<int>> OrigReconstructMasks;
5554 int MaxV1Elt = 0, MaxV2Elt = 0;
5555 unsigned NumElts = VT->getNumElements();
5556 for (ShuffleVectorInst *SVN : Shuffles) {
5557 SmallVector<int> Mask;
5558 SVN->getShuffleMask(Mask);
5559
5560 // Check the operands are the same as the original, or reversed (in which
5561 // case we need to commute the mask).
5562 Value *SVOp0 = SVN->getOperand(0);
5563 Value *SVOp1 = SVN->getOperand(1);
5564 if (isa<UndefValue>(SVOp1)) {
5565 auto *SSV = cast<ShuffleVectorInst>(SVOp0);
5566 SVOp0 = SSV->getOperand(0);
5567 SVOp1 = SSV->getOperand(1);
5568 for (int &Elem : Mask) {
5569 if (Elem >= static_cast<int>(SSV->getShuffleMask().size()))
5570 return false;
5571 Elem = Elem < 0 ? Elem : SSV->getMaskValue(Elem);
5572 }
5573 }
5574 if (SVOp0 == Op1 && SVOp1 == Op0) {
5575 std::swap(SVOp0, SVOp1);
5577 }
5578 if (SVOp0 != Op0 || SVOp1 != Op1)
5579 return false;
5580
5581 // Calculate the reconstruction mask for this shuffle, as the mask needed to
5582 // take the packed values from Op0/Op1 and reconstructing to the original
5583 // order.
5584 SmallVector<int> ReconstructMask;
5585 for (unsigned I = 0; I < Mask.size(); I++) {
5586 if (Mask[I] < 0) {
5587 ReconstructMask.push_back(-1);
5588 } else if (Mask[I] < static_cast<int>(NumElts)) {
5589 MaxV1Elt = std::max(MaxV1Elt, Mask[I]);
5590 auto It = find_if(V1, [&](const std::pair<int, int> &A) {
5591 return Mask[I] == A.first;
5592 });
5593 if (It != V1.end())
5594 ReconstructMask.push_back(It - V1.begin());
5595 else {
5596 ReconstructMask.push_back(V1.size());
5597 V1.emplace_back(Mask[I], V1.size());
5598 }
5599 } else {
5600 MaxV2Elt = std::max<int>(MaxV2Elt, Mask[I] - NumElts);
5601 auto It = find_if(V2, [&](const std::pair<int, int> &A) {
5602 return Mask[I] - static_cast<int>(NumElts) == A.first;
5603 });
5604 if (It != V2.end())
5605 ReconstructMask.push_back(NumElts + It - V2.begin());
5606 else {
5607 ReconstructMask.push_back(NumElts + V2.size());
5608 V2.emplace_back(Mask[I] - NumElts, NumElts + V2.size());
5609 }
5610 }
5611 }
5612
5613 // For reductions, we know that the lane ordering out doesn't alter the
5614 // result. In-order can help simplify the shuffle away.
5615 if (FromReduction)
5616 sort(ReconstructMask);
5617 OrigReconstructMasks.push_back(std::move(ReconstructMask));
5618 }
5619
5620 // If the Maximum element used from V1 and V2 are not larger than the new
5621 // vectors, the vectors are already packes and performing the optimization
5622 // again will likely not help any further. This also prevents us from getting
5623 // stuck in a cycle in case the costs do not also rule it out.
5624 if (V1.empty() || V2.empty() ||
5625 (MaxV1Elt == static_cast<int>(V1.size()) - 1 &&
5626 MaxV2Elt == static_cast<int>(V2.size()) - 1))
5627 return false;
5628
5629 // GetBaseMaskValue takes one of the inputs, which may either be a shuffle, a
5630 // shuffle of another shuffle, or not a shuffle (that is treated like a
5631 // identity shuffle).
5632 auto GetBaseMaskValue = [&](Instruction *I, int M) {
5634 if (!SV)
5635 return M;
5636 if (isa<UndefValue>(SV->getOperand(1)))
5637 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5638 if (InputShuffles.contains(SSV))
5639 return SSV->getMaskValue(SV->getMaskValue(M));
5640 return SV->getMaskValue(M);
5641 };
5642
5643 // Attempt to sort the inputs my ascending mask values to make simpler input
5644 // shuffles and push complex shuffles down to the uses. We sort on the first
5645 // of the two input shuffle orders, to try and get at least one input into a
5646 // nice order.
5647 auto SortBase = [&](Instruction *A, std::pair<int, int> X,
5648 std::pair<int, int> Y) {
5649 int MXA = GetBaseMaskValue(A, X.first);
5650 int MYA = GetBaseMaskValue(A, Y.first);
5651 return MXA < MYA;
5652 };
5653 stable_sort(V1, [&](std::pair<int, int> A, std::pair<int, int> B) {
5654 return SortBase(SVI0A, A, B);
5655 });
5656 stable_sort(V2, [&](std::pair<int, int> A, std::pair<int, int> B) {
5657 return SortBase(SVI1A, A, B);
5658 });
5659 // Calculate our ReconstructMasks from the OrigReconstructMasks and the
5660 // modified order of the input shuffles.
5661 SmallVector<SmallVector<int>> ReconstructMasks;
5662 for (const auto &Mask : OrigReconstructMasks) {
5663 SmallVector<int> ReconstructMask;
5664 for (int M : Mask) {
5665 auto FindIndex = [](const SmallVector<std::pair<int, int>> &V, int M) {
5666 auto It = find_if(V, [M](auto A) { return A.second == M; });
5667 assert(It != V.end() && "Expected all entries in Mask");
5668 return std::distance(V.begin(), It);
5669 };
5670 if (M < 0)
5671 ReconstructMask.push_back(-1);
5672 else if (M < static_cast<int>(NumElts)) {
5673 ReconstructMask.push_back(FindIndex(V1, M));
5674 } else {
5675 ReconstructMask.push_back(NumElts + FindIndex(V2, M));
5676 }
5677 }
5678 ReconstructMasks.push_back(std::move(ReconstructMask));
5679 }
5680
5681 // Calculate the masks needed for the new input shuffles, which get padded
5682 // with undef
5683 SmallVector<int> V1A, V1B, V2A, V2B;
5684 for (unsigned I = 0; I < V1.size(); I++) {
5685 V1A.push_back(GetBaseMaskValue(SVI0A, V1[I].first));
5686 V1B.push_back(GetBaseMaskValue(SVI0B, V1[I].first));
5687 }
5688 for (unsigned I = 0; I < V2.size(); I++) {
5689 V2A.push_back(GetBaseMaskValue(SVI1A, V2[I].first));
5690 V2B.push_back(GetBaseMaskValue(SVI1B, V2[I].first));
5691 }
5692 while (V1A.size() < NumElts) {
5695 }
5696 while (V2A.size() < NumElts) {
5699 }
5700
5701 auto AddShuffleCost = [&](InstructionCost C, Instruction *I) {
5703 if (!SV)
5704 return C;
5705 return C + TTI.getShuffleCost(isa<UndefValue>(SV->getOperand(1))
5708 VT, VT, CostKind, SV->getShuffleMask());
5709 };
5710 auto AddShuffleMaskCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5711 return C +
5712 TTI.getShuffleCost(TTI::SK_PermuteTwoSrc, VT, VT, CostKind, Mask);
5713 };
5714
5715 unsigned ElementSize = VT->getElementType()->getPrimitiveSizeInBits();
5716 unsigned MaxVectorSize =
5718 unsigned MaxElementsInVector = MaxVectorSize / ElementSize;
5719 if (MaxElementsInVector == 0)
5720 return false;
5721 // When there are multiple shufflevector operations on the same input,
5722 // especially when the vector length is larger than the register size,
5723 // identical shuffle patterns may occur across different groups of elements.
5724 // To avoid overestimating the cost by counting these repeated shuffles more
5725 // than once, we only account for unique shuffle patterns. This adjustment
5726 // prevents inflated costs in the cost model for wide vectors split into
5727 // several register-sized groups.
5728 std::set<SmallVector<int, 4>> UniqueShuffles;
5729 auto AddShuffleMaskAdjustedCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5730 // Compute the cost for performing the shuffle over the full vector.
5731 auto ShuffleCost =
5732 TTI.getShuffleCost(TTI::SK_PermuteTwoSrc, VT, VT, CostKind, Mask);
5733 unsigned NumFullVectors = Mask.size() / MaxElementsInVector;
5734 if (NumFullVectors < 2)
5735 return C + ShuffleCost;
5736 SmallVector<int, 4> SubShuffle(MaxElementsInVector);
5737 unsigned NumUniqueGroups = 0;
5738 unsigned NumGroups = Mask.size() / MaxElementsInVector;
5739 // For each group of MaxElementsInVector contiguous elements,
5740 // collect their shuffle pattern and insert into the set of unique patterns.
5741 for (unsigned I = 0; I < NumFullVectors; ++I) {
5742 for (unsigned J = 0; J < MaxElementsInVector; ++J)
5743 SubShuffle[J] = Mask[MaxElementsInVector * I + J];
5744 if (UniqueShuffles.insert(SubShuffle).second)
5745 NumUniqueGroups += 1;
5746 }
5747 return C + ShuffleCost * NumUniqueGroups / NumGroups;
5748 };
5749 auto AddShuffleAdjustedCost = [&](InstructionCost C, Instruction *I) {
5751 if (!SV)
5752 return C;
5753 SmallVector<int, 16> Mask;
5754 SV->getShuffleMask(Mask);
5755 return AddShuffleMaskAdjustedCost(C, Mask);
5756 };
5757 // Check that input consists of ShuffleVectors applied to the same input
5758 auto AllShufflesHaveSameOperands =
5759 [](SmallPtrSetImpl<Instruction *> &InputShuffles) {
5760 if (InputShuffles.size() < 2)
5761 return false;
5762 ShuffleVectorInst *FirstSV =
5763 dyn_cast<ShuffleVectorInst>(*InputShuffles.begin());
5764 if (!FirstSV)
5765 return false;
5766
5767 Value *In0 = FirstSV->getOperand(0), *In1 = FirstSV->getOperand(1);
5768 return std::all_of(
5769 std::next(InputShuffles.begin()), InputShuffles.end(),
5770 [&](Instruction *I) {
5771 ShuffleVectorInst *SV = dyn_cast<ShuffleVectorInst>(I);
5772 return SV && SV->getOperand(0) == In0 && SV->getOperand(1) == In1;
5773 });
5774 };
5775
5776 // Get the costs of the shuffles + binops before and after with the new
5777 // shuffle masks.
5778 InstructionCost CostBefore =
5779 TTI.getArithmeticInstrCost(Op0->getOpcode(), VT, CostKind) +
5780 TTI.getArithmeticInstrCost(Op1->getOpcode(), VT, CostKind);
5781 CostBefore += std::accumulate(Shuffles.begin(), Shuffles.end(),
5782 InstructionCost(0), AddShuffleCost);
5783 if (AllShufflesHaveSameOperands(InputShuffles)) {
5784 UniqueShuffles.clear();
5785 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5786 InstructionCost(0), AddShuffleAdjustedCost);
5787 } else {
5788 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5789 InstructionCost(0), AddShuffleCost);
5790 }
5791
5792 // The new binops will be unused for lanes past the used shuffle lengths.
5793 // These types attempt to get the correct cost for that from the target.
5794 FixedVectorType *Op0SmallVT =
5795 FixedVectorType::get(VT->getScalarType(), V1.size());
5796 FixedVectorType *Op1SmallVT =
5797 FixedVectorType::get(VT->getScalarType(), V2.size());
5798 InstructionCost CostAfter =
5799 TTI.getArithmeticInstrCost(Op0->getOpcode(), Op0SmallVT, CostKind) +
5800 TTI.getArithmeticInstrCost(Op1->getOpcode(), Op1SmallVT, CostKind);
5801 UniqueShuffles.clear();
5802 CostAfter += std::accumulate(ReconstructMasks.begin(), ReconstructMasks.end(),
5803 InstructionCost(0), AddShuffleMaskAdjustedCost);
5804 std::set<SmallVector<int>> OutputShuffleMasks({V1A, V1B, V2A, V2B});
5805 CostAfter +=
5806 std::accumulate(OutputShuffleMasks.begin(), OutputShuffleMasks.end(),
5807 InstructionCost(0), AddShuffleMaskCost);
5808
5809 LLVM_DEBUG(dbgs() << "Found a binop select shuffle pattern: " << I << "\n");
5810 LLVM_DEBUG(dbgs() << " CostBefore: " << CostBefore
5811 << " vs CostAfter: " << CostAfter << "\n");
5812 if (CostBefore < CostAfter ||
5813 (CostBefore == CostAfter && !feedsIntoVectorReduction(SVI)))
5814 return false;
5815
5816 // The cost model has passed, create the new instructions.
5817 auto GetShuffleOperand = [&](Instruction *I, unsigned Op) -> Value * {
5819 if (!SV)
5820 return I;
5821 if (isa<UndefValue>(SV->getOperand(1)))
5822 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5823 if (InputShuffles.contains(SSV))
5824 return SSV->getOperand(Op);
5825 return SV->getOperand(Op);
5826 };
5827 Builder.SetInsertPoint(*SVI0A->getInsertionPointAfterDef());
5828 Value *NSV0A = Builder.CreateShuffleVector(GetShuffleOperand(SVI0A, 0),
5829 GetShuffleOperand(SVI0A, 1), V1A);
5830 Builder.SetInsertPoint(*SVI0B->getInsertionPointAfterDef());
5831 Value *NSV0B = Builder.CreateShuffleVector(GetShuffleOperand(SVI0B, 0),
5832 GetShuffleOperand(SVI0B, 1), V1B);
5833 Builder.SetInsertPoint(*SVI1A->getInsertionPointAfterDef());
5834 Value *NSV1A = Builder.CreateShuffleVector(GetShuffleOperand(SVI1A, 0),
5835 GetShuffleOperand(SVI1A, 1), V2A);
5836 Builder.SetInsertPoint(*SVI1B->getInsertionPointAfterDef());
5837 Value *NSV1B = Builder.CreateShuffleVector(GetShuffleOperand(SVI1B, 0),
5838 GetShuffleOperand(SVI1B, 1), V2B);
5839 Builder.SetInsertPoint(Op0);
5840 Value *NOp0 = Builder.CreateBinOp((Instruction::BinaryOps)Op0->getOpcode(),
5841 NSV0A, NSV0B);
5842 if (auto *I = dyn_cast<Instruction>(NOp0))
5843 I->copyIRFlags(Op0, true);
5844 Builder.SetInsertPoint(Op1);
5845 Value *NOp1 = Builder.CreateBinOp((Instruction::BinaryOps)Op1->getOpcode(),
5846 NSV1A, NSV1B);
5847 if (auto *I = dyn_cast<Instruction>(NOp1))
5848 I->copyIRFlags(Op1, true);
5849
5850 for (int S = 0, E = ReconstructMasks.size(); S != E; S++) {
5851 Builder.SetInsertPoint(Shuffles[S]);
5852 Value *NSV = Builder.CreateShuffleVector(NOp0, NOp1, ReconstructMasks[S]);
5853 replaceValue(*Shuffles[S], *NSV, false);
5854 }
5855
5856 return true;
5857}
5858
5859/// Check if instruction depends on ZExt and this ZExt can be moved after the
5860/// instruction. Move ZExt if it is profitable. For example:
5861/// logic(zext(x),y) -> zext(logic(x,trunc(y)))
5862/// lshr((zext(x),y) -> zext(lshr(x,trunc(y)))
5863/// Cost model calculations takes into account if zext(x) has other users and
5864/// whether it can be propagated through them too.
5865bool VectorCombine::shrinkType(Instruction &I) {
5866 Value *ZExted, *OtherOperand;
5867 if (!match(&I, m_c_BitwiseLogic(m_ZExt(m_Value(ZExted)),
5868 m_Value(OtherOperand))) &&
5869 !match(&I, m_LShr(m_ZExt(m_Value(ZExted)), m_Value(OtherOperand))))
5870 return false;
5871
5872 Value *ZExtOperand = I.getOperand(I.getOperand(0) == OtherOperand ? 1 : 0);
5873
5874 auto *BigTy = cast<FixedVectorType>(I.getType());
5875 auto *SmallTy = cast<FixedVectorType>(ZExted->getType());
5876 unsigned BW = SmallTy->getElementType()->getPrimitiveSizeInBits();
5877
5878 if (I.getOpcode() == Instruction::LShr) {
5879 // Check that the shift amount is less than the number of bits in the
5880 // smaller type. Otherwise, the smaller lshr will return a poison value.
5881 KnownBits ShAmtKB = computeKnownBits(I.getOperand(1), *DL);
5882 if (ShAmtKB.getMaxValue().uge(BW))
5883 return false;
5884 } else {
5885 // Check that the expression overall uses at most the same number of bits as
5886 // ZExted
5887 KnownBits KB = computeKnownBits(&I, *DL);
5888 if (KB.countMaxActiveBits() > BW)
5889 return false;
5890 }
5891
5892 // Calculate costs of leaving current IR as it is and moving ZExt operation
5893 // later, along with adding truncates if needed
5895 Instruction::ZExt, BigTy, SmallTy,
5896 TargetTransformInfo::CastContextHint::None, CostKind);
5897 InstructionCost CurrentCost = ZExtCost;
5898 InstructionCost ShrinkCost = 0;
5899
5900 // Calculate total cost and check that we can propagate through all ZExt users
5901 for (User *U : ZExtOperand->users()) {
5902 auto *UI = cast<Instruction>(U);
5903 if (UI == &I) {
5904 CurrentCost +=
5905 TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5906 ShrinkCost +=
5907 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5908 ShrinkCost += ZExtCost;
5909 continue;
5910 }
5911
5912 if (!Instruction::isBinaryOp(UI->getOpcode()))
5913 return false;
5914
5915 // Check if we can propagate ZExt through its other users
5916 KnownBits KB = computeKnownBits(UI, *DL);
5917 if (KB.countMaxActiveBits() > BW)
5918 return false;
5919
5920 CurrentCost += TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5921 ShrinkCost +=
5922 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5923 ShrinkCost += ZExtCost;
5924 }
5925
5926 // If the other instruction operand is not a constant, we'll need to
5927 // generate a truncate instruction. So we have to adjust cost
5928 if (!isa<Constant>(OtherOperand))
5929 ShrinkCost += TTI.getCastInstrCost(
5930 Instruction::Trunc, SmallTy, BigTy,
5931 TargetTransformInfo::CastContextHint::None, CostKind);
5932
5933 // If the cost of shrinking types and leaving the IR is the same, we'll lean
5934 // towards modifying the IR because shrinking opens opportunities for other
5935 // shrinking optimisations.
5936 if (ShrinkCost > CurrentCost)
5937 return false;
5938
5939 Builder.SetInsertPoint(&I);
5940 Value *Op0 = ZExted;
5941 Value *Op1 = Builder.CreateTrunc(OtherOperand, SmallTy);
5942 // Keep the order of operands the same
5943 if (I.getOperand(0) == OtherOperand)
5944 std::swap(Op0, Op1);
5945 Value *NewBinOp =
5946 Builder.CreateBinOp((Instruction::BinaryOps)I.getOpcode(), Op0, Op1);
5947 if (auto *NewBinOpI = dyn_cast<Instruction>(NewBinOp)) {
5948 NewBinOpI->copyIRFlags(&I);
5949 NewBinOpI->copyMetadata(I);
5950 }
5951 Value *NewZExtr = Builder.CreateZExt(NewBinOp, BigTy);
5952 replaceValue(I, *NewZExtr);
5953 return true;
5954}
5955
5956/// insert (DstVec, (extract SrcVec, ExtIdx), InsIdx) -->
5957/// shuffle (DstVec, SrcVec, Mask)
5958bool VectorCombine::foldInsExtVectorToShuffle(Instruction &I) {
5959 Value *DstVec, *SrcVec;
5960 uint64_t ExtIdx, InsIdx;
5961 if (!match(&I,
5962 m_InsertElt(m_Value(DstVec),
5963 m_ExtractElt(m_Value(SrcVec), m_ConstantInt(ExtIdx)),
5964 m_ConstantInt(InsIdx))))
5965 return false;
5966
5967 auto *DstVecTy = dyn_cast<FixedVectorType>(I.getType());
5968 auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcVec->getType());
5969 // We can try combining vectors with different element sizes.
5970 if (!DstVecTy || !SrcVecTy ||
5971 SrcVecTy->getElementType() != DstVecTy->getElementType())
5972 return false;
5973
5974 unsigned NumDstElts = DstVecTy->getNumElements();
5975 unsigned NumSrcElts = SrcVecTy->getNumElements();
5976 if (InsIdx >= NumDstElts || ExtIdx >= NumSrcElts || NumDstElts == 1)
5977 return false;
5978
5979 // Insertion into poison is a cheaper single operand shuffle.
5981 SmallVector<int> Mask(NumDstElts, PoisonMaskElem);
5982
5983 bool NeedExpOrNarrow = NumSrcElts != NumDstElts;
5984 bool NeedDstSrcSwap = isa<PoisonValue>(DstVec) && !isa<UndefValue>(SrcVec);
5985 if (NeedDstSrcSwap) {
5987 Mask[InsIdx] = ExtIdx % NumDstElts;
5988 std::swap(DstVec, SrcVec);
5989 } else {
5991 std::iota(Mask.begin(), Mask.end(), 0);
5992 Mask[InsIdx] = (ExtIdx % NumDstElts) + NumDstElts;
5993 }
5994
5995 // Cost
5996 auto *Ins = cast<InsertElementInst>(&I);
5997 auto *Ext = cast<ExtractElementInst>(I.getOperand(1));
5998 InstructionCost InsCost =
5999 TTI.getVectorInstrCost(*Ins, DstVecTy, CostKind, InsIdx);
6000 InstructionCost ExtCost =
6001 TTI.getVectorInstrCost(*Ext, DstVecTy, CostKind, ExtIdx);
6002 InstructionCost OldCost = ExtCost + InsCost;
6003
6004 InstructionCost NewCost = 0;
6005 SmallVector<int> ExtToVecMask;
6006 if (!NeedExpOrNarrow) {
6007 // Ignore 'free' identity insertion shuffle.
6008 // TODO: getShuffleCost should return TCC_Free for Identity shuffles.
6009 if (!ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts))
6010 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, CostKind, Mask, 0,
6011 nullptr, {DstVec, SrcVec});
6012 } else {
6013 // When creating a length-changing-vector, always try to keep the relevant
6014 // element in an equivalent position, so that bulk shuffles are more likely
6015 // to be useful.
6016 ExtToVecMask.assign(NumDstElts, PoisonMaskElem);
6017 ExtToVecMask[ExtIdx % NumDstElts] = ExtIdx;
6018 // Add cost for expanding or narrowing
6020 DstVecTy, SrcVecTy, CostKind, ExtToVecMask);
6021 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, CostKind, Mask);
6022 }
6023
6024 if (!Ext->hasOneUse())
6025 NewCost += ExtCost;
6026
6027 LLVM_DEBUG(dbgs() << "Found a insert/extract shuffle-like pair: " << I
6028 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6029 << "\n");
6030
6031 if (OldCost < NewCost)
6032 return false;
6033
6034 if (NeedExpOrNarrow) {
6035 if (!NeedDstSrcSwap)
6036 SrcVec = Builder.CreateShuffleVector(SrcVec, ExtToVecMask);
6037 else
6038 DstVec = Builder.CreateShuffleVector(DstVec, ExtToVecMask);
6039 }
6040
6041 // Canonicalize undef param to RHS to help further folds.
6042 if (isa<UndefValue>(DstVec) && !isa<UndefValue>(SrcVec)) {
6043 ShuffleVectorInst::commuteShuffleMask(Mask, NumDstElts);
6044 std::swap(DstVec, SrcVec);
6045 }
6046
6047 Value *Shuf = Builder.CreateShuffleVector(DstVec, SrcVec, Mask);
6048 replaceValue(I, *Shuf);
6049
6050 return true;
6051}
6052
6053/// Try to replace a chain of insertelements of parts of the same scalar with a
6054/// bitcast and a shuffle (little endian):
6055/// insert (insert poison, (trunc (lshr X, 32)), 0), (trunc X), 1 -->
6056/// shuffle (bitcast X to <2 x i32>), poison, <1, 0>
6057bool VectorCombine::foldInsertScalarPartsToShuffle(Instruction &I) {
6058 auto *VecTy = dyn_cast<FixedVectorType>(I.getType());
6059 if (!VecTy)
6060 return false;
6061
6062 // Start from the last insertelement of the chain.
6063 if (I.hasOneUse() && isa<InsertElementInst>(I.user_back()))
6064 return false;
6065
6066 Type *EltTy = VecTy->getElementType();
6067 if ((!EltTy->isIntegerTy() && !EltTy->isIEEELikeFPTy()) ||
6068 !DL->typeSizeEqualsStoreSize(EltTy))
6069 return false;
6070 unsigned EltBits = EltTy->getPrimitiveSizeInBits();
6071 unsigned NumElts = VecTy->getNumElements();
6072
6073 Value *Src = nullptr;
6074 unsigned NumSrcElts = 0;
6075 SmallVector<int> Mask(NumElts, PoisonMaskElem);
6076 APInt DemandedElts = APInt::getZero(NumElts);
6077 InstructionCost OldCost = 0;
6078 Value *Vec = &I;
6079 while (auto *Ins = dyn_cast<InsertElementInst>(Vec)) {
6080 if (Ins != &I && !Ins->hasOneUse())
6081 return false;
6082 uint64_t Idx;
6083 if (!match(Ins->getOperand(2), m_ConstantInt(Idx)) || Idx >= NumElts)
6084 return false;
6085 Vec = Ins->getOperand(0);
6086 // A later insert to the same element overrides this one.
6087 if (DemandedElts[Idx])
6088 continue;
6089 DemandedElts.setBit(Idx);
6090
6091 // Match (bitcast (trunc (lshr X, ShAmt))), the bitcast and shift being
6092 // optional.
6093 Value *Elt = Ins->getOperand(1);
6094 Value *Trunc = Elt;
6095 match(Trunc, m_BitCast(m_Value(Trunc)));
6096 Value *X;
6097 if (!match(Trunc, m_Trunc(m_Value(X))) || !X->getType()->isIntegerTy() ||
6098 Trunc->getType()->getPrimitiveSizeInBits() != EltBits)
6099 return false;
6100 Value *Shift = nullptr;
6101 uint64_t ShAmt = 0;
6102 if (match(X, m_LShr(m_Value(), m_ConstantInt(ShAmt)))) {
6103 Shift = X;
6104 X = cast<Instruction>(Shift)->getOperand(0);
6105 }
6106
6107 if (!Src) {
6108 unsigned SrcBits = X->getType()->getIntegerBitWidth();
6109 if (SrcBits % EltBits)
6110 return false;
6111 Src = X;
6112 NumSrcElts = SrcBits / EltBits;
6113 } else if (X != Src) {
6114 return false;
6115 }
6116 uint64_t Part = ShAmt / EltBits;
6117 if (ShAmt % EltBits || Part >= NumSrcElts)
6118 return false;
6119 Mask[Idx] = DL->isBigEndian() ? NumSrcElts - 1 - Part : Part;
6120
6121 // The scalar ops die with the chain if it is their only user.
6122 for (Value *V : {Elt == Trunc ? nullptr : Elt, Trunc, Shift}) {
6123 if (!V)
6124 continue;
6125 if (!V->hasOneUse())
6126 break;
6127 OldCost += TTI.getInstructionCost(cast<Instruction>(V), CostKind);
6128 }
6129 }
6130 // Elements that are not inserted become poison, so the base must be poison
6131 // unless every element is inserted.
6132 if (!Src || (!isa<PoisonValue>(Vec) && !DemandedElts.isAllOnes()))
6133 return false;
6134 // Inserting a single part is a scalar insert or a splat, whose canonical
6135 // insertelement (+ splat shuffle) form is better left alone.
6136 if (all_equal(
6137 make_filter_range(Mask, [](int M) { return M != PoisonMaskElem; })))
6138 return false;
6139
6140 OldCost += TTI.getScalarizationOverhead(VecTy, DemandedElts, /*Insert=*/true,
6141 /*Extract=*/false, CostKind);
6142
6143 auto *SrcVecTy = FixedVectorType::get(EltTy, NumSrcElts);
6144 InstructionCost NewCost =
6145 TTI.getCastInstrCost(Instruction::BitCast, SrcVecTy, Src->getType(),
6146 TTI::CastContextHint::None, CostKind);
6147 bool IsIdentity = NumSrcElts == NumElts &&
6148 ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts);
6149 if (!IsIdentity)
6150 NewCost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, VecTy, SrcVecTy,
6151 CostKind, Mask);
6152
6153 LLVM_DEBUG(dbgs() << "Found an insertelement chain of scalar parts: " << I
6154 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6155 << "\n");
6156 if (!OldCost.isValid() || !NewCost.isValid() || NewCost >= OldCost)
6157 return false;
6158
6159 Value *Cast = Builder.CreateBitCast(Src, SrcVecTy);
6160 Value *Shuf = IsIdentity ? Cast : Builder.CreateShuffleVector(Cast, Mask);
6161 replaceValue(I, *Shuf);
6162 return true;
6163}
6164
6165/// Return the number of data operands of \p Inst.
6166static unsigned getNumDataOperands(const Instruction *Inst) {
6167 if (auto *CB = dyn_cast<CallBase>(Inst))
6168 return CB->arg_size(); // Exclude callee operand and bundles.
6169 return Inst->getNumOperands();
6170}
6171
6172/// Return true if \p Inst is an elementwise operation that can be rebuilt at a
6173/// wider element count.
6175 auto *ResultTy = dyn_cast<VectorType>(Inst->getType());
6176 if (!ResultTy || !isSafeToSpeculativelyExecute(Inst))
6177 return false;
6178
6179 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
6180 if (II->hasOperandBundles() ||
6181 !isTriviallyVectorizable(II->getIntrinsicID()))
6182 return false;
6184 FreezeInst>(Inst)) {
6185 return false;
6186 }
6187
6188 // Reject operations that change the element-count.
6189 // E.g., bitcast <vscale x 4 x i16> %v to <vscale x 8 x i8>
6190 for (unsigned Op = 0, E = getNumDataOperands(Inst); Op != E; ++Op) {
6191 auto *OperandTy = dyn_cast<VectorType>(Inst->getOperand(Op)->getType());
6192 if (OperandTy &&
6193 OperandTy->getElementCount() != ResultTy->getElementCount())
6194 return false;
6195 }
6196
6197 return true;
6198}
6199
6200/// Return the common splat value of \p Values.
6202 auto GetSplatOrScalar = [](Value *V) {
6203 return isa<VectorType>(V->getType()) ? getSplatValue(V) : V;
6204 };
6205
6206 Value *CommonValue = GetSplatOrScalar(Values.front());
6207 if (!CommonValue)
6208 return nullptr;
6209 for (Value *V : Values.drop_front())
6210 if (GetSplatOrScalar(V) != CommonValue)
6211 return nullptr;
6212 return CommonValue;
6213}
6214
6215/// Return the common deinterleave intrinsic if \p Members are its extracts in
6216/// field order.
6218 IntrinsicInst *Deinterleave = nullptr;
6219 for (const auto &[Index, Member] : enumerate(Members)) {
6220 auto *Extract = dyn_cast<ExtractValueInst>(Member);
6221 if (!Extract || Extract->getNumIndices() != 1 ||
6222 *Extract->idx_begin() != Index)
6223 return nullptr;
6224
6225 auto *Current = dyn_cast<IntrinsicInst>(Extract->getAggregateOperand());
6226 if (!Current || (Deinterleave && Current != Deinterleave))
6227 return nullptr;
6228 Deinterleave = Current;
6229 }
6230 unsigned Factor = Members.size();
6231 if (Deinterleave->hasOperandBundles() ||
6232 getDeinterleaveIntrinsicFactor(Deinterleave->getIntrinsicID()) !=
6233 Factor ||
6234 !Deinterleave->hasNUndroppableUses(Factor))
6235 return nullptr;
6236 return Deinterleave;
6237}
6238
6239/// Return the operand at \p OperandIndex of each \p Members.
6241 unsigned OperandIndex) {
6243 for (Value *Member : Members)
6244 Operands.push_back(cast<Instruction>(Member)->getOperand(OperandIndex));
6245 return Operands;
6246}
6247
6248/// Check whether the tree of elementwise operations each feeding \p Members
6249/// can be rebuilt at the interleaved width.
6250static bool canWidenDeinterleavedOperations(const VectorizeOptions &Opts,
6251 ArrayRef<Value *> Members,
6252 unsigned &NumScanned) {
6253 unsigned Factor = Members.size();
6254 if (getCommonDeinterleavedSource(Members))
6255 return true;
6256 if (NumScanned + Factor > Opts.vector_combine_max_scan_instrs)
6257 return false;
6258 NumScanned += Factor;
6259
6260 auto *FirstInst = dyn_cast<Instruction>(Members.front());
6261 if (!FirstInst || !isSupportedElementwise(FirstInst) ||
6262 !FirstInst->getSingleUndroppableUse())
6263 return false;
6264
6265 for (Value *Member : Members.drop_front()) {
6266 auto *Inst = dyn_cast<Instruction>(Member);
6267 if (!Inst || !Inst->getSingleUndroppableUse() ||
6268 !FirstInst->isSameOperationAs(Inst, Instruction::CompareCallTargets))
6269 return false;
6270 }
6271
6272 // Scalars operands should be equal among all members.
6273 // Vector operands should be a common splat value or can be widened.
6274 for (unsigned Op = 0, E = getNumDataOperands(FirstInst); Op != E; ++Op) {
6277 !canWidenDeinterleavedOperations(Opts, Operands, NumScanned))
6278 return false;
6279 }
6280 return true;
6281}
6282
6284 ArrayRef<Value *> NewOperands,
6285 VectorType *WideResultTy,
6286 IRBuilderBase &Builder) {
6287 if (isa<BinaryOperator, UnaryOperator>(NarrowInst))
6288 return Builder.CreateNAryOp(NarrowInst->getOpcode(), NewOperands);
6289 if (auto *Cast = dyn_cast<CastInst>(NarrowInst))
6290 return Builder.CreateCast(Cast->getOpcode(), NewOperands[0], WideResultTy);
6291 if (auto *Cmp = dyn_cast<CmpInst>(NarrowInst))
6292 return Builder.CreateCmp(Cmp->getPredicate(), NewOperands[0],
6293 NewOperands[1]);
6294 if (isa<SelectInst>(NarrowInst))
6295 return Builder.CreateSelect(
6296 NewOperands[0], NewOperands[1], NewOperands[2], /*Name=*/"",
6297 ProfcheckDisableMetadataFixes ? nullptr : NarrowInst);
6298 if (isa<FreezeInst>(NarrowInst))
6299 return Builder.CreateFreeze(NewOperands[0]);
6300 if (auto *II = dyn_cast<IntrinsicInst>(NarrowInst))
6301 return Builder.CreateIntrinsic(WideResultTy, II->getIntrinsicID(),
6302 NewOperands);
6303 llvm_unreachable("Unsupported instruction");
6304}
6305
6307 ElementCount WideEC,
6308 IRBuilderBase &Builder) {
6309 if (auto *Deinterleave = getCommonDeinterleavedSource(Members)) {
6310 Value *Source = Deinterleave->getArgOperand(0);
6311 assert(cast<VectorType>(Source->getType())->getElementCount() == WideEC &&
6312 "deinterleave source must have the interleaved element count");
6313 return Source;
6314 }
6315
6316 auto *NarrowInst = cast<Instruction>(Members.front());
6317 unsigned NumOperands = getNumDataOperands(NarrowInst);
6318 SmallVector<Value *, 4> NewOperands;
6319 NewOperands.reserve(NumOperands);
6320 for (unsigned Op = 0; Op != NumOperands; ++Op) {
6322 Value *NewOperand = nullptr;
6323 if ((NewOperand = getCommonSplatValue(Operands))) {
6324 if (isa<VectorType>(Operands.front()->getType())) {
6325 Builder.SetCurrentDebugLocation(NarrowInst->getDebugLoc());
6326 NewOperand = Builder.CreateVectorSplat(WideEC, NewOperand);
6327 } else {
6328 assert(all_equal(Operands) && "expected all operands to be equal");
6329 }
6330 } else {
6331 NewOperand = widenDeinterleavedOperations(Operands, WideEC, Builder);
6332 }
6333 NewOperands.push_back(NewOperand);
6334 }
6335
6336 Builder.SetCurrentDebugLocation(NarrowInst->getDebugLoc());
6337 auto *WideResultTy =
6338 VectorType::get(NarrowInst->getType()->getScalarType(), WideEC);
6339 Value *NewValue =
6340 createWideInstruction(NarrowInst, NewOperands, WideResultTy, Builder);
6341 if (auto *NewInst = dyn_cast<Instruction>(NewValue)) {
6342 propagateIRFlags(NewInst, Members);
6343 propagateMetadata(NewInst, Members);
6344 }
6345 return NewValue;
6346}
6347
6348/// Fold away vector.deinterleave/interleave intrinsics with matching trees of
6349/// elementwise operations between them.
6350///
6351/// For example:
6352/// ```
6353/// %d = call { <2 x i16>, <2 x i16> } @deinterleave2.v4i16(<4 x i16> %v)
6354/// %f0 = extractvalue { <2 x i16>, <2 x i16> } %d, 0
6355/// %f1 = extractvalue { <2 x i16>, <2 x i16> } %d, 1
6356///
6357/// %u0 = add <2 x i16> %f0, splat (i16 3)
6358/// %u1 = add <2 x i16> %f1, splat (i16 3)
6359///
6360/// %r = call <4 x i16> @interleave2.v4i16(<2 x i16> %u0, <2 x i16> %u1)
6361/// ```
6362/// Folds to:
6363/// ```
6364/// %r = add <4 x i16> %v, splat (i16 3)
6365/// ```
6366/// And with two sources:
6367/// ```
6368/// %da = call { <2 x i16>, <2 x i16> } @deinterleave2.v4i16(<4 x i16> %a)
6369/// %a0 = extractvalue { <2 x i16>, <2 x i16> } %da, 0
6370/// %a1 = extractvalue { <2 x i16>, <2 x i16> } %da, 1
6371/// %db = call { <2 x i16>, <2 x i16> } @deinterleave2.v4i16(<4 x i16> %b)
6372/// %b0 = extractvalue { <2 x i16>, <2 x i16> } %db, 0
6373/// %b1 = extractvalue { <2 x i16>, <2 x i16> } %db, 1
6374///
6375/// %m0 = mul <2 x i16> %a0, %b0
6376/// %m1 = mul <2 x i16> %a1, %b1
6377///
6378/// %r = call <4 x i16> @interleave2.v4i16(<2 x i16> %m0, <2 x i16> %m1)
6379/// ```
6380/// Folds to:
6381/// ```
6382/// %r = mul <4 x i16> %a, %b
6383/// ```
6384bool VectorCombine::foldInterleaveOfDeinterleaveChains(Instruction &I) {
6385 auto *Interleave = dyn_cast<IntrinsicInst>(&I);
6386 if (!Interleave)
6387 return false;
6388
6389 unsigned Factor = getInterleaveIntrinsicFactor(Interleave->getIntrinsicID());
6390 if (!Factor || Interleave->hasOperandBundles())
6391 return false;
6392
6393 SmallVector<Value *, 8> RootMembers(Interleave->args());
6394 unsigned NumScanned = 0;
6395 if (!canWidenDeinterleavedOperations(Opts, RootMembers, NumScanned))
6396 return false;
6397
6398 ElementCount WideEC = cast<VectorType>(I.getType())->getElementCount();
6399 Builder.SetInsertPoint(Interleave);
6400 Value *WideValue = widenDeinterleavedOperations(RootMembers, WideEC, Builder);
6401 assert(WideValue->getType() == Interleave->getType());
6402 replaceValue(*Interleave, *WideValue);
6403 return true;
6404}
6405
6406/// If we're interleaving 2 constant splats, for instance `<vscale x 8 x i32>
6407/// <splat of 666>` and `<vscale x 8 x i32> <splat of 777>`, we can create a
6408/// larger splat `<vscale x 8 x i64> <splat of ((777 << 32) | 666)>` first
6409/// before casting it back into `<vscale x 16 x i32>`.
6410bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
6411 if (foldInterleaveOfDeinterleaveChains(I))
6412 return true;
6413
6414 const APInt *SplatVal0, *SplatVal1;
6416 m_APInt(SplatVal0), m_APInt(SplatVal1))))
6417 return false;
6418
6419 LLVM_DEBUG(dbgs() << "VC: Folding interleave2 with two splats: " << I
6420 << "\n");
6421
6422 auto *VTy =
6423 cast<VectorType>(cast<IntrinsicInst>(I).getArgOperand(0)->getType());
6424 auto *ExtVTy = VectorType::getExtendedElementVectorType(VTy);
6425 unsigned Width = VTy->getElementType()->getIntegerBitWidth();
6426
6427 // Just in case the cost of interleave2 intrinsic and bitcast are both
6428 // invalid, in which case we want to bail out, we use <= rather
6429 // than < here. Even they both have valid and equal costs, it's probably
6430 // not a good idea to emit a high-cost constant splat.
6431 if (TTI.getInstructionCost(&I, CostKind) <=
6432 TTI.getCastInstrCost(Instruction::BitCast, I.getType(), ExtVTy,
6433 TTI::CastContextHint::None, CostKind)) {
6434 LLVM_DEBUG(dbgs() << "VC: The cost to cast from " << *ExtVTy << " to "
6435 << *I.getType() << " is too high.\n");
6436 return false;
6437 }
6438
6439 APInt NewSplatVal = SplatVal1->zext(Width * 2);
6440 NewSplatVal <<= Width;
6441 NewSplatVal |= SplatVal0->zext(Width * 2);
6442 auto *NewSplat = ConstantVector::getSplat(
6443 ExtVTy->getElementCount(), ConstantInt::get(F.getContext(), NewSplatVal));
6444
6445 Builder.SetInsertPoint(&I);
6446 replaceValue(I, *Builder.CreateBitCast(NewSplat, I.getType()));
6447 return true;
6448}
6449
6450/// Given this sequence:
6451/// ```
6452/// %d = llvm.vector.deinterleave2 <vscale x 16 x i32> %v
6453/// %f0 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 0
6454/// %f1 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 1
6455///
6456/// %low0 = and <vscale x 8 x i32> %f0, splat (i32 65535)
6457/// %low1 = shl <vscale x 8 x i32> %f1, splat (i32 16)
6458/// %merge0 = or disjoint <vscale x 8 x i32> %low0, %low1
6459///
6460/// %high0 = and <vscale x 8 x i32> %f1, splat (i32 -65536)
6461/// %high1 = lshr <vscale x 8 x i32> %f0, splat (i32 16)
6462/// %merge1 = or disjoint <vscale x 8 x i32> %high0, %high1
6463/// ```
6464/// It is actually just de-interleaving a 16-bit vector with double the
6465/// vector length. More generally speaking, it's de-interleaving on a vector
6466/// with half the element width as the original vector.
6467///
6468/// Therefore, we can turn it into:
6469/// ```
6470/// %narrow.v = bitcast <vscale x 16 x i32> %v to <vscale x 32 x i16>
6471/// %d = llvm.vector.deinterleave2 <vscale x 32 x i16> %narrow.v
6472/// %f0 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 0
6473/// %f1 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 1
6474///
6475/// %merge0 = bitcast <vscale x 16 x i16> %f0 to <vscale x 8 x i32>
6476/// %merge1 = bitcast <vscale x 16 x i16> %f1 to <vscale x 8 x i32>
6477/// ```
6478bool VectorCombine::foldDeinterleaveIntrinsics(Instruction &I) {
6479 // This pattern involves bitcast that is not compatible with big endian.
6480 if (DL->isBigEndian())
6481 return false;
6482
6483 using namespace PatternMatch;
6484 Value *DeinterleavedVal;
6485 if (!match(&I, m_Deinterleave2(m_Value(DeinterleavedVal))))
6486 return false;
6487
6488 VectorType *VecTy = cast<VectorType>(DeinterleavedVal->getType());
6489 IntegerType *ElementTy = dyn_cast<IntegerType>(VecTy->getElementType());
6490 if (!ElementTy)
6491 return false;
6492 unsigned ElementWidth = ElementTy->getBitWidth();
6493 if (ElementWidth < 2 || !isPowerOf2_32(ElementWidth))
6494 return false;
6495 unsigned HalfElementWidth = ElementWidth / 2;
6496
6497 if (!I.hasNUses(2))
6498 return false;
6499 std::array<ExtractValueInst *, 2> OrigFields{};
6500 for (User *Usr : I.users()) {
6501 auto *E = dyn_cast<ExtractValueInst>(Usr);
6502 // The deinterleave result can only be used by extractions.
6503 if (!E || E->getNumIndices() != 1)
6504 return false;
6505 unsigned Idx = *E->idx_begin();
6506 // A single field cannot be extracted more than once.
6507 if (Idx >= 2 || OrigFields[Idx] || !E->hasNUses(2))
6508 return false;
6509 OrigFields[Idx] = E;
6510 }
6511
6512 // Find the merge instruction (i.e. OR) first.
6513 SmallVector<Instruction *, 2> MergeInsts;
6514 for (auto *FieldUsr : OrigFields[0]->users()) {
6515 if (!FieldUsr->hasOneUse() || !isa<Instruction>(FieldUsr->user_back()))
6516 return false;
6517 MergeInsts.push_back(cast<Instruction>(FieldUsr->user_back()));
6518 }
6519 assert(MergeInsts.size() == 2);
6520
6521 // Pattern match bottom-up from the merge instructions.
6522 auto MatchMerge = [&](void) -> bool {
6523 APInt LoMask = APInt::getLowBitsSet(ElementWidth, HalfElementWidth);
6524 APInt HiMask = APInt::getHighBitsSet(ElementWidth, HalfElementWidth);
6525 return match(MergeInsts[0],
6526 m_c_Or(m_And(m_Specific(OrigFields[0]), m_SpecificInt(LoMask)),
6527 m_Shl(m_Specific(OrigFields[1]),
6528 m_SpecificInt(HalfElementWidth)))) &&
6529 match(MergeInsts[1],
6530 m_c_Or(m_And(m_Specific(OrigFields[1]), m_SpecificInt(HiMask)),
6531 m_LShr(m_Specific(OrigFields[0]),
6532 m_SpecificInt(HalfElementWidth))));
6533 };
6534 if (!MatchMerge()) {
6535 std::swap(MergeInsts[0], MergeInsts[1]);
6536 if (!MatchMerge())
6537 return false;
6538 }
6539
6540 // Profitability check.
6541 InstructionCost OldCost =
6542 TTI.getInstructionCost(MergeInsts[0], CostKind) +
6543 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(0)),
6544 CostKind) +
6545 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(1)),
6546 CostKind);
6547 // There are two fields (assuming SHL has the same cost as LSHR).
6548 OldCost *= 2;
6549
6550 auto *NewFieldTy = VecTy->getWithNewBitWidth(HalfElementWidth);
6551 auto *NewVecTy =
6552 VectorType::getDoubleElementsVectorType(cast<VectorType>(NewFieldTy));
6553 InstructionCost NewCost =
6554 TTI.getCastInstrCost(Instruction::BitCast, VecTy, NewVecTy,
6555 TTI::CastContextHint::None, CostKind) +
6556 TTI.getCastInstrCost(Instruction::BitCast, NewFieldTy,
6557 MergeInsts[0]->getType(), TTI::CastContextHint::None,
6558 CostKind) *
6559 2;
6560 if (OldCost <= NewCost || !NewCost.isValid()) {
6561 LLVM_DEBUG(
6562 dbgs() << "VC: New deinterleave2 sequence cost (" << NewCost << ")"
6563 << " is higher than that of the old one (" << OldCost << ")\n");
6564 return false;
6565 }
6566
6567 // Do the replacement.
6568 Builder.SetInsertPoint(&I);
6569 Value *NewVecCast = Builder.CreateBitCast(DeinterleavedVal, NewVecTy);
6570 Value *NewDeinterleave = Builder.CreateIntrinsic(
6571 Intrinsic::vector_deinterleave2, {NewVecTy}, {NewVecCast});
6572 for (auto [Idx, MergeInst] : enumerate(MergeInsts)) {
6573 Value *NewField = Builder.CreateExtractValue(NewDeinterleave, Idx);
6574 NewField = Builder.CreateBitCast(NewField, MergeInst->getType());
6575 replaceValue(*MergeInst, *NewField);
6576 }
6577
6578 return true;
6579}
6580
6581bool VectorCombine::foldBitcastOfVPLoad(Instruction &I) {
6582 const DataLayout &DL = I.getDataLayout();
6583 auto *Cast = dyn_cast<CastInst>(&I);
6584 if (!Cast || !Cast->isNoopCast(DL) || !isa<VectorType>(Cast->getDestTy()))
6585 return false;
6586
6587 // Fold away bit casts of the loaded value by loading the desired type,
6588 // if the mask is all-ones.
6589 Value *EVL;
6590 auto *II = dyn_cast<VPIntrinsic>(I.getOperand(0));
6592 m_Value(), m_AllOnes(), m_Value(EVL)))))
6593 return false;
6594
6595 VectorType *OrigVecTy = cast<VectorType>(II->getType());
6596 Align OrigAlign =
6597 DL.getValueOrABITypeAlignment(II->getPointerAlignment(), OrigVecTy);
6598 ElementCount OrigVecCnt = OrigVecTy->getElementCount();
6599 VectorType *NewVecTy = cast<VectorType>(Cast->getDestTy());
6600 ElementCount NewVecCnt = NewVecTy->getElementCount();
6601
6602 // Right now we only support cases where the NewVec is longer, because for
6603 // cases where it's shorter, we have to be sure that EVL can be exactly
6604 // divided, otherwise it might yield incorrect results or even page faults
6605 // (if we round-up during the division).
6606 if (!(OrigVecCnt.isScalable() == NewVecCnt.isScalable() &&
6607 NewVecCnt.hasKnownScalarFactor(OrigVecCnt)))
6608 return false;
6609
6610 InstructionCost OldCost =
6611 TTI.getMemIntrinsicInstrCost({Intrinsic::vp_load, OrigVecTy,
6612 II->getMemoryPointerParam(), false,
6613 OrigAlign},
6614 CostKind) +
6615 TTI.getCastInstrCost(Instruction::BitCast, Cast->getType(), OrigVecTy,
6616 TTI::CastContextHint::None, CostKind);
6618 {Intrinsic::vp_load, NewVecTy, II->getMemoryPointerParam(), false,
6619 OrigAlign},
6620 CostKind);
6621 LLVM_DEBUG(dbgs() << "foldBitcastOfVPLoad: OldCost=" << OldCost
6622 << " NewCost=" << NewCost << "\n");
6623 if (NewCost > OldCost || !NewCost.isValid())
6624 return false;
6625
6626 Builder.SetInsertPoint(II);
6627 unsigned Factor = NewVecCnt.getKnownScalarFactor(OrigVecCnt);
6628 Value *NewEVL = Builder.CreateNUWMul(EVL, Builder.getInt32(Factor));
6629 Value *NewMask = Builder.CreateVectorSplat(NewVecCnt, Builder.getTrue());
6630 CallInst *NewVP = Builder.CreateIntrinsicWithoutFolding(
6631 NewVecTy, Intrinsic::vp_load,
6632 {II->getMemoryPointerParam(), NewMask, NewEVL});
6633 // Preserve the original alignment.
6634 NewVP->addParamAttrs(
6635 0, AttrBuilder(II->getContext()).addAlignmentAttr(OrigAlign));
6636 replaceValue(*Cast, *NewVP);
6637 return true;
6638}
6639/// Fold the following cases into a single byte-level bit-reverse operation
6640/// and accepts bswap and bitreverse intrinsics:
6641/// bswap(bitreverse(x)) --> bitcast(bitreverse(bitcast(x)))
6642/// bitreverse(bswap(x)) <--> bitcast(bitreverse(bitcast(x)))
6643/// The direction of the fold is cost-model driven.
6644/// Also supports:
6645/// bitcast(bitreverse(bitcast(x))) --> bitreverse(fshl(x))
6646bool VectorCombine::foldBitOrderReverseAndSwap(Instruction &I) {
6647 Value *X;
6648
6650 Type *Ty = X->getType();
6651 Type *VecTy = I.getOperand(0)->getType();
6652 // Detect the case when bitreversing every octet in X individually. Then we
6653 // can use bswap to reorder the octets before doing a single bitreverse.
6654 bool CanUseBswap =
6655 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6656 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy(8) &&
6657 Ty->getIntegerBitWidth() % 16 == 0;
6658 // Detect the case when bitreversing upper and lower half of X
6659 // individually. Then we can use fshl as a rotate operation, to swap the
6660 // halves before doing a single bitreverse.
6661 bool CanUseFshl =
6662 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6663 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy() &&
6664 cast<FixedVectorType>(VecTy)->getNumElements() == 2;
6665 if (CanUseBswap || CanUseFshl) {
6666 auto *InnerCall = dyn_cast<Instruction>(I.getOperand(0));
6667 if (!InnerCall)
6668 return false;
6669 auto *InnerBitCast = dyn_cast<BitCastInst>(InnerCall->getOperand(0));
6670 if (!InnerBitCast)
6671 return false;
6672 Constant *HalfBW = ConstantInt::get(Ty, Ty->getIntegerBitWidth() / 2);
6673 InstructionCost OldCost = TTI.getInstructionCost(InnerBitCast, CostKind) +
6674 TTI.getInstructionCost(InnerCall, CostKind) +
6675 TTI.getInstructionCost(&I, CostKind);
6676 IntrinsicCostAttributes ICABSwap(Intrinsic::bswap, Ty, {Ty});
6677 IntrinsicCostAttributes ICABFshl(Intrinsic::fshl, Ty, {X, X, HalfBW},
6678 {Ty, Ty, Ty});
6679 IntrinsicCostAttributes ICABRev(Intrinsic::bitreverse, Ty, {Ty});
6680 InstructionCost NewCost =
6681 TTI.getIntrinsicInstrCost(CanUseBswap ? ICABSwap : ICABFshl,
6682 CostKind) +
6683 TTI.getIntrinsicInstrCost(ICABRev, CostKind);
6684 if (!InnerCall->hasOneUse())
6685 NewCost += TTI.getInstructionCost(InnerCall, CostKind) +
6686 TTI.getInstructionCost(InnerBitCast, CostKind);
6687 else if (!InnerBitCast->hasOneUse())
6688 NewCost += TTI.getInstructionCost(InnerBitCast, CostKind);
6689 LLVM_DEBUG(dbgs() << "Found bitreverse vector roundtrip: " << I
6690 << "\n OldCost: " << OldCost
6691 << " vs NewCost: " << NewCost << "\n");
6692 if (NewCost.isValid() && NewCost < OldCost) {
6693 Builder.SetInsertPoint(&I);
6694 Value *Swap =
6695 CanUseBswap
6696 ? Builder.CreateUnaryIntrinsic(Intrinsic::bswap, X)
6697 : Builder.CreateIntrinsic(Ty, Intrinsic::fshl, {X, X, HalfBW});
6698 Value *BRev = Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, Swap);
6699 replaceValue(I, *BRev);
6700 return true;
6701 }
6702 }
6703 }
6704
6705 if (!match(&I, m_BitReverse(m_BSwap(m_Value(X)))) &&
6707 return false;
6708 Type *Ty = I.getType();
6709 Type *I8Ty = Builder.getInt8Ty();
6710 TypeSize ElementSize = DL->getTypeStoreSize(Ty);
6711 ElementCount NewVecCnt = ElementCount::get(ElementSize.getKnownMinValue(),
6712 ElementSize.isScalable());
6713 Type *NewVecTy = VectorType::get(I8Ty, NewVecCnt);
6714 auto *II = cast<IntrinsicInst>(&I);
6715 auto *InnerII = cast<IntrinsicInst>(II->getArgOperand(0));
6716 // OldCost = cost of bitreverse/bswap + cost of bswap/bitreverse
6717 InstructionCost OldCost = TTI.getInstructionCost(II, CostKind) +
6718 TTI.getInstructionCost(InnerII, CostKind);
6719 // NewCost = cost of bitcast to byte vector +
6720 // cost of bitreverse/bswap on byte vector +
6721 // cost of bitcast back to original type
6722 InstructionCost CastToVecCost = TTI.getCastInstrCost(
6723 Instruction::BitCast, NewVecTy, Ty, TTI::CastContextHint::None, CostKind);
6724 InstructionCost CastToOrigCost = TTI.getCastInstrCost(
6725 Instruction::BitCast, Ty, NewVecTy, TTI::CastContextHint::None, CostKind);
6726 IntrinsicCostAttributes ICANew(Intrinsic::bitreverse, NewVecTy, {NewVecTy});
6727 InstructionCost NewIntrinsicCost =
6728 TTI.getIntrinsicInstrCost(ICANew, CostKind);
6729 InstructionCost NewCost = CastToVecCost + NewIntrinsicCost + CastToOrigCost;
6730 if (!InnerII->hasOneUse())
6731 NewCost += TTI.getInstructionCost(InnerII, CostKind);
6732 LLVM_DEBUG(dbgs() << "Found bitorder reverse and swap: " << I
6733 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6734 << "\n");
6735 if (!NewCost.isValid() || NewCost >= OldCost)
6736 return false;
6737 // Perform transform: bitcast(arg, <N x i8>), bitreverse, bitcast back
6738 Builder.SetInsertPoint(II);
6739 Value *CastToVec = Builder.CreateBitCast(X, NewVecTy);
6740 Value *NewCall =
6741 Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, CastToVec);
6742 Value *CastToOrig = Builder.CreateBitCast(NewCall, Ty);
6743 replaceValue(I, *CastToOrig);
6744 return true;
6745}
6746
6747/// Given the maximum shuffle index and load vector type, compute the number of
6748/// elements for the shrunk load, rounding up to the next full vector register
6749/// boundary to avoid scalar remainders that legalize poorly.
6750static unsigned getAlignedNumElements(unsigned MaxIdx, FixedVectorType *LoadTy,
6751 const TargetTransformInfo &TTI,
6752 const DataLayout &DL) {
6753 unsigned RawNumElements = MaxIdx + 1u;
6754 Type *ElemTy = LoadTy->getElementType();
6755 // Skip alignment for illegal element types.
6756 if (!TTI.isTypeLegal(ElemTy))
6757 return RawNumElements;
6758
6759 TypeSize ElemSize = DL.getTypeSizeInBits(ElemTy);
6760 if (ElemSize.isScalable() || ElemSize.isZero())
6761 return RawNumElements;
6762
6765 if (RegSize.isScalable() || RegSize.isZero())
6766 return RawNumElements;
6767
6768 unsigned ElemsPerReg = RegSize.getFixedValue() / ElemSize.getFixedValue();
6769 // If the load already fits in a register, keep the exact size.
6770 // Otherwise round up to the next full register boundary.
6771 if (ElemsPerReg == 0 || RawNumElements <= ElemsPerReg)
6772 return RawNumElements;
6773
6774 return alignTo(RawNumElements, ElemsPerReg);
6775}
6776
6777// Attempt to shrink loads that are only used by shufflevector instructions.
6778bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
6779 auto *OldLoad = dyn_cast<LoadInst>(&I);
6780 if (!OldLoad || !OldLoad->isSimple())
6781 return false;
6782
6783 auto *OldLoadTy = dyn_cast<FixedVectorType>(OldLoad->getType());
6784 if (!OldLoadTy)
6785 return false;
6786
6787 unsigned const OldNumElements = OldLoadTy->getNumElements();
6788
6789 // Search all uses of load. If all uses are shufflevector instructions, and
6790 // the second operands are all poison values, find the minimum and maximum
6791 // indices of the vector elements referenced by all shuffle masks.
6792 // Otherwise return `std::nullopt`.
6793 using IndexRange = std::pair<int, int>;
6794 auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
6795 IndexRange OutputRange = IndexRange(OldNumElements, -1);
6796 for (llvm::Use &Use : I.uses()) {
6797 // Ensure all uses match the required pattern.
6798 User *Shuffle = Use.getUser();
6799 ArrayRef<int> Mask;
6800
6801 if (!match(Shuffle,
6802 m_Shuffle(m_Specific(OldLoad), m_Undef(), m_Mask(Mask))))
6803 return std::nullopt;
6804
6805 // Ignore shufflevector instructions that have no uses.
6806 if (Shuffle->use_empty())
6807 continue;
6808
6809 // Find the min and max indices used by the shufflevector instruction.
6810 for (int Index : Mask) {
6811 if (Index >= 0 && Index < static_cast<int>(OldNumElements)) {
6812 OutputRange.first = std::min(Index, OutputRange.first);
6813 OutputRange.second = std::max(Index, OutputRange.second);
6814 }
6815 }
6816 }
6817
6818 if (OutputRange.second < OutputRange.first)
6819 return std::nullopt;
6820
6821 return OutputRange;
6822 };
6823
6824 // Get the range of vector elements used by shufflevector instructions.
6825 if (std::optional<IndexRange> Indices = GetIndexRangeInShuffles()) {
6826 unsigned const NewNumElements =
6827 getAlignedNumElements(Indices->second, OldLoadTy, TTI, *DL);
6828
6829 // If the range of vector elements is smaller than the full load, attempt
6830 // to create a smaller load.
6831 if (NewNumElements < OldNumElements) {
6832 Builder.SetInsertPoint(&I);
6833 Builder.SetCurrentDebugLocation(I.getDebugLoc());
6834
6835 // Calculate costs of old and new ops.
6836 Type *ElemTy = OldLoadTy->getElementType();
6837 FixedVectorType *NewLoadTy = FixedVectorType::get(ElemTy, NewNumElements);
6838 Value *PtrOp = OldLoad->getPointerOperand();
6839
6841 Instruction::Load, OldLoad->getType(), OldLoad->getAlign(),
6842 OldLoad->getPointerAddressSpace(), CostKind);
6843 InstructionCost NewCost =
6844 TTI.getMemoryOpCost(Instruction::Load, NewLoadTy, OldLoad->getAlign(),
6845 OldLoad->getPointerAddressSpace(), CostKind);
6846
6847 using UseEntry = std::pair<ShuffleVectorInst *, std::vector<int>>;
6849 unsigned const MaxIndex = NewNumElements * 2u;
6850
6851 for (llvm::Use &Use : I.uses()) {
6852 auto *Shuffle = cast<ShuffleVectorInst>(Use.getUser());
6853
6854 // Ignore shufflevector instructions that have no uses.
6855 if (Shuffle->use_empty())
6856 continue;
6857
6858 ArrayRef<int> OldMask = Shuffle->getShuffleMask();
6859
6860 // Create entry for new use.
6861 NewUses.push_back({Shuffle, OldMask});
6862
6863 // Validate mask indices.
6864 for (int Index : OldMask) {
6865 if (Index >= static_cast<int>(MaxIndex))
6866 return false;
6867 }
6868
6869 // Update costs.
6870 OldCost +=
6872 OldLoadTy, CostKind, OldMask);
6873 NewCost +=
6875 NewLoadTy, CostKind, OldMask);
6876 }
6877
6878 LLVM_DEBUG(
6879 dbgs() << "Found a load used only by shufflevector instructions: "
6880 << I << "\n OldCost: " << OldCost
6881 << " vs NewCost: " << NewCost << "\n");
6882
6883 if (OldCost < NewCost || !NewCost.isValid())
6884 return false;
6885
6886 // Create new load of smaller vector.
6887 auto *NewLoad = cast<LoadInst>(
6888 Builder.CreateAlignedLoad(NewLoadTy, PtrOp, OldLoad->getAlign()));
6889 NewLoad->copyMetadata(I);
6890
6891 // Replace all uses.
6892 for (UseEntry &Use : NewUses) {
6893 ShuffleVectorInst *Shuffle = Use.first;
6894 std::vector<int> &NewMask = Use.second;
6895
6896 Builder.SetInsertPoint(Shuffle);
6897 Builder.SetCurrentDebugLocation(Shuffle->getDebugLoc());
6898 Value *NewShuffle = Builder.CreateShuffleVector(
6899 NewLoad, PoisonValue::get(NewLoadTy), NewMask);
6900
6901 replaceValue(*Shuffle, *NewShuffle, false);
6902 }
6903
6904 return true;
6905 }
6906 }
6907 return false;
6908}
6909
6910// Attempt to combine two adjacent fixed-length vector loads, that only feed
6911// shufflevector instructions, into a single wider load, rewriting every such
6912// shuffle so that operand 0 is the wide load and operand 1 is poison.
6913// clang-format off
6914// e.g.
6915// %loadA = load <16 x i8>, ptr %a
6916// %gep = getelementptr inbounds <16 x i8>, ptr %a, i64 1
6917// %loadB = load <16 x i8>, ptr %gep
6918// %shuffle0 = shufflevector <16 x i8> %loadA, <16 x i8> %loadB,
6919// <32 x i8> <...>
6920// %shuffle1 = shufflevector <16 x i8> %loadA, <16 x i8> %loadB,
6921// <32 x i8> <...>
6922//
6923// The fold would transform this to:
6924// %loadAB = load <32 x i8>, ptr %a
6925// %shuffle0 = shufflevector <32 x i8> %loadAB, <32 x i8> poison,
6926// <32 x i8> <...>
6927// %shuffle1 = shufflevector <32 x i8> %loadAB, <32 x i8> poison,
6928// <32 x i8> <...>
6929//
6930// clang-format on
6931// Matching this pattern in codegen becomes difficult and hence, we prefer doing
6932// this here.
6933bool VectorCombine::foldShuffleOfAdjacentLoads(Instruction &I) {
6934 auto *SV = cast<ShuffleVectorInst>(&I);
6935
6936 // The two operands must be distinct loads of the same fixed vector type.
6937 auto *Load0 = dyn_cast<LoadInst>(SV->getOperand(0));
6938 auto *Load1 = dyn_cast<LoadInst>(SV->getOperand(1));
6939 if (!Load0 || !Load1 || Load0 == Load1 || !Load0->isSimple() ||
6940 !Load1->isSimple())
6941 return false;
6942
6943 // Confirm both loads are of fixed vector type.
6944 auto *LoadTy = dyn_cast<FixedVectorType>(Load0->getType());
6945 if (!LoadTy)
6946 return false;
6947
6948 // We restrict to loads occurring in the same BB for now.
6949 if (Load0->getParent() != Load1->getParent())
6950 return false;
6951
6952 if (Load0->getPointerAddressSpace() != Load1->getPointerAddressSpace())
6953 return false;
6954
6955 // Check that the original load type has no padding bits otherwise the wide
6956 // load would be incorrect.
6957 if (DL->getTypeSizeInBits(LoadTy) != 8 * DL->getTypeStoreSize(LoadTy))
6958 return false;
6959
6960 const unsigned NumElts = LoadTy->getNumElements();
6961 // Avoid overflow/wraparound issues.
6962 if (NumElts > INT_MAX / 2)
6963 return false;
6964
6965 // Determine which load is at the lower address and confirm the two loads are
6966 // exactly contiguous: both pointers must strip to the same base, and their
6967 // constant offsets from it must differ by exactly the store size of LoadTy.
6968 unsigned AS = Load0->getPointerAddressSpace();
6969 unsigned IdxWidth = DL->getIndexSizeInBits(AS);
6970 APInt Offset0(IdxWidth, 0), Offset1(IdxWidth, 0);
6971 const Value *Base0 =
6972 Load0->getPointerOperand()->stripAndAccumulateConstantOffsets(
6973 *DL, Offset0, /*AllowNonInbounds=*/true);
6974 const Value *Base1 =
6975 Load1->getPointerOperand()->stripAndAccumulateConstantOffsets(
6976 *DL, Offset1, /*AllowNonInbounds=*/true);
6977 // Offsets accumulated across an addrspacecast are not comparable.
6978 if (Base0 != Base1 || Base0->getType()->getPointerAddressSpace() != AS)
6979 return false;
6980
6981 int64_t LoadSize = DL->getTypeStoreSize(LoadTy).getFixedValue();
6982 std::optional<int64_t> Dist = (Offset1 - Offset0).trySExtValue();
6983 LoadInst *LowLoad, *HighLoad;
6984 if (Dist == LoadSize) {
6985 LowLoad = Load0;
6986 HighLoad = Load1;
6987 } else if (Dist == -LoadSize) {
6988 LowLoad = Load1;
6989 HighLoad = Load0;
6990 } else {
6991 return false;
6992 }
6993
6994 // 1. Check all users of both loads are shuffles.
6995 // 2. Check that both loads feed exactly the same set of shuffles.
6996 SmallPtrSet<ShuffleVectorInst *, 4> Shuffles;
6997 if (!std::is_permutation(LowLoad->user_begin(), LowLoad->user_end(),
6998 HighLoad->user_begin(), HighLoad->user_end()) ||
6999 !all_of(LowLoad->users(), [&Shuffles](User *U) {
7000 if (auto *SVI = dyn_cast<ShuffleVectorInst>(U)) {
7001 Shuffles.insert(SVI);
7002 return true;
7003 }
7004 return false;
7005 }))
7006 return false;
7007
7008 // The value loaded by either load must not be clobbered in between the loads.
7009 auto *WideTy = FixedVectorType::get(LoadTy->getElementType(), NumElts * 2);
7010 LoadInst *FirstLoad = LowLoad, *LastLoad = HighLoad;
7011 if (HighLoad->comesBefore(LowLoad))
7012 std::swap(FirstLoad, LastLoad);
7013 MemoryLocation FirstLoc = MemoryLocation::get(FirstLoad);
7014 if (isMemModifiedBetween(Opts, std::next(FirstLoad->getIterator()),
7015 LastLoad->getIterator(), FirstLoc, AA))
7016 return false;
7017
7018 // case 1: wide load = LowLoad + HighLoad ,
7019 // shuffle 0th operand = LowLoad
7020 // shuffle 1st operand = HighLoad
7021 // Implication with this is shuffle mask for the wide load remains unchanged
7022 // case 2: wide load = LowLoad + HighLoad ,
7023 // shuffle 0th operand = HighLoad
7024 // shuffle 1st operand = LowLoad
7025 // Implication with this is shuffle mask for the wide load changes
7026 auto RemapMask = [&](ShuffleVectorInst *SV, SmallVectorImpl<int> &NewMask) {
7027 Value *SVOp0 = SV->getOperand(0);
7028 assert(((SVOp0 == LowLoad && SV->getOperand(1) == HighLoad) ||
7029 (SVOp0 == HighLoad && SV->getOperand(1) == LowLoad)) &&
7030 "Shuffle operands must be exactly {LowLoad, HighLoad} or {HighLoad, "
7031 "LowLoad}");
7032 SV->getShuffleMask(NewMask);
7033 if (SVOp0 == HighLoad)
7034 ShuffleVectorInst::commuteShuffleMask(NewMask, NumElts);
7035 };
7036
7037 // Cost model checks
7038 Value *Poison = PoisonValue::get(WideTy);
7039 InstructionCost OldCost =
7040 TTI.getMemoryOpCost(Instruction::Load, LoadTy, LowLoad->getAlign(),
7041 LowLoad->getPointerAddressSpace(), CostKind);
7042 OldCost +=
7043 TTI.getMemoryOpCost(Instruction::Load, LoadTy, HighLoad->getAlign(),
7044 HighLoad->getPointerAddressSpace(), CostKind);
7045 InstructionCost NewCost =
7046 TTI.getMemoryOpCost(Instruction::Load, WideTy, LowLoad->getAlign(),
7047 LowLoad->getPointerAddressSpace(), CostKind);
7048 for (ShuffleVectorInst *SV : Shuffles) {
7049 OldCost += TTI.getShuffleCost(TTI::SK_PermuteTwoSrc, SV->getType(), LoadTy,
7050 CostKind, SV->getShuffleMask());
7051 SmallVector<int, 32> NewMask;
7052 RemapMask(SV, NewMask);
7053 // LoadSz = initial load size
7054 // WideSz = 2 * LoadSz
7055 // MaxMaskSize = WideSz * 2
7056 // Check if MaxMaskSize fits within an integer range.
7057 if (!ShuffleVectorInst::isValidOperands(Poison, Poison, NewMask))
7058 return false;
7059 NewCost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, SV->getType(),
7060 WideTy, CostKind, NewMask);
7061 }
7062
7063 LLVM_DEBUG(dbgs() << "Found adjacent loads feeding shuffles: " << *LowLoad
7064 << ", " << *HighLoad << "\n OldCost: " << OldCost
7065 << " vs NewCost: " << NewCost << "\n");
7066
7067 if (!NewCost.isValid() || NewCost > OldCost)
7068 return false;
7069
7070 // Insert the wide load at whichever original load comes last, so that both
7071 // halves of the contiguous range are known to be dereferenceable there.
7072 LoadInst *InsertPt = LastLoad;
7073
7074 // Build the wide load at the insertion point using the low load's pointer and
7075 // alignment, intersecting alias metadata from both original loads.
7076 Builder.SetInsertPoint(InsertPt);
7077 Builder.SetCurrentDebugLocation(InsertPt->getDebugLoc());
7078 LoadInst *WideLoad = Builder.CreateAlignedLoad(
7079 WideTy, LowLoad->getPointerOperand(), LowLoad->getAlign());
7080
7081 // Set the metadata on the wide load. copyMetadataForLoad seeds it from
7082 // LowLoad, then combineMetadataForCSE intersects every known kind against
7083 // HighLoad (taking the most-generic value where applicable, keeping facts
7084 // only where both loads agree, and dropping unknown metadata), so nothing is
7085 // asserted over the combined load unless justified by both halves.
7086 copyMetadataForLoad(*WideLoad, *LowLoad);
7087 combineMetadataForCSE(WideLoad, HighLoad, /*DoesKMove=*/true);
7088
7089 for (ShuffleVectorInst *SV : Shuffles) {
7090 SmallVector<int, 32> NewMask;
7091 RemapMask(SV, NewMask);
7092
7093 Builder.SetInsertPoint(SV);
7094 Builder.SetCurrentDebugLocation(SV->getDebugLoc());
7095 Value *NewShuf = Builder.CreateShuffleVector(WideLoad, Poison, NewMask);
7096 // We do not want to erase shuffles immediately because they may invalidate
7097 // the NextInst pointer in the caller's BB traversal.
7098 replaceValue(*SV, *NewShuf, /*Erase=*/false);
7099 }
7100 return true;
7101}
7102
7103// Attempt to narrow a phi of shufflevector instructions where the two incoming
7104// values have the same operands but different masks. If the two shuffle masks
7105// are offsets of one another we can use one branch to rotate the incoming
7106// vector and perform one larger shuffle after the phi.
7107bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
7108 auto *Phi = dyn_cast<PHINode>(&I);
7109 if (!Phi || Phi->getNumIncomingValues() != 2u)
7110 return false;
7111
7112 Value *Op = nullptr;
7113 ArrayRef<int> Mask0;
7114 ArrayRef<int> Mask1;
7115
7116 if (!match(Phi->getOperand(0u),
7117 m_OneUse(m_Shuffle(m_Value(Op), m_Poison(), m_Mask(Mask0)))) ||
7118 !match(Phi->getOperand(1u),
7119 m_OneUse(m_Shuffle(m_Specific(Op), m_Poison(), m_Mask(Mask1)))))
7120 return false;
7121
7122 auto *Shuf = cast<ShuffleVectorInst>(Phi->getOperand(0u));
7123
7124 // Ensure result vectors are wider than the argument vector.
7125 auto *InputVT = cast<FixedVectorType>(Op->getType());
7126 auto *ResultVT = cast<FixedVectorType>(Shuf->getType());
7127 auto const InputNumElements = InputVT->getNumElements();
7128
7129 if (InputNumElements >= ResultVT->getNumElements())
7130 return false;
7131
7132 // Take the difference of the two shuffle masks at each index. Ignore poison
7133 // values at the same index in both masks.
7134 SmallVector<int, 16> NewMask;
7135 NewMask.reserve(Mask0.size());
7136
7137 auto IsPoison = [InputNumElements](int M) {
7138 return M < 0 || (unsigned)M >= InputNumElements;
7139 };
7140
7141 for (auto [M0, M1] : zip(Mask0, Mask1)) {
7142 bool P0 = IsPoison(M0);
7143 bool P1 = IsPoison(M1);
7144 if (!P0 && !P1)
7145 NewMask.push_back(M0 - M1);
7146 else if (P0 && P1)
7147 continue;
7148 else
7149 return false;
7150 }
7151
7152 // Ensure all elements of the new mask are equal. If the difference between
7153 // the incoming mask elements is the same, the two must be constant offsets
7154 // of one another.
7155 if (NewMask.empty() || !all_equal(NewMask))
7156 return false;
7157
7158 // Create new mask using difference of the two incoming masks.
7159 int MaskOffset = NewMask[0u];
7160 unsigned Index = (InputNumElements + MaskOffset) % InputNumElements;
7161 NewMask.clear();
7162
7163 for (unsigned I = 0u; I < InputNumElements; ++I) {
7164 NewMask.push_back(Index);
7165 Index = (Index + 1u) % InputNumElements;
7166 }
7167
7168 // Calculate costs for worst cases and compare.
7169 auto const Kind = TTI::SK_PermuteSingleSrc;
7170 auto OldCost =
7171 std::max(TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask0),
7172 TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask1));
7173 auto NewCost = TTI.getShuffleCost(Kind, InputVT, InputVT, CostKind, NewMask) +
7174 TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask1);
7175
7176 LLVM_DEBUG(dbgs() << "Found a phi of mergeable shuffles: " << I
7177 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
7178 << "\n");
7179
7180 if (NewCost > OldCost)
7181 return false;
7182
7183 // Create new shuffles and narrowed phi.
7184 Builder.SetInsertPoint(Shuf);
7185 Builder.SetCurrentDebugLocation(Shuf->getDebugLoc());
7186 auto *PoisonVal = PoisonValue::get(InputVT);
7187 auto *NewShuf0 = Builder.CreateShuffleVector(Op, PoisonVal, NewMask);
7188
7189 Builder.SetInsertPoint(Phi);
7190 Builder.SetCurrentDebugLocation(Phi->getDebugLoc());
7191 auto *NewPhi = Builder.CreatePHI(NewShuf0->getType(), 2u);
7192 NewPhi->addIncoming(NewShuf0, Phi->getIncomingBlock(0u));
7193 NewPhi->addIncoming(Op, Phi->getIncomingBlock(1u));
7194
7195 Builder.SetInsertPoint(*NewPhi->getInsertionPointAfterDef());
7196 PoisonVal = PoisonValue::get(NewPhi->getType());
7197 auto *NewShuf1 = Builder.CreateShuffleVector(NewPhi, PoisonVal, Mask1);
7198
7199 replaceValue(*Phi, *NewShuf1);
7200 return true;
7201}
7202
7203/// This is the entry point for all transforms. Pass manager differences are
7204/// handled in the callers of this function.
7205bool VectorCombine::run() {
7206 if (Opts.disable_vector_combine)
7207 return false;
7208
7209 // Don't attempt vectorization if the target does not support vectors.
7210 if (!TTI.getNumberOfRegisters(TTI.getRegisterClassForType(/*Vector*/ true)))
7211 return false;
7212
7213 LLVM_DEBUG(dbgs() << "\n\nVECTORCOMBINE on " << F.getName() << "\n");
7214
7215 auto FoldInst = [this](Instruction &I) {
7216 Builder.SetInsertPoint(&I);
7217 bool IsVectorType = isa<VectorType>(I.getType());
7218 bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
7219 auto Opcode = I.getOpcode();
7220
7221 LLVM_DEBUG(dbgs() << "VC: Visiting: " << I << '\n');
7222
7223 // These folds should be beneficial regardless of when this pass is run
7224 // in the optimization pipeline.
7225 // The type checking is for run-time efficiency. We can avoid wasting time
7226 // dispatching to folding functions if there's no chance of matching.
7227 if (IsFixedVectorType) {
7228 switch (Opcode) {
7229 case Instruction::InsertElement:
7230 if (vectorizeLoadInsert(I))
7231 return true;
7232 break;
7233 case Instruction::ShuffleVector:
7234 if (widenSubvectorLoad(I))
7235 return true;
7236 break;
7237 default:
7238 break;
7239 }
7240 }
7241
7242 // This transform works with scalable and fixed vectors
7243 // TODO: Identify and allow other scalable transforms
7244 if (IsVectorType) {
7245 if (scalarizeOpOrCmp(I))
7246 return true;
7247 if (scalarizeLoad(I))
7248 return true;
7249 if (scalarizeExtExtract(I))
7250 return true;
7251 if (foldInterleaveIntrinsics(I))
7252 return true;
7253 if (foldBitcastOfVPLoad(I))
7254 return true;
7255 }
7256
7257 if (foldDeinterleaveIntrinsics(I))
7258 return true;
7259
7260 if (Opcode == Instruction::Store)
7261 if (foldInsertElementsToStores(I))
7262 return true;
7263
7264 // If this is an early pipeline invocation of this pass, we are done.
7265 if (TryEarlyFoldsOnly)
7266 return false;
7267
7268 if (Opcode == Instruction::Call)
7269 if (foldBitOrderReverseAndSwap(I))
7270 return true;
7271 if (Opcode == Instruction::BitCast)
7272 if (foldBitOrderReverseAndSwap(I))
7273 return true;
7274
7275 // Otherwise, try folds that improve codegen but may interfere with
7276 // early IR canonicalizations.
7277 // The type checking is for run-time efficiency. We can avoid wasting time
7278 // dispatching to folding functions if there's no chance of matching.
7279 if (IsFixedVectorType) {
7280 switch (Opcode) {
7281 case Instruction::InsertElement:
7282 if (foldInsExtFNeg(I))
7283 return true;
7284 if (foldInsExtBinop(I))
7285 return true;
7286 if (foldInsExtVectorToShuffle(I))
7287 return true;
7288 if (foldInsertScalarPartsToShuffle(I))
7289 return true;
7290 break;
7291 case Instruction::ShuffleVector:
7292 if (foldPermuteOfBinops(I))
7293 return true;
7294 if (foldShuffleOfBinops(I))
7295 return true;
7296 if (foldShuffleOfSelects(I))
7297 return true;
7298 if (foldShuffleOfCastops(I))
7299 return true;
7300 if (foldShuffleOfShuffles(I))
7301 return true;
7302 if (foldShuffleOfAdjacentLoads(I))
7303 return true;
7304 if (foldPermuteOfIntrinsic(I))
7305 return true;
7306 if (foldShufflesOfLengthChangingShuffles(I))
7307 return true;
7308 if (foldShuffleOfIntrinsics(I))
7309 return true;
7310 if (foldSelectShuffle(I))
7311 return true;
7312 if (foldShuffleToIdentity(I))
7313 return true;
7314 break;
7315 case Instruction::Load:
7316 if (shrinkLoadForShuffles(I))
7317 return true;
7318 break;
7319 case Instruction::BitCast:
7320 if (foldBitcastShuffle(I))
7321 return true;
7322 if (foldSelectsFromBitcast(I))
7323 return true;
7324 break;
7325 case Instruction::And:
7326 case Instruction::Or:
7327 case Instruction::Xor:
7328 if (foldBitOpOfCastops(I))
7329 return true;
7330 if (foldBitOpOfCastConstant(I))
7331 return true;
7332 break;
7333 case Instruction::PHI:
7334 if (shrinkPhiOfShuffles(I))
7335 return true;
7336 break;
7337 default:
7338 if (shrinkType(I))
7339 return true;
7340 break;
7341 }
7342 } else {
7343 switch (Opcode) {
7344 case Instruction::Call:
7345 if (foldShuffleFromReductions(I))
7346 return true;
7347 if (foldCastFromReductions(I))
7348 return true;
7349 break;
7350 case Instruction::ExtractElement:
7351 if (foldShuffleChainsToReduce(I))
7352 return true;
7353 break;
7354 case Instruction::ICmp:
7355 if (foldSignBitReductionCmp(I))
7356 return true;
7357 if (foldICmpEqZeroVectorReduce(I))
7358 return true;
7359 if (foldReductionZeroTest(I))
7360 return true;
7361 if (foldEquivalentReductionCmp(I))
7362 return true;
7363 if (foldReduceAddCmpZero(I))
7364 return true;
7365 [[fallthrough]];
7366 case Instruction::FCmp:
7367 if (foldExtractExtract(I))
7368 return true;
7369 break;
7370 case Instruction::Or:
7371 if (foldConcatOfBoolMasks(I))
7372 return true;
7373 [[fallthrough]];
7374 default:
7375 if (Instruction::isBinaryOp(Opcode)) {
7376 if (foldExtractExtract(I))
7377 return true;
7378 if (foldExtractedCmps(I))
7379 return true;
7380 if (foldBinopOfReductions(I))
7381 return true;
7382 }
7383 break;
7384 }
7385 }
7386 return false;
7387 };
7388
7389 bool MadeChange = false;
7390 for (BasicBlock &BB : F) {
7391 // Ignore unreachable basic blocks.
7392 if (!DT.isReachableFromEntry(&BB))
7393 continue;
7394 // Use early increment range so that we can erase instructions in loop.
7395 // make_early_inc_range is not applicable here, as the next iterator may
7396 // be invalidated by RecursivelyDeleteTriviallyDeadInstructions.
7397 // We manually maintain the next instruction and update it when it is about
7398 // to be deleted.
7399 Instruction *I = &BB.front();
7400 while (I) {
7401 NextInst = I->getNextNode();
7402 MadeChange |= FoldInst(*I);
7403 I = NextInst;
7404 }
7405 }
7406
7407 NextInst = nullptr;
7408
7409 while (!Worklist.isEmpty()) {
7410 // Push deferred instructions in reverse order, so that they'll end up
7411 // popped from the worklist in-order.
7412 while (Instruction *I = Worklist.popDeferred()) {
7415 continue;
7416 }
7417
7418 Worklist.push(I);
7419 }
7420
7421 Instruction *I = Worklist.removeOne();
7422 if (!I)
7423 continue;
7424
7427 continue;
7428 }
7429
7430 MadeChange |= FoldInst(*I);
7431 }
7432
7433 return MadeChange;
7434}
7435
7438 auto &AC = FAM.getResult<AssumptionAnalysis>(F);
7440 DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
7441 AAResults &AA = FAM.getResult<AAManager>(F);
7442 const DataLayout *DL = &F.getDataLayout();
7443 TTI::TargetCostKind CostKind =
7445 VectorCombine Combiner(getVectorizeOptions(F), F, TTI, DT, AA, AC, DL,
7446 CostKind, TryEarlyFoldsOnly);
7447 if (!Combiner.run())
7448 return PreservedAnalyses::all();
7451 return PA;
7452}
SDValue Pred
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
This is the interface for LLVM's primary stateless and local alias analysis.
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
#define Check(C,...)
This is the interface for a simple mod/ref and alias analysis over globals.
Hexagon Common GEP
iv users
Definition IVUsers.cpp:48
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, const LICMDependencies &Deps)
Definition LICM.cpp:1188
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T1
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
if(PassOpts->AAPipeline)
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
int64_t C1
int64_t C0
SI Fold Operands
This file contains some templates that are useful if you are working with the STL at all.
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
static Value * widenDeinterleavedOperations(ArrayRef< Value * > Members, ElementCount WideEC, IRBuilderBase &Builder)
static bool isEquivBitcast(Value *X, Value *Y)
Helper to peek through bitcasts to the same value.
static SmallVector< Value *, 8 > getInstrOperandsAtIdx(ArrayRef< Value * > Members, unsigned OperandIndex)
Return the operand at OperandIndex of each Members.
static bool isFreeConcat(ArrayRef< InstLane > Item, TTI::TargetCostKind CostKind, const TargetTransformInfo &TTI)
Detect concat of multiple values into a vector.
static void analyzeCostOfVecReduction(const IntrinsicInst &II, TTI::TargetCostKind CostKind, const TargetTransformInfo &TTI, InstructionCost &CostBeforeReduction, InstructionCost &CostAfterReduction)
static Value * generateNewInstTree(ArrayRef< InstLane > Item, Use *From, const DenseSet< std::pair< Value *, Use * > > &IdentityLeafs, const DenseSet< std::pair< Value *, Use * > > &SplatLeafs, const DenseSet< std::pair< Value *, Use * > > &ConcatLeafs, IRBuilderBase &Builder, InstructionWorklist &WorkList, const TargetTransformInfo *TTI)
static SmallVector< InstLane > generateInstLaneVectorFromOperand(ArrayRef< InstLane > Item, int Op)
static Value * createShiftShuffle(Value *Vec, unsigned OldIndex, unsigned NewIndex, IRBuilderBase &Builder)
Create a shuffle that translates (shifts) 1 element from the input vector to a new element location.
std::pair< Value *, int > InstLane
static Value * createWideInstruction(Instruction *NarrowInst, ArrayRef< Value * > NewOperands, VectorType *WideResultTy, IRBuilderBase &Builder)
static unsigned getNumDataOperands(const Instruction *Inst)
Return the number of data operands of Inst.
static bool isKnownNonPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Used by foldReduceAddCmpZero to check if we can prove that a value is non-positive.
static bool isSupportedElementwise(Instruction *Inst)
Return true if Inst is an elementwise operation that can be rebuilt at a wider element count.
static Value * materializeScalarizedGEPIndex(Value *Idx, IntegerType *GEPIndexTy, IRBuilderBase &Builder)
Materialize an index for a scalarized GEP after profitability is known.
static Align computeAlignmentAfterScalarization(Align VectorAlignment, Type *ScalarType, Value *Idx, const DataLayout &DL)
The memory operation on a vector of ScalarType had alignment of VectorAlignment.
static bool feedsIntoVectorReduction(ShuffleVectorInst *SVI)
Returns true if this ShuffleVectorInst eventually feeds into a vector reduction intrinsic (e....
static bool canWidenDeinterleavedOperations(const VectorizeOptions &Opts, ArrayRef< Value * > Members, unsigned &NumScanned)
Check whether the tree of elementwise operations each feeding Members can be rebuilt at the interleav...
static bool canWidenLoad(LoadInst *Load, const TargetTransformInfo &TTI)
static const unsigned InvalidIndex
static Value * getCommonSplatValue(ArrayRef< Value * > Values)
Return the common splat value of Values.
static IntegerType * getScalarizedGEPIndexInfo(VectorType *VecTy, Value *Idx, Type *PtrTy, const DataLayout &DL)
Return the GEP index type if the unsigned vector index Idx can be represented by an inbounds GEP.
static Value * translateExtract(ExtractElementInst *ExtElt, unsigned NewIndex, IRBuilderBase &Builder)
Given an extract element instruction with constant index operand, shuffle the source vector (shift th...
static ScalarizationResult canScalarizeAccess(VectorType *VecTy, Value *Idx, const SimplifyQuery &SQ)
Check if it is legal to scalarize a memory access to VecTy at index Idx.
static unsigned getAlignedNumElements(unsigned MaxIdx, FixedVectorType *LoadTy, const TargetTransformInfo &TTI, const DataLayout &DL)
Given the maximum shuffle index and load vector type, compute the number of elements for the shrunk l...
static InstLane lookThroughShuffles(Value *V, int Lane)
static IntrinsicInst * getCommonDeinterleavedSource(ArrayRef< Value * > Members)
Return the common deinterleave intrinsic if Members are its extracts in field order.
static bool isMemModifiedBetween(const VectorizeOptions &Opts, BasicBlock::iterator Begin, BasicBlock::iterator End, const MemoryLocation &Loc, AAResults &AA)
static constexpr int Concat[]
Value * RHS
Value * LHS
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1350
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition APInt.h:1186
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
unsigned countl_one() const
Count the number of leading one bits.
Definition APInt.h:1635
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1030
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:292
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:385
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1225
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition ArrayRef.h:194
const T & front() const
Get the first element.
Definition ArrayRef.h:144
size_t size() const
Get the array size.
Definition ArrayRef.h:141
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
BinaryOps getOpcode() const
Definition InstrTypes.h:409
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Value * getArgOperand(unsigned i) const
void addParamAttrs(unsigned ArgNo, const AttrBuilder &B)
Adds attributes to the indicated argument.
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Definition InstrTypes.h:728
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
bool isFPPredicate() const
Definition InstrTypes.h:845
static LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
Combiner implementation.
Definition Combiner.h:33
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This class represents a range of values.
LLVM_ABI ConstantRange urem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned remainder operation of...
LLVM_ABI ConstantRange binaryAnd(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-and of a value in this ra...
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
bool empty() const
Definition DenseMap.h:716
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:856
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:312
This instruction extracts a single (scalar) element from a VectorType value.
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
bool noSignedZeros() const
Definition FMF.h:67
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * getDoubleElementsVectorType(FixedVectorType *VTy)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
This class represents a freeze function that returns random concrete value if an operand is either a ...
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
Value * CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1465
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2709
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2697
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1934
Value * CreateNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, bool IsNUW, bool IsNSW, const Twine &Name="")
Definition IRBuilder.h:1744
LLVM_ABI Value * CreateSelectFMF(Value *C, Value *True, Value *False, FMFSource FMFSource, const Twine &Name="", Instruction *MDFrom=nullptr)
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2756
ConstantInt * getTrue()
Get the constant value for i1 true.
Definition IRBuilder.h:445
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
Definition IRBuilder.h:2775
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Definition IRBuilder.h:228
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1528
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Definition IRBuilder.h:2324
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
Definition IRBuilder.h:2813
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition IRBuilder.h:2019
Value * CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2349
Value * CreateFCmpFMF(CmpInst::Predicate P, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2550
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:470
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:465
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2556
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2587
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Definition IRBuilder.h:147
Value * CreateBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1733
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Definition IRBuilder.h:2808
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2283
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1907
Value * CreateUnOpFMF(Instruction::UnaryOps Opc, Value *V, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1860
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1507
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2161
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition IRBuilder.h:2731
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1566
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1925
Value * CreateExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, bool IsExact, const Twine &Name="")
Definition IRBuilder.h:1756
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2147
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:565
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1727
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:196
Value * CreateFNegFMF(Value *V, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1840
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2532
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1588
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:512
LLVM_ABI Value * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
Definition IRBuilder.h:74
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
InstructionWorklist - This is the worklist management logic for InstCombine and other simplification ...
void push(Instruction *I)
Push the instruction onto the worklist stack.
void remove(Instruction *I)
Remove I from the worklist if it exists.
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
bool isBinaryOp() const
LLVM_ABI void setNonNeg(bool b=true)
Set or clear the nneg flag on this instruction, which must be a zext instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
user_iterator user_begin()
@ CompareCallTargets
Check for equivalence by comparing call targets.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
user_iterator user_end()
bool isIdempotent() const
Return true if the instruction is idempotent:
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
bool isIntDivRem() const
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
void setAlignment(Align Align)
Value * getPointerOperand()
Type * getPointerOperandType() const
Align getAlign() const
Return the alignment of the access that is being performed.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
This class represents the LLVM 'select' instruction.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
This instruction constructs a fixed permutation of two input vectors.
int getMaskValue(unsigned Elt) const
Return the shuffle mask value of this instruction for the given element index.
static LLVM_ABI bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask)
Return true if a shufflevector instruction can be formed with the specified operands.
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.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
static void commuteShuffleMask(MutableArrayRef< int > Mask, unsigned InVecNumElts)
Change values in a shuffle permute mask assuming the two vector operands of length InVecNumElts have ...
size_type size() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void setAlignment(Align Align)
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI CastContextHint getCastContextHint(const Instruction *I)
Calculates a CastContextHint from I.
LLVM_ABI InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TargetCostKind CostKind, Type *AccessType=nullptr) const
Estimate the cost of a GEP operation when lowered.
LLVM_ABI TypeSize getRegisterBitWidth(RegisterKind K) const
LLVM_ABI InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, OperandValueInfo OpdInfo={OK_AnyValue, OP_None}, const Instruction *I=nullptr) const
static LLVM_ABI OperandValueInfo commonOperandInfo(const Value *X, const Value *Y)
Collect common data between two OperandValueInfo inputs.
LLVM_ABI bool allowVectorElementIndexingUsingGEP() const
Returns true if GEP should not be used to index into vectors for this target.
LLVM_ABI InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const
LLVM_ABI InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index=-1, const Value *Op0=nullptr, const Value *Op1=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
LLVM_ABI InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, OperandValueInfo Op1Info={OK_AnyValue, OP_None}, OperandValueInfo Op2Info={OK_AnyValue, OP_None}, const Instruction *I=nullptr) const
LLVM_ABI InstructionCost getShuffleCost(ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask={}, int Index=0, VectorType *SubTp=nullptr, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
LLVM_ABI InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const
LLVM_ABI unsigned getRegisterClassForType(bool Vector, Type *Ty=nullptr) const
LLVM_ABI InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const
Calculate the cost of vector reduction intrinsics.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
LLVM_ABI InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
LLVM_ABI InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const
LLVM_ABI unsigned getMinVectorRegisterBitWidth() const
LLVM_ABI InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const
LLVM_ABI unsigned getNumberOfRegisters(unsigned ClassID) const
LLVM_ABI InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, const TargetLibraryInfo *TLibInfo=nullptr) const
This is an approximation of reciprocal throughput of a math/logic op.
LLVM_ABI InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TargetCostKind CostKind) const
Estimate the cost of a given IR user when lowered.
LLVM_ABI InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
Estimate the overhead of scalarizing an instruction.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout,...
Definition Type.h:172
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
Definition Value.h:729
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
Definition Value.cpp:158
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:548
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition Value.cpp:985
unsigned getValueID() const
Return an ID for the concrete type of this object.
Definition Value.h:545
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
Definition Value.cpp:142
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:707
bool use_empty() const
Definition Value.h:348
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
bool user_empty() const
Definition Value.h:391
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
size_type size() const
Definition DenseSet.h:85
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS*X will result in a value whose quantity matches our ...
Definition TypeSize.h:266
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS*X will result in a value whose quantity matches our own.
Definition TypeSize.h:274
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
constexpr bool isZero() const
Definition TypeSize.h:154
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
Definition APInt.h:2274
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition APInt.h:2279
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
AllOnesConstantMatch m_AllOnes()
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
auto m_BSwap(const Opnd0 &Op0)
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
auto m_BitReverse(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
auto m_Poison()
Match an arbitrary poison constant.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
cst_pred_ty< is_non_zero_int > m_NonZeroInt()
Match a non-zero integer or a vector with all non-zero elements.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
auto m_AnyIntrinsic()
Matches any intrinsic call and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op, true > m_c_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations in either order.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_Deinterleave2(const Opnd &Op)
FNeg_match< OpTy, true > m_FNegOrFSubNegZero(const OpTy &X)
Match fneg X or fsub -0.0, X.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
@ Valid
The data is already valid.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:339
@ Offset
Definition DWP.cpp:577
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition STLExtras.h:846
void stable_sort(R &&Range)
Definition STLExtras.h:2132
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
Definition LoopInfo.cpp:61
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1748
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:522
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI Value * simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q)
Given operand for a UnaryOperator, fold the result or return null.
scope_exit(Callable) -> scope_exit< Callable >
@ Load
The value being inserted comes from a load (InsertElement only).
LLVM_ABI void copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source)
Copy the metadata from the source instruction to the destination (the replacement for the source inst...
Definition Local.cpp:3140
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI unsigned getArithmeticReductionInstruction(Intrinsic::ID RdxID)
Returns the arithmetic instruction opcode used when expanding a reduction.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
LLVM_ABI Value * simplifyCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)
Given a callsite, callee, and arguments, fold the result or return null.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=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 bool mustSuppressSpeculation(const LoadInst &LI)
Return true if speculation of the given load must be suppressed to avoid ordering or interfering with...
Definition Loads.cpp:452
LLVM_ABI bool widenShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Try to transform a shuffle mask by replacing elements with the scaled index for an equivalent mask of...
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
LLVM_ABI Instruction * propagateMetadata(Instruction *I, ArrayRef< Value * > VL)
Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath, MD_nontemporal,...
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
unsigned M1(unsigned Val)
Definition VE.h:394
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition Local.cpp:408
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
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:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI bool programUndefinedIfPoison(const Instruction *Inst)
LLVM_ABI unsigned getDeinterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.deinterleaveN intrinsics.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
LLVM_ABI unsigned getInterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.interleaveN intrinsics.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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 void propagateIRFlags(Value *I, ArrayRef< Value * > VL, Value *OpValue=nullptr, bool IncludeWrapFlags=true)
Get the intersection (logical and) of all of the potential IR flags of each scalar operation (VL) tha...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr int PoisonMaskElem
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
Definition Local.cpp:3131
@ Other
Any other memory.
Definition ModRef.h:68
TargetTransformInfo TTI
LLVM_ABI bool isSafeToLoadUnconditionally(Value *V, Align Alignment, const APInt &Size, const SimplifyQuery &SQ, bool IgnoreFree=false)
Return true if we know that executing a load from this value cannot trap.
Definition Loads.cpp:456
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
LLVM_ABI void narrowShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Replace each shuffle mask index with the scaled sequential indices for an equivalent mask of narrowed...
LLVM_ABI Intrinsic::ID getReductionForBinop(Instruction::BinaryOps Opc)
Returns the reduction intrinsic id corresponding to the binary operation.
@ And
Bitwise or logical AND of integers.
LLVM_ABI bool isVectorIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic has a scalar operand.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
Definition VE.h:393
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool willNotFreeBetween(const Instruction *Assume, const Instruction *CtxI, const DominatorTree *DT=nullptr)
Returns true, if no instruction between Assume and CtxI may free (including through synchronization).
constexpr unsigned BitWidth
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
const VectorizeOptions & getVectorizeOptions(const LLVMContext &C)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:206
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Definition STLExtras.h:2182
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicID(Intrinsic::ID IID)
Returns the llvm.vector.reduce min/max intrinsic that corresponds to the intrinsic op.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
LLVM_ABI AAMDNodes adjustForAccess(unsigned AccessSize)
Create a new AAMDNode for accessing AccessSize bytes of this AAMDNode.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
Definition KnownBits.h:310
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
Definition KnownBits.h:262
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Definition KnownBits.h:146
const DataLayout & DL
const DominatorTree * DT
SimplifyQuery getWithInstruction(const Instruction *I) const
AssumptionCache * AC
const Instruction * CtxI