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