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 foldInsertElementsToStores(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),
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),
313 return false;
314
315 // Update alignment with offset value. Note that the offset could be negated
316 // to more accurately represent "(new) SrcPtr - Offset = (old) SrcPtr", but
317 // negation does not change the result of the alignment calculation.
318 Alignment = commonAlignment(Alignment, Offset.getZExtValue());
319 }
320
321 // Original pattern: insertelt undef, load [free casts of] PtrOp, 0
322 // Use the greater of the alignment on the load or its source pointer.
323 Alignment = std::max(SrcPtr->getPointerAlignment(*DL), Alignment);
324 Type *LoadTy = Load->getType();
325 unsigned AS = Load->getPointerAddressSpace();
326 InstructionCost OldCost =
327 TTI.getMemoryOpCost(Instruction::Load, LoadTy, Alignment, AS, CostKind);
328 APInt DemandedElts = APInt::getOneBitSet(MinVecNumElts, 0);
329 OldCost +=
330 TTI.getScalarizationOverhead(MinVecTy, DemandedElts,
331 /* Insert */ true, HasExtract, CostKind);
332
333 // New pattern: load VecPtr
334 InstructionCost NewCost =
335 TTI.getMemoryOpCost(Instruction::Load, MinVecTy, Alignment, AS, CostKind);
336 // Optionally, we are shuffling the loaded vector element(s) into place.
337 // For the mask set everything but element 0 to undef to prevent poison from
338 // propagating from the extra loaded memory. This will also optionally
339 // shrink/grow the vector from the loaded size to the output size.
340 // We assume this operation has no cost in codegen if there was no offset.
341 // Note that we could use freeze to avoid poison problems, but then we might
342 // still need a shuffle to change the vector size.
343 auto *Ty = cast<FixedVectorType>(I.getType());
344 unsigned OutputNumElts = Ty->getNumElements();
345 SmallVector<int, 16> Mask(OutputNumElts, PoisonMaskElem);
346 assert(OffsetEltIndex < MinVecNumElts && "Address offset too big");
347 Mask[0] = OffsetEltIndex;
348 if (OffsetEltIndex)
349 NewCost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, Ty, MinVecTy,
350 CostKind, Mask);
351
352 // We can aggressively convert to the vector form because the backend can
353 // invert this transform if it does not result in a performance win.
354 if (OldCost < NewCost || !NewCost.isValid())
355 return false;
356
357 // It is safe and potentially profitable to load a vector directly:
358 // inselt undef, load Scalar, 0 --> load VecPtr
359 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),
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, CostKind, ShuffleMask, 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, CostKind, Mask);
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, CostKind, SrcMask);
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, CostKind, NewMask) +
1164 (NumOps * TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy,
1165 TargetTransformInfo::CastContextHint::None,
1166 CostKind));
1167 InstructionCost OldCost =
1168 TTI.getShuffleCost(SK, OldShuffleTy, SrcTy, CostKind, Mask) +
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 // We need to pass the flags during the creation of instrucitons. Constant
1341 // folding might remove the instructions, so post setting the flags might
1342 // pollute the later instructions.
1343 if (CI) {
1344 if (FPMathOperator *FPMO = dyn_cast<FPMathOperator>(&I)) {
1345 Scalar = Builder.CreateFCmpFMF(CI->getPredicate(), ScalarOps[0],
1346 ScalarOps[1], FPMO->getFastMathFlags(),
1347 CI->getName() + ".scalar");
1348 } else {
1349 Scalar = Builder.CreateICmp(CI->getPredicate(), ScalarOps[0],
1350 ScalarOps[1], CI->getName() + ".scalar");
1351 }
1352 } else if (UO) {
1353 Scalar = Builder.CreateUnOpFMF(UO->getOpcode(), ScalarOps[0], UO,
1354 UO->getName() + ".scalar");
1355 } else if (BO) {
1356 if (OverflowingBinaryOperator *OBO =
1358 Scalar = Builder.CreateNoWrapBinOp(
1359 BO->getOpcode(), ScalarOps[0], ScalarOps[1], OBO->hasNoUnsignedWrap(),
1360 OBO->hasNoSignedWrap(), BO->getName() + ".scalar");
1361 } else if (PossiblyDisjointInst *PDI = dyn_cast<PossiblyDisjointInst>(&I)) {
1362 Scalar = Builder.CreateOr(ScalarOps[0], ScalarOps[1],
1363 BO->getName() + ".scalar", PDI->isDisjoint());
1364 } else if (PossiblyExactOperator *PEO =
1366 Scalar =
1367 Builder.CreateExactBinOp(BO->getOpcode(), ScalarOps[0], ScalarOps[1],
1368 PEO->isExact(), BO->getName() + ".scalar");
1369 } else if (FPMathOperator *FPMO = dyn_cast<FPMathOperator>(&I)) {
1370 Scalar = Builder.CreateBinOpFMF(BO->getOpcode(), ScalarOps[0],
1371 ScalarOps[1], FPMO->getFastMathFlags(),
1372 BO->getName() + ".scalar");
1373 } else {
1374 Scalar = Builder.CreateBinOp(BO->getOpcode(), ScalarOps[0], ScalarOps[1],
1375 BO->getName() + ".scalar");
1376 }
1377 } else {
1378 FastMathFlags FMF;
1379 if (auto *FPMO = dyn_cast<FPMathOperator>(&I))
1380 FMF = FPMO->getFastMathFlags();
1381 Scalar = Builder.CreateIntrinsic(ScalarTy, II->getIntrinsicID(), ScalarOps,
1382 FMF, II->getName() + ".scalar");
1383 }
1384
1385 Value *Insert = Builder.CreateInsertElement(NewVecC, Scalar, *Index);
1386 replaceValue(I, *Insert);
1387 return true;
1388}
1389
1390/// Try to combine a scalar binop + 2 scalar compares of extracted elements of
1391/// a vector into vector operations followed by extract. Note: The SLP pass
1392/// may miss this pattern because of implementation problems.
1393bool VectorCombine::foldExtractedCmps(Instruction &I) {
1394 auto *BI = dyn_cast<BinaryOperator>(&I);
1395
1396 // We are looking for a scalar binop of booleans.
1397 // binop i1 (cmp Pred I0, C0), (cmp Pred I1, C1)
1398 if (!BI || !I.getType()->isIntegerTy(1))
1399 return false;
1400
1401 // The compare predicates should match, and each compare should have a
1402 // constant operand.
1403 Value *B0 = I.getOperand(0), *B1 = I.getOperand(1);
1404 Instruction *I0, *I1;
1405 Constant *C0, *C1;
1406 CmpPredicate P0, P1;
1407 if (!match(B0, m_Cmp(P0, m_Instruction(I0), m_Constant(C0))) ||
1408 !match(B1, m_Cmp(P1, m_Instruction(I1), m_Constant(C1))))
1409 return false;
1410
1411 auto MatchingPred = CmpPredicate::getMatching(P0, P1);
1412 if (!MatchingPred)
1413 return false;
1414
1415 // The compare operands must be extracts of the same vector with constant
1416 // extract indexes.
1417 Value *X;
1418 uint64_t Index0, Index1;
1419 if (!match(I0, m_ExtractElt(m_Value(X), m_ConstantInt(Index0))) ||
1420 !match(I1, m_ExtractElt(m_Specific(X), m_ConstantInt(Index1))))
1421 return false;
1422
1423 auto *Ext0 = cast<ExtractElementInst>(I0);
1424 auto *Ext1 = cast<ExtractElementInst>(I1);
1425 ExtractElementInst *ConvertToShuf = getShuffleExtract(Ext0, Ext1, CostKind);
1426 if (!ConvertToShuf)
1427 return false;
1428 assert((ConvertToShuf == Ext0 || ConvertToShuf == Ext1) &&
1429 "Unknown ExtractElementInst");
1430
1431 // The original scalar pattern is:
1432 // binop i1 (cmp Pred (ext X, Index0), C0), (cmp Pred (ext X, Index1), C1)
1433 CmpInst::Predicate Pred = *MatchingPred;
1434 unsigned CmpOpcode =
1435 CmpInst::isFPPredicate(Pred) ? Instruction::FCmp : Instruction::ICmp;
1436 auto *VecTy = dyn_cast<FixedVectorType>(X->getType());
1437 if (!VecTy)
1438 return false;
1439
1440 if (Index0 >= VecTy->getNumElements() || Index1 >= VecTy->getNumElements())
1441 return false;
1442
1443 InstructionCost Ext0Cost =
1444 TTI.getVectorInstrCost(*Ext0, VecTy, CostKind, Index0);
1445 InstructionCost Ext1Cost =
1446 TTI.getVectorInstrCost(*Ext1, VecTy, CostKind, Index1);
1448 CmpOpcode, I0->getType(), CmpInst::makeCmpResultType(I0->getType()), Pred,
1449 CostKind);
1450
1451 InstructionCost OldCost =
1452 Ext0Cost + Ext1Cost + CmpCost * 2 +
1453 TTI.getArithmeticInstrCost(I.getOpcode(), I.getType(), CostKind);
1454
1455 // The proposed vector pattern is:
1456 // vcmp = cmp Pred X, VecC
1457 // ext (binop vNi1 vcmp, (shuffle vcmp, Index1)), Index0
1458 int CheapIndex = ConvertToShuf == Ext0 ? Index1 : Index0;
1459 int ExpensiveIndex = ConvertToShuf == Ext0 ? Index0 : Index1;
1462 CmpOpcode, VecTy, CmpInst::makeCmpResultType(VecTy), Pred, CostKind);
1463 SmallVector<int, 32> ShufMask(VecTy->getNumElements(), PoisonMaskElem);
1464 ShufMask[CheapIndex] = ExpensiveIndex;
1466 CmpTy, CostKind, ShufMask);
1467 NewCost += TTI.getArithmeticInstrCost(I.getOpcode(), CmpTy, CostKind);
1468 NewCost += TTI.getVectorInstrCost(*Ext0, CmpTy, CostKind, CheapIndex);
1469 NewCost += Ext0->hasOneUse() ? 0 : Ext0Cost;
1470 NewCost += Ext1->hasOneUse() ? 0 : Ext1Cost;
1471
1472 // Aggressively form vector ops if the cost is equal because the transform
1473 // may enable further optimization.
1474 // Codegen can reverse this transform (scalarize) if it was not profitable.
1475 if (OldCost < NewCost || !NewCost.isValid())
1476 return false;
1477
1478 // Create a vector constant from the 2 scalar constants.
1479 SmallVector<Constant *, 32> CmpC(VecTy->getNumElements(),
1480 PoisonValue::get(VecTy->getElementType()));
1481 CmpC[Index0] = C0;
1482 CmpC[Index1] = C1;
1483 Value *VCmp = Builder.CreateCmp(Pred, X, ConstantVector::get(CmpC));
1484 Value *Shuf = createShiftShuffle(VCmp, ExpensiveIndex, CheapIndex, Builder);
1485 Value *LHS = ConvertToShuf == Ext0 ? Shuf : VCmp;
1486 Value *RHS = ConvertToShuf == Ext0 ? VCmp : Shuf;
1487 Value *VecLogic = Builder.CreateBinOp(BI->getOpcode(), LHS, RHS);
1488 Value *NewExt = Builder.CreateExtractElement(VecLogic, CheapIndex);
1489 replaceValue(I, *NewExt);
1490 ++NumVecCmpBO;
1491 return true;
1492}
1493
1494/// Try to fold scalar selects that select between extracted elements and zero
1495/// into extracting from a vector select. This is rooted at the bitcast.
1496///
1497/// This pattern arises when a vector is bitcast to a smaller element type,
1498/// elements are extracted, and then conditionally selected with zero:
1499///
1500/// %bc = bitcast <4 x i32> %src to <16 x i8>
1501/// %e0 = extractelement <16 x i8> %bc, i32 0
1502/// %s0 = select i1 %cond, i8 %e0, i8 0
1503/// %e1 = extractelement <16 x i8> %bc, i32 1
1504/// %s1 = select i1 %cond, i8 %e1, i8 0
1505/// ...
1506///
1507/// Transforms to:
1508/// %sel = select i1 %cond, <4 x i32> %src, <4 x i32> zeroinitializer
1509/// %bc = bitcast <4 x i32> %sel to <16 x i8>
1510/// %e0 = extractelement <16 x i8> %bc, i32 0
1511/// %e1 = extractelement <16 x i8> %bc, i32 1
1512/// ...
1513///
1514/// This is profitable because vector select on wider types produces fewer
1515/// select/cndmask instructions than scalar selects on each element.
1516bool VectorCombine::foldSelectsFromBitcast(Instruction &I) {
1517 auto *BC = dyn_cast<BitCastInst>(&I);
1518 if (!BC)
1519 return false;
1520
1521 FixedVectorType *SrcVecTy = dyn_cast<FixedVectorType>(BC->getSrcTy());
1522 FixedVectorType *DstVecTy = dyn_cast<FixedVectorType>(BC->getDestTy());
1523 if (!SrcVecTy || !DstVecTy)
1524 return false;
1525
1526 // Source must be 32-bit or 64-bit elements, destination must be smaller
1527 // integer elements. Zero in all these types is all-bits-zero.
1528 Type *SrcEltTy = SrcVecTy->getElementType();
1529 Type *DstEltTy = DstVecTy->getElementType();
1530 unsigned SrcEltBits = SrcEltTy->getPrimitiveSizeInBits();
1531 unsigned DstEltBits = DstEltTy->getPrimitiveSizeInBits();
1532
1533 if (SrcEltBits != 32 && SrcEltBits != 64)
1534 return false;
1535
1536 if (!DstEltTy->isIntegerTy() || DstEltBits >= SrcEltBits)
1537 return false;
1538
1539 // Check profitability using TTI before collecting users.
1540 Type *CondTy = CmpInst::makeCmpResultType(DstEltTy);
1541 Type *VecCondTy = CmpInst::makeCmpResultType(SrcVecTy);
1542
1543 InstructionCost ScalarSelCost =
1544 TTI.getCmpSelInstrCost(Instruction::Select, DstEltTy, CondTy,
1546 InstructionCost VecSelCost =
1547 TTI.getCmpSelInstrCost(Instruction::Select, SrcVecTy, VecCondTy,
1549
1550 // We need at least this many selects for vectorization to be profitable.
1551 // VecSelCost < ScalarSelCost * NumSelects => NumSelects > VecSelCost /
1552 // ScalarSelCost
1553 if (!ScalarSelCost.isValid() || ScalarSelCost == 0)
1554 return false;
1555
1556 unsigned MinSelects = (VecSelCost.getValue() / ScalarSelCost.getValue()) + 1;
1557
1558 // Quick check: if bitcast doesn't have enough users, bail early.
1559 if (!BC->hasNUsesOrMore(MinSelects))
1560 return false;
1561
1562 // Collect all select users that match the pattern, grouped by condition.
1563 // Pattern: select i1 %cond, (extractelement %bc, idx), 0
1564 DenseMap<Value *, SmallVector<SelectInst *, 8>> CondToSelects;
1565
1566 for (User *U : BC->users()) {
1567 auto *Ext = dyn_cast<ExtractElementInst>(U);
1568 if (!Ext)
1569 continue;
1570
1571 for (User *ExtUser : Ext->users()) {
1572 Value *Cond;
1573 // Match: select i1 %cond, %ext, 0
1574 if (match(ExtUser, m_Select(m_Value(Cond), m_Specific(Ext), m_Zero())) &&
1575 Cond->getType()->isIntegerTy(1))
1576 CondToSelects[Cond].push_back(cast<SelectInst>(ExtUser));
1577 }
1578 }
1579
1580 if (CondToSelects.empty())
1581 return false;
1582
1583 bool MadeChange = false;
1584 Value *SrcVec = BC->getOperand(0);
1585
1586 // Process each group of selects with the same condition.
1587 for (auto [Cond, Selects] : CondToSelects) {
1588 // Only profitable if vector select cost < total scalar select cost.
1589 if (Selects.size() < MinSelects) {
1590 LLVM_DEBUG(dbgs() << "VectorCombine: foldSelectsFromBitcast not "
1591 << "profitable (VecCost=" << VecSelCost
1592 << ", ScalarCost=" << ScalarSelCost
1593 << ", NumSelects=" << Selects.size() << ")\n");
1594 continue;
1595 }
1596
1597 // Create the vector select and bitcast once for this condition.
1598 auto InsertPt = std::next(BC->getIterator());
1599
1600 if (auto *CondInst = dyn_cast<Instruction>(Cond))
1601 if (DT.dominates(BC, CondInst))
1602 InsertPt = std::next(CondInst->getIterator());
1603
1604 Builder.SetInsertPoint(InsertPt);
1605 Value *VecSel =
1606 Builder.CreateSelect(Cond, SrcVec, Constant::getNullValue(SrcVecTy));
1607 Value *NewBC = Builder.CreateBitCast(VecSel, DstVecTy);
1608
1609 // Replace each scalar select with an extract from the new bitcast.
1610 for (SelectInst *Sel : Selects) {
1611 auto *Ext = cast<ExtractElementInst>(Sel->getTrueValue());
1612 Value *Idx = Ext->getIndexOperand();
1613
1614 Builder.SetInsertPoint(Sel);
1615 Value *NewExt = Builder.CreateExtractElement(NewBC, Idx);
1616 replaceValue(*Sel, *NewExt);
1617 MadeChange = true;
1618 }
1619
1620 LLVM_DEBUG(dbgs() << "VectorCombine: folded " << Selects.size()
1621 << " selects into vector select\n");
1622 }
1623
1624 return MadeChange;
1625}
1626
1629 const TargetTransformInfo &TTI,
1630 InstructionCost &CostBeforeReduction,
1631 InstructionCost &CostAfterReduction) {
1632 Instruction *Op0, *Op1;
1633 auto *RedOp = dyn_cast<Instruction>(II.getOperand(0));
1634 auto *VecRedTy = cast<VectorType>(II.getOperand(0)->getType());
1635 unsigned ReductionOpc =
1636 getArithmeticReductionInstruction(II.getIntrinsicID());
1637 if (RedOp && match(RedOp, m_ZExtOrSExt(m_Value()))) {
1638 bool IsUnsigned = isa<ZExtInst>(RedOp);
1639 auto *ExtType = cast<VectorType>(RedOp->getOperand(0)->getType());
1640
1641 CostBeforeReduction =
1642 TTI.getCastInstrCost(RedOp->getOpcode(), VecRedTy, ExtType,
1644 CostAfterReduction =
1645 TTI.getExtendedReductionCost(ReductionOpc, IsUnsigned, II.getType(),
1646 ExtType, FastMathFlags(), CostKind);
1647 return;
1648 }
1649 if (RedOp && II.getIntrinsicID() == Intrinsic::vector_reduce_add &&
1650 match(RedOp,
1652 match(Op0, m_ZExtOrSExt(m_Value())) &&
1653 Op0->getOpcode() == Op1->getOpcode() &&
1654 Op0->getOperand(0)->getType() == Op1->getOperand(0)->getType() &&
1655 (Op0->getOpcode() == RedOp->getOpcode() || Op0 == Op1)) {
1656 // Matched reduce.add(ext(mul(ext(A), ext(B)))
1657 bool IsUnsigned = isa<ZExtInst>(Op0);
1658 auto *ExtType = cast<VectorType>(Op0->getOperand(0)->getType());
1659 VectorType *MulType = VectorType::get(Op0->getType(), VecRedTy);
1660
1661 InstructionCost ExtCost =
1662 TTI.getCastInstrCost(Op0->getOpcode(), MulType, ExtType,
1664 InstructionCost MulCost =
1665 TTI.getArithmeticInstrCost(Instruction::Mul, MulType, CostKind);
1666 InstructionCost Ext2Cost =
1667 TTI.getCastInstrCost(RedOp->getOpcode(), VecRedTy, MulType,
1669
1670 CostBeforeReduction = ExtCost * 2 + MulCost + Ext2Cost;
1671 CostAfterReduction = TTI.getMulAccReductionCost(
1672 IsUnsigned, ReductionOpc, II.getType(), ExtType, CostKind);
1673 return;
1674 }
1675 CostAfterReduction = TTI.getArithmeticReductionCost(ReductionOpc, VecRedTy,
1676 std::nullopt, CostKind);
1677}
1678
1679bool VectorCombine::foldBinopOfReductions(Instruction &I) {
1680 Instruction::BinaryOps BinOpOpc = cast<BinaryOperator>(&I)->getOpcode();
1681 Intrinsic::ID ReductionIID = getReductionForBinop(BinOpOpc);
1682 if (BinOpOpc == Instruction::Sub)
1683 ReductionIID = Intrinsic::vector_reduce_add;
1684 if (ReductionIID == Intrinsic::not_intrinsic)
1685 return false;
1686 // FP reductions have a start-value operand that this fold doesn't handle.
1687 if (ReductionIID == Intrinsic::vector_reduce_fadd ||
1688 ReductionIID == Intrinsic::vector_reduce_fmul)
1689 return false;
1690
1691 auto checkIntrinsicAndGetItsArgument = [](Value *V,
1692 Intrinsic::ID IID) -> Value * {
1693 auto *II = dyn_cast<IntrinsicInst>(V);
1694 if (!II)
1695 return nullptr;
1696 if (II->getIntrinsicID() == IID && II->hasOneUse())
1697 return II->getArgOperand(0);
1698 return nullptr;
1699 };
1700
1701 Value *V0 = checkIntrinsicAndGetItsArgument(I.getOperand(0), ReductionIID);
1702 if (!V0)
1703 return false;
1704 Value *V1 = checkIntrinsicAndGetItsArgument(I.getOperand(1), ReductionIID);
1705 if (!V1)
1706 return false;
1707
1708 auto *VTy = cast<VectorType>(V0->getType());
1709 if (V1->getType() != VTy)
1710 return false;
1711 const auto &II0 = *cast<IntrinsicInst>(I.getOperand(0));
1712 const auto &II1 = *cast<IntrinsicInst>(I.getOperand(1));
1713 unsigned ReductionOpc =
1714 getArithmeticReductionInstruction(II0.getIntrinsicID());
1715
1716 InstructionCost OldCost = 0;
1717 InstructionCost NewCost = 0;
1718 InstructionCost CostOfRedOperand0 = 0;
1719 InstructionCost CostOfRed0 = 0;
1720 InstructionCost CostOfRedOperand1 = 0;
1721 InstructionCost CostOfRed1 = 0;
1722 analyzeCostOfVecReduction(II0, CostKind, TTI, CostOfRedOperand0, CostOfRed0);
1723 analyzeCostOfVecReduction(II1, CostKind, TTI, CostOfRedOperand1, CostOfRed1);
1724 OldCost = CostOfRed0 + CostOfRed1 + TTI.getInstructionCost(&I, CostKind);
1725 NewCost =
1726 CostOfRedOperand0 + CostOfRedOperand1 +
1727 TTI.getArithmeticInstrCost(BinOpOpc, VTy, CostKind) +
1728 TTI.getArithmeticReductionCost(ReductionOpc, VTy, std::nullopt, CostKind);
1729 if (NewCost >= OldCost || !NewCost.isValid())
1730 return false;
1731
1732 LLVM_DEBUG(dbgs() << "Found two mergeable reductions: " << I
1733 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
1734 << "\n");
1735 Value *VectorBO;
1736 if (BinOpOpc == Instruction::Or)
1737 VectorBO = Builder.CreateOr(V0, V1, "",
1738 cast<PossiblyDisjointInst>(I).isDisjoint());
1739 else
1740 VectorBO = Builder.CreateBinOp(BinOpOpc, V0, V1);
1741
1742 Value *Rdx = Builder.CreateIntrinsic(ReductionIID, {VTy}, {VectorBO});
1743 replaceValue(I, *Rdx);
1744 return true;
1745}
1746
1747// Check if memory is modified, freed, or synchronized between two instrs in
1748// the same BB.
1751 const MemoryLocation &Loc, AAResults &AA) {
1752 unsigned NumScanned = 0;
1753 if (std::any_of(Begin, End, [&](const Instruction &Instr) {
1754 return isModSet(AA.getModRefInfo(&Instr, Loc)) ||
1755 ++NumScanned > MaxInstrsToScan;
1756 }))
1757 return true;
1758
1759 // willNotFreeBetween expects instructions rather than iterators. An empty
1760 // range cannot free or synchronize, so avoid dereferencing its end.
1761 return Begin != End && !willNotFreeBetween(&*Begin, &*End);
1762}
1763
1764namespace {
1765/// Helper class to indicate whether a vector index can be safely scalarized and
1766/// if a freeze needs to be inserted.
1767class ScalarizationResult {
1768 enum class StatusTy { Unsafe, Safe, SafeWithFreeze };
1769
1770 StatusTy Status;
1771 Value *ToFreeze;
1772
1773 ScalarizationResult(StatusTy Status, Value *ToFreeze = nullptr)
1774 : Status(Status), ToFreeze(ToFreeze) {}
1775
1776public:
1777 ScalarizationResult(const ScalarizationResult &Other) = default;
1778 ~ScalarizationResult() {
1779 assert(!ToFreeze && "freeze() not called with ToFreeze being set");
1780 }
1781
1782 static ScalarizationResult unsafe() { return {StatusTy::Unsafe}; }
1783 static ScalarizationResult safe() { return {StatusTy::Safe}; }
1784 static ScalarizationResult safeWithFreeze(Value *ToFreeze) {
1785 return {StatusTy::SafeWithFreeze, ToFreeze};
1786 }
1787
1788 /// Returns true if the index can be scalarize without requiring a freeze.
1789 bool isSafe() const { return Status == StatusTy::Safe; }
1790 /// Returns true if the index cannot be scalarized.
1791 bool isUnsafe() const { return Status == StatusTy::Unsafe; }
1792 /// Returns true if the index can be scalarize, but requires inserting a
1793 /// freeze.
1794 bool isSafeWithFreeze() const { return Status == StatusTy::SafeWithFreeze; }
1795
1796 /// Reset the state of Unsafe and clear ToFreze if set.
1797 void discard() {
1798 ToFreeze = nullptr;
1799 Status = StatusTy::Unsafe;
1800 }
1801
1802 /// Freeze the ToFreeze and update the use in \p User to use it.
1803 void freeze(IRBuilderBase &Builder, Instruction &UserI) {
1804 assert(isSafeWithFreeze() &&
1805 "should only be used when freezing is required");
1806 assert(is_contained(ToFreeze->users(), &UserI) &&
1807 "UserI must be a user of ToFreeze");
1808 IRBuilder<>::InsertPointGuard Guard(Builder);
1809 Builder.SetInsertPoint(cast<Instruction>(&UserI));
1810 Value *Frozen =
1811 Builder.CreateFreeze(ToFreeze, ToFreeze->getName() + ".frozen");
1812 for (Use &U : make_early_inc_range((UserI.operands())))
1813 if (U.get() == ToFreeze)
1814 U.set(Frozen);
1815
1816 ToFreeze = nullptr;
1817 }
1818};
1819} // namespace
1820
1821/// Check if it is legal to scalarize a memory access to \p VecTy at index \p
1822/// Idx. \p Idx must access a valid vector element.
1823static ScalarizationResult canScalarizeAccess(VectorType *VecTy, Value *Idx,
1824 const SimplifyQuery &SQ) {
1825 // We do checks for both fixed vector types and scalable vector types.
1826 // This is the number of elements of fixed vector types,
1827 // or the minimum number of elements of scalable vector types.
1828 uint64_t NumElements = VecTy->getElementCount().getKnownMinValue();
1829 unsigned IntWidth = Idx->getType()->getScalarSizeInBits();
1830
1831 if (auto *C = dyn_cast<ConstantInt>(Idx)) {
1832 if (C->getValue().ult(NumElements))
1833 return ScalarizationResult::safe();
1834 return ScalarizationResult::unsafe();
1835 }
1836
1837 // Always unsafe if the index type can't handle all inbound values.
1838 if (!llvm::isUIntN(IntWidth, NumElements))
1839 return ScalarizationResult::unsafe();
1840
1841 APInt Zero(IntWidth, 0);
1842 APInt MaxElts(IntWidth, NumElements);
1843 ConstantRange ValidIndices(Zero, MaxElts);
1844 ConstantRange IdxRange(IntWidth, true);
1845
1846 if (isGuaranteedNotToBePoison(Idx, SQ.AC, SQ.CtxI, SQ.DT)) {
1847 if (ValidIndices.contains(
1848 computeConstantRange(Idx, /*ForSigned=*/false, SQ)))
1849 return ScalarizationResult::safe();
1850 return ScalarizationResult::unsafe();
1851 }
1852
1853 // If the index may be poison, check if we can insert a freeze before the
1854 // range of the index is restricted.
1855 Value *IdxBase;
1856 ConstantInt *CI;
1857 if (match(Idx, m_And(m_Value(IdxBase), m_ConstantInt(CI)))) {
1858 IdxRange = IdxRange.binaryAnd(CI->getValue());
1859 } else if (match(Idx, m_URem(m_Value(IdxBase), m_ConstantInt(CI)))) {
1860 IdxRange = IdxRange.urem(CI->getValue());
1861 }
1862
1863 if (ValidIndices.contains(IdxRange))
1864 return ScalarizationResult::safeWithFreeze(IdxBase);
1865 return ScalarizationResult::unsafe();
1866}
1867
1868/// Return the GEP index type if the unsigned vector index \p Idx can be
1869/// represented by an inbounds GEP. A null result means that the maximum byte
1870/// offset cannot be represented by the pointer's signed GEP index type.
1871///
1872/// unsigned lane range
1873/// |
1874/// v
1875/// MaxByteOffset = MaxLane * element store size
1876/// |
1877/// +-- unavailable or outside signed GEP range --> reject
1878/// |
1879/// v
1880/// valid range --> use the pointer's GEP index type
1882 Type *PtrTy,
1883 const DataLayout &DL) {
1884 auto *GEPIndexTy = cast<IntegerType>(DL.getIndexType(PtrTy));
1885 unsigned GEPBits = GEPIndexTy->getBitWidth();
1886 uint64_t NumElements = VecTy->getElementCount().getKnownMinValue();
1887
1888 uint64_t MaxLane = NumElements - 1;
1889 if (auto *C = dyn_cast<ConstantInt>(Idx)) {
1890 if (C->getValue().uge(NumElements))
1891 return nullptr;
1892 MaxLane = C->getZExtValue();
1893 }
1894
1895 Type *ElemTy = VecTy->getElementType();
1896 if (!DL.typeSizeEqualsStoreSize(ElemTy))
1897 return nullptr;
1898
1899 TypeSize ElemStride = DL.getTypeStoreSize(ElemTy);
1900 if (ElemStride.isScalable())
1901 return nullptr;
1902
1903 // Compare both values in a common width:
1904 //
1905 // MaxLane (uint64_t) * ElemStride (uint64_t) signed_max(GEPBits)
1906 // | |
1907 // v v
1908 // ByteOffset (up to 128 bits) sext to WideBits
1909 // \ /
1910 // +------------ ugt ------------+
1911 // |
1912 // greater -> reject
1913 //
1914 // WideBits = max(GEPBits, 128) prevents the multiplication from wrapping
1915 // and preserves the GEP limit during the comparison.
1916 unsigned WideBits = std::max(GEPBits, 128u);
1917 APInt MaxLaneValue(WideBits, MaxLane);
1918 APInt ByteOffset = MaxLaneValue;
1919 ByteOffset *= APInt(WideBits, ElemStride.getFixedValue());
1920 APInt MaxGEPOffset = APInt::getSignedMaxValue(GEPBits).sext(WideBits);
1921 // Reject offsets outside the GEP's positive signed range. Compare as
1922 // unsigned because the full 128-bit product may set its sign bit.
1923 if (ByteOffset.ugt(MaxGEPOffset))
1924 return nullptr;
1925
1926 return GEPIndexTy;
1927}
1928
1929/// Materialize an index for a scalarized GEP after profitability is known.
1930/// Vector element indices are unsigned, but GEP sign-extends narrow integer
1931/// indices. Widen a narrow index explicitly so its unsigned value is retained.
1933 IRBuilderBase &Builder) {
1934 unsigned SrcBits = Idx->getType()->getIntegerBitWidth();
1935 unsigned DstBits = GEPIndexTy->getBitWidth();
1936 if (SrcBits >= DstBits)
1937 return Idx;
1938
1939 return Builder.CreateZExt(Idx, GEPIndexTy, Idx->getName() + ".gepidx");
1940}
1941
1942/// The memory operation on a vector of \p ScalarType had alignment of
1943/// \p VectorAlignment. Compute the maximal, but conservatively correct,
1944/// alignment that will be valid for the memory operation on a single scalar
1945/// element of the same type with index \p Idx.
1947 Type *ScalarType, Value *Idx,
1948 const DataLayout &DL) {
1949 if (auto *C = dyn_cast<ConstantInt>(Idx))
1950 return commonAlignment(VectorAlignment,
1951 C->getZExtValue() * DL.getTypeStoreSize(ScalarType));
1952 return commonAlignment(VectorAlignment, DL.getTypeStoreSize(ScalarType));
1953}
1954
1955/// Fold a vector store fed by a single-use insertelement chain into scalar
1956/// stores.
1957///
1958/// Before:
1959///
1960/// %p --> vector load --> insert %x, lane 1 --> insert %y, lane 3
1961/// |
1962/// v
1963/// vector store to %p
1964///
1965/// Vector lanes: [ 0 ] [ 1 ] [ 2 ] [ 3 ]
1966/// Stored value: [ old | x | old | y ] (one vector store)
1967///
1968/// After:
1969///
1970/// +--> GEP(%p, lane 1) --> store %x
1971/// %p -------------+
1972/// +--> GEP(%p, lane 3) --> store %y
1973///
1974/// Vector lanes: [ 0 ] [ 1 ] [ 2 ] [ 3 ]
1975/// Scalar stores: x y
1976/// store@1 store@3
1977///
1978/// Step 1. Gate:
1979/// target supports vector-element GEP addressing
1980///
1981/// Step 2. Trace:
1982/// vector store <-- insertelement <-- ... <-- insertelement <-- load
1983///
1984/// Steps 3-5. Validate:
1985/// reject unprofitable full overwrites; require simple accesses, a
1986/// common address/block, no memory write in between, and scalarizable
1987/// indices.
1988bool VectorCombine::foldInsertElementsToStores(Instruction &I) {
1989 // Step 1: The target must support addressing a vector element with a GEP.
1991 return false;
1992
1993 auto *SI = cast<StoreInst>(&I);
1994 if (!SI->isSimple() || !isa<VectorType>(SI->getValueOperand()->getType()))
1995 return false;
1996
1997 // Step 2: Collect a single-use insertelement chain, starting at the vector
1998 // store and walking back to the candidate load.
1999 Value *Source = SI->getValueOperand();
2000 SmallVector<std::pair<Value *, Value *>, 4> InsertElements;
2001 Value *Base = Source;
2002 while (auto *Insert = dyn_cast<InsertElementInst>(Base)) {
2003 if (!Insert->hasOneUse())
2004 break;
2005 Value *InsertVal = Insert->getOperand(1);
2006 Value *Idx = Insert->getOperand(2);
2007 InsertElements.push_back({InsertVal, Idx});
2008 Base = Insert->getOperand(0);
2009 }
2010
2011 if (InsertElements.empty())
2012 return false;
2013
2014 // The backwards walk collected the inserts in reverse program order. Restore
2015 // it now so later scalar stores preserve writes to duplicate/equal indices.
2016 std::reverse(InsertElements.begin(), InsertElements.end());
2017 auto *Load = dyn_cast<LoadInst>(Base);
2018 if (!Load)
2019 return false;
2020 auto *VecTy = cast<VectorType>(SI->getValueOperand()->getType());
2021
2022 // Step 3: Avoid replacing a complete overwrite with scalar stores when every
2023 // lane receives the same value; keeping the vector operation is preferable.
2024 if (auto *FVT = dyn_cast<FixedVectorType>(VecTy)) {
2025 if (InsertElements.size() == FVT->getNumElements()) {
2026 Value *FirstVal = InsertElements.front().first;
2027 if (all_of(InsertElements,
2028 [FirstVal](const auto &Elt) { return Elt.first == FirstVal; }))
2029 return false;
2030 }
2031 }
2032 Value *SrcAddr = Load->getPointerOperand()->stripPointerCasts();
2033 // Step 4: Establish the load/store update is legal: both accesses are simple,
2034 // have the same base address and block, have scalar elements whose type size
2035 // equals their store size, and no intervening operation modifies the updated
2036 // memory.
2037 if (!Load->isSimple() || Load->getParent() != SI->getParent() ||
2038 !DL->typeSizeEqualsStoreSize(Load->getType()->getScalarType()) ||
2039 SrcAddr != SI->getPointerOperand()->stripPointerCasts())
2040 return false;
2041
2042 if (isMemModifiedBetween(Load->getIterator(), SI->getIterator(),
2043 MemoryLocation::get(SI), AA))
2044 return false;
2045
2046 // Step 5: Validate every index before changing IR. A safe-with-freeze result
2047 // is recorded by ScalarizationResult, so discard it until profitability is
2048 // known; otherwise a rejected candidate could leave a freeze behind.
2049 for (auto [InsertVal, Idx] : InsertElements) {
2050 auto ScalarizableIdx =
2051 canScalarizeAccess(VecTy, Idx, SQ.getWithInstruction(&I));
2052 if (ScalarizableIdx.isUnsafe())
2053 return false;
2054
2055 auto GEPIndex =
2056 getScalarizedGEPIndexInfo(VecTy, Idx, SI->getPointerOperandType(), *DL);
2057 if (!GEPIndex) {
2058 ScalarizableIdx.discard();
2059 return false;
2060 }
2061
2062 // We are only checking legality here. Do not mutate IR before the
2063 // profitability check, but also do not leave a pending ToFreeze behind.
2064 ScalarizableIdx.discard();
2065 }
2066
2068 Instruction::Store, SI->getValueOperand()->getType(), SI->getAlign(),
2069 SI->getPointerAddressSpace(), CostKind);
2070
2071 if (Load->hasOneUse())
2072 OldCost += TTI.getMemoryOpCost(Instruction::Load, Load->getType(),
2073 Load->getAlign(),
2074 Load->getPointerAddressSpace(), CostKind);
2075
2076 for (auto [InsertVal, Idx] : InsertElements) {
2077 int Index = -1;
2078 if (auto *CIdx = dyn_cast<ConstantInt>(Idx))
2079 Index = CIdx->getZExtValue();
2080
2081 OldCost += TTI.getVectorInstrCost(Instruction::InsertElement, VecTy,
2082 CostKind, Index);
2083 }
2084
2085 InstructionCost NewCost = 0;
2086 // This transform replaces insertelement operations on a single vector with
2087 // GEPs and scalar stores, so assume constant-index GEP offsets stay within
2088 // addressing-mode ranges that getGEPCost considers TCC_Free. Cost only GEPs
2089 // with dynamic indices.
2090 for (auto [InsertVal, Idx] : InsertElements) {
2091 if (isa<ConstantInt>(Idx))
2092 continue;
2093 const Value *GEPIndices[] = {ConstantInt::get(Idx->getType(), 0), Idx};
2094 NewCost += TTI.getGEPCost(VecTy, SI->getPointerOperand(), GEPIndices,
2095 CostKind, InsertVal->getType());
2096 }
2097
2098 for (auto [InsertVal, Idx] : InsertElements) {
2099 Align ScalarOpAlignment = computeAlignmentAfterScalarization(
2100 std::max(SI->getAlign(), Load->getAlign()), InsertVal->getType(), Idx,
2101 *DL);
2102
2103 NewCost += TTI.getMemoryOpCost(Instruction::Store, InsertVal->getType(),
2104 ScalarOpAlignment,
2105 SI->getPointerAddressSpace(), CostKind);
2106 }
2107
2108 LLVM_DEBUG(dbgs() << "Found an insert-elements vector store scalarization "
2109 "candidate: "
2110 << I << "\n"
2111 << " NumInserts: " << InsertElements.size() << "\n"
2112 << " OldCost: " << OldCost << " vs NewCost: " << NewCost
2113 << "\n");
2114
2115 if (OldCost <= NewCost)
2116 return false;
2117
2118 for (auto [InsertVal, Idx] : InsertElements) {
2119 auto ScalarizableIdx =
2120 canScalarizeAccess(VecTy, Idx, SQ.getWithInstruction(&I));
2121 assert(!ScalarizableIdx.isUnsafe() && "already checked above");
2122
2123 if (ScalarizableIdx.isSafeWithFreeze())
2124 ScalarizableIdx.freeze(Builder, *cast<Instruction>(Idx));
2125 }
2126
2127 Worklist.push(Load);
2128 StoreInst *LastStore = nullptr;
2129 for (auto [InsertVal, Idx] : InsertElements) {
2130 auto ScalarizableIdx =
2131 canScalarizeAccess(VecTy, Idx, SQ.getWithInstruction(&I));
2132 if (ScalarizableIdx.isUnsafe())
2133 return false;
2134
2135 IntegerType *GEPIndexTy =
2136 getScalarizedGEPIndexInfo(VecTy, Idx, SI->getPointerOperandType(), *DL);
2137
2138 Value *GEPIdx = materializeScalarizedGEPIndex(Idx, GEPIndexTy, Builder);
2139 Value *GEP = Builder.CreateInBoundsGEP(
2140 SI->getValueOperand()->getType(), SI->getPointerOperand(),
2141 {ConstantInt::get(GEPIdx->getType(), 0), GEPIdx});
2142
2143 LastStore = Builder.CreateStore(InsertVal, GEP);
2144 LastStore->copyMetadata(*SI);
2145
2146 // The new GEP may change the pointer operand, so !invariant.group cannot
2147 // be transferred to the scalar store.
2148 LastStore->setMetadata(LLVMContext::MD_invariant_group, nullptr);
2149 Align ScalarOpAlignment = computeAlignmentAfterScalarization(
2150 std::max(SI->getAlign(), Load->getAlign()), InsertVal->getType(), Idx,
2151 *DL);
2152 LastStore->setAlignment(ScalarOpAlignment);
2153 }
2154
2155 replaceValue(I, *LastStore);
2157 return true;
2158}
2159
2160/// Try to scalarize vector loads feeding extractelement or bitcast
2161/// instructions.
2162bool VectorCombine::scalarizeLoad(Instruction &I) {
2163 Value *Ptr;
2164 if (!match(&I, m_Load(m_Value(Ptr))))
2165 return false;
2166
2167 auto *LI = cast<LoadInst>(&I);
2168 auto *VecTy = cast<VectorType>(LI->getType());
2169
2170 // The isSimple() check could be isUnordered(), but for now we cowardly
2171 // refuse to handle even unordered atomics.
2172 if (!LI->isSimple() || !DL->typeSizeEqualsStoreSize(VecTy->getScalarType()))
2173 return false;
2174
2175 bool AllExtracts = true;
2176 bool AllBitcasts = true;
2177 Instruction *LastCheckedInst = LI;
2178 unsigned NumInstChecked = 0;
2179
2180 // Check what type of users we have (must either all be extracts or
2181 // bitcasts) and ensure no memory modifications between the load and
2182 // its users.
2183 for (User *U : LI->users()) {
2184 auto *UI = dyn_cast<Instruction>(U);
2185 if (!UI || UI->getParent() != LI->getParent())
2186 return false;
2187
2188 // If any user is waiting to be erased, then bail out as this will
2189 // distort the cost calculation and possibly lead to infinite loops.
2190 if (UI->use_empty())
2191 return false;
2192
2193 if (!isa<ExtractElementInst>(UI))
2194 AllExtracts = false;
2195 if (!isa<BitCastInst>(UI))
2196 AllBitcasts = false;
2197
2198 // Check if any instruction between the load and the user may modify memory.
2199 if (LastCheckedInst->comesBefore(UI)) {
2200 for (Instruction &I :
2201 make_range(std::next(LI->getIterator()), UI->getIterator())) {
2202 // Bail out if we reached the check limit or the instruction may write
2203 // to memory.
2204 if (NumInstChecked == MaxInstrsToScan || I.mayWriteToMemory())
2205 return false;
2206 NumInstChecked++;
2207 }
2208 LastCheckedInst = UI;
2209 }
2210 }
2211
2212 if (AllExtracts)
2213 return scalarizeLoadExtract(LI, VecTy, Ptr);
2214 if (AllBitcasts)
2215 return scalarizeLoadBitcast(LI, VecTy, Ptr);
2216 return false;
2217}
2218
2219/// Try to scalarize vector loads feeding extractelement instructions.
2220bool VectorCombine::scalarizeLoadExtract(LoadInst *LI, VectorType *VecTy,
2221 Value *Ptr) {
2223 return false;
2224
2225 DenseMap<ExtractElementInst *, ScalarizationResult> NeedFreeze;
2226 DenseMap<ExtractElementInst *, IntegerType *> GEPIndexInfos;
2227 llvm::scope_exit FailureGuard([&]() {
2228 // If the transform is aborted, discard the ScalarizationResults.
2229 for (auto &Pair : NeedFreeze)
2230 Pair.second.discard();
2231 });
2232
2233 InstructionCost OriginalCost =
2234 TTI.getMemoryOpCost(Instruction::Load, VecTy, LI->getAlign(),
2236 InstructionCost ScalarizedCost = 0;
2237
2238 for (User *U : LI->users()) {
2239 auto *UI = cast<ExtractElementInst>(U);
2240
2241 auto ScalarIdx = canScalarizeAccess(VecTy, UI->getIndexOperand(),
2242 SQ.getWithInstruction(LI));
2243 if (ScalarIdx.isUnsafe())
2244 return false;
2245
2246 IntegerType *GEPIndex = getScalarizedGEPIndexInfo(
2247 VecTy, UI->getIndexOperand(), LI->getPointerOperandType(), *DL);
2248 if (!GEPIndex) {
2249 ScalarIdx.discard();
2250 return false;
2251 }
2252
2253 GEPIndexInfos.try_emplace(UI, GEPIndex);
2254
2255 if (ScalarIdx.isSafeWithFreeze()) {
2256 NeedFreeze.try_emplace(UI, ScalarIdx);
2257 ScalarIdx.discard();
2258 }
2259
2260 auto *Index = dyn_cast<ConstantInt>(UI->getIndexOperand());
2261 OriginalCost +=
2262 TTI.getVectorInstrCost(Instruction::ExtractElement, VecTy, CostKind,
2263 Index ? Index->getZExtValue() : -1);
2264 ScalarizedCost +=
2265 TTI.getMemoryOpCost(Instruction::Load, VecTy->getElementType(),
2267 ScalarizedCost += TTI.getAddressComputationCost(LI->getPointerOperandType(),
2268 nullptr, nullptr, CostKind);
2269 if (!Index && UI->getIndexOperand()->getType()->getIntegerBitWidth() <
2270 GEPIndex->getBitWidth())
2271 ScalarizedCost += TTI.getCastInstrCost(
2272 Instruction::ZExt, GEPIndex, UI->getIndexOperand()->getType(),
2274 }
2275
2276 LLVM_DEBUG(dbgs() << "Found all extractions of a vector load: " << *LI
2277 << "\n LoadExtractCost: " << OriginalCost
2278 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2279
2280 if (ScalarizedCost > OriginalCost)
2281 return false;
2282 if (ScalarizedCost == OriginalCost && !LI->hasOneUse())
2283 return false;
2284
2285 // Ensure we add the load back to the worklist BEFORE its users so they can
2286 // erased in the correct order.
2287 Worklist.push(LI);
2288
2289 Type *ElemType = VecTy->getElementType();
2290
2291 // Replace extracts with narrow scalar loads.
2292 for (User *U : LI->users()) {
2293 auto *EI = cast<ExtractElementInst>(U);
2294 Value *Idx = EI->getIndexOperand();
2295
2296 // Insert 'freeze' for poison indexes.
2297 if (auto It = NeedFreeze.find(EI); It != NeedFreeze.end())
2298 It->second.freeze(Builder, *cast<Instruction>(Idx));
2299
2300 Builder.SetInsertPoint(EI);
2301 auto It = GEPIndexInfos.find(EI);
2302 assert(It != GEPIndexInfos.end() &&
2303 "Missing scalarized GEP index information");
2304 Value *GEPIdx = materializeScalarizedGEPIndex(Idx, It->second, Builder);
2305 Value *GEP = Builder.CreateInBoundsGEP(
2306 VecTy, Ptr, {ConstantInt::get(GEPIdx->getType(), 0), GEPIdx});
2307 auto *NewLoad = cast<LoadInst>(
2308 Builder.CreateLoad(ElemType, GEP, EI->getName() + ".scalar"));
2309
2310 Align ScalarOpAlignment =
2311 computeAlignmentAfterScalarization(LI->getAlign(), ElemType, Idx, *DL);
2312 NewLoad->setAlignment(ScalarOpAlignment);
2313
2314 if (auto *ConstIdx = dyn_cast<ConstantInt>(Idx)) {
2315 size_t Offset = ConstIdx->getZExtValue() * DL->getTypeStoreSize(ElemType);
2316 AAMDNodes OldAAMD = LI->getAAMetadata();
2317 NewLoad->setAAMetadata(OldAAMD.adjustForAccess(Offset, ElemType, *DL));
2318 }
2319
2320 replaceValue(*EI, *NewLoad, false);
2321 }
2322
2323 FailureGuard.release();
2324 return true;
2325}
2326
2327/// Try to scalarize vector loads feeding bitcast instructions.
2328bool VectorCombine::scalarizeLoadBitcast(LoadInst *LI, VectorType *VecTy,
2329 Value *Ptr) {
2330 InstructionCost OriginalCost =
2331 TTI.getMemoryOpCost(Instruction::Load, VecTy, LI->getAlign(),
2333
2334 if (!isa<FixedVectorType>(VecTy))
2335 return false;
2336
2337 Type *TargetScalarType = nullptr;
2338 unsigned VecBitWidth = DL->getTypeSizeInBits(VecTy);
2339
2340 for (User *U : LI->users()) {
2341 auto *BC = cast<BitCastInst>(U);
2342
2343 Type *DestTy = BC->getDestTy();
2344 if (!DestTy->isIntegerTy() && !DestTy->isFloatingPointTy())
2345 return false;
2346
2347 unsigned DestBitWidth = DL->getTypeSizeInBits(DestTy);
2348 if (DestBitWidth != VecBitWidth)
2349 return false;
2350
2351 // All bitcasts must target the same scalar type.
2352 if (!TargetScalarType)
2353 TargetScalarType = DestTy;
2354 else if (TargetScalarType != DestTy)
2355 return false;
2356
2357 OriginalCost +=
2358 TTI.getCastInstrCost(Instruction::BitCast, TargetScalarType, VecTy,
2360 }
2361
2362 if (!TargetScalarType)
2363 return false;
2364
2365 assert(!LI->user_empty() && "Unexpected load without bitcast users");
2366 InstructionCost ScalarizedCost =
2367 TTI.getMemoryOpCost(Instruction::Load, TargetScalarType, LI->getAlign(),
2369
2370 LLVM_DEBUG(dbgs() << "Found vector load feeding only bitcasts: " << *LI
2371 << "\n OriginalCost: " << OriginalCost
2372 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2373
2374 if (ScalarizedCost >= OriginalCost)
2375 return false;
2376
2377 // Ensure we add the load back to the worklist BEFORE its users so they can
2378 // erased in the correct order.
2379 Worklist.push(LI);
2380
2381 Builder.SetInsertPoint(LI);
2382 auto *ScalarLoad =
2383 Builder.CreateLoad(TargetScalarType, Ptr, LI->getName() + ".scalar");
2384 ScalarLoad->setAlignment(LI->getAlign());
2385 ScalarLoad->copyMetadata(*LI);
2386
2387 // Replace all bitcast users with the scalar load.
2388 for (User *U : LI->users()) {
2389 auto *BC = cast<BitCastInst>(U);
2390 replaceValue(*BC, *ScalarLoad, false);
2391 }
2392
2393 return true;
2394}
2395
2396bool VectorCombine::scalarizeExtExtract(Instruction &I) {
2398 return false;
2399 auto *Ext = dyn_cast<ZExtInst>(&I);
2400 if (!Ext)
2401 return false;
2402
2403 // Try to convert a vector zext feeding only extracts to a set of scalar
2404 // (Src << ExtIdx *Size) & (Size -1)
2405 // if profitable .
2406 auto *SrcTy = dyn_cast<FixedVectorType>(Ext->getOperand(0)->getType());
2407 if (!SrcTy)
2408 return false;
2409 auto *DstTy = cast<FixedVectorType>(Ext->getType());
2410
2411 Type *ScalarDstTy = DstTy->getElementType();
2412 if (DL->getTypeSizeInBits(SrcTy) != DL->getTypeSizeInBits(ScalarDstTy))
2413 return false;
2414
2415 InstructionCost VectorCost =
2416 TTI.getCastInstrCost(Instruction::ZExt, DstTy, SrcTy,
2418 unsigned ExtCnt = 0;
2419 bool ExtLane0 = false;
2420 for (User *U : Ext->users()) {
2421 uint64_t Idx;
2422 if (!match(U, m_ExtractElt(m_Value(), m_ConstantInt(Idx))))
2423 return false;
2424 // An out-of-bounds extractelement produces poison; bail out rather
2425 // than computing a shift amount that overflows the packed type.
2426 if (Idx >= SrcTy->getNumElements())
2427 return false;
2428 if (cast<Instruction>(U)->use_empty())
2429 continue;
2430 ExtCnt += 1;
2431 ExtLane0 |= !Idx;
2432 VectorCost += TTI.getVectorInstrCost(Instruction::ExtractElement, DstTy,
2433 CostKind, Idx, U);
2434 }
2435
2436 InstructionCost ScalarCost =
2437 ExtCnt * TTI.getArithmeticInstrCost(
2438 Instruction::And, ScalarDstTy, CostKind,
2441 (ExtCnt - ExtLane0) *
2443 Instruction::LShr, ScalarDstTy, CostKind,
2446 if (ScalarCost > VectorCost)
2447 return false;
2448
2449 Value *ScalarV = Ext->getOperand(0);
2450 if (!isGuaranteedNotToBePoison(ScalarV, SQ.AC, dyn_cast<Instruction>(ScalarV),
2451 SQ.DT)) {
2452 // Check wether all lanes are extracted, all extracts trigger UB
2453 // on poison, and the last extract (and hence all previous ones)
2454 // are guaranteed to execute if Ext executes. If so, we do not
2455 // need to insert a freeze.
2456 SmallDenseSet<ConstantInt *, 8> ExtractedLanes;
2457 bool AllExtractsTriggerUB = true;
2458 ExtractElementInst *LastExtract = nullptr;
2459 BasicBlock *ExtBB = Ext->getParent();
2460 for (User *U : Ext->users()) {
2461 auto *Extract = cast<ExtractElementInst>(U);
2462 if (Extract->getParent() != ExtBB || !programUndefinedIfPoison(Extract)) {
2463 AllExtractsTriggerUB = false;
2464 break;
2465 }
2466 ExtractedLanes.insert(cast<ConstantInt>(Extract->getIndexOperand()));
2467 if (!LastExtract || LastExtract->comesBefore(Extract))
2468 LastExtract = Extract;
2469 }
2470 if (ExtractedLanes.size() != DstTy->getNumElements() ||
2471 !AllExtractsTriggerUB ||
2473 LastExtract->getIterator()))
2474 ScalarV = Builder.CreateFreeze(ScalarV);
2475 }
2476 ScalarV = Builder.CreateBitCast(
2477 ScalarV,
2478 IntegerType::get(SrcTy->getContext(), DL->getTypeSizeInBits(SrcTy)));
2479 uint64_t SrcEltSizeInBits = DL->getTypeSizeInBits(SrcTy->getElementType());
2480 uint64_t TotalBits = DL->getTypeSizeInBits(SrcTy);
2481 APInt EltBitMask = APInt::getLowBitsSet(TotalBits, SrcEltSizeInBits);
2482 Type *PackedTy = IntegerType::get(SrcTy->getContext(), TotalBits);
2483 Value *Mask = ConstantInt::get(PackedTy, EltBitMask);
2484 for (User *U : Ext->users()) {
2485 auto *Extract = cast<ExtractElementInst>(U);
2486 uint64_t Idx =
2487 cast<ConstantInt>(Extract->getIndexOperand())->getZExtValue();
2488 uint64_t ShiftAmt =
2489 DL->isBigEndian()
2490 ? (TotalBits - SrcEltSizeInBits - Idx * SrcEltSizeInBits)
2491 : (Idx * SrcEltSizeInBits);
2492 Value *LShr = Builder.CreateLShr(ScalarV, ShiftAmt);
2493 Value *And = Builder.CreateAnd(LShr, Mask);
2494 U->replaceAllUsesWith(And);
2495 }
2496 return true;
2497}
2498
2499/// Try to fold "(or (zext (bitcast X)), (shl (zext (bitcast Y)), C))"
2500/// to "(bitcast (concat X, Y))"
2501/// where X/Y are bitcasted from i1 mask vectors.
2502bool VectorCombine::foldConcatOfBoolMasks(Instruction &I) {
2503 Type *Ty = I.getType();
2504 if (!Ty->isIntegerTy())
2505 return false;
2506
2507 // TODO: Add big endian test coverage
2508 if (DL->isBigEndian())
2509 return false;
2510
2511 // Restrict to disjoint cases so the mask vectors aren't overlapping.
2512 Instruction *X, *Y;
2514 return false;
2515
2516 // Allow both sources to contain shl, to handle more generic pattern:
2517 // "(or (shl (zext (bitcast X)), C1), (shl (zext (bitcast Y)), C2))"
2518 Value *SrcX;
2519 uint64_t ShAmtX = 0;
2520 if (!match(X, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcX)))))) &&
2521 !match(X, m_OneUse(
2523 m_ConstantInt(ShAmtX)))))
2524 return false;
2525
2526 Value *SrcY;
2527 uint64_t ShAmtY = 0;
2528 if (!match(Y, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcY)))))) &&
2529 !match(Y, m_OneUse(
2531 m_ConstantInt(ShAmtY)))))
2532 return false;
2533
2534 // Canonicalize larger shift to the RHS.
2535 if (ShAmtX > ShAmtY) {
2536 std::swap(X, Y);
2537 std::swap(SrcX, SrcY);
2538 std::swap(ShAmtX, ShAmtY);
2539 }
2540
2541 // Ensure both sources are matching vXi1 bool mask types, and that the shift
2542 // difference is the mask width so they can be easily concatenated together.
2543 uint64_t ShAmtDiff = ShAmtY - ShAmtX;
2544 unsigned NumSHL = (ShAmtX > 0) + (ShAmtY > 0);
2545 unsigned BitWidth = Ty->getPrimitiveSizeInBits();
2546 auto *MaskTy = dyn_cast<FixedVectorType>(SrcX->getType());
2547 if (!MaskTy || SrcX->getType() != SrcY->getType() ||
2548 !MaskTy->getElementType()->isIntegerTy(1) ||
2549 MaskTy->getNumElements() != ShAmtDiff ||
2550 MaskTy->getNumElements() > (BitWidth / 2))
2551 return false;
2552
2553 auto *ConcatTy = FixedVectorType::getDoubleElementsVectorType(MaskTy);
2554 auto *ConcatIntTy =
2555 Type::getIntNTy(Ty->getContext(), ConcatTy->getNumElements());
2556 auto *MaskIntTy = Type::getIntNTy(Ty->getContext(), ShAmtDiff);
2557
2558 SmallVector<int, 32> ConcatMask(ConcatTy->getNumElements());
2559 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
2560
2561 // TODO: Is it worth supporting multi use cases?
2562 InstructionCost OldCost = 0;
2563 OldCost += TTI.getArithmeticInstrCost(Instruction::Or, Ty, CostKind);
2564 OldCost +=
2565 NumSHL * TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2566 OldCost += 2 * TTI.getCastInstrCost(Instruction::ZExt, Ty, MaskIntTy,
2568 OldCost += 2 * TTI.getCastInstrCost(Instruction::BitCast, MaskIntTy, MaskTy,
2570
2571 InstructionCost NewCost = 0;
2573 MaskTy, CostKind, ConcatMask);
2574 NewCost += TTI.getCastInstrCost(Instruction::BitCast, ConcatIntTy, ConcatTy,
2576 if (Ty != ConcatIntTy)
2577 NewCost += TTI.getCastInstrCost(Instruction::ZExt, Ty, ConcatIntTy,
2579 if (ShAmtX > 0)
2580 NewCost += TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2581
2582 LLVM_DEBUG(dbgs() << "Found a concatenation of bitcasted bool masks: " << I
2583 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2584 << "\n");
2585
2586 if (NewCost > OldCost)
2587 return false;
2588
2589 // Build bool mask concatenation, bitcast back to scalar integer, and perform
2590 // any residual zero-extension or shifting.
2591 Value *Concat = Builder.CreateShuffleVector(SrcX, SrcY, ConcatMask);
2592 Worklist.pushValue(Concat);
2593
2594 Value *Result = Builder.CreateBitCast(Concat, ConcatIntTy);
2595
2596 if (Ty != ConcatIntTy) {
2597 Worklist.pushValue(Result);
2598 Result = Builder.CreateZExt(Result, Ty);
2599 }
2600
2601 if (ShAmtX > 0) {
2602 Worklist.pushValue(Result);
2603 Result = Builder.CreateShl(Result, ShAmtX);
2604 }
2605
2606 replaceValue(I, *Result);
2607 return true;
2608}
2609
2610/// Try to convert "shuffle (binop (shuffle, shuffle)), undef"
2611/// --> "binop (shuffle), (shuffle)".
2612bool VectorCombine::foldPermuteOfBinops(Instruction &I) {
2613 BinaryOperator *BinOp;
2614 ArrayRef<int> OuterMask;
2615 if (!match(&I, m_Shuffle(m_BinOp(BinOp), m_Undef(), m_Mask(OuterMask))))
2616 return false;
2617
2618 // Don't introduce poison into div/rem.
2619 if (BinOp->isIntDivRem() && llvm::is_contained(OuterMask, PoisonMaskElem))
2620 return false;
2621
2622 Value *Op00, *Op01, *Op10, *Op11;
2623 ArrayRef<int> Mask0, Mask1;
2624 bool Match0 = match(BinOp->getOperand(0),
2625 m_Shuffle(m_Value(Op00), m_Value(Op01), m_Mask(Mask0)));
2626 bool Match1 = match(BinOp->getOperand(1),
2627 m_Shuffle(m_Value(Op10), m_Value(Op11), m_Mask(Mask1)));
2628 if (!Match0 && !Match1)
2629 return false;
2630
2631 Op00 = Match0 ? Op00 : BinOp->getOperand(0);
2632 Op01 = Match0 ? Op01 : BinOp->getOperand(0);
2633 Op10 = Match1 ? Op10 : BinOp->getOperand(1);
2634 Op11 = Match1 ? Op11 : BinOp->getOperand(1);
2635
2636 Instruction::BinaryOps Opcode = BinOp->getOpcode();
2637 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2638 auto *BinOpTy = dyn_cast<FixedVectorType>(BinOp->getType());
2639 auto *Op0Ty = dyn_cast<FixedVectorType>(Op00->getType());
2640 auto *Op1Ty = dyn_cast<FixedVectorType>(Op10->getType());
2641 if (!ShuffleDstTy || !BinOpTy || !Op0Ty || !Op1Ty)
2642 return false;
2643
2644 unsigned NumSrcElts = BinOpTy->getNumElements();
2645
2646 // Don't accept shuffles that reference the second operand in
2647 // div/rem or if its an undef arg.
2648 if ((BinOp->isIntDivRem() || !isa<PoisonValue>(I.getOperand(1))) &&
2649 any_of(OuterMask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
2650 return false;
2651
2652 // Merge outer / inner (or identity if no match) shuffles.
2653 SmallVector<int> NewMask0, NewMask1;
2654 for (int M : OuterMask) {
2655 if (M < 0 || M >= (int)NumSrcElts) {
2656 NewMask0.push_back(PoisonMaskElem);
2657 NewMask1.push_back(PoisonMaskElem);
2658 } else {
2659 NewMask0.push_back(Match0 ? Mask0[M] : M);
2660 NewMask1.push_back(Match1 ? Mask1[M] : M);
2661 }
2662 }
2663
2664 unsigned NumOpElts = Op0Ty->getNumElements();
2665 bool IsIdentity0 = ShuffleDstTy == Op0Ty &&
2666 all_of(NewMask0, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2667 ShuffleVectorInst::isIdentityMask(NewMask0, NumOpElts);
2668 bool IsIdentity1 = ShuffleDstTy == Op1Ty &&
2669 all_of(NewMask1, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2670 ShuffleVectorInst::isIdentityMask(NewMask1, NumOpElts);
2671
2672 InstructionCost NewCost = 0;
2673 // Try to merge shuffles across the binop if the new shuffles are not costly.
2674 InstructionCost BinOpCost =
2675 TTI.getArithmeticInstrCost(Opcode, BinOpTy, CostKind);
2676 InstructionCost OldCost =
2678 ShuffleDstTy, BinOpTy, CostKind, OuterMask,
2679 0, nullptr, {BinOp}, &I);
2680 if (!BinOp->hasOneUse())
2681 NewCost += BinOpCost;
2682
2683 if (Match0) {
2685 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op0Ty, CostKind, Mask0,
2686 0, nullptr, {Op00, Op01}, cast<Instruction>(BinOp->getOperand(0)));
2687 OldCost += Shuf0Cost;
2688 if (!BinOp->hasOneUse() || !BinOp->getOperand(0)->hasOneUse())
2689 NewCost += Shuf0Cost;
2690 }
2691 if (Match1) {
2693 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op1Ty, CostKind, Mask1,
2694 0, nullptr, {Op10, Op11}, cast<Instruction>(BinOp->getOperand(1)));
2695 OldCost += Shuf1Cost;
2696 if (!BinOp->hasOneUse() || !BinOp->getOperand(1)->hasOneUse())
2697 NewCost += Shuf1Cost;
2698 }
2699
2700 NewCost += TTI.getArithmeticInstrCost(Opcode, ShuffleDstTy, CostKind);
2701
2702 if (!IsIdentity0)
2703 NewCost +=
2705 Op0Ty, CostKind, NewMask0, 0, nullptr, {Op00, Op01});
2706 if (!IsIdentity1)
2707 NewCost +=
2709 Op1Ty, CostKind, NewMask1, 0, nullptr, {Op10, Op11});
2710
2711 LLVM_DEBUG(dbgs() << "Found a shuffle feeding a shuffled binop: " << I
2712 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2713 << "\n");
2714
2715 // If costs are equal, still fold as we reduce instruction count.
2716 if (NewCost > OldCost)
2717 return false;
2718
2719 Value *LHS =
2720 IsIdentity0 ? Op00 : Builder.CreateShuffleVector(Op00, Op01, NewMask0);
2721 Value *RHS =
2722 IsIdentity1 ? Op10 : Builder.CreateShuffleVector(Op10, Op11, NewMask1);
2723 Value *NewBO = Builder.CreateBinOp(Opcode, LHS, RHS);
2724
2725 // Intersect flags from the old binops.
2726 if (auto *NewInst = dyn_cast<Instruction>(NewBO))
2727 NewInst->copyIRFlags(BinOp);
2728
2729 Worklist.pushValue(LHS);
2730 Worklist.pushValue(RHS);
2731 replaceValue(I, *NewBO);
2732 return true;
2733}
2734
2735/// Try to convert "shuffle (binop), (binop)" into "binop (shuffle), (shuffle)".
2736/// Try to convert "shuffle (cmpop), (cmpop)" into "cmpop (shuffle), (shuffle)".
2737bool VectorCombine::foldShuffleOfBinops(Instruction &I) {
2738 ArrayRef<int> OldMask;
2739 Instruction *LHS, *RHS;
2741 m_Mask(OldMask))))
2742 return false;
2743
2744 // TODO: Add support for addlike etc.
2745 if (LHS->getOpcode() != RHS->getOpcode())
2746 return false;
2747
2748 Value *X, *Y, *Z, *W;
2749 bool IsCommutative = false;
2750 CmpPredicate PredLHS = CmpInst::BAD_ICMP_PREDICATE;
2751 CmpPredicate PredRHS = CmpInst::BAD_ICMP_PREDICATE;
2752 if (match(LHS, m_BinOp(m_Value(X), m_Value(Y))) &&
2753 match(RHS, m_BinOp(m_Value(Z), m_Value(W)))) {
2754 auto *BO = cast<BinaryOperator>(LHS);
2755 // Don't introduce poison into div/rem.
2756 if (llvm::is_contained(OldMask, PoisonMaskElem) && BO->isIntDivRem())
2757 return false;
2758 IsCommutative = BinaryOperator::isCommutative(BO->getOpcode());
2759 } else if (match(LHS, m_Cmp(PredLHS, m_Value(X), m_Value(Y))) &&
2760 match(RHS, m_Cmp(PredRHS, m_Value(Z), m_Value(W))) &&
2761 (CmpInst::Predicate)PredLHS == (CmpInst::Predicate)PredRHS) {
2762 IsCommutative = cast<CmpInst>(LHS)->isCommutative();
2763 } else
2764 return false;
2765
2766 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2767 auto *BinResTy = dyn_cast<FixedVectorType>(LHS->getType());
2768 auto *BinOpTy = dyn_cast<FixedVectorType>(X->getType());
2769 if (!ShuffleDstTy || !BinResTy || !BinOpTy || X->getType() != Z->getType())
2770 return false;
2771
2772 bool SameBinOp = LHS == RHS;
2773 unsigned NumSrcElts = BinOpTy->getNumElements();
2774
2775 // If we have something like "add X, Y" and "add Z, X", swap ops to match.
2776 if (IsCommutative && X != Z && Y != W && (X == W || Y == Z))
2777 std::swap(X, Y);
2778
2779 auto ConvertToUnary = [NumSrcElts](int &M) {
2780 if (M >= (int)NumSrcElts)
2781 M -= NumSrcElts;
2782 };
2783
2784 SmallVector<int> NewMask0(OldMask);
2786 TTI::OperandValueInfo Op0Info = TTI.commonOperandInfo(X, Z);
2787 if (X == Z) {
2788 llvm::for_each(NewMask0, ConvertToUnary);
2790 Z = PoisonValue::get(BinOpTy);
2791 }
2792
2793 SmallVector<int> NewMask1(OldMask);
2795 TTI::OperandValueInfo Op1Info = TTI.commonOperandInfo(Y, W);
2796 if (Y == W) {
2797 llvm::for_each(NewMask1, ConvertToUnary);
2799 W = PoisonValue::get(BinOpTy);
2800 }
2801
2802 // Try to replace a binop with a shuffle if the shuffle is not costly.
2803 // When SameBinOp, only count the binop cost once.
2806
2807 InstructionCost OldCost = LHSCost;
2808 if (!SameBinOp) {
2809 OldCost += RHSCost;
2810 }
2812 ShuffleDstTy, BinResTy, CostKind, OldMask, 0,
2813 nullptr, {LHS, RHS}, &I);
2814
2815 // Handle shuffle(binop(shuffle(x),y),binop(z,shuffle(w))) style patterns
2816 // where one use shuffles have gotten split across the binop/cmp. These
2817 // often allow a major reduction in total cost that wouldn't happen as
2818 // individual folds.
2819 auto MergeInner = [&](Value *&Op, int Offset, MutableArrayRef<int> Mask,
2820 TTI::TargetCostKind CostKind) -> bool {
2821 Value *InnerOp;
2822 ArrayRef<int> InnerMask;
2823 if (match(Op, m_OneUse(m_Shuffle(m_Value(InnerOp), m_Undef(),
2824 m_Mask(InnerMask)))) &&
2825 InnerOp->getType() == Op->getType() &&
2826 all_of(InnerMask,
2827 [NumSrcElts](int M) { return M < (int)NumSrcElts; })) {
2828 for (int &M : Mask)
2829 if (Offset <= M && M < (int)(Offset + NumSrcElts)) {
2830 M = InnerMask[M - Offset];
2831 M = 0 <= M ? M + Offset : M;
2832 }
2834 Op = InnerOp;
2835 return true;
2836 }
2837 return false;
2838 };
2839 bool ReducedInstCount = false;
2840 ReducedInstCount |= MergeInner(X, 0, NewMask0, CostKind);
2841 ReducedInstCount |= MergeInner(Y, 0, NewMask1, CostKind);
2842 ReducedInstCount |= MergeInner(Z, NumSrcElts, NewMask0, CostKind);
2843 ReducedInstCount |= MergeInner(W, NumSrcElts, NewMask1, CostKind);
2844 bool SingleSrcBinOp = (X == Y) && (Z == W) && (NewMask0 == NewMask1);
2845 // SingleSrcBinOp only reduces instruction count if we also eliminate the
2846 // original binop(s). If binops have multiple uses, they won't be eliminated.
2847 ReducedInstCount |= SingleSrcBinOp && LHS->hasOneUser() && RHS->hasOneUser();
2848
2849 // For concat shuffles of i1 vectors where both binops are one-use, the
2850 // transform keeps the same instruction count but canonicalises to a single
2851 // wider binop, enabling downstream folds (e.g. NOT(XOR(concat(a,b),
2852 // concat(c,d))) -> XNOR(concat(a,b),concat(c,d)) on AVX-512 mask regs).
2853 // Restrict to BinaryOperator (not CmpInst) since narrow comparisons may
2854 // be cheaper than wide ones on some targets (e.g. AVX-512 vpcmpeq).
2855 ReducedInstCount |= cast<ShuffleVectorInst>(&I)->isConcat() &&
2856 I.getType()->getScalarType()->isIntegerTy(1) &&
2858 RHS->hasOneUser();
2859
2860 auto *ShuffleCmpTy =
2861 FixedVectorType::get(BinOpTy->getElementType(), ShuffleDstTy);
2863 SK0, ShuffleCmpTy, BinOpTy, CostKind, NewMask0, 0, nullptr, {X, Z});
2864 if (!SingleSrcBinOp)
2865 NewCost += TTI.getShuffleCost(SK1, ShuffleCmpTy, BinOpTy, CostKind,
2866 NewMask1, 0, nullptr, {Y, W});
2867
2868 if (PredLHS == CmpInst::BAD_ICMP_PREDICATE) {
2869 NewCost += TTI.getArithmeticInstrCost(LHS->getOpcode(), ShuffleDstTy,
2870 CostKind, Op0Info, Op1Info);
2871 } else {
2872 NewCost +=
2873 TTI.getCmpSelInstrCost(LHS->getOpcode(), ShuffleCmpTy, ShuffleDstTy,
2874 PredLHS, CostKind, Op0Info, Op1Info);
2875 }
2876 // If LHS/RHS have other uses, we need to account for the cost of keeping
2877 // the original instructions. When SameBinOp, only add the cost once.
2878 if (!LHS->hasOneUser())
2879 NewCost += LHSCost;
2880 if (!SameBinOp && !RHS->hasOneUser())
2881 NewCost += RHSCost;
2882
2883 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two binops: " << I
2884 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2885 << "\n");
2886
2887 // If either shuffle will constant fold away, then fold for the same cost as
2888 // we will reduce the instruction count.
2889 ReducedInstCount |= (isa<Constant>(X) && isa<Constant>(Z)) ||
2890 (isa<Constant>(Y) && isa<Constant>(W));
2891 if (ReducedInstCount ? (NewCost > OldCost) : (NewCost >= OldCost))
2892 return false;
2893
2894 Value *Shuf0 = Builder.CreateShuffleVector(X, Z, NewMask0);
2895 Value *Shuf1 =
2896 SingleSrcBinOp ? Shuf0 : Builder.CreateShuffleVector(Y, W, NewMask1);
2897 Value *NewBO = PredLHS == CmpInst::BAD_ICMP_PREDICATE
2898 ? Builder.CreateBinOp(
2899 cast<BinaryOperator>(LHS)->getOpcode(), Shuf0, Shuf1)
2900 : Builder.CreateCmp(PredLHS, Shuf0, Shuf1);
2901
2902 // Intersect flags from the old binops.
2903 if (auto *NewInst = dyn_cast<Instruction>(NewBO)) {
2904 NewInst->copyIRFlags(LHS);
2905 NewInst->andIRFlags(RHS);
2906 }
2907
2908 Worklist.pushValue(Shuf0);
2909 Worklist.pushValue(Shuf1);
2910 replaceValue(I, *NewBO);
2911 return true;
2912}
2913
2914/// Try to convert,
2915/// (shuffle(select(c1,t1,f1)), (select(c2,t2,f2)), m) into
2916/// (select (shuffle c1,c2,m), (shuffle t1,t2,m), (shuffle f1,f2,m))
2917bool VectorCombine::foldShuffleOfSelects(Instruction &I) {
2918 ArrayRef<int> Mask;
2919 Value *C1, *T1, *F1, *C2, *T2, *F2;
2920 if (!match(&I, m_Shuffle(m_Select(m_Value(C1), m_Value(T1), m_Value(F1)),
2921 m_Select(m_Value(C2), m_Value(T2), m_Value(F2)),
2922 m_Mask(Mask))))
2923 return false;
2924
2925 auto *Sel1 = cast<Instruction>(I.getOperand(0));
2926 auto *Sel2 = cast<Instruction>(I.getOperand(1));
2927
2928 auto *C1VecTy = dyn_cast<FixedVectorType>(C1->getType());
2929 auto *C2VecTy = dyn_cast<FixedVectorType>(C2->getType());
2930 if (!C1VecTy || !C2VecTy || C1VecTy != C2VecTy)
2931 return false;
2932
2933 auto *SI0FOp = dyn_cast<FPMathOperator>(I.getOperand(0));
2934 auto *SI1FOp = dyn_cast<FPMathOperator>(I.getOperand(1));
2935 // SelectInsts must have the same FMF.
2936 if (((SI0FOp == nullptr) != (SI1FOp == nullptr)) ||
2937 ((SI0FOp != nullptr) &&
2938 (SI0FOp->getFastMathFlags() != SI1FOp->getFastMathFlags())))
2939 return false;
2940
2941 auto *SrcVecTy = cast<FixedVectorType>(T1->getType());
2942 auto *DstVecTy = cast<FixedVectorType>(I.getType());
2944 auto SelOp = Instruction::Select;
2945
2947 SelOp, SrcVecTy, C1VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2949 SelOp, SrcVecTy, C2VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2950
2951 InstructionCost OldCost =
2952 CostSel1 + CostSel2 +
2953 TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0, nullptr,
2954 {I.getOperand(0), I.getOperand(1)}, &I);
2955
2957 SK, FixedVectorType::get(C1VecTy->getScalarType(), Mask.size()), C1VecTy,
2958 CostKind, Mask, 0, nullptr, {C1, C2});
2959 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0,
2960 nullptr, {T1, T2});
2961 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0,
2962 nullptr, {F1, F2});
2963 auto *C1C2ShuffledVecTy = FixedVectorType::get(
2964 Type::getInt1Ty(I.getContext()), DstVecTy->getNumElements());
2965 NewCost += TTI.getCmpSelInstrCost(SelOp, DstVecTy, C1C2ShuffledVecTy,
2967
2968 if (!Sel1->hasOneUse())
2969 NewCost += CostSel1;
2970 if (!Sel2->hasOneUse())
2971 NewCost += CostSel2;
2972
2973 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two selects: " << I
2974 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2975 << "\n");
2976 if (NewCost > OldCost)
2977 return false;
2978
2979 Value *ShuffleCmp = Builder.CreateShuffleVector(C1, C2, Mask);
2980 Value *ShuffleTrue = Builder.CreateShuffleVector(T1, T2, Mask);
2981 Value *ShuffleFalse = Builder.CreateShuffleVector(F1, F2, Mask);
2982 Value *NewSel;
2983 // We presuppose that the SelectInsts have the same FMF.
2984 if (SI0FOp)
2985 NewSel = Builder.CreateSelectFMF(ShuffleCmp, ShuffleTrue, ShuffleFalse,
2986 SI0FOp->getFastMathFlags());
2987 else
2988 NewSel = Builder.CreateSelect(ShuffleCmp, ShuffleTrue, ShuffleFalse);
2989
2990 Worklist.pushValue(ShuffleCmp);
2991 Worklist.pushValue(ShuffleTrue);
2992 Worklist.pushValue(ShuffleFalse);
2993 replaceValue(I, *NewSel);
2994 return true;
2995}
2996
2997/// Try to convert "shuffle (castop), (castop)" with a shared castop operand
2998/// into "castop (shuffle)".
2999bool VectorCombine::foldShuffleOfCastops(Instruction &I) {
3000 Value *V0, *V1;
3001 ArrayRef<int> OldMask;
3002 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
3003 return false;
3004
3005 // Check whether this is a binary shuffle.
3006 bool IsBinaryShuffle = !isa<UndefValue>(V1);
3007
3008 auto *C0 = dyn_cast<CastInst>(V0);
3009 auto *C1 = dyn_cast<CastInst>(V1);
3010 if (!C0 || (IsBinaryShuffle && !C1))
3011 return false;
3012
3013 Instruction::CastOps Opcode = C0->getOpcode();
3014
3015 // If this is allowed, foldShuffleOfCastops can get stuck in a loop
3016 // with foldBitcastOfShuffle. Reject in favor of foldBitcastOfShuffle.
3017 if (!IsBinaryShuffle && Opcode == Instruction::BitCast)
3018 return false;
3019
3020 if (IsBinaryShuffle) {
3021 if (C0->getSrcTy() != C1->getSrcTy())
3022 return false;
3023 // Handle shuffle(zext_nneg(x), sext(y)) -> sext(shuffle(x,y)) folds.
3024 if (Opcode != C1->getOpcode()) {
3025 if (match(C0, m_SExtLike(m_Value())) && match(C1, m_SExtLike(m_Value())))
3026 Opcode = Instruction::SExt;
3027 else
3028 return false;
3029 }
3030 }
3031
3032 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3033 auto *CastDstTy = dyn_cast<FixedVectorType>(C0->getDestTy());
3034 auto *CastSrcTy = dyn_cast<FixedVectorType>(C0->getSrcTy());
3035 if (!ShuffleDstTy || !CastDstTy || !CastSrcTy)
3036 return false;
3037
3038 unsigned NumSrcElts = CastSrcTy->getNumElements();
3039 unsigned NumDstElts = CastDstTy->getNumElements();
3040 assert((NumDstElts == NumSrcElts || Opcode == Instruction::BitCast) &&
3041 "Only bitcasts expected to alter src/dst element counts");
3042
3043 // Check for bitcasting of unscalable vector types.
3044 // e.g. <32 x i40> -> <40 x i32>
3045 if (NumDstElts != NumSrcElts && (NumSrcElts % NumDstElts) != 0 &&
3046 (NumDstElts % NumSrcElts) != 0)
3047 return false;
3048
3049 SmallVector<int, 16> NewMask;
3050 if (NumSrcElts >= NumDstElts) {
3051 // The bitcast is from wide to narrow/equal elements. The shuffle mask can
3052 // always be expanded to the equivalent form choosing narrower elements.
3053 assert(NumSrcElts % NumDstElts == 0 && "Unexpected shuffle mask");
3054 unsigned ScaleFactor = NumSrcElts / NumDstElts;
3055 narrowShuffleMaskElts(ScaleFactor, OldMask, NewMask);
3056 } else {
3057 // The bitcast is from narrow elements to wide elements. The shuffle mask
3058 // must choose consecutive elements to allow casting first.
3059 assert(NumDstElts % NumSrcElts == 0 && "Unexpected shuffle mask");
3060 unsigned ScaleFactor = NumDstElts / NumSrcElts;
3061 if (!widenShuffleMaskElts(ScaleFactor, OldMask, NewMask))
3062 return false;
3063 }
3064
3065 auto *NewShuffleDstTy =
3066 FixedVectorType::get(CastSrcTy->getScalarType(), NewMask.size());
3067
3068 // Try to replace a castop with a shuffle if the shuffle is not costly.
3069 InstructionCost CostC0 =
3070 TTI.getCastInstrCost(C0->getOpcode(), CastDstTy, CastSrcTy,
3072
3074 if (IsBinaryShuffle)
3076 else
3078
3079 InstructionCost OldCost = CostC0;
3080 OldCost += TTI.getShuffleCost(ShuffleKind, ShuffleDstTy, CastDstTy, CostKind,
3081 OldMask, 0, nullptr, {}, &I);
3082
3083 InstructionCost NewCost = TTI.getShuffleCost(ShuffleKind, NewShuffleDstTy,
3084 CastSrcTy, CostKind, NewMask);
3085 NewCost += TTI.getCastInstrCost(Opcode, ShuffleDstTy, NewShuffleDstTy,
3087 if (!C0->hasOneUse())
3088 NewCost += CostC0;
3089 if (IsBinaryShuffle) {
3090 InstructionCost CostC1 =
3091 TTI.getCastInstrCost(C1->getOpcode(), CastDstTy, CastSrcTy,
3093 OldCost += CostC1;
3094 if (!C1->hasOneUse())
3095 NewCost += CostC1;
3096 }
3097
3098 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two casts: " << I
3099 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3100 << "\n");
3101 if (NewCost > OldCost)
3102 return false;
3103
3104 Value *Shuf;
3105 if (IsBinaryShuffle)
3106 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), C1->getOperand(0),
3107 NewMask);
3108 else
3109 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), NewMask);
3110
3111 Value *Cast = Builder.CreateCast(Opcode, Shuf, ShuffleDstTy);
3112
3113 // Intersect flags from the old casts.
3114 if (auto *NewInst = dyn_cast<Instruction>(Cast)) {
3115 NewInst->copyIRFlags(C0);
3116 if (IsBinaryShuffle)
3117 NewInst->andIRFlags(C1);
3118 }
3119
3120 Worklist.pushValue(Shuf);
3121 replaceValue(I, *Cast);
3122 return true;
3123}
3124
3125/// Try to convert any of:
3126/// "shuffle (shuffle x, y), (shuffle y, x)"
3127/// "shuffle (shuffle x, undef), (shuffle y, undef)"
3128/// "shuffle (shuffle x, undef), y"
3129/// "shuffle x, (shuffle y, undef)"
3130/// into "shuffle x, y".
3131bool VectorCombine::foldShuffleOfShuffles(Instruction &I) {
3132 ArrayRef<int> OuterMask;
3133 Value *OuterV0, *OuterV1;
3134 if (!match(&I,
3135 m_Shuffle(m_Value(OuterV0), m_Value(OuterV1), m_Mask(OuterMask))))
3136 return false;
3137
3138 ArrayRef<int> InnerMask0, InnerMask1;
3139 Value *X0, *X1, *Y0, *Y1;
3140 bool Match0 =
3141 match(OuterV0, m_Shuffle(m_Value(X0), m_Value(Y0), m_Mask(InnerMask0)));
3142 bool Match1 =
3143 match(OuterV1, m_Shuffle(m_Value(X1), m_Value(Y1), m_Mask(InnerMask1)));
3144 if (!Match0 && !Match1)
3145 return false;
3146
3147 // If the outer shuffle is a permute, then create a fake inner all-poison
3148 // shuffle. This is easier than accounting for length-changing shuffles below.
3149 SmallVector<int, 16> PoisonMask1;
3150 if (!Match1 && isa<PoisonValue>(OuterV1)) {
3151 X1 = X0;
3152 Y1 = Y0;
3153 PoisonMask1.append(InnerMask0.size(), PoisonMaskElem);
3154 InnerMask1 = PoisonMask1;
3155 Match1 = true; // fake match
3156 }
3157
3158 X0 = Match0 ? X0 : OuterV0;
3159 Y0 = Match0 ? Y0 : OuterV0;
3160 X1 = Match1 ? X1 : OuterV1;
3161 Y1 = Match1 ? Y1 : OuterV1;
3162 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3163 auto *ShuffleSrcTy = dyn_cast<FixedVectorType>(X0->getType());
3164 auto *ShuffleImmTy = dyn_cast<FixedVectorType>(OuterV0->getType());
3165 if (!ShuffleDstTy || !ShuffleSrcTy || !ShuffleImmTy ||
3166 X0->getType() != X1->getType())
3167 return false;
3168
3169 unsigned NumSrcElts = ShuffleSrcTy->getNumElements();
3170 unsigned NumImmElts = ShuffleImmTy->getNumElements();
3171
3172 // Attempt to merge shuffles, matching upto 2 source operands.
3173 // Replace index to a poison arg with PoisonMaskElem.
3174 // Bail if either inner masks reference an undef arg.
3175 SmallVector<int, 16> NewMask(OuterMask);
3176 Value *NewX = nullptr, *NewY = nullptr;
3177 for (int &M : NewMask) {
3178 Value *Src = nullptr;
3179 if (0 <= M && M < (int)NumImmElts) {
3180 Src = OuterV0;
3181 if (Match0) {
3182 M = InnerMask0[M];
3183 Src = M >= (int)NumSrcElts ? Y0 : X0;
3184 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3185 }
3186 } else if (M >= (int)NumImmElts) {
3187 Src = OuterV1;
3188 M -= NumImmElts;
3189 if (Match1) {
3190 M = InnerMask1[M];
3191 Src = M >= (int)NumSrcElts ? Y1 : X1;
3192 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3193 }
3194 }
3195 if (Src && M != PoisonMaskElem) {
3196 assert(0 <= M && M < (int)NumSrcElts && "Unexpected shuffle mask index");
3197 if (isa<UndefValue>(Src)) {
3198 // We've referenced an undef element - if its poison, update the shuffle
3199 // mask, else bail.
3200 if (!isa<PoisonValue>(Src))
3201 return false;
3202 M = PoisonMaskElem;
3203 continue;
3204 }
3205 if (!NewX || NewX == Src) {
3206 NewX = Src;
3207 continue;
3208 }
3209 if (!NewY || NewY == Src) {
3210 M += NumSrcElts;
3211 NewY = Src;
3212 continue;
3213 }
3214 return false;
3215 }
3216 }
3217
3218 if (!NewX) {
3219 replaceValue(I, *PoisonValue::get(ShuffleDstTy));
3220 return true;
3221 }
3222
3223 if (!NewY)
3224 NewY = PoisonValue::get(ShuffleSrcTy);
3225
3226 // Have we folded to an Identity shuffle?
3227 if (ShuffleVectorInst::isIdentityMask(NewMask, NumSrcElts)) {
3228 replaceValue(I, *NewX);
3229 return true;
3230 }
3231
3232 // Try to merge the shuffles if the new shuffle is not costly.
3233 InstructionCost InnerCost0 = 0;
3234 if (Match0)
3235 InnerCost0 = TTI.getInstructionCost(cast<User>(OuterV0), CostKind);
3236
3237 InstructionCost InnerCost1 = 0;
3238 if (Match1)
3239 InnerCost1 = TTI.getInstructionCost(cast<User>(OuterV1), CostKind);
3240
3242
3243 InstructionCost OldCost = InnerCost0 + InnerCost1 + OuterCost;
3244
3245 bool IsUnary = all_of(NewMask, [&](int M) { return M < (int)NumSrcElts; });
3249 InstructionCost NewCost =
3250 TTI.getShuffleCost(SK, ShuffleDstTy, ShuffleSrcTy, CostKind, NewMask, 0,
3251 nullptr, {NewX, NewY});
3252 if (!OuterV0->hasOneUse())
3253 NewCost += InnerCost0;
3254 if (!OuterV1->hasOneUse())
3255 NewCost += InnerCost1;
3256
3257 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two shuffles: " << I
3258 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3259 << "\n");
3260 if (NewCost > OldCost)
3261 return false;
3262
3263 Value *Shuf = Builder.CreateShuffleVector(NewX, NewY, NewMask);
3264 replaceValue(I, *Shuf);
3265 return true;
3266}
3267
3268/// Try to convert a chain of length-preserving shuffles that are fed by
3269/// length-changing shuffles from the same source, e.g. a chain of length 3:
3270///
3271/// "shuffle (shuffle (shuffle x, (shuffle y, undef)),
3272/// (shuffle y, undef)),
3273// (shuffle y, undef)"
3274///
3275/// into a single shuffle fed by a length-changing shuffle:
3276///
3277/// "shuffle x, (shuffle y, undef)"
3278///
3279/// Such chains arise e.g. from folding extract/insert sequences.
3280bool VectorCombine::foldShufflesOfLengthChangingShuffles(Instruction &I) {
3281 FixedVectorType *TrunkType = dyn_cast<FixedVectorType>(I.getType());
3282 if (!TrunkType)
3283 return false;
3284
3285 unsigned ChainLength = 0;
3286 SmallVector<int> Mask;
3287 SmallVector<int> YMask;
3288 InstructionCost OldCost = 0;
3289 InstructionCost NewCost = 0;
3290 Value *Trunk = &I;
3291 unsigned NumTrunkElts = TrunkType->getNumElements();
3292 Value *Y = nullptr;
3293
3294 for (;;) {
3295 // Match the current trunk against (commutations of) the pattern
3296 // "shuffle trunk', (shuffle y, undef)"
3297 ArrayRef<int> OuterMask;
3298 Value *OuterV0, *OuterV1;
3299 if (ChainLength != 0 && !Trunk->hasOneUse())
3300 break;
3301 if (!match(Trunk, m_Shuffle(m_Value(OuterV0), m_Value(OuterV1),
3302 m_Mask(OuterMask))))
3303 break;
3304 if (OuterV0->getType() != TrunkType) {
3305 // This shuffle is not length-preserving, so it cannot be part of the
3306 // chain.
3307 break;
3308 }
3309
3310 ArrayRef<int> InnerMask0, InnerMask1;
3311 Value *A0, *A1, *B0, *B1;
3312 bool Match0 =
3313 match(OuterV0, m_Shuffle(m_Value(A0), m_Value(B0), m_Mask(InnerMask0)));
3314 bool Match1 =
3315 match(OuterV1, m_Shuffle(m_Value(A1), m_Value(B1), m_Mask(InnerMask1)));
3316 bool Match0Leaf = Match0 && A0->getType() != I.getType();
3317 bool Match1Leaf = Match1 && A1->getType() != I.getType();
3318 if (Match0Leaf == Match1Leaf) {
3319 // Only handle the case of exactly one leaf in each step. The "two leaves"
3320 // case is handled by foldShuffleOfShuffles.
3321 break;
3322 }
3323
3324 SmallVector<int> CommutedOuterMask;
3325 if (Match0Leaf) {
3326 std::swap(OuterV0, OuterV1);
3327 std::swap(InnerMask0, InnerMask1);
3328 std::swap(A0, A1);
3329 std::swap(B0, B1);
3330 llvm::append_range(CommutedOuterMask, OuterMask);
3331 for (int &M : CommutedOuterMask) {
3332 if (M == PoisonMaskElem)
3333 continue;
3334 if (M < (int)NumTrunkElts)
3335 M += NumTrunkElts;
3336 else
3337 M -= NumTrunkElts;
3338 }
3339 OuterMask = CommutedOuterMask;
3340 }
3341 if (!OuterV1->hasOneUse())
3342 break;
3343
3344 if (!isa<UndefValue>(A1)) {
3345 if (!Y)
3346 Y = A1;
3347 else if (Y != A1)
3348 break;
3349 }
3350 if (!isa<UndefValue>(B1)) {
3351 if (!Y)
3352 Y = B1;
3353 else if (Y != B1)
3354 break;
3355 }
3356
3357 auto *YType = cast<FixedVectorType>(A1->getType());
3358 int NumLeafElts = YType->getNumElements();
3359 SmallVector<int> LocalYMask(InnerMask1);
3360 for (int &M : LocalYMask) {
3361 if (M >= NumLeafElts)
3362 M -= NumLeafElts;
3363 }
3364
3365 InstructionCost LocalOldCost =
3368
3369 // Handle the initial (start of chain) case.
3370 if (!ChainLength) {
3371 Mask.assign(OuterMask);
3372 YMask.assign(LocalYMask);
3373 OldCost = NewCost = LocalOldCost;
3374 Trunk = OuterV0;
3375 ChainLength++;
3376 continue;
3377 }
3378
3379 // For the non-root case, first attempt to combine masks.
3380 SmallVector<int> NewYMask(YMask);
3381 bool Valid = true;
3382 for (auto [CombinedM, LeafM] : llvm::zip(NewYMask, LocalYMask)) {
3383 if (LeafM == -1 || CombinedM == LeafM)
3384 continue;
3385 if (CombinedM == -1) {
3386 CombinedM = LeafM;
3387 } else {
3388 Valid = false;
3389 break;
3390 }
3391 }
3392 if (!Valid)
3393 break;
3394
3395 SmallVector<int> NewMask;
3396 NewMask.reserve(NumTrunkElts);
3397 for (int M : Mask) {
3398 if (M < 0 || M >= static_cast<int>(NumTrunkElts))
3399 NewMask.push_back(M);
3400 else
3401 NewMask.push_back(OuterMask[M]);
3402 }
3403
3404 // Break the chain if adding this new step complicates the shuffles such
3405 // that it would increase the new cost by more than the old cost of this
3406 // step.
3407 InstructionCost LocalNewCost =
3409 YType, CostKind, NewYMask) +
3411 TrunkType, CostKind, NewMask);
3412
3413 if (LocalNewCost >= NewCost && LocalOldCost < LocalNewCost - NewCost)
3414 break;
3415
3416 LLVM_DEBUG({
3417 if (ChainLength == 1) {
3418 dbgs() << "Found chain of shuffles fed by length-changing shuffles: "
3419 << I << '\n';
3420 }
3421 dbgs() << " next chain link: " << *Trunk << '\n'
3422 << " old cost: " << (OldCost + LocalOldCost)
3423 << " new cost: " << LocalNewCost << '\n';
3424 });
3425
3426 Mask = NewMask;
3427 YMask = NewYMask;
3428 OldCost += LocalOldCost;
3429 NewCost = LocalNewCost;
3430 Trunk = OuterV0;
3431 ChainLength++;
3432 }
3433 if (ChainLength <= 1)
3434 return false;
3435
3436 // Bail out if all leaves were poison.
3437 if (!Y)
3438 return false;
3439
3440 if (llvm::all_of(Mask, [&](int M) {
3441 return M < 0 || M >= static_cast<int>(NumTrunkElts);
3442 })) {
3443 // Produce a canonical simplified form if all elements are sourced from Y.
3444 for (int &M : Mask) {
3445 if (M >= static_cast<int>(NumTrunkElts))
3446 M = YMask[M - NumTrunkElts];
3447 }
3448 Value *Root =
3449 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), Mask);
3450 replaceValue(I, *Root);
3451 return true;
3452 }
3453
3454 Value *Leaf =
3455 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), YMask);
3456 Value *Root = Builder.CreateShuffleVector(Trunk, Leaf, Mask);
3457 replaceValue(I, *Root);
3458 return true;
3459}
3460
3461/// Try to convert
3462/// "shuffle (intrinsic), (intrinsic)" into "intrinsic (shuffle), (shuffle)".
3463bool VectorCombine::foldShuffleOfIntrinsics(Instruction &I) {
3464 Value *V0, *V1;
3465 ArrayRef<int> OldMask;
3466 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
3467 return false;
3468
3469 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3470 auto *II1 = dyn_cast<IntrinsicInst>(V1);
3471 if (!II0 || !II1)
3472 return false;
3473
3474 Intrinsic::ID IID = II0->getIntrinsicID();
3475 if (IID != II1->getIntrinsicID())
3476 return false;
3477 InstructionCost CostII0 =
3478 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3479 InstructionCost CostII1 =
3480 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II1), CostKind);
3481
3482 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3483 auto *II0Ty = dyn_cast<FixedVectorType>(II0->getType());
3484 if (!ShuffleDstTy || !II0Ty)
3485 return false;
3486
3487 if (!isTriviallyVectorizable(IID))
3488 return false;
3489
3490 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3491 Value *Arg0 = II0->getArgOperand(Idx);
3492 Value *Arg1 = II1->getArgOperand(Idx);
3493 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3494 // Scalar operands must be identical.
3495 if (Arg0 != Arg1)
3496 return false;
3497 } else if (Arg0->getType() != Arg1->getType()) {
3498 // The corresponding vector operands are shuffled together, so they must
3499 // share the same type. For intrinsics overloaded on their operand type
3500 // (e.g. llvm.fptosi.sat), two calls can produce the same result type
3501 // from different operand types; shuffling those would be invalid.
3502 return false;
3503 }
3504 }
3505
3506 InstructionCost OldCost =
3507 CostII0 + CostII1 +
3509 II0Ty, CostKind, OldMask, 0, nullptr, {II0, II1}, &I);
3510
3511 SmallVector<Type *> NewArgsTy;
3512 InstructionCost NewCost = 0;
3513 SmallDenseSet<std::pair<Value *, Value *>> SeenOperandPairs;
3514 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3515 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3516 NewArgsTy.push_back(II0->getArgOperand(Idx)->getType());
3517 } else {
3518 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(Idx)->getType());
3519 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3520 ShuffleDstTy->getNumElements());
3521 NewArgsTy.push_back(ArgTy);
3522 std::pair<Value *, Value *> OperandPair =
3523 std::make_pair(II0->getArgOperand(Idx), II1->getArgOperand(Idx));
3524 if (!SeenOperandPairs.insert(OperandPair).second) {
3525 // We've already computed the cost for this operand pair.
3526 continue;
3527 }
3528 NewCost += TTI.getShuffleCost(
3530 OldMask, 0, nullptr,
3531 {II0->getArgOperand(Idx), II1->getArgOperand(Idx)});
3532 }
3533 }
3534 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3535
3536 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3537 if (!II0->hasOneUse())
3538 NewCost += CostII0;
3539 if (II1 != II0 && !II1->hasOneUse())
3540 NewCost += CostII1;
3541
3542 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two intrinsics: " << I
3543 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3544 << "\n");
3545
3546 if (NewCost > OldCost)
3547 return false;
3548
3549 SmallVector<Value *> NewArgs;
3550 SmallDenseMap<std::pair<Value *, Value *>, Value *> ShuffleCache;
3551 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3552 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3553 NewArgs.push_back(II0->getArgOperand(Idx));
3554 } else {
3555 std::pair<Value *, Value *> OperandPair =
3556 std::make_pair(II0->getArgOperand(Idx), II1->getArgOperand(Idx));
3557 auto It = ShuffleCache.find(OperandPair);
3558 if (It != ShuffleCache.end()) {
3559 // Reuse previously created shuffle for this operand pair.
3560 NewArgs.push_back(It->second);
3561 continue;
3562 }
3563 Value *Shuf = Builder.CreateShuffleVector(
3564 II0->getArgOperand(Idx), II1->getArgOperand(Idx), OldMask);
3565 ShuffleCache[OperandPair] = Shuf;
3566 NewArgs.push_back(Shuf);
3567 Worklist.pushValue(Shuf);
3568 }
3569 }
3570 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3571
3572 // Intersect flags from the old intrinsics.
3573 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic)) {
3574 NewInst->copyIRFlags(II0);
3575 NewInst->andIRFlags(II1);
3576 }
3577
3578 replaceValue(I, *NewIntrinsic);
3579 return true;
3580}
3581
3582/// Try to convert
3583/// "shuffle (intrinsic), (poison/undef)" into "intrinsic (shuffle)".
3584bool VectorCombine::foldPermuteOfIntrinsic(Instruction &I) {
3585 Value *V0;
3586 ArrayRef<int> Mask;
3587 if (!match(&I, m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask))))
3588 return false;
3589
3590 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3591 if (!II0)
3592 return false;
3593
3594 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3595 auto *IntrinsicSrcTy = dyn_cast<FixedVectorType>(II0->getType());
3596 if (!ShuffleDstTy || !IntrinsicSrcTy)
3597 return false;
3598
3599 // Validate it's a pure permute, mask should only reference the first vector
3600 unsigned NumSrcElts = IntrinsicSrcTy->getNumElements();
3601 if (any_of(Mask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
3602 return false;
3603
3604 Intrinsic::ID IID = II0->getIntrinsicID();
3605 if (!isTriviallyVectorizable(IID))
3606 return false;
3607
3608 // Cost analysis
3610 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3611 InstructionCost OldCost =
3614 IntrinsicSrcTy, CostKind, Mask, 0, nullptr, {V0}, &I);
3615
3616 SmallVector<Type *> NewArgsTy;
3617 InstructionCost NewCost = 0;
3618 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3620 NewArgsTy.push_back(II0->getArgOperand(I)->getType());
3621 } else {
3622 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(I)->getType());
3623 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3624 ShuffleDstTy->getNumElements());
3625 NewArgsTy.push_back(ArgTy);
3627 ArgTy, VecTy, CostKind, Mask, 0, nullptr,
3628 {II0->getArgOperand(I)});
3629 }
3630 }
3631 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3632 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3633
3634 // If the intrinsic has multiple uses, we need to account for the cost of
3635 // keeping the original intrinsic around.
3636 if (!II0->hasOneUse())
3637 NewCost += IntrinsicCost;
3638
3639 LLVM_DEBUG(dbgs() << "Found a permute of intrinsic: " << I << "\n OldCost: "
3640 << OldCost << " vs NewCost: " << NewCost << "\n");
3641
3642 if (NewCost > OldCost)
3643 return false;
3644
3645 // Transform
3646 SmallVector<Value *> NewArgs;
3647 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3649 NewArgs.push_back(II0->getArgOperand(I));
3650 } else {
3651 Value *Shuf = Builder.CreateShuffleVector(II0->getArgOperand(I), Mask);
3652 NewArgs.push_back(Shuf);
3653 Worklist.pushValue(Shuf);
3654 }
3655 }
3656
3657 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3658
3659 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic))
3660 NewInst->copyIRFlags(II0);
3661
3662 replaceValue(I, *NewIntrinsic);
3663 return true;
3664}
3665
3666using InstLane = std::pair<Value *, int>;
3667
3668static InstLane lookThroughShuffles(Value *V, int Lane) {
3669 while (auto *SV = dyn_cast<ShuffleVectorInst>(V)) {
3670 unsigned NumElts =
3671 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
3672 int M = SV->getMaskValue(Lane);
3673 if (M < 0)
3674 return {nullptr, PoisonMaskElem};
3675 if (static_cast<unsigned>(M) < NumElts) {
3676 V = SV->getOperand(0);
3677 Lane = M;
3678 } else {
3679 V = SV->getOperand(1);
3680 Lane = M - NumElts;
3681 }
3682 }
3683 return InstLane{V, Lane};
3684}
3685
3689 for (InstLane IL : Item) {
3690 auto [U, Lane] = IL;
3691 InstLane OpLane =
3692 U ? lookThroughShuffles(cast<Instruction>(U)->getOperand(Op), Lane)
3693 : InstLane{nullptr, PoisonMaskElem};
3694 NItem.emplace_back(OpLane);
3695 }
3696 return NItem;
3697}
3698
3699/// Detect concat of multiple values into a vector
3701 const TargetTransformInfo &TTI) {
3702 auto *Ty = cast<FixedVectorType>(Item.front().first->getType());
3703 unsigned NumElts = Ty->getNumElements();
3704 if (Item.size() == NumElts || NumElts == 1 || Item.size() % NumElts != 0)
3705 return false;
3706
3707 // Check that the concat is free, usually meaning that the type will be split
3708 // during legalization.
3709 SmallVector<int, 16> ConcatMask(NumElts * 2);
3710 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
3711 if (TTI.getShuffleCost(TTI::SK_PermuteTwoSrc,
3712 FixedVectorType::get(Ty->getScalarType(), NumElts * 2),
3713 Ty, CostKind, ConcatMask) != 0)
3714 return false;
3715
3716 unsigned NumSlices = Item.size() / NumElts;
3717 // Currently we generate a tree of shuffles for the concats, which limits us
3718 // to a power2.
3719 if (!isPowerOf2_32(NumSlices))
3720 return false;
3721 for (unsigned Slice = 0; Slice < NumSlices; ++Slice) {
3722 Value *SliceV = Item[Slice * NumElts].first;
3723 if (!SliceV || SliceV->getType() != Ty)
3724 return false;
3725 for (unsigned Elt = 0; Elt < NumElts; ++Elt) {
3726 auto [V, Lane] = Item[Slice * NumElts + Elt];
3727 if (Lane != static_cast<int>(Elt) || SliceV != V)
3728 return false;
3729 }
3730 }
3731 return true;
3732}
3733
3734static Value *
3736 const DenseSet<std::pair<Value *, Use *>> &IdentityLeafs,
3737 const DenseSet<std::pair<Value *, Use *>> &SplatLeafs,
3738 const DenseSet<std::pair<Value *, Use *>> &ConcatLeafs,
3739 IRBuilderBase &Builder, InstructionWorklist &WorkList,
3740 const TargetTransformInfo *TTI) {
3741 auto [FrontV, FrontLane] = Item.front();
3742
3743 if (IdentityLeafs.contains(std::make_pair(FrontV, From))) {
3744 return FrontV;
3745 }
3746 if (SplatLeafs.contains(std::make_pair(FrontV, From))) {
3747 SmallVector<int, 16> Mask(Item.size(), FrontLane);
3748 return Builder.CreateShuffleVector(FrontV, Mask);
3749 }
3750 if (ConcatLeafs.contains(std::make_pair(FrontV, From))) {
3751 unsigned NumElts =
3752 cast<FixedVectorType>(FrontV->getType())->getNumElements();
3753 SmallVector<Value *> Values(Item.size() / NumElts, nullptr);
3754 for (unsigned S = 0; S < Values.size(); ++S)
3755 Values[S] = Item[S * NumElts].first;
3756
3757 while (Values.size() > 1) {
3758 NumElts *= 2;
3759 SmallVector<int, 16> Mask(NumElts, 0);
3760 std::iota(Mask.begin(), Mask.end(), 0);
3761 SmallVector<Value *> NewValues(Values.size() / 2, nullptr);
3762 for (unsigned S = 0; S < NewValues.size(); ++S)
3763 NewValues[S] =
3764 Builder.CreateShuffleVector(Values[S * 2], Values[S * 2 + 1], Mask);
3765 Values = NewValues;
3766 }
3767 return Values[0];
3768 }
3769
3770 auto *I = cast<Instruction>(FrontV);
3771
3772 // Handle vector bitcasts that change element count. We cannot use
3773 // generateInstLaneVectorFromOperand for these because the lane indices
3774 // don't map 1:1 through the bitcast.
3775 if (auto *BitCast = dyn_cast<BitCastInst>(I)) {
3776 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3777 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3778 if (BCDstTy && BCSrcTy &&
3779 BCDstTy->getElementCount() != BCSrcTy->getElementCount()) {
3780 unsigned DstElts = BCDstTy->getNumElements();
3781 unsigned SrcElts = BCSrcTy->getNumElements();
3782 SmallVector<InstLane> NewItem;
3783 if (DstElts > SrcElts) {
3784 // Widening: compress operand Item.
3785 unsigned R = DstElts / SrcElts;
3786 if (Item.size() % R != 0)
3787 return nullptr;
3788 for (unsigned Idx = 0, E = Item.size(); Idx < E; Idx += R) {
3789 auto [V, Lane] = Item[Idx];
3790 if (!V) {
3791 NewItem.push_back({nullptr, PoisonMaskElem});
3792 continue;
3793 }
3794 NewItem.push_back(
3795 lookThroughShuffles(cast<Operator>(V)->getOperand(0), Lane / R));
3796 }
3797 } else {
3798 // Narrowing: expand operand Item.
3799 unsigned R = SrcElts / DstElts;
3800 for (auto [V, Lane] : Item) {
3801 if (!V) {
3802 NewItem.append(R, {nullptr, PoisonMaskElem});
3803 continue;
3804 }
3805 Value *Op = cast<Operator>(V)->getOperand(0);
3806 for (unsigned J = 0; J < R; ++J)
3807 NewItem.push_back(lookThroughShuffles(Op, Lane * R + J));
3808 }
3809 }
3810 Value *Op = generateNewInstTree(NewItem, &BitCast->getOperandUse(0),
3811 IdentityLeafs, SplatLeafs, ConcatLeafs,
3812 Builder, WorkList, TTI);
3813 WorkList.pushValue(Op);
3814 return Builder.CreateBitCast(
3815 Op, FixedVectorType::get(BCDstTy->getScalarType(), Item.size()));
3816 }
3817 }
3818 auto *II = dyn_cast<IntrinsicInst>(I);
3819 unsigned NumOps = I->getNumOperands() - (II ? 1 : 0);
3821 for (unsigned Idx = 0; Idx < NumOps; Idx++) {
3822 if (II &&
3823 isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Idx, TTI)) {
3824 Ops[Idx] = II->getOperand(Idx);
3825 continue;
3826 }
3827 Ops[Idx] = generateNewInstTree(
3828 generateInstLaneVectorFromOperand(Item, Idx), &I->getOperandUse(Idx),
3829 IdentityLeafs, SplatLeafs, ConcatLeafs, Builder, WorkList, TTI);
3830 // Don't re-queue the operand of a bitcast we just regenerated. Doing so
3831 // lets foldBitcastShuffle sink the bitcast back into a shuffle(bitcast),
3832 // which foldShuffleToIdentity then re-matches as the same superfluous
3833 // identity - an infinite loop between the two folds.
3834 if (!isa<BitCastInst>(I))
3835 WorkList.pushValue(Ops[Idx]);
3836 }
3837
3838 SmallVector<Value *, 8> ValueList;
3839 for (const auto &Lane : Item)
3840 if (Lane.first)
3841 ValueList.push_back(Lane.first);
3842
3843 Type *DstTy =
3844 FixedVectorType::get(I->getType()->getScalarType(), Item.size());
3845 if (auto *BI = dyn_cast<BinaryOperator>(I)) {
3846 auto *Value = Builder.CreateBinOp((Instruction::BinaryOps)BI->getOpcode(),
3847 Ops[0], Ops[1]);
3848 propagateIRFlags(Value, ValueList);
3849 return Value;
3850 }
3851 if (auto *CI = dyn_cast<CmpInst>(I)) {
3852 auto *Value = Builder.CreateCmp(CI->getPredicate(), Ops[0], Ops[1]);
3853 propagateIRFlags(Value, ValueList);
3854 return Value;
3855 }
3856 if (auto *SI = dyn_cast<SelectInst>(I)) {
3857 auto *Value = Builder.CreateSelect(Ops[0], Ops[1], Ops[2], "", SI);
3858 propagateIRFlags(Value, ValueList);
3859 return Value;
3860 }
3861 if (auto *CI = dyn_cast<CastInst>(I)) {
3862 auto *Value = Builder.CreateCast(CI->getOpcode(), Ops[0], DstTy);
3863 propagateIRFlags(Value, ValueList);
3864 return Value;
3865 }
3866 if (II) {
3867 auto *Value = Builder.CreateIntrinsic(DstTy, II->getIntrinsicID(), Ops);
3868 propagateIRFlags(Value, ValueList);
3869 return Value;
3870 }
3871 assert(isa<UnaryInstruction>(I) && "Unexpected instruction type in Generate");
3872 auto *Value =
3873 Builder.CreateUnOp((Instruction::UnaryOps)I->getOpcode(), Ops[0]);
3874 propagateIRFlags(Value, ValueList);
3875 return Value;
3876}
3877
3878// Starting from a shuffle, look up through operands tracking the shuffled index
3879// of each lane. If we can simplify away the shuffles to identities then
3880// do so.
3881bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
3882 auto *Ty = dyn_cast<FixedVectorType>(I.getType());
3883 if (!Ty || I.use_empty())
3884 return false;
3885
3886 SmallVector<InstLane> Start(Ty->getNumElements());
3887 for (unsigned M = 0, E = Ty->getNumElements(); M < E; ++M)
3888 Start[M] = lookThroughShuffles(&I, M);
3889
3891 Candidates.push_back(std::make_pair(Start, &*I.use_begin()));
3892 DenseSet<std::pair<Value *, Use *>> IdentityLeafs, SplatLeafs, ConcatLeafs;
3893 unsigned NumVisited = 0;
3894 bool TraversedElCountChangingBitcast = false;
3895
3896 while (!Candidates.empty()) {
3897 if (++NumVisited > MaxInstrsToScan)
3898 return false;
3899
3900 auto ItemFrom = Candidates.pop_back_val();
3901 auto Item = ItemFrom.first;
3902 auto From = ItemFrom.second;
3903 auto [FrontV, FrontLane] = Item.front();
3904
3905 // If we found an undef first lane then bail out to keep things simple.
3906 if (!FrontV)
3907 return false;
3908
3909 // Look for an identity value.
3910 if (FrontLane == 0 &&
3911 cast<FixedVectorType>(FrontV->getType())->getNumElements() ==
3912 Item.size() &&
3913 all_of(drop_begin(enumerate(Item)), [Item](const auto &E) {
3914 Value *FrontV = Item.front().first;
3915 return !E.value().first || (isEquivBitcast(E.value().first, FrontV) &&
3916 E.value().second == (int)E.index());
3917 })) {
3918 IdentityLeafs.insert(std::make_pair(FrontV, From));
3919 continue;
3920 }
3921 // Look for constants, for the moment only supporting constant splats.
3922 if (auto *C = dyn_cast<Constant>(FrontV);
3923 C && C->getSplatValue() &&
3924 all_of(drop_begin(Item), [Item](InstLane &IL) {
3925 Value *FrontV = Item.front().first;
3926 Value *V = IL.first;
3927 return !V || (isa<Constant>(V) &&
3928 cast<Constant>(V)->getSplatValue() ==
3929 cast<Constant>(FrontV)->getSplatValue());
3930 })) {
3931 SplatLeafs.insert(std::make_pair(FrontV, From));
3932 continue;
3933 }
3934 // Look for a splat value.
3935 if (all_of(drop_begin(Item), [Item](InstLane &IL) {
3936 auto [FrontV, FrontLane] = Item.front();
3937 auto [V, Lane] = IL;
3938 return !V || (V == FrontV && Lane == FrontLane);
3939 })) {
3940 SplatLeafs.insert(std::make_pair(FrontV, From));
3941 continue;
3942 }
3943
3944 // We need each element to be the same type of value, and check that each
3945 // element has a single use.
3946 auto CheckLaneIsEquivalentToFirst = [Item](InstLane IL) {
3947 Value *FrontV = Item.front().first;
3948 if (!IL.first)
3949 return true;
3950 Value *V = IL.first;
3951 if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUser())
3952 return false;
3953 if (V->getValueID() != FrontV->getValueID())
3954 return false;
3955 if (auto *CI = dyn_cast<CmpInst>(V))
3956 if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
3957 return false;
3958 if (auto *CI = dyn_cast<CastInst>(V))
3959 if (CI->getSrcTy()->getScalarType() !=
3960 cast<CastInst>(FrontV)->getSrcTy()->getScalarType())
3961 return false;
3962 if (auto *SI = dyn_cast<SelectInst>(V))
3963 if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
3964 SI->getOperand(0)->getType() !=
3965 cast<SelectInst>(FrontV)->getOperand(0)->getType())
3966 return false;
3967 if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
3968 return false;
3969 auto *II = dyn_cast<IntrinsicInst>(V);
3970 return !II || (isa<IntrinsicInst>(FrontV) &&
3971 II->getIntrinsicID() ==
3972 cast<IntrinsicInst>(FrontV)->getIntrinsicID() &&
3973 !II->hasOperandBundles());
3974 };
3975 if (all_of(drop_begin(Item), CheckLaneIsEquivalentToFirst)) {
3976 // Check the operator is one that we support.
3977 if (isa<BinaryOperator, CmpInst>(FrontV)) {
3978 // We exclude div/rem in case they hit UB from poison lanes.
3979 if (auto *BO = dyn_cast<BinaryOperator>(FrontV);
3980 BO && BO->isIntDivRem())
3981 return false;
3983 &cast<Instruction>(FrontV)->getOperandUse(0));
3985 &cast<Instruction>(FrontV)->getOperandUse(1));
3986 continue;
3987 } else if (isa<UnaryOperator, TruncInst, ZExtInst, SExtInst, FPToSIInst,
3988 FPToUIInst, SIToFPInst, UIToFPInst>(FrontV)) {
3990 &cast<Instruction>(FrontV)->getOperandUse(0));
3991 continue;
3992 } else if (auto *BitCast = dyn_cast<BitCastInst>(FrontV)) {
3993 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3994 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3995 if (BCDstTy && BCSrcTy) {
3996 ElementCount DstEC = BCDstTy->getElementCount();
3997 ElementCount SrcEC = BCSrcTy->getElementCount();
3998 if (DstEC == SrcEC) {
3999 // Same element count - simple pass-through.
4001 &BitCast->getOperandUse(0));
4002 continue;
4003 }
4004 unsigned DstElts = DstEC.getFixedValue();
4005 unsigned SrcElts = SrcEC.getFixedValue();
4006 if (DstElts > SrcElts && DstElts % SrcElts == 0) {
4007 // Widening bitcast (e.g. <2 x i32> -> <4 x i16>). Compress
4008 // consecutive groups of R destination lanes into one source
4009 // lane.
4010 unsigned R = DstElts / SrcElts;
4012 bool Valid = Item.size() % R == 0;
4013 for (unsigned Idx = 0, E = Item.size(); Valid && Idx < E;
4014 Idx += R) {
4015 auto [V0, L0] = Item[Idx];
4016 if (!V0) {
4017 if (any_of(ArrayRef(Item).slice(Idx + 1, R - 1),
4018 [](InstLane IL) { return IL.first != nullptr; })) {
4019 Valid = false;
4020 break;
4021 }
4022 NItem.push_back({nullptr, PoisonMaskElem});
4023 continue;
4024 }
4025 if (L0 % R != 0) {
4026 Valid = false;
4027 break;
4028 }
4029 for (unsigned J = 1; J < R; ++J) {
4030 auto [VJ, LJ] = Item[Idx + J];
4031 if (!VJ || VJ != V0 || LJ != L0 + (int)J) {
4032 Valid = false;
4033 break;
4034 }
4035 }
4036 if (!Valid)
4037 break;
4039 cast<Operator>(V0)->getOperand(0), L0 / R));
4040 }
4041 if (Valid) {
4042 TraversedElCountChangingBitcast = true;
4043 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
4044 continue;
4045 }
4046 } else if (SrcElts > DstElts && SrcElts % DstElts == 0) {
4047 // Narrowing bitcast (e.g. <4 x i16> -> <2 x i32>). Expand
4048 // each destination lane into R source lanes.
4049 unsigned R = SrcElts / DstElts;
4051 for (auto [V, Lane] : Item) {
4052 if (!V) {
4053 NItem.append(R, {nullptr, PoisonMaskElem});
4054 continue;
4055 }
4056 Value *Op = cast<Operator>(V)->getOperand(0);
4057 for (unsigned J = 0; J < R; ++J)
4058 NItem.push_back(lookThroughShuffles(Op, Lane * R + J));
4059 }
4060 TraversedElCountChangingBitcast = true;
4061 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
4062 continue;
4063 }
4064 }
4065 } else if (auto *Sel = dyn_cast<SelectInst>(FrontV)) {
4067 &Sel->getOperandUse(0));
4069 &Sel->getOperandUse(1));
4071 &Sel->getOperandUse(2));
4072 continue;
4073 } else if (auto *II = dyn_cast<IntrinsicInst>(FrontV);
4074 II && isTriviallyVectorizable(II->getIntrinsicID()) &&
4075 !II->hasOperandBundles()) {
4076 for (unsigned Op = 0, E = II->getNumOperands() - 1; Op < E; Op++) {
4077 if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Op,
4078 &TTI)) {
4079 if (!all_of(drop_begin(Item), [Item, Op](InstLane &IL) {
4080 Value *FrontV = Item.front().first;
4081 Value *V = IL.first;
4082 return !V || (cast<Instruction>(V)->getOperand(Op) ==
4083 cast<Instruction>(FrontV)->getOperand(Op));
4084 }))
4085 return false;
4086 continue;
4087 }
4088 Candidates.emplace_back(
4090 &cast<Instruction>(FrontV)->getOperandUse(Op));
4091 }
4092 continue;
4093 }
4094 }
4095
4096 if (isFreeConcat(Item, CostKind, TTI)) {
4097 ConcatLeafs.insert(std::make_pair(FrontV, From));
4098 continue;
4099 }
4100
4101 return false;
4102 }
4103
4104 if (NumVisited <= 1)
4105 return false;
4106
4107 // If the only non-leaf node traversed was a single bitcast that changes
4108 // element count, the fold would just commute the bitcast and shuffle.
4109 // foldBitcastShuffle does the reverse transform, causing an infinite loop.
4110 if (NumVisited == 2 && TraversedElCountChangingBitcast)
4111 return false;
4112
4113 LLVM_DEBUG(dbgs() << "Found a superfluous identity shuffle: " << I << "\n");
4114
4115 // If we got this far, we know the shuffles are superfluous and can be
4116 // removed. Scan through again and generate the new tree of instructions.
4117 Builder.SetInsertPoint(&I);
4118 Value *V =
4119 generateNewInstTree(Start, &*I.use_begin(), IdentityLeafs, SplatLeafs,
4120 ConcatLeafs, Builder, Worklist, &TTI);
4121 replaceValue(I, *V);
4122 return true;
4123}
4124
4125/// Given a commutative reduction, the order of the input lanes does not alter
4126/// the results. We can use this to remove certain shuffles feeding the
4127/// reduction, removing the need to shuffle at all.
4128bool VectorCombine::foldShuffleFromReductions(Instruction &I) {
4129 auto *II = dyn_cast<IntrinsicInst>(&I);
4130 if (!II)
4131 return false;
4132 switch (II->getIntrinsicID()) {
4133 case Intrinsic::vector_reduce_add:
4134 case Intrinsic::vector_reduce_mul:
4135 case Intrinsic::vector_reduce_and:
4136 case Intrinsic::vector_reduce_or:
4137 case Intrinsic::vector_reduce_xor:
4138 case Intrinsic::vector_reduce_smin:
4139 case Intrinsic::vector_reduce_smax:
4140 case Intrinsic::vector_reduce_umin:
4141 case Intrinsic::vector_reduce_umax:
4142 break;
4143 default:
4144 return false;
4145 }
4146
4147 // Find all the inputs when looking through operations that do not alter the
4148 // lane order (binops, for example). Currently we look for a single shuffle,
4149 // and can ignore splat values.
4150 std::queue<Value *> Worklist;
4151 SmallPtrSet<Value *, 4> Visited;
4152 ShuffleVectorInst *Shuffle = nullptr;
4153 if (auto *Op = dyn_cast<Instruction>(I.getOperand(0)))
4154 Worklist.push(Op);
4155
4156 while (!Worklist.empty()) {
4157 Value *CV = Worklist.front();
4158 Worklist.pop();
4159 if (Visited.contains(CV))
4160 continue;
4161
4162 // Splats don't change the order, so can be safely ignored.
4163 if (isSplatValue(CV))
4164 continue;
4165
4166 Visited.insert(CV);
4167
4168 if (auto *CI = dyn_cast<Instruction>(CV)) {
4169 if (CI->isBinaryOp()) {
4170 for (auto *Op : CI->operand_values())
4171 Worklist.push(Op);
4172 continue;
4173 } else if (auto *SV = dyn_cast<ShuffleVectorInst>(CI)) {
4174 if (Shuffle && Shuffle != SV)
4175 return false;
4176 Shuffle = SV;
4177 continue;
4178 }
4179 }
4180
4181 // Anything else is currently an unknown node.
4182 return false;
4183 }
4184
4185 if (!Shuffle)
4186 return false;
4187
4188 // Check all uses of the binary ops and shuffles are also included in the
4189 // lane-invariant operations (Visited should be the list of lanewise
4190 // instructions, including the shuffle that we found).
4191 for (auto *V : Visited)
4192 for (auto *U : V->users())
4193 if (!Visited.contains(U) && U != &I)
4194 return false;
4195
4196 FixedVectorType *VecType =
4197 dyn_cast<FixedVectorType>(II->getOperand(0)->getType());
4198 if (!VecType)
4199 return false;
4200 FixedVectorType *ShuffleInputType =
4202 if (!ShuffleInputType)
4203 return false;
4204 unsigned NumInputElts = ShuffleInputType->getNumElements();
4205
4206 // Find the mask from sorting the lanes into order. This is most likely to
4207 // become a identity or concat mask. Undef elements are pushed to the end.
4208 SmallVector<int> ConcatMask;
4209 Shuffle->getShuffleMask(ConcatMask);
4210 sort(ConcatMask, [](int X, int Y) { return (unsigned)X < (unsigned)Y; });
4211 bool UsesSecondVec =
4212 any_of(ConcatMask, [&](int M) { return M >= (int)NumInputElts; });
4213
4215 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4216 ShuffleInputType, CostKind, Shuffle->getShuffleMask());
4218 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4219 ShuffleInputType, CostKind, ConcatMask);
4220
4221 LLVM_DEBUG(dbgs() << "Found a reduction feeding from a shuffle: " << *Shuffle
4222 << "\n");
4223 LLVM_DEBUG(dbgs() << " OldCost: " << OldCost << " vs NewCost: " << NewCost
4224 << "\n");
4225 bool MadeChanges = false;
4226 if (NewCost < OldCost) {
4227 Builder.SetInsertPoint(Shuffle);
4228 Value *NewShuffle = Builder.CreateShuffleVector(
4229 Shuffle->getOperand(0), Shuffle->getOperand(1), ConcatMask);
4230 LLVM_DEBUG(dbgs() << "Created new shuffle: " << *NewShuffle << "\n");
4231 replaceValue(*Shuffle, *NewShuffle);
4232 return true;
4233 }
4234
4235 // See if we can re-use foldSelectShuffle, getting it to reduce the size of
4236 // the shuffle into a nicer order, as it can ignore the order of the shuffles.
4237 MadeChanges |= foldSelectShuffle(*Shuffle, true);
4238 return MadeChanges;
4239}
4240
4241/// Try to fold a chain of shuffles and ops feeding extractelement(..., 0)
4242/// into llvm.vector.reduce.*, by tracking which lanes contribute to the
4243/// extracted lane and reducing the widest vector whose lanes each contribute
4244/// once.
4245///
4246/// For example:
4247///
4248/// %lo = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 0, i32 1>
4249/// %hi = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 2, i32 3>
4250/// %s = add <2 x i32> %lo, %hi
4251/// %sh = shufflevector <2 x i32> %s, poison, <2 x i32> <i32 1, i32 poison>
4252/// %r = add <2 x i32> %s, %sh
4253/// %e = extractelement <2 x i32> %r, i64 0
4254///
4255/// transforms to:
4256///
4257/// %e = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
4258bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
4259 Value *VecOpEE;
4260 if (!match(&I, m_ExtractElt(m_Value(VecOpEE), m_Zero())))
4261 return false;
4262
4263 auto *FVT = dyn_cast<FixedVectorType>(VecOpEE->getType());
4264 if (!FVT)
4265 return false;
4266
4267 if (FVT->getNumElements() < 2)
4268 return false;
4269
4270 std::optional<Instruction::BinaryOps> CommonBinOp;
4271 std::optional<Intrinsic::ID> CommonCallOp;
4272
4273 if (auto *BO = dyn_cast<BinaryOperator>(VecOpEE)) {
4274 if (!getReductionForBinop(BO->getOpcode()))
4275 return false;
4276 CommonBinOp = BO->getOpcode();
4277 } else if (auto *MMI = dyn_cast<MinMaxIntrinsic>(VecOpEE)) {
4278 CommonCallOp = MMI->getIntrinsicID();
4279 } else {
4280 return false;
4281 }
4282
4283 // For floating-point reductions, track FMF intersection across all binops.
4284 FastMathFlags CommonFMF;
4285 bool IsFloatReduction = false;
4286
4287 // A chain node is one we walk through, either a matching-opcode binop/min-max
4288 // or a single-source shuffle. Anything else is a leaf source.
4289 auto IsChainNode = [&](Value *V) {
4290 if (auto *BO = dyn_cast<BinaryOperator>(V))
4291 return CommonBinOp && BO->getOpcode() == *CommonBinOp;
4292 if (auto *MMI = dyn_cast<MinMaxIntrinsic>(V))
4293 return CommonCallOp && MMI->getIntrinsicID() == *CommonCallOp;
4294 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V))
4295 return isa<PoisonValue>(SVI->getOperand(1));
4296 return false;
4297 };
4298
4299 // Collect the chain, building Nodes in postorder. Bail if the chain is empty
4300 // or exceeds MaxChainNodes.
4301 constexpr unsigned MaxChainNodes = 32;
4302 SmallSetVector<Value *, 16> Nodes;
4303 SmallSetVector<Value *, 4> Sources;
4304 unsigned NumVisited = 0;
4305 auto AddSource = [&](Value *V) {
4306 if (!isa<FixedVectorType>(V->getType()))
4307 return false;
4308 Sources.insert(V);
4309 return true;
4310 };
4311 auto Walk = [&](Value *V, auto &&Walk) -> bool {
4312 if (Nodes.contains(V) || Sources.contains(V))
4313 return true;
4314 if (++NumVisited > MaxChainNodes)
4315 return false;
4316 if (!IsChainNode(V))
4317 return AddSource(V);
4318 // Chain shuffles always have poison as op1, so only op0 matters.
4319 auto *U = cast<Instruction>(V);
4320 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4321 for (unsigned I = 0; I != NumOps; ++I)
4322 if (!Walk(U->getOperand(I), Walk))
4323 return false;
4324 if (isa<ShuffleVectorInst>(U) || Nodes.contains(U->getOperand(0)) ||
4325 Nodes.contains(U->getOperand(1))) {
4326 Nodes.insert(V);
4327 return true;
4328 }
4329 // Both operands are leaves so treat this binop as a source rather than
4330 // walking into it.
4331 return AddSource(V);
4332 };
4333 if (!Walk(VecOpEE, Walk) || Nodes.empty())
4334 return false;
4335
4336 bool IsIdempotent =
4337 CommonCallOp || (CommonBinOp && Instruction::isIdempotent(*CommonBinOp));
4338
4339 // For FP reductions, require reassoc on every binop and collect FMF.
4340 for (Value *V : Nodes) {
4341 auto *BinOp = dyn_cast<BinaryOperator>(V);
4342 if (!BinOp || !BinOp->getType()->isFPOrFPVectorTy())
4343 continue;
4344 if (!BinOp->hasAllowReassoc())
4345 return false;
4346 if (!IsFloatReduction) {
4347 CommonFMF = BinOp->getFastMathFlags();
4348 IsFloatReduction = true;
4349 } else {
4350 CommonFMF &= BinOp->getFastMathFlags();
4351 }
4352 }
4353
4354 // Top-down demanded elements. For each chain value, track which lanes feed
4355 // the extracted lane 0 and which feed it more than once. Reverse postorder
4356 // visits every use before its value. A binop forwards its demand to both
4357 // operands and a shuffle follows its mask back to the source lane.
4358 struct Demand {
4359 APInt Lanes;
4360 APInt Duplicates;
4361 };
4362 DenseMap<Value *, Demand> Demands;
4363 auto DemandOf = [&](Value *V) -> Demand & {
4364 unsigned N = cast<FixedVectorType>(V->getType())->getNumElements();
4365 Demand &D = Demands[V];
4366 if (D.Lanes.getBitWidth() != N)
4367 D.Lanes = D.Duplicates = APInt::getZero(N);
4368 return D;
4369 };
4370 DemandOf(VecOpEE).Lanes.setBit(0);
4371 for (Value *V : reverse(Nodes)) {
4372 Demand DV = Demands.lookup(V);
4373 if (DV.Lanes.isZero())
4374 continue;
4375 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V)) {
4376 ArrayRef<int> Mask = SVI->getShuffleMask();
4377 Demand &DS = DemandOf(SVI->getOperand(0));
4378 for (unsigned I = 0, E = Mask.size(); I != E; ++I) {
4379 // Skip lanes that are undemanded or map to poison.
4380 if (!DV.Lanes[I] || Mask[I] < 0 ||
4381 (unsigned)Mask[I] >= DS.Lanes.getBitWidth())
4382 continue;
4383 if (DS.Lanes[Mask[I]] || DV.Duplicates[I])
4384 DS.Duplicates.setBit(Mask[I]);
4385 DS.Lanes.setBit(Mask[I]);
4386 }
4387 } else {
4388 auto *U = cast<User>(V);
4389 for (Value *Op : {U->getOperand(0), U->getOperand(1)}) {
4390 Demand &DOp = DemandOf(Op);
4391 // Lanes demanded through more than one path accumulate in Duplicates.
4392 DOp.Duplicates |= DV.Duplicates | (DOp.Lanes & DV.Lanes);
4393 DOp.Lanes |= DV.Lanes;
4394 }
4395 }
4396 }
4397
4398 // Reducing V replaces the entire chain, so every contribution to the result
4399 // must flow through V. Reject if anything above V reads outside the chain.
4400 auto CoversChain = [&](Value *V) {
4401 SmallVector<Value *, 8> Worklist(1, VecOpEE);
4402 SmallPtrSet<Value *, 8> Seen;
4403 Seen.insert(VecOpEE);
4404 while (!Worklist.empty()) {
4405 auto *U = cast<Instruction>(Worklist.pop_back_val());
4406 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4407 for (unsigned I = 0; I != NumOps; ++I) {
4408 Value *Op = U->getOperand(I);
4409 if (Op == V || !Seen.insert(Op).second)
4410 continue;
4411 if (!Nodes.contains(Op))
4412 return false;
4413 Worklist.push_back(Op);
4414 }
4415 }
4416 return true;
4417 };
4418
4419 // Reduce a single cleanly demanded source if there is one, otherwise the
4420 // deepest intermediate that covers the chain.
4421 struct ReductionCut {
4422 Value *Src;
4423 APInt Elts;
4424 };
4425 std::optional<ReductionCut> Cut;
4426 for (Value *S : Sources) {
4427 auto It = Demands.find(S);
4428 if (It == Demands.end() || It->second.Lanes.isZero())
4429 continue;
4430 if (!IsIdempotent && !It->second.Duplicates.isZero()) {
4431 Cut.reset();
4432 break;
4433 }
4434 if (!Cut) {
4435 Cut = ReductionCut{S, It->second.Lanes};
4436 continue;
4437 }
4438 if (!isEquivBitcast(Cut->Src, S)) {
4439 Cut.reset();
4440 break;
4441 }
4442 if (!IsIdempotent && !(Cut->Elts & It->second.Lanes).isZero()) {
4443 Cut.reset();
4444 break;
4445 }
4446 Cut->Elts |= It->second.Lanes;
4447 }
4448 if (!Cut) {
4449 for (Value *V : Nodes) {
4451 continue;
4452 auto It = Demands.find(V);
4453 if (It == Demands.end() || !It->second.Lanes.isAllOnes())
4454 continue;
4455 if (!IsIdempotent && !It->second.Duplicates.isZero())
4456 continue;
4457 if (!CoversChain(V))
4458 continue;
4459 Cut = ReductionCut{V, It->second.Lanes};
4460 break;
4461 }
4462 }
4463 // Reducing one lane is just an extract and can refold forever.
4464 if (!Cut || Cut->Elts.popcount() < 2)
4465 return false;
4466
4467 Intrinsic::ID ReducedOp =
4468 (CommonCallOp ? getMinMaxReductionIntrinsicID(*CommonCallOp)
4469 : getReductionForBinop(*CommonBinOp));
4470 if (!ReducedOp)
4471 return false;
4472
4473 InstructionCost OrigCost = 0;
4474 for (Value *V : Nodes)
4476
4477 auto *SrcVT = cast<FixedVectorType>(Cut->Src->getType());
4478 bool IsPartialReduction = !Cut->Elts.isAllOnes();
4479 FixedVectorType *ReduceVecTy =
4480 IsPartialReduction
4481 ? FixedVectorType::get(FVT->getElementType(), Cut->Elts.popcount())
4482 : SrcVT;
4483
4484 SmallVector<int> ExtractMask;
4485 InstructionCost NewCost = 0;
4486 if (IsPartialReduction) {
4487 for (unsigned I = 0, E = Cut->Elts.getBitWidth(); I != E; ++I)
4488 if (Cut->Elts[I])
4489 ExtractMask.push_back(I);
4490 unsigned SubIdx = 0, SubLen;
4491 auto SK = Cut->Elts.isShiftedMask(SubIdx, SubLen)
4494 NewCost += TTI.getShuffleCost(SK, ReduceVecTy, SrcVT, CostKind, ExtractMask,
4495 SubIdx, ReduceVecTy);
4496 }
4497
4498 IntrinsicCostAttributes ICA(
4499 ReducedOp, ReduceVecTy->getElementType(),
4500 IsFloatReduction
4501 ? SmallVector<Type *, 2>{ReduceVecTy->getElementType(), ReduceVecTy}
4502 : SmallVector<Type *, 2>{ReduceVecTy},
4503 IsFloatReduction ? CommonFMF : FastMathFlags());
4504 NewCost += TTI.getIntrinsicInstrCost(ICA, CostKind);
4505
4506 LLVM_DEBUG(dbgs() << "Found reduction shuffle chain: " << I << "\n OldCost : "
4507 << OrigCost << " vs NewCost: " << NewCost << "\n");
4508
4509 if (!OrigCost.isValid() || !NewCost.isValid())
4510 return false;
4511
4512 if (VecOpEE->hasOneUse() ? (NewCost > OrigCost) : (NewCost >= OrigCost))
4513 return false;
4514
4515 Value *ReduceInput = Cut->Src;
4516 if (IsPartialReduction)
4517 ReduceInput = Builder.CreateShuffleVector(Cut->Src, ExtractMask);
4518
4519 Value *ReducedResult;
4520 if (IsFloatReduction) {
4522 *CommonBinOp, ReduceVecTy->getElementType(), /*AllowRHSConstant=*/false,
4523 CommonFMF.noSignedZeros());
4524 ReducedResult = Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy},
4525 {Identity, ReduceInput}, CommonFMF);
4526 } else {
4527 ReducedResult =
4528 Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy}, {ReduceInput});
4529 }
4530 replaceValue(I, *ReducedResult);
4531
4532 return true;
4533}
4534
4535/// Determine if its more efficient to fold:
4536/// reduce(trunc(x)) -> trunc(reduce(x)).
4537/// reduce(sext(x)) -> sext(reduce(x)).
4538/// reduce(zext(x)) -> zext(reduce(x)).
4539bool VectorCombine::foldCastFromReductions(Instruction &I) {
4540 auto *II = dyn_cast<IntrinsicInst>(&I);
4541 if (!II)
4542 return false;
4543
4544 bool TruncOnly = false;
4545 Intrinsic::ID IID = II->getIntrinsicID();
4546 switch (IID) {
4547 case Intrinsic::vector_reduce_add:
4548 case Intrinsic::vector_reduce_mul:
4549 TruncOnly = true;
4550 break;
4551 case Intrinsic::vector_reduce_and:
4552 case Intrinsic::vector_reduce_or:
4553 case Intrinsic::vector_reduce_xor:
4554 break;
4555 default:
4556 return false;
4557 }
4558
4559 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
4560 Value *ReductionSrc = I.getOperand(0);
4561
4562 Value *Src;
4563 if (!match(ReductionSrc, m_OneUse(m_Trunc(m_Value(Src)))) &&
4564 (TruncOnly || !match(ReductionSrc, m_OneUse(m_ZExtOrSExt(m_Value(Src))))))
4565 return false;
4566
4567 auto CastOpc =
4568 (Instruction::CastOps)cast<Instruction>(ReductionSrc)->getOpcode();
4569
4570 auto *SrcTy = cast<VectorType>(Src->getType());
4571 auto *ReductionSrcTy = cast<VectorType>(ReductionSrc->getType());
4572 Type *ResultTy = I.getType();
4573
4575 ReductionOpc, ReductionSrcTy, std::nullopt, CostKind);
4576 OldCost += TTI.getCastInstrCost(CastOpc, ReductionSrcTy, SrcTy,
4578 cast<CastInst>(ReductionSrc));
4579 InstructionCost NewCost =
4580 TTI.getArithmeticReductionCost(ReductionOpc, SrcTy, std::nullopt,
4581 CostKind) +
4582 TTI.getCastInstrCost(CastOpc, ResultTy, ReductionSrcTy->getScalarType(),
4584
4585 if (OldCost <= NewCost || !NewCost.isValid())
4586 return false;
4587
4588 Value *NewReduction = Builder.CreateIntrinsic(SrcTy->getScalarType(),
4589 II->getIntrinsicID(), {Src});
4590 Value *NewCast = Builder.CreateCast(CastOpc, NewReduction, ResultTy);
4591 replaceValue(I, *NewCast);
4592 return true;
4593}
4594
4595/// Fold:
4596/// icmp pred (reduce.{add,or,and,umax,umin}(signbit_extract(x))), C
4597/// into:
4598/// icmp sgt/slt (reduce.{or,umax,and,umin}(x)), -1/0
4599///
4600/// Sign-bit reductions produce values with known semantics:
4601/// - reduce.{or,umax}: 0 if no element is negative, 1 if any is
4602/// - reduce.{and,umin}: 1 if all elements are negative, 0 if any isn't
4603/// - reduce.add: count of negative elements (0 to NumElts)
4604///
4605/// Both lshr and ashr are supported:
4606/// - lshr produces 0 or 1, so reduce.add range is [0, N]
4607/// - ashr produces 0 or -1, so reduce.add range is [-N, 0]
4608///
4609/// The fold generalizes to multiple source vectors combined with the same
4610/// operation as the reduction. For example:
4611/// reduce.or(or(shr A, shr B)) conceptually extends the vector
4612/// For reduce.add, this changes the count to M*N where M is the number of
4613/// source vectors.
4614///
4615/// We transform to a direct sign check on the original vector using
4616/// reduce.{or,umax} or reduce.{and,umin}.
4617///
4618/// In spirit, it's similar to foldSignBitCheck in InstCombine.
4619bool VectorCombine::foldSignBitReductionCmp(Instruction &I) {
4620 CmpPredicate Pred;
4621 IntrinsicInst *ReduceOp;
4622 const APInt *CmpVal;
4623 if (!match(&I,
4624 m_ICmp(Pred, m_OneUse(m_AnyIntrinsic(ReduceOp)), m_APInt(CmpVal))))
4625 return false;
4626
4627 Intrinsic::ID OrigIID = ReduceOp->getIntrinsicID();
4628 switch (OrigIID) {
4629 case Intrinsic::vector_reduce_or:
4630 case Intrinsic::vector_reduce_umax:
4631 case Intrinsic::vector_reduce_and:
4632 case Intrinsic::vector_reduce_umin:
4633 case Intrinsic::vector_reduce_add:
4634 break;
4635 default:
4636 return false;
4637 }
4638
4639 Value *ReductionSrc = ReduceOp->getArgOperand(0);
4640 auto *VecTy = dyn_cast<FixedVectorType>(ReductionSrc->getType());
4641 if (!VecTy)
4642 return false;
4643
4644 unsigned BitWidth = VecTy->getScalarSizeInBits();
4645 if (BitWidth == 1)
4646 return false;
4647
4648 unsigned NumElts = VecTy->getNumElements();
4649
4650 // Determine the expected tree opcode for multi-vector patterns.
4651 // The tree opcode must match the reduction's underlying operation.
4652 //
4653 // TODO: for pairs of equivalent operators, we should match both,
4654 // not only the most common.
4655 Instruction::BinaryOps TreeOpcode;
4656 switch (OrigIID) {
4657 case Intrinsic::vector_reduce_or:
4658 case Intrinsic::vector_reduce_umax:
4659 TreeOpcode = Instruction::Or;
4660 break;
4661 case Intrinsic::vector_reduce_and:
4662 case Intrinsic::vector_reduce_umin:
4663 TreeOpcode = Instruction::And;
4664 break;
4665 case Intrinsic::vector_reduce_add:
4666 TreeOpcode = Instruction::Add;
4667 break;
4668 default:
4669 llvm_unreachable("Unexpected intrinsic");
4670 }
4671
4672 // Collect sign-bit extraction leaves from an associative tree of TreeOpcode.
4673 // The tree conceptually extends the vector being reduced.
4674 SmallVector<Value *, 8> Worklist;
4675 SmallVector<Value *, 8> Sources; // Original vectors (X in shr X, BW-1)
4676 Worklist.push_back(ReductionSrc);
4677 std::optional<bool> IsAShr;
4678 constexpr unsigned MaxSources = 8;
4679
4680 // Calculate old cost: all shifts + tree ops + reduction
4681 InstructionCost OldCost = TTI.getInstructionCost(ReduceOp, CostKind);
4682
4683 while (!Worklist.empty() && Worklist.size() <= MaxSources &&
4684 Sources.size() <= MaxSources) {
4685 Value *V = Worklist.pop_back_val();
4686
4687 // Try to match sign-bit extraction: shr X, (bitwidth-1)
4688 Value *X;
4689 if (match(V, m_OneUse(m_Shr(m_Value(X), m_SpecificInt(BitWidth - 1))))) {
4690 auto *Shr = cast<Instruction>(V);
4691
4692 // All shifts must be the same type (all lshr or all ashr)
4693 bool ThisIsAShr = Shr->getOpcode() == Instruction::AShr;
4694 if (!IsAShr)
4695 IsAShr = ThisIsAShr;
4696 else if (*IsAShr != ThisIsAShr)
4697 return false;
4698
4699 Sources.push_back(X);
4700
4701 // As part of the fold, we remove all of the shifts, so we need to keep
4702 // track of their costs.
4703 OldCost += TTI.getInstructionCost(Shr, CostKind);
4704
4705 continue;
4706 }
4707
4708 // Try to extend through a tree node of the expected opcode
4709 Value *A, *B;
4710 if (!match(V, m_OneUse(m_BinOp(TreeOpcode, m_Value(A), m_Value(B)))))
4711 return false;
4712
4713 // We are potentially replacing these operations as well, so we add them
4714 // to the costs.
4716
4717 Worklist.push_back(A);
4718 Worklist.push_back(B);
4719 }
4720
4721 // Must have at least one source and not exceed limit
4722 if (Sources.empty() || Sources.size() > MaxSources ||
4723 Worklist.size() > MaxSources || !IsAShr)
4724 return false;
4725
4726 unsigned NumSources = Sources.size();
4727
4728 // For reduce.add, the total count must fit as a signed integer.
4729 // Range is [0, M*N] for lshr or [-M*N, 0] for ashr.
4730 if (OrigIID == Intrinsic::vector_reduce_add &&
4731 !isIntN(BitWidth, NumSources * NumElts))
4732 return false;
4733
4734 // Compute the boundary value when all elements are negative:
4735 // - Per-element contribution: 1 for lshr, -1 for ashr
4736 // - For add: M*N (total elements across all sources); for others: just 1
4737 unsigned Count =
4738 (OrigIID == Intrinsic::vector_reduce_add) ? NumSources * NumElts : 1;
4739 APInt NegativeVal(CmpVal->getBitWidth(), Count);
4740 if (*IsAShr)
4741 NegativeVal.negate();
4742
4743 // Range is [min(0, AllNegVal), max(0, AllNegVal)]
4744 APInt Zero = APInt::getZero(CmpVal->getBitWidth());
4745 APInt RangeLow = APIntOps::smin(Zero, NegativeVal);
4746 APInt RangeHigh = APIntOps::smax(Zero, NegativeVal);
4747
4748 // Determine comparison semantics:
4749 // - IsEq: true for equality test, false for inequality
4750 // - TestsNegative: true if testing against AllNegVal, false for zero
4751 //
4752 // In addition to EQ/NE against 0 or AllNegVal, we support inequalities
4753 // that fold to boundary tests given the narrow value range:
4754 // < RangeHigh -> != RangeHigh
4755 // > RangeHigh-1 -> == RangeHigh
4756 // > RangeLow -> != RangeLow
4757 // < RangeLow+1 -> == RangeLow
4758 //
4759 // For inequalities, we work with signed predicates only. Unsigned predicates
4760 // are canonicalized to signed when the range is non-negative (where they are
4761 // equivalent). When the range includes negative values, unsigned predicates
4762 // would have different semantics due to wrap-around, so we reject them.
4763 if (!ICmpInst::isEquality(Pred) && !ICmpInst::isSigned(Pred)) {
4764 if (RangeLow.isNegative())
4765 return false;
4766 Pred = ICmpInst::getSignedPredicate(Pred);
4767 }
4768
4769 bool IsEq;
4770 bool TestsNegative;
4771 if (ICmpInst::isEquality(Pred)) {
4772 if (CmpVal->isZero()) {
4773 TestsNegative = false;
4774 } else if (*CmpVal == NegativeVal) {
4775 TestsNegative = true;
4776 } else {
4777 return false;
4778 }
4779 IsEq = Pred == ICmpInst::ICMP_EQ;
4780 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeHigh) {
4781 IsEq = false;
4782 TestsNegative = (RangeHigh == NegativeVal);
4783 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeHigh - 1) {
4784 IsEq = true;
4785 TestsNegative = (RangeHigh == NegativeVal);
4786 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeLow) {
4787 IsEq = false;
4788 TestsNegative = (RangeLow == NegativeVal);
4789 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeLow + 1) {
4790 IsEq = true;
4791 TestsNegative = (RangeLow == NegativeVal);
4792 } else {
4793 return false;
4794 }
4795
4796 // For this fold we support four types of checks:
4797 //
4798 // 1. All lanes are negative - AllNeg
4799 // 2. All lanes are non-negative - AllNonNeg
4800 // 3. At least one negative lane - AnyNeg
4801 // 4. At least one non-negative lane - AnyNonNeg
4802 //
4803 // For each case, we can generate the following code:
4804 //
4805 // 1. AllNeg - reduce.and/umin(X) < 0
4806 // 2. AllNonNeg - reduce.or/umax(X) > -1
4807 // 3. AnyNeg - reduce.or/umax(X) < 0
4808 // 4. AnyNonNeg - reduce.and/umin(X) > -1
4809 //
4810 // The table below shows the aggregation of all supported cases
4811 // using these four cases.
4812 //
4813 // Reduction | == 0 | != 0 | == MAX | != MAX
4814 // ------------+-----------+-----------+-----------+-----------
4815 // or/umax | AllNonNeg | AnyNeg | AnyNeg | AllNonNeg
4816 // and/umin | AnyNonNeg | AllNeg | AllNeg | AnyNonNeg
4817 // add | AllNonNeg | AnyNeg | AllNeg | AnyNonNeg
4818 //
4819 // NOTE: MAX = 1 for or/and/umax/umin, and the vector size N for add
4820 //
4821 // For easier codegen and check inversion, we use the following encoding:
4822 //
4823 // 1. Bit-3 === requires or/umax (1) or and/umin (0) check
4824 // 2. Bit-2 === checks < 0 (1) or > -1 (0)
4825 // 3. Bit-1 === universal (1) or existential (0) check
4826 //
4827 // AnyNeg = 0b110: uses or/umax, checks negative, any-check
4828 // AllNonNeg = 0b101: uses or/umax, checks non-neg, all-check
4829 // AnyNonNeg = 0b000: uses and/umin, checks non-neg, any-check
4830 // AllNeg = 0b011: uses and/umin, checks negative, all-check
4831 //
4832 // XOR with 0b011 inverts the check (swaps all/any and neg/non-neg).
4833 //
4834 enum CheckKind : unsigned {
4835 AnyNonNeg = 0b000,
4836 AllNeg = 0b011,
4837 AllNonNeg = 0b101,
4838 AnyNeg = 0b110,
4839 };
4840 // Return true if we fold this check into or/umax and false for and/umin
4841 auto RequiresOr = [](CheckKind C) -> bool { return C & 0b100; };
4842 // Return true if we should check if result is negative and false otherwise
4843 auto IsNegativeCheck = [](CheckKind C) -> bool { return C & 0b010; };
4844 // Logically invert the check
4845 auto Invert = [](CheckKind C) { return CheckKind(C ^ 0b011); };
4846
4847 CheckKind Base;
4848 switch (OrigIID) {
4849 case Intrinsic::vector_reduce_or:
4850 case Intrinsic::vector_reduce_umax:
4851 Base = TestsNegative ? AnyNeg : AllNonNeg;
4852 break;
4853 case Intrinsic::vector_reduce_and:
4854 case Intrinsic::vector_reduce_umin:
4855 Base = TestsNegative ? AllNeg : AnyNonNeg;
4856 break;
4857 case Intrinsic::vector_reduce_add:
4858 Base = TestsNegative ? AllNeg : AllNonNeg;
4859 break;
4860 default:
4861 llvm_unreachable("Unexpected intrinsic");
4862 }
4863
4864 CheckKind Check = IsEq ? Base : Invert(Base);
4865
4866 auto PickCheaper = [&](Intrinsic::ID Arith, Intrinsic::ID MinMax) {
4867 InstructionCost ArithCost =
4869 VecTy, std::nullopt, CostKind);
4870 InstructionCost MinMaxCost =
4872 FastMathFlags(), CostKind);
4873 return ArithCost <= MinMaxCost ? std::make_pair(Arith, ArithCost)
4874 : std::make_pair(MinMax, MinMaxCost);
4875 };
4876
4877 // Choose output reduction based on encoding's MSB
4878 auto [NewIID, NewCost] = RequiresOr(Check)
4879 ? PickCheaper(Intrinsic::vector_reduce_or,
4880 Intrinsic::vector_reduce_umax)
4881 : PickCheaper(Intrinsic::vector_reduce_and,
4882 Intrinsic::vector_reduce_umin);
4883
4884 // Add cost of combining multiple sources with or/and
4885 if (NumSources > 1) {
4886 unsigned CombineOpc =
4887 RequiresOr(Check) ? Instruction::Or : Instruction::And;
4888 NewCost += TTI.getArithmeticInstrCost(CombineOpc, VecTy, CostKind) *
4889 (NumSources - 1);
4890 }
4891
4892 LLVM_DEBUG(dbgs() << "Found sign-bit reduction cmp: " << I << "\n OldCost: "
4893 << OldCost << " vs NewCost: " << NewCost << "\n");
4894
4895 if (NewCost > OldCost)
4896 return false;
4897
4898 // Generate the combined input and reduction
4899 Builder.SetInsertPoint(&I);
4900 Type *ScalarTy = VecTy->getScalarType();
4901
4902 Value *Input;
4903 if (NumSources == 1) {
4904 Input = Sources[0];
4905 } else {
4906 // Combine sources with or/and based on check type
4907 Input = RequiresOr(Check) ? Builder.CreateOr(Sources)
4908 : Builder.CreateAnd(Sources);
4909 }
4910
4911 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, NewIID, {Input});
4912 Value *NewCmp = IsNegativeCheck(Check) ? Builder.CreateIsNeg(NewReduce)
4913 : Builder.CreateIsNotNeg(NewReduce);
4914 replaceValue(I, *NewCmp);
4915 return true;
4916}
4917
4918/// Fold a zero test of reduce.or or reduce.umax into a boolean reduction.
4919///
4920/// Vectorization may produce IR that compares the result of a scalar reduction
4921/// with zero. Depending on the target, lowering a reduction and a scalar
4922/// comparison separately can cost more than reducing lane-wise comparison
4923/// results. This fold creates the latter form only when it is not costlier.
4924///
4925/// Before:
4926/// %r = call iT @llvm.vector.reduce.or.vNiT(<N x iT> %x)
4927/// %cmp = icmp ne iT %r, 0
4928///
4929/// After:
4930/// %lane.cmp = icmp ne <N x iT> %x, zeroinitializer
4931/// %cmp = call i1 @llvm.vector.reduce.or.vNi1(<N x i1> %lane.cmp)
4932///
4933/// `reduce.or` and `reduce.umax` are non-zero when at least one lane is
4934/// non-zero. Therefore, `icmp ne` uses the existential `reduce.or` test.
4935/// Conversely, `icmp eq` must check that every lane is zero, so it uses the
4936/// universal `reduce.and` test.
4937///
4938/// Before:
4939/// %r = call iT @llvm.vector.reduce.umax.vNiT(<N x iT> %x)
4940/// %cmp = icmp eq iT %r, 0
4941///
4942/// After:
4943/// %lane.cmp = icmp eq <N x iT> %x, zeroinitializer
4944/// %cmp = call i1 @llvm.vector.reduce.and.vNi1(<N x i1> %lane.cmp)
4945bool VectorCombine::foldReductionZeroTest(Instruction &I) {
4946 CmpPredicate Pred;
4947 Value *Op;
4948
4949 if (!match(&I, m_c_ICmp(Pred, m_Value(Op), m_Zero())) ||
4950 !ICmpInst::isEquality(Pred))
4951 return false;
4952
4953 auto *II = dyn_cast<IntrinsicInst>(Op);
4954 if (!II || !II->hasOneUse())
4955 return false;
4956
4957 auto ReduceID = II->getIntrinsicID();
4958 if (ReduceID != Intrinsic::vector_reduce_or &&
4959 ReduceID != Intrinsic::vector_reduce_umax)
4960 return false;
4961
4962 Value *Vec = II->getArgOperand(0);
4963 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
4964 if (!VecTy || !VecTy->getElementType()->isIntegerTy())
4965 return false;
4966
4967 // Map the scalar zero test to an any-lane or all-lane boolean reduction.
4968 Intrinsic::ID NewIID = (Pred == ICmpInst::ICMP_NE)
4969 ? Intrinsic::vector_reduce_or
4970 : Intrinsic::vector_reduce_and;
4971
4972 // This is not an unconditional canonicalization: compare the cost of the
4973 // original scalar reduction and compare with the vector compare and i1
4974 // reduction replacement for both reduce.or and reduce.umax.
4977
4978 auto *CmpTy = cast<VectorType>(CmpInst::makeCmpResultType(VecTy));
4979 InstructionCost NewCost =
4980 TTI.getCmpSelInstrCost(Instruction::ICmp, VecTy, CmpTy, Pred, CostKind);
4982 getArithmeticReductionInstruction(NewIID), CmpTy, std::nullopt, CostKind);
4983
4984 LLVM_DEBUG(dbgs() << "Found a reduction zero test: " << I << "\n OldCost: "
4985 << OldCost << " vs NewCost: " << NewCost << "\n");
4986
4987 if (!OldCost.isValid() || !NewCost.isValid() || NewCost > OldCost)
4988 return false;
4989
4990 Builder.SetInsertPoint(&I);
4991 Value *NewCmp = Builder.CreateICmp(Pred, Vec, Constant::getNullValue(VecTy));
4992 Value *NewReduce = Builder.CreateIntrinsic(NewIID, {CmpTy}, {NewCmp});
4993 replaceValue(I, *NewReduce);
4994 return true;
4995}
4996
4997/// vector.reduce.OP f(X_i) == 0 -> vector.reduce.OP X_i == 0
4998///
4999/// We can prove it for cases when:
5000///
5001/// 1. OP X_i == 0 <=> \forall i \in [1, N] X_i == 0
5002/// 1'. OP X_i == 0 <=> \exists j \in [1, N] X_j == 0
5003/// 2. f(x) == 0 <=> x == 0
5004///
5005/// From 1 and 2 (or 1' and 2), we can infer that
5006///
5007/// OP f(X_i) == 0 <=> OP X_i == 0.
5008///
5009/// (1)
5010/// OP f(X_i) == 0 <=> \forall i \in [1, N] f(X_i) == 0
5011/// (2)
5012/// <=> \forall i \in [1, N] X_i == 0
5013/// (1)
5014/// <=> OP(X_i) == 0
5015///
5016/// For some of the OP's and f's, we need to have domain constraints on X
5017/// to ensure properties 1 (or 1') and 2.
5018bool VectorCombine::foldICmpEqZeroVectorReduce(Instruction &I) {
5019 CmpPredicate Pred;
5020 Value *Op;
5021 if (!match(&I, m_ICmp(Pred, m_Value(Op), m_Zero())) ||
5022 !ICmpInst::isEquality(Pred))
5023 return false;
5024
5025 auto *II = dyn_cast<IntrinsicInst>(Op);
5026 if (!II)
5027 return false;
5028
5029 switch (II->getIntrinsicID()) {
5030 case Intrinsic::vector_reduce_add:
5031 case Intrinsic::vector_reduce_or:
5032 case Intrinsic::vector_reduce_umin:
5033 case Intrinsic::vector_reduce_umax:
5034 case Intrinsic::vector_reduce_smin:
5035 case Intrinsic::vector_reduce_smax:
5036 break;
5037 default:
5038 return false;
5039 }
5040
5041 Value *InnerOp = II->getArgOperand(0);
5042
5043 // TODO: fixed vector type might be too restrictive
5044 if (!II->hasOneUse() || !isa<FixedVectorType>(InnerOp->getType()))
5045 return false;
5046
5047 Value *X = nullptr;
5048
5049 // Check for zero-preserving operations where f(x) = 0 <=> x = 0
5050 //
5051 // 1. f(x) = shl nuw x, y for arbitrary y
5052 // 2. f(x) = mul nuw x, c for defined c != 0
5053 // 3. f(x) = zext x
5054 // 4. f(x) = sext x
5055 // 5. f(x) = neg x
5056 //
5057 if (!(match(InnerOp, m_NUWShl(m_Value(X), m_Value())) || // Case 1
5058 match(InnerOp, m_NUWMul(m_Value(X), m_NonZeroInt())) || // Case 2
5059 match(InnerOp, m_ZExt(m_Value(X))) || // Case 3
5060 match(InnerOp, m_SExt(m_Value(X))) || // Case 4
5061 match(InnerOp, m_Neg(m_Value(X))) // Case 5
5062 ))
5063 return false;
5064
5065 SimplifyQuery S = SQ.getWithInstruction(&I);
5066 auto *XTy = cast<FixedVectorType>(X->getType());
5067
5068 // Check for domain constraints for all supported reductions.
5069 //
5070 // a. OR X_i - has property 1 for every X
5071 // b. UMAX X_i - has property 1 for every X
5072 // c. UMIN X_i - has property 1' for every X
5073 // d. SMAX X_i - has property 1 for X >= 0
5074 // e. SMIN X_i - has property 1' for X >= 0
5075 // f. ADD X_i - has property 1 for X >= 0 && ADD X_i doesn't sign wrap
5076 //
5077 // In order for the proof to work, we need 1 (or 1') to be true for both
5078 // OP f(X_i) and OP X_i and that's why below we check constraints twice.
5079 //
5080 // NOTE: ADD X_i holds property 1 for a mirror case as well, i.e. when
5081 // X <= 0 && ADD X_i doesn't sign wrap. However, due to the nature
5082 // of known bits, we can't reasonably hold knowledge of "either 0
5083 // or negative".
5084 switch (II->getIntrinsicID()) {
5085 case Intrinsic::vector_reduce_add: {
5086 // We need to check that both X_i and f(X_i) have enough leading
5087 // zeros to not overflow.
5088 KnownBits KnownX = computeKnownBits(X, S);
5089 KnownBits KnownFX = computeKnownBits(InnerOp, S);
5090 unsigned NumElems = XTy->getNumElements();
5091 // Adding N elements loses at most ceil(log2(N)) leading bits.
5092 unsigned LostBits = Log2_32_Ceil(NumElems);
5093 unsigned LeadingZerosX = KnownX.countMinLeadingZeros();
5094 unsigned LeadingZerosFX = KnownFX.countMinLeadingZeros();
5095 // Need at least one leading zero left after summation to ensure no overflow
5096 if (LeadingZerosX <= LostBits || LeadingZerosFX <= LostBits)
5097 return false;
5098
5099 // We are not checking whether X or f(X) are positive explicitly because
5100 // we implicitly checked for it when we checked if both cases have enough
5101 // leading zeros to not wrap addition.
5102 break;
5103 }
5104 case Intrinsic::vector_reduce_smin:
5105 case Intrinsic::vector_reduce_smax:
5106 // Check whether X >= 0 and f(X) >= 0
5107 if (!isKnownNonNegative(InnerOp, S) || !isKnownNonNegative(X, S))
5108 return false;
5109
5110 break;
5111 default:
5112 break;
5113 };
5114
5115 LLVM_DEBUG(dbgs() << "Found a reduction to 0 comparison with removable op: "
5116 << *II << "\n");
5117
5118 // For zext/sext, check if the transform is profitable using cost model.
5119 // For other operations (shl, mul, neg), we're removing an instruction
5120 // while keeping the same reduction type, so it's always profitable.
5121 if (isa<ZExtInst>(InnerOp) || isa<SExtInst>(InnerOp)) {
5122 auto *FXTy = cast<FixedVectorType>(InnerOp->getType());
5123 Intrinsic::ID IID = II->getIntrinsicID();
5124
5126 cast<CastInst>(InnerOp)->getOpcode(), FXTy, XTy,
5128
5129 InstructionCost OldReduceCost, NewReduceCost;
5130 switch (IID) {
5131 case Intrinsic::vector_reduce_add:
5132 case Intrinsic::vector_reduce_or:
5133 OldReduceCost = TTI.getArithmeticReductionCost(
5134 getArithmeticReductionInstruction(IID), FXTy, std::nullopt, CostKind);
5135 NewReduceCost = TTI.getArithmeticReductionCost(
5136 getArithmeticReductionInstruction(IID), XTy, std::nullopt, CostKind);
5137 break;
5138 case Intrinsic::vector_reduce_umin:
5139 case Intrinsic::vector_reduce_umax:
5140 case Intrinsic::vector_reduce_smin:
5141 case Intrinsic::vector_reduce_smax:
5142 OldReduceCost = TTI.getMinMaxReductionCost(
5143 getMinMaxReductionIntrinsicOp(IID), FXTy, FastMathFlags(), CostKind);
5144 NewReduceCost = TTI.getMinMaxReductionCost(
5145 getMinMaxReductionIntrinsicOp(IID), XTy, FastMathFlags(), CostKind);
5146 break;
5147 default:
5148 llvm_unreachable("Unexpected reduction");
5149 }
5150
5151 InstructionCost OldCost = OldReduceCost + ExtCost;
5152 InstructionCost NewCost =
5153 NewReduceCost + (InnerOp->hasOneUse() ? 0 : ExtCost);
5154
5155 LLVM_DEBUG(dbgs() << "Found a removable extension before reduction: "
5156 << *InnerOp << "\n OldCost: " << OldCost
5157 << " vs NewCost: " << NewCost << "\n");
5158
5159 // We consider transformation to still be potentially beneficial even
5160 // when the costs are the same because we might remove a use from f(X)
5161 // and unlock other optimizations. Equal costs would just mean that we
5162 // didn't make it worse in the worst case.
5163 if (NewCost > OldCost)
5164 return false;
5165 }
5166
5167 // Since we support zext and sext as f, we might change the scalar type
5168 // of the intrinsic.
5169 Type *Ty = XTy->getScalarType();
5170 Value *NewReduce = Builder.CreateIntrinsic(Ty, II->getIntrinsicID(), {X});
5171 Value *NewCmp =
5172 Builder.CreateICmp(Pred, NewReduce, ConstantInt::getNullValue(Ty));
5173 replaceValue(I, *NewCmp);
5174 return true;
5175}
5176
5177/// Fold comparisons of reduce.or/reduce.and with reduce.umax/reduce.umin
5178/// based on cost, preserving the comparison semantics.
5179///
5180/// We use two fundamental properties for each pair:
5181///
5182/// 1. or(X) == 0 <=> umax(X) == 0
5183/// 2. or(X) == 1 <=> umax(X) == 1
5184/// 3. sign(or(X)) == sign(umax(X))
5185///
5186/// 1. and(X) == -1 <=> umin(X) == -1
5187/// 2. and(X) == -2 <=> umin(X) == -2
5188/// 3. sign(and(X)) == sign(umin(X))
5189///
5190/// From these we can infer the following transformations:
5191/// a. or(X) ==/!= 0 <-> umax(X) ==/!= 0
5192/// b. or(X) s< 0 <-> umax(X) s< 0
5193/// c. or(X) s> -1 <-> umax(X) s> -1
5194/// d. or(X) s< 1 <-> umax(X) s< 1
5195/// e. or(X) ==/!= 1 <-> umax(X) ==/!= 1
5196/// f. or(X) s< 2 <-> umax(X) s< 2
5197/// g. and(X) ==/!= -1 <-> umin(X) ==/!= -1
5198/// h. and(X) s< 0 <-> umin(X) s< 0
5199/// i. and(X) s> -1 <-> umin(X) s> -1
5200/// j. and(X) s> -2 <-> umin(X) s> -2
5201/// k. and(X) ==/!= -2 <-> umin(X) ==/!= -2
5202/// l. and(X) s> -3 <-> umin(X) s> -3
5203///
5204bool VectorCombine::foldEquivalentReductionCmp(Instruction &I) {
5205 CmpPredicate Pred;
5206 Value *ReduceOp;
5207 const APInt *CmpVal;
5208 if (!match(&I, m_ICmp(Pred, m_Value(ReduceOp), m_APInt(CmpVal))))
5209 return false;
5210
5211 auto *II = dyn_cast<IntrinsicInst>(ReduceOp);
5212 if (!II || !II->hasOneUse())
5213 return false;
5214
5215 const auto IsValidOrUmaxCmp = [&]() {
5216 // or === umax for i1
5217 if (CmpVal->getBitWidth() == 1)
5218 return true;
5219
5220 // Cases a and e
5221 bool IsEquality =
5222 (CmpVal->isZero() || CmpVal->isOne()) && ICmpInst::isEquality(Pred);
5223 // Case c
5224 bool IsPositive = CmpVal->isAllOnes() && Pred == ICmpInst::ICMP_SGT;
5225 // Cases b, d, and f
5226 bool IsNegative = (CmpVal->isZero() || CmpVal->isOne() || *CmpVal == 2) &&
5227 Pred == ICmpInst::ICMP_SLT;
5228 return IsEquality || IsPositive || IsNegative;
5229 };
5230
5231 const auto IsValidAndUminCmp = [&]() {
5232 // and === umin for i1
5233 if (CmpVal->getBitWidth() == 1)
5234 return true;
5235
5236 const auto LeadingOnes = CmpVal->countl_one();
5237
5238 // Cases g and k
5239 bool IsEquality =
5240 (CmpVal->isAllOnes() || LeadingOnes + 1 == CmpVal->getBitWidth()) &&
5242 // Case h
5243 bool IsNegative = CmpVal->isZero() && Pred == ICmpInst::ICMP_SLT;
5244 // Cases i, j, and l
5245 bool IsPositive =
5246 // if the number has at least N - 2 leading ones
5247 // and the two LSBs are:
5248 // - 1 x 1 -> -1
5249 // - 1 x 0 -> -2
5250 // - 0 x 1 -> -3
5251 LeadingOnes + 2 >= CmpVal->getBitWidth() &&
5252 ((*CmpVal)[0] || (*CmpVal)[1]) && Pred == ICmpInst::ICMP_SGT;
5253 return IsEquality || IsNegative || IsPositive;
5254 };
5255
5256 Intrinsic::ID OriginalIID = II->getIntrinsicID();
5257 Intrinsic::ID AlternativeIID;
5258
5259 // Check if this is a valid comparison pattern and determine the alternate
5260 // reduction intrinsic.
5261 switch (OriginalIID) {
5262 case Intrinsic::vector_reduce_or:
5263 if (!IsValidOrUmaxCmp())
5264 return false;
5265 AlternativeIID = Intrinsic::vector_reduce_umax;
5266 break;
5267 case Intrinsic::vector_reduce_umax:
5268 if (!IsValidOrUmaxCmp())
5269 return false;
5270 AlternativeIID = Intrinsic::vector_reduce_or;
5271 break;
5272 case Intrinsic::vector_reduce_and:
5273 if (!IsValidAndUminCmp())
5274 return false;
5275 AlternativeIID = Intrinsic::vector_reduce_umin;
5276 break;
5277 case Intrinsic::vector_reduce_umin:
5278 if (!IsValidAndUminCmp())
5279 return false;
5280 AlternativeIID = Intrinsic::vector_reduce_and;
5281 break;
5282 default:
5283 return false;
5284 }
5285
5286 Value *X = II->getArgOperand(0);
5287 auto *VecTy = dyn_cast<FixedVectorType>(X->getType());
5288 if (!VecTy)
5289 return false;
5290
5291 const auto GetReductionCost = [&](Intrinsic::ID IID) -> InstructionCost {
5292 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
5293 if (ReductionOpc != Instruction::ICmp)
5294 return TTI.getArithmeticReductionCost(ReductionOpc, VecTy, std::nullopt,
5295 CostKind);
5297 FastMathFlags(), CostKind);
5298 };
5299
5300 InstructionCost OrigCost = GetReductionCost(OriginalIID);
5301 InstructionCost AltCost = GetReductionCost(AlternativeIID);
5302
5303 LLVM_DEBUG(dbgs() << "Found equivalent reduction cmp: " << I
5304 << "\n OrigCost: " << OrigCost
5305 << " vs AltCost: " << AltCost << "\n");
5306
5307 if (AltCost >= OrigCost)
5308 return false;
5309
5310 Builder.SetInsertPoint(&I);
5311 Type *ScalarTy = VecTy->getScalarType();
5312 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, AlternativeIID, {X});
5313 Value *NewCmp =
5314 Builder.CreateICmp(Pred, NewReduce, ConstantInt::get(ScalarTy, *CmpVal));
5315
5316 replaceValue(I, *NewCmp);
5317 return true;
5318}
5319
5320/// Used by foldReduceAddCmpZero to check if we can prove that a value is
5321/// non-positive.
5322/// KnownBits cannot see sext <? x i1> as non-positive: each top bit equals a
5323/// single unknown input bit, which a per-bit lattice cannot track. The fold's
5324/// target shape is popcount-style sums of <N x i1> valid/invalid masks (e.g.
5325/// ray-intersection hits) tested for any-hit.
5326/// Previous attempts to approximate the known bits of such expressions were
5327/// using a fully recursive value tracking approach to infer a constant range
5328/// but ultimately turned to be too expensive in compile time.
5329static bool isKnownNonPositive(const Value *V, const SimplifyQuery &SQ,
5330 unsigned Depth = 0) {
5331 constexpr unsigned MaxLocalDepth = 2;
5332 if (Depth > MaxLocalDepth)
5333 return false;
5334
5335 auto NumSignBits = [&](const Value *X) {
5336 return ComputeNumSignBits(X, SQ.DL, SQ.AC, SQ.CtxI, SQ.DT);
5337 };
5338 if (NumSignBits(V) == V->getType()->getScalarSizeInBits())
5339 return true;
5340
5341 Value *A, *B;
5342 if (match(V, m_Add(m_Value(A), m_Value(B))))
5343 return NumSignBits(A) >= 2 && NumSignBits(B) >= 2 &&
5344 isKnownNonPositive(A, SQ, Depth + 1) &&
5345 isKnownNonPositive(B, SQ, Depth + 1);
5346
5347 return computeKnownBits(V, SQ).isNonPositive();
5348}
5349
5350/// Fold (icmp pred (reduce.add X), 0) to (icmp pred' (reduce.or X), 0) when X
5351/// has lanes known to all be non-negative or all non-positive, so that
5352/// sum == 0 iff every lane is 0. Falls back to reduce.umax if reduce.or is
5353/// more expensive on the target.
5354bool VectorCombine::foldReduceAddCmpZero(Instruction &I) {
5355 CmpPredicate Pred;
5356 Value *Vec;
5357 if (!match(&I, m_ICmp(Pred,
5359 m_Value(Vec))),
5360 m_Zero())))
5361 return false;
5362
5363 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
5364 if (!VecTy || VecTy->getNumElements() < 2)
5365 return false;
5366
5367 SimplifyQuery Q = SQ.getWithInstruction(&I);
5368 bool IsNonNegative = isKnownNonNegative(Vec, Q);
5369 bool IsNonPositive = !IsNonNegative && isKnownNonPositive(Vec, Q);
5370 if (!IsNonNegative && !IsNonPositive)
5371 return false;
5372
5373 // Summing NumElts lanes can consume up to log2(NumElts) sign bits. Require
5374 // strictly more headroom than that so the sum cannot wrap to zero.
5375 unsigned NumElts = VecTy->getNumElements();
5376 unsigned NumSignBits = ComputeNumSignBits(Vec, *DL, SQ.AC, &I, &DT);
5377 if (Log2_32(NumElts) >= NumSignBits)
5378 return false;
5379
5380 ICmpInst::Predicate NewPred;
5381 switch (Pred) {
5382 case ICmpInst::ICMP_EQ:
5383 case ICmpInst::ICMP_ULE:
5384 case ICmpInst::ICMP_SLE:
5385 case ICmpInst::ICMP_SGE:
5386 NewPred = ICmpInst::ICMP_EQ;
5387 break;
5388 case ICmpInst::ICMP_NE:
5389 case ICmpInst::ICMP_UGT:
5390 case ICmpInst::ICMP_SGT:
5391 case ICmpInst::ICMP_SLT:
5392 NewPred = ICmpInst::ICMP_NE;
5393 break;
5394 default:
5395 return false;
5396 }
5397
5398 // SGT and SLE on a non-positive tree, and SLT and SGE on a non-negative
5399 // tree, are tautologies (always true or always false). Leave those to
5400 // InstCombine rather than mapping them here. Remaining signed inequalities
5401 // also need one extra sign bit so the sum cannot flip sign.
5402 if (!IsNonNegative &&
5403 (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE))
5404 return false;
5405 if (!IsNonPositive &&
5406 (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE))
5407 return false;
5408 if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE ||
5409 Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) &&
5410 Log2_32(NumElts) >= NumSignBits - 1)
5411 return false;
5412
5414 Instruction::Add, VecTy, std::nullopt, CostKind);
5416 Instruction::Or, VecTy, std::nullopt, CostKind);
5418 Intrinsic::umax, VecTy, FastMathFlags(), CostKind);
5419 if (!OrCost.isValid() && !UmaxCost.isValid())
5420 return false;
5421 bool UseOr = OrCost.isValid() && (!UmaxCost.isValid() || OrCost <= UmaxCost);
5422 InstructionCost AltCost = UseOr ? OrCost : UmaxCost;
5423 if (AltCost > OrigCost)
5424 return false;
5425
5426 Builder.SetInsertPoint(&I);
5427 Value *NewReduce = UseOr ? Builder.CreateOrReduce(Vec)
5428 : Builder.CreateIntrinsic(
5429 Intrinsic::vector_reduce_umax, {VecTy}, {Vec});
5430 Worklist.pushValue(NewReduce);
5431 Value *NewCmp = Builder.CreateICmp(
5432 NewPred, NewReduce, ConstantInt::getNullValue(VecTy->getScalarType()));
5433 replaceValue(I, *NewCmp);
5434 return true;
5435}
5436
5437/// Returns true if this ShuffleVectorInst eventually feeds into a
5438/// vector reduction intrinsic (e.g., vector_reduce_add) by only following
5439/// chains of shuffles and binary operators (in any combination/order).
5440/// The search does not go deeper than the given Depth.
5442 constexpr unsigned MaxVisited = 32;
5445 bool FoundReduction = false;
5446
5447 WorkList.push_back(SVI);
5448 while (!WorkList.empty()) {
5449 Instruction *I = WorkList.pop_back_val();
5450 for (User *U : I->users()) {
5451 auto *UI = cast<Instruction>(U);
5452 if (!UI || !Visited.insert(UI).second)
5453 continue;
5454 if (Visited.size() > MaxVisited)
5455 return false;
5456 if (auto *II = dyn_cast<IntrinsicInst>(UI)) {
5457 // More than one reduction reached
5458 if (FoundReduction)
5459 return false;
5460 switch (II->getIntrinsicID()) {
5461 case Intrinsic::vector_reduce_add:
5462 case Intrinsic::vector_reduce_mul:
5463 case Intrinsic::vector_reduce_and:
5464 case Intrinsic::vector_reduce_or:
5465 case Intrinsic::vector_reduce_xor:
5466 case Intrinsic::vector_reduce_smin:
5467 case Intrinsic::vector_reduce_smax:
5468 case Intrinsic::vector_reduce_umin:
5469 case Intrinsic::vector_reduce_umax:
5470 FoundReduction = true;
5471 continue;
5472 default:
5473 return false;
5474 }
5475 }
5476
5478 return false;
5479
5480 WorkList.emplace_back(UI);
5481 }
5482 }
5483 return FoundReduction;
5484}
5485
5486/// This method looks for groups of shuffles acting on binops, of the form:
5487/// %x = shuffle ...
5488/// %y = shuffle ...
5489/// %a = binop %x, %y
5490/// %b = binop %x, %y
5491/// shuffle %a, %b, selectmask
5492/// We may, especially if the shuffle is wider than legal, be able to convert
5493/// the shuffle to a form where only parts of a and b need to be computed. On
5494/// architectures with no obvious "select" shuffle, this can reduce the total
5495/// number of operations if the target reports them as cheaper.
5496bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
5497 auto *SVI = cast<ShuffleVectorInst>(&I);
5498 auto *VT = cast<FixedVectorType>(I.getType());
5499 auto *Op0 = dyn_cast<Instruction>(SVI->getOperand(0));
5500 auto *Op1 = dyn_cast<Instruction>(SVI->getOperand(1));
5501 if (!Op0 || !Op1 || Op0 == Op1 || !Op0->isBinaryOp() || !Op1->isBinaryOp() ||
5502 VT != Op0->getType())
5503 return false;
5504
5505 auto *SVI0A = dyn_cast<Instruction>(Op0->getOperand(0));
5506 auto *SVI0B = dyn_cast<Instruction>(Op0->getOperand(1));
5507 auto *SVI1A = dyn_cast<Instruction>(Op1->getOperand(0));
5508 auto *SVI1B = dyn_cast<Instruction>(Op1->getOperand(1));
5509 SmallPtrSet<Instruction *, 4> InputShuffles({SVI0A, SVI0B, SVI1A, SVI1B});
5510 auto checkSVNonOpUses = [&](Instruction *I) {
5511 if (!I || I->getOperand(0)->getType() != VT)
5512 return true;
5513 return any_of(I->users(), [&](User *U) {
5514 return U != Op0 && U != Op1 &&
5515 !(isa<ShuffleVectorInst>(U) &&
5516 (InputShuffles.contains(cast<Instruction>(U)) ||
5517 isInstructionTriviallyDead(cast<Instruction>(U))));
5518 });
5519 };
5520 if (checkSVNonOpUses(SVI0A) || checkSVNonOpUses(SVI0B) ||
5521 checkSVNonOpUses(SVI1A) || checkSVNonOpUses(SVI1B))
5522 return false;
5523
5524 // Collect all the uses that are shuffles that we can transform together. We
5525 // may not have a single shuffle, but a group that can all be transformed
5526 // together profitably.
5528 auto collectShuffles = [&](Instruction *I) {
5529 for (auto *U : I->users()) {
5531 if (!SV || SV->getType() != VT)
5532 return false;
5533 if ((SV->getOperand(0) != Op0 && SV->getOperand(0) != Op1) ||
5534 (SV->getOperand(1) != Op0 && SV->getOperand(1) != Op1))
5535 return false;
5536 if (!llvm::is_contained(Shuffles, SV))
5537 Shuffles.push_back(SV);
5538 }
5539 return true;
5540 };
5541 if (!collectShuffles(Op0) || !collectShuffles(Op1))
5542 return false;
5543 // From a reduction, we need to be processing a single shuffle, otherwise the
5544 // other uses will not be lane-invariant.
5545 if (FromReduction && Shuffles.size() > 1)
5546 return false;
5547
5548 // Add any shuffle uses for the shuffles we have found, to include them in our
5549 // cost calculations.
5550 if (!FromReduction) {
5551 for (size_t Idx = 0, E = Shuffles.size(); Idx != E; ++Idx) {
5552 for (auto *U : Shuffles[Idx]->users()) {
5553 ShuffleVectorInst *SSV = dyn_cast<ShuffleVectorInst>(U);
5554 if (SSV && isa<UndefValue>(SSV->getOperand(1)) && SSV->getType() == VT)
5555 Shuffles.push_back(SSV);
5556 }
5557 }
5558 }
5559
5560 // For each of the output shuffles, we try to sort all the first vector
5561 // elements to the beginning, followed by the second array elements at the
5562 // end. If the binops are legalized to smaller vectors, this may reduce total
5563 // number of binops. We compute the ReconstructMask mask needed to convert
5564 // back to the original lane order.
5566 SmallVector<SmallVector<int>> OrigReconstructMasks;
5567 int MaxV1Elt = 0, MaxV2Elt = 0;
5568 unsigned NumElts = VT->getNumElements();
5569 for (ShuffleVectorInst *SVN : Shuffles) {
5570 SmallVector<int> Mask;
5571 SVN->getShuffleMask(Mask);
5572
5573 // Check the operands are the same as the original, or reversed (in which
5574 // case we need to commute the mask).
5575 Value *SVOp0 = SVN->getOperand(0);
5576 Value *SVOp1 = SVN->getOperand(1);
5577 if (isa<UndefValue>(SVOp1)) {
5578 auto *SSV = cast<ShuffleVectorInst>(SVOp0);
5579 SVOp0 = SSV->getOperand(0);
5580 SVOp1 = SSV->getOperand(1);
5581 for (int &Elem : Mask) {
5582 if (Elem >= static_cast<int>(SSV->getShuffleMask().size()))
5583 return false;
5584 Elem = Elem < 0 ? Elem : SSV->getMaskValue(Elem);
5585 }
5586 }
5587 if (SVOp0 == Op1 && SVOp1 == Op0) {
5588 std::swap(SVOp0, SVOp1);
5590 }
5591 if (SVOp0 != Op0 || SVOp1 != Op1)
5592 return false;
5593
5594 // Calculate the reconstruction mask for this shuffle, as the mask needed to
5595 // take the packed values from Op0/Op1 and reconstructing to the original
5596 // order.
5597 SmallVector<int> ReconstructMask;
5598 for (unsigned I = 0; I < Mask.size(); I++) {
5599 if (Mask[I] < 0) {
5600 ReconstructMask.push_back(-1);
5601 } else if (Mask[I] < static_cast<int>(NumElts)) {
5602 MaxV1Elt = std::max(MaxV1Elt, Mask[I]);
5603 auto It = find_if(V1, [&](const std::pair<int, int> &A) {
5604 return Mask[I] == A.first;
5605 });
5606 if (It != V1.end())
5607 ReconstructMask.push_back(It - V1.begin());
5608 else {
5609 ReconstructMask.push_back(V1.size());
5610 V1.emplace_back(Mask[I], V1.size());
5611 }
5612 } else {
5613 MaxV2Elt = std::max<int>(MaxV2Elt, Mask[I] - NumElts);
5614 auto It = find_if(V2, [&](const std::pair<int, int> &A) {
5615 return Mask[I] - static_cast<int>(NumElts) == A.first;
5616 });
5617 if (It != V2.end())
5618 ReconstructMask.push_back(NumElts + It - V2.begin());
5619 else {
5620 ReconstructMask.push_back(NumElts + V2.size());
5621 V2.emplace_back(Mask[I] - NumElts, NumElts + V2.size());
5622 }
5623 }
5624 }
5625
5626 // For reductions, we know that the lane ordering out doesn't alter the
5627 // result. In-order can help simplify the shuffle away.
5628 if (FromReduction)
5629 sort(ReconstructMask);
5630 OrigReconstructMasks.push_back(std::move(ReconstructMask));
5631 }
5632
5633 // If the Maximum element used from V1 and V2 are not larger than the new
5634 // vectors, the vectors are already packes and performing the optimization
5635 // again will likely not help any further. This also prevents us from getting
5636 // stuck in a cycle in case the costs do not also rule it out.
5637 if (V1.empty() || V2.empty() ||
5638 (MaxV1Elt == static_cast<int>(V1.size()) - 1 &&
5639 MaxV2Elt == static_cast<int>(V2.size()) - 1))
5640 return false;
5641
5642 // GetBaseMaskValue takes one of the inputs, which may either be a shuffle, a
5643 // shuffle of another shuffle, or not a shuffle (that is treated like a
5644 // identity shuffle).
5645 auto GetBaseMaskValue = [&](Instruction *I, int M) {
5647 if (!SV)
5648 return M;
5649 if (isa<UndefValue>(SV->getOperand(1)))
5650 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5651 if (InputShuffles.contains(SSV))
5652 return SSV->getMaskValue(SV->getMaskValue(M));
5653 return SV->getMaskValue(M);
5654 };
5655
5656 // Attempt to sort the inputs my ascending mask values to make simpler input
5657 // shuffles and push complex shuffles down to the uses. We sort on the first
5658 // of the two input shuffle orders, to try and get at least one input into a
5659 // nice order.
5660 auto SortBase = [&](Instruction *A, std::pair<int, int> X,
5661 std::pair<int, int> Y) {
5662 int MXA = GetBaseMaskValue(A, X.first);
5663 int MYA = GetBaseMaskValue(A, Y.first);
5664 return MXA < MYA;
5665 };
5666 stable_sort(V1, [&](std::pair<int, int> A, std::pair<int, int> B) {
5667 return SortBase(SVI0A, A, B);
5668 });
5669 stable_sort(V2, [&](std::pair<int, int> A, std::pair<int, int> B) {
5670 return SortBase(SVI1A, A, B);
5671 });
5672 // Calculate our ReconstructMasks from the OrigReconstructMasks and the
5673 // modified order of the input shuffles.
5674 SmallVector<SmallVector<int>> ReconstructMasks;
5675 for (const auto &Mask : OrigReconstructMasks) {
5676 SmallVector<int> ReconstructMask;
5677 for (int M : Mask) {
5678 auto FindIndex = [](const SmallVector<std::pair<int, int>> &V, int M) {
5679 auto It = find_if(V, [M](auto A) { return A.second == M; });
5680 assert(It != V.end() && "Expected all entries in Mask");
5681 return std::distance(V.begin(), It);
5682 };
5683 if (M < 0)
5684 ReconstructMask.push_back(-1);
5685 else if (M < static_cast<int>(NumElts)) {
5686 ReconstructMask.push_back(FindIndex(V1, M));
5687 } else {
5688 ReconstructMask.push_back(NumElts + FindIndex(V2, M));
5689 }
5690 }
5691 ReconstructMasks.push_back(std::move(ReconstructMask));
5692 }
5693
5694 // Calculate the masks needed for the new input shuffles, which get padded
5695 // with undef
5696 SmallVector<int> V1A, V1B, V2A, V2B;
5697 for (unsigned I = 0; I < V1.size(); I++) {
5698 V1A.push_back(GetBaseMaskValue(SVI0A, V1[I].first));
5699 V1B.push_back(GetBaseMaskValue(SVI0B, V1[I].first));
5700 }
5701 for (unsigned I = 0; I < V2.size(); I++) {
5702 V2A.push_back(GetBaseMaskValue(SVI1A, V2[I].first));
5703 V2B.push_back(GetBaseMaskValue(SVI1B, V2[I].first));
5704 }
5705 while (V1A.size() < NumElts) {
5708 }
5709 while (V2A.size() < NumElts) {
5712 }
5713
5714 auto AddShuffleCost = [&](InstructionCost C, Instruction *I) {
5716 if (!SV)
5717 return C;
5718 return C + TTI.getShuffleCost(isa<UndefValue>(SV->getOperand(1))
5721 VT, VT, CostKind, SV->getShuffleMask());
5722 };
5723 auto AddShuffleMaskCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5724 return C +
5726 };
5727
5728 unsigned ElementSize = VT->getElementType()->getPrimitiveSizeInBits();
5729 unsigned MaxVectorSize =
5731 unsigned MaxElementsInVector = MaxVectorSize / ElementSize;
5732 if (MaxElementsInVector == 0)
5733 return false;
5734 // When there are multiple shufflevector operations on the same input,
5735 // especially when the vector length is larger than the register size,
5736 // identical shuffle patterns may occur across different groups of elements.
5737 // To avoid overestimating the cost by counting these repeated shuffles more
5738 // than once, we only account for unique shuffle patterns. This adjustment
5739 // prevents inflated costs in the cost model for wide vectors split into
5740 // several register-sized groups.
5741 std::set<SmallVector<int, 4>> UniqueShuffles;
5742 auto AddShuffleMaskAdjustedCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5743 // Compute the cost for performing the shuffle over the full vector.
5744 auto ShuffleCost =
5746 unsigned NumFullVectors = Mask.size() / MaxElementsInVector;
5747 if (NumFullVectors < 2)
5748 return C + ShuffleCost;
5749 SmallVector<int, 4> SubShuffle(MaxElementsInVector);
5750 unsigned NumUniqueGroups = 0;
5751 unsigned NumGroups = Mask.size() / MaxElementsInVector;
5752 // For each group of MaxElementsInVector contiguous elements,
5753 // collect their shuffle pattern and insert into the set of unique patterns.
5754 for (unsigned I = 0; I < NumFullVectors; ++I) {
5755 for (unsigned J = 0; J < MaxElementsInVector; ++J)
5756 SubShuffle[J] = Mask[MaxElementsInVector * I + J];
5757 if (UniqueShuffles.insert(SubShuffle).second)
5758 NumUniqueGroups += 1;
5759 }
5760 return C + ShuffleCost * NumUniqueGroups / NumGroups;
5761 };
5762 auto AddShuffleAdjustedCost = [&](InstructionCost C, Instruction *I) {
5764 if (!SV)
5765 return C;
5766 SmallVector<int, 16> Mask;
5767 SV->getShuffleMask(Mask);
5768 return AddShuffleMaskAdjustedCost(C, Mask);
5769 };
5770 // Check that input consists of ShuffleVectors applied to the same input
5771 auto AllShufflesHaveSameOperands =
5772 [](SmallPtrSetImpl<Instruction *> &InputShuffles) {
5773 if (InputShuffles.size() < 2)
5774 return false;
5775 ShuffleVectorInst *FirstSV =
5776 dyn_cast<ShuffleVectorInst>(*InputShuffles.begin());
5777 if (!FirstSV)
5778 return false;
5779
5780 Value *In0 = FirstSV->getOperand(0), *In1 = FirstSV->getOperand(1);
5781 return std::all_of(
5782 std::next(InputShuffles.begin()), InputShuffles.end(),
5783 [&](Instruction *I) {
5784 ShuffleVectorInst *SV = dyn_cast<ShuffleVectorInst>(I);
5785 return SV && SV->getOperand(0) == In0 && SV->getOperand(1) == In1;
5786 });
5787 };
5788
5789 // Get the costs of the shuffles + binops before and after with the new
5790 // shuffle masks.
5791 InstructionCost CostBefore =
5792 TTI.getArithmeticInstrCost(Op0->getOpcode(), VT, CostKind) +
5793 TTI.getArithmeticInstrCost(Op1->getOpcode(), VT, CostKind);
5794 CostBefore += std::accumulate(Shuffles.begin(), Shuffles.end(),
5795 InstructionCost(0), AddShuffleCost);
5796 if (AllShufflesHaveSameOperands(InputShuffles)) {
5797 UniqueShuffles.clear();
5798 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5799 InstructionCost(0), AddShuffleAdjustedCost);
5800 } else {
5801 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5802 InstructionCost(0), AddShuffleCost);
5803 }
5804
5805 // The new binops will be unused for lanes past the used shuffle lengths.
5806 // These types attempt to get the correct cost for that from the target.
5807 FixedVectorType *Op0SmallVT =
5808 FixedVectorType::get(VT->getScalarType(), V1.size());
5809 FixedVectorType *Op1SmallVT =
5810 FixedVectorType::get(VT->getScalarType(), V2.size());
5811 InstructionCost CostAfter =
5812 TTI.getArithmeticInstrCost(Op0->getOpcode(), Op0SmallVT, CostKind) +
5813 TTI.getArithmeticInstrCost(Op1->getOpcode(), Op1SmallVT, CostKind);
5814 UniqueShuffles.clear();
5815 CostAfter += std::accumulate(ReconstructMasks.begin(), ReconstructMasks.end(),
5816 InstructionCost(0), AddShuffleMaskAdjustedCost);
5817 std::set<SmallVector<int>> OutputShuffleMasks({V1A, V1B, V2A, V2B});
5818 CostAfter +=
5819 std::accumulate(OutputShuffleMasks.begin(), OutputShuffleMasks.end(),
5820 InstructionCost(0), AddShuffleMaskCost);
5821
5822 LLVM_DEBUG(dbgs() << "Found a binop select shuffle pattern: " << I << "\n");
5823 LLVM_DEBUG(dbgs() << " CostBefore: " << CostBefore
5824 << " vs CostAfter: " << CostAfter << "\n");
5825 if (CostBefore < CostAfter ||
5826 (CostBefore == CostAfter && !feedsIntoVectorReduction(SVI)))
5827 return false;
5828
5829 // The cost model has passed, create the new instructions.
5830 auto GetShuffleOperand = [&](Instruction *I, unsigned Op) -> Value * {
5832 if (!SV)
5833 return I;
5834 if (isa<UndefValue>(SV->getOperand(1)))
5835 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5836 if (InputShuffles.contains(SSV))
5837 return SSV->getOperand(Op);
5838 return SV->getOperand(Op);
5839 };
5840 Builder.SetInsertPoint(*SVI0A->getInsertionPointAfterDef());
5841 Value *NSV0A = Builder.CreateShuffleVector(GetShuffleOperand(SVI0A, 0),
5842 GetShuffleOperand(SVI0A, 1), V1A);
5843 Builder.SetInsertPoint(*SVI0B->getInsertionPointAfterDef());
5844 Value *NSV0B = Builder.CreateShuffleVector(GetShuffleOperand(SVI0B, 0),
5845 GetShuffleOperand(SVI0B, 1), V1B);
5846 Builder.SetInsertPoint(*SVI1A->getInsertionPointAfterDef());
5847 Value *NSV1A = Builder.CreateShuffleVector(GetShuffleOperand(SVI1A, 0),
5848 GetShuffleOperand(SVI1A, 1), V2A);
5849 Builder.SetInsertPoint(*SVI1B->getInsertionPointAfterDef());
5850 Value *NSV1B = Builder.CreateShuffleVector(GetShuffleOperand(SVI1B, 0),
5851 GetShuffleOperand(SVI1B, 1), V2B);
5852 Builder.SetInsertPoint(Op0);
5853 Value *NOp0 = Builder.CreateBinOp((Instruction::BinaryOps)Op0->getOpcode(),
5854 NSV0A, NSV0B);
5855 if (auto *I = dyn_cast<Instruction>(NOp0))
5856 I->copyIRFlags(Op0, true);
5857 Builder.SetInsertPoint(Op1);
5858 Value *NOp1 = Builder.CreateBinOp((Instruction::BinaryOps)Op1->getOpcode(),
5859 NSV1A, NSV1B);
5860 if (auto *I = dyn_cast<Instruction>(NOp1))
5861 I->copyIRFlags(Op1, true);
5862
5863 for (int S = 0, E = ReconstructMasks.size(); S != E; S++) {
5864 Builder.SetInsertPoint(Shuffles[S]);
5865 Value *NSV = Builder.CreateShuffleVector(NOp0, NOp1, ReconstructMasks[S]);
5866 replaceValue(*Shuffles[S], *NSV, false);
5867 }
5868
5869 Worklist.pushValue(NSV0A);
5870 Worklist.pushValue(NSV0B);
5871 Worklist.pushValue(NSV1A);
5872 Worklist.pushValue(NSV1B);
5873 return true;
5874}
5875
5876/// Check if instruction depends on ZExt and this ZExt can be moved after the
5877/// instruction. Move ZExt if it is profitable. For example:
5878/// logic(zext(x),y) -> zext(logic(x,trunc(y)))
5879/// lshr((zext(x),y) -> zext(lshr(x,trunc(y)))
5880/// Cost model calculations takes into account if zext(x) has other users and
5881/// whether it can be propagated through them too.
5882bool VectorCombine::shrinkType(Instruction &I) {
5883 Value *ZExted, *OtherOperand;
5884 if (!match(&I, m_c_BitwiseLogic(m_ZExt(m_Value(ZExted)),
5885 m_Value(OtherOperand))) &&
5886 !match(&I, m_LShr(m_ZExt(m_Value(ZExted)), m_Value(OtherOperand))))
5887 return false;
5888
5889 Value *ZExtOperand = I.getOperand(I.getOperand(0) == OtherOperand ? 1 : 0);
5890
5891 auto *BigTy = cast<FixedVectorType>(I.getType());
5892 auto *SmallTy = cast<FixedVectorType>(ZExted->getType());
5893 unsigned BW = SmallTy->getElementType()->getPrimitiveSizeInBits();
5894
5895 if (I.getOpcode() == Instruction::LShr) {
5896 // Check that the shift amount is less than the number of bits in the
5897 // smaller type. Otherwise, the smaller lshr will return a poison value.
5898 KnownBits ShAmtKB = computeKnownBits(I.getOperand(1), *DL);
5899 if (ShAmtKB.getMaxValue().uge(BW))
5900 return false;
5901 } else {
5902 // Check that the expression overall uses at most the same number of bits as
5903 // ZExted
5904 KnownBits KB = computeKnownBits(&I, *DL);
5905 if (KB.countMaxActiveBits() > BW)
5906 return false;
5907 }
5908
5909 // Calculate costs of leaving current IR as it is and moving ZExt operation
5910 // later, along with adding truncates if needed
5912 Instruction::ZExt, BigTy, SmallTy,
5913 TargetTransformInfo::CastContextHint::None, CostKind);
5914 InstructionCost CurrentCost = ZExtCost;
5915 InstructionCost ShrinkCost = 0;
5916
5917 // Calculate total cost and check that we can propagate through all ZExt users
5918 for (User *U : ZExtOperand->users()) {
5919 auto *UI = cast<Instruction>(U);
5920 if (UI == &I) {
5921 CurrentCost +=
5922 TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5923 ShrinkCost +=
5924 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5925 ShrinkCost += ZExtCost;
5926 continue;
5927 }
5928
5929 if (!Instruction::isBinaryOp(UI->getOpcode()))
5930 return false;
5931
5932 // Check if we can propagate ZExt through its other users
5933 KnownBits KB = computeKnownBits(UI, *DL);
5934 if (KB.countMaxActiveBits() > BW)
5935 return false;
5936
5937 CurrentCost += TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5938 ShrinkCost +=
5939 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5940 ShrinkCost += ZExtCost;
5941 }
5942
5943 // If the other instruction operand is not a constant, we'll need to
5944 // generate a truncate instruction. So we have to adjust cost
5945 if (!isa<Constant>(OtherOperand))
5946 ShrinkCost += TTI.getCastInstrCost(
5947 Instruction::Trunc, SmallTy, BigTy,
5948 TargetTransformInfo::CastContextHint::None, CostKind);
5949
5950 // If the cost of shrinking types and leaving the IR is the same, we'll lean
5951 // towards modifying the IR because shrinking opens opportunities for other
5952 // shrinking optimisations.
5953 if (ShrinkCost > CurrentCost)
5954 return false;
5955
5956 Builder.SetInsertPoint(&I);
5957 Value *Op0 = ZExted;
5958 Value *Op1 = Builder.CreateTrunc(OtherOperand, SmallTy);
5959 // Keep the order of operands the same
5960 if (I.getOperand(0) == OtherOperand)
5961 std::swap(Op0, Op1);
5962 Value *NewBinOp =
5963 Builder.CreateBinOp((Instruction::BinaryOps)I.getOpcode(), Op0, Op1);
5964 if (auto *NewBinOpI = dyn_cast<Instruction>(NewBinOp)) {
5965 NewBinOpI->copyIRFlags(&I);
5966 NewBinOpI->copyMetadata(I);
5967 }
5968 Value *NewZExtr = Builder.CreateZExt(NewBinOp, BigTy);
5969 replaceValue(I, *NewZExtr);
5970 return true;
5971}
5972
5973/// insert (DstVec, (extract SrcVec, ExtIdx), InsIdx) -->
5974/// shuffle (DstVec, SrcVec, Mask)
5975bool VectorCombine::foldInsExtVectorToShuffle(Instruction &I) {
5976 Value *DstVec, *SrcVec;
5977 uint64_t ExtIdx, InsIdx;
5978 if (!match(&I,
5979 m_InsertElt(m_Value(DstVec),
5980 m_ExtractElt(m_Value(SrcVec), m_ConstantInt(ExtIdx)),
5981 m_ConstantInt(InsIdx))))
5982 return false;
5983
5984 auto *DstVecTy = dyn_cast<FixedVectorType>(I.getType());
5985 auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcVec->getType());
5986 // We can try combining vectors with different element sizes.
5987 if (!DstVecTy || !SrcVecTy ||
5988 SrcVecTy->getElementType() != DstVecTy->getElementType())
5989 return false;
5990
5991 unsigned NumDstElts = DstVecTy->getNumElements();
5992 unsigned NumSrcElts = SrcVecTy->getNumElements();
5993 if (InsIdx >= NumDstElts || ExtIdx >= NumSrcElts || NumDstElts == 1)
5994 return false;
5995
5996 // Insertion into poison is a cheaper single operand shuffle.
5998 SmallVector<int> Mask(NumDstElts, PoisonMaskElem);
5999
6000 bool NeedExpOrNarrow = NumSrcElts != NumDstElts;
6001 bool NeedDstSrcSwap = isa<PoisonValue>(DstVec) && !isa<UndefValue>(SrcVec);
6002 if (NeedDstSrcSwap) {
6004 Mask[InsIdx] = ExtIdx % NumDstElts;
6005 std::swap(DstVec, SrcVec);
6006 } else {
6008 std::iota(Mask.begin(), Mask.end(), 0);
6009 Mask[InsIdx] = (ExtIdx % NumDstElts) + NumDstElts;
6010 }
6011
6012 // Cost
6013 auto *Ins = cast<InsertElementInst>(&I);
6014 auto *Ext = cast<ExtractElementInst>(I.getOperand(1));
6015 InstructionCost InsCost =
6016 TTI.getVectorInstrCost(*Ins, DstVecTy, CostKind, InsIdx);
6017 InstructionCost ExtCost =
6018 TTI.getVectorInstrCost(*Ext, DstVecTy, CostKind, ExtIdx);
6019 InstructionCost OldCost = ExtCost + InsCost;
6020
6021 InstructionCost NewCost = 0;
6022 SmallVector<int> ExtToVecMask;
6023 if (!NeedExpOrNarrow) {
6024 // Ignore 'free' identity insertion shuffle.
6025 // TODO: getShuffleCost should return TCC_Free for Identity shuffles.
6026 if (!ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts))
6027 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, CostKind, Mask, 0,
6028 nullptr, {DstVec, SrcVec});
6029 } else {
6030 // When creating a length-changing-vector, always try to keep the relevant
6031 // element in an equivalent position, so that bulk shuffles are more likely
6032 // to be useful.
6033 ExtToVecMask.assign(NumDstElts, PoisonMaskElem);
6034 ExtToVecMask[ExtIdx % NumDstElts] = ExtIdx;
6035 // Add cost for expanding or narrowing
6037 DstVecTy, SrcVecTy, CostKind, ExtToVecMask);
6038 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, CostKind, Mask);
6039 }
6040
6041 if (!Ext->hasOneUse())
6042 NewCost += ExtCost;
6043
6044 LLVM_DEBUG(dbgs() << "Found a insert/extract shuffle-like pair: " << I
6045 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6046 << "\n");
6047
6048 if (OldCost < NewCost)
6049 return false;
6050
6051 if (NeedExpOrNarrow) {
6052 if (!NeedDstSrcSwap)
6053 SrcVec = Builder.CreateShuffleVector(SrcVec, ExtToVecMask);
6054 else
6055 DstVec = Builder.CreateShuffleVector(DstVec, ExtToVecMask);
6056 }
6057
6058 // Canonicalize undef param to RHS to help further folds.
6059 if (isa<UndefValue>(DstVec) && !isa<UndefValue>(SrcVec)) {
6060 ShuffleVectorInst::commuteShuffleMask(Mask, NumDstElts);
6061 std::swap(DstVec, SrcVec);
6062 }
6063
6064 Value *Shuf = Builder.CreateShuffleVector(DstVec, SrcVec, Mask);
6065 replaceValue(I, *Shuf);
6066
6067 return true;
6068}
6069
6070/// Fold away a matched pair of vector.deinterleave/interleave intrinsics
6071/// with a chain of elementwise operations on each between the
6072/// deinterleave and interleave.
6073///
6074/// For example:
6075/// ```
6076/// %d = call { <2 x i16>, <2 x i16> } @deinterleave2.v4i16(<4 x i16> %v)
6077/// %f0 = extractvalue { <2 x i16>, <2 x i16> } %d, 0
6078/// %f1 = extractvalue { <2 x i16>, <2 x i16> } %d, 1
6079///
6080/// %u0 = add <2 x i16> %f0, splat (i16 3)
6081/// %u1 = add <2 x i16> %f1, splat (i16 3)
6082///
6083/// %r = call <4 x i16> @interleave2.v4i16(<2 x i16> %u0, <2 x i16> %u1)
6084/// ```
6085/// Folds to:
6086/// ```
6087/// %r = add <4 x i16> %v, splat (i16 3)
6088/// ```
6089bool VectorCombine::foldDeinterleaveInterleavePair(Instruction &I) {
6091 if (!Deinterleave)
6092 return false;
6093
6094 unsigned Factor =
6096 if (!Factor || Deinterleave->hasOperandBundles() ||
6097 !Deinterleave->hasNUndroppableUses(Factor))
6098 return false;
6099
6100 const Intrinsic::ID ExpectedInterleaveIID =
6102
6103 // Collect one extract for each deinterleaved field.
6104 SmallVector<Use *, 8> CurrentUses(Factor, nullptr);
6105 for (Use &U : Deinterleave->uses()) {
6106 if (U.getUser()->isDroppable())
6107 continue;
6108
6109 auto *Extract = dyn_cast<ExtractValueInst>(U.getUser());
6110 if (!Extract || Extract->getNumIndices() != 1)
6111 return false;
6112
6113 unsigned Index = *Extract->idx_begin();
6114 if (Index >= Factor || CurrentUses[Index])
6115 return false;
6116
6117 CurrentUses[Index] = &U;
6118 }
6119
6120 using ElementwiseStep = SmallVector<Use *, 8>;
6122 IntrinsicInst *Interleave = nullptr;
6123 unsigned NumVisited = 0;
6124
6125 auto GetNumDataOperands = [](Instruction *Inst) {
6126 if (auto *CB = dyn_cast<CallBase>(Inst))
6127 return CB->arg_size(); // Exclude callee operand and bundles.
6128 return Inst->getNumOperands();
6129 };
6130
6131 auto IsSupportedElementwise = [&](Instruction *Inst) {
6132 auto *ResultTy = dyn_cast<VectorType>(Inst->getType());
6133 if (!ResultTy || !isSafeToSpeculativelyExecute(Inst))
6134 return false;
6135
6136 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
6137 if (II->hasOperandBundles() ||
6138 !isTriviallyVectorizable(II->getIntrinsicID()))
6139 return false;
6140 } else if (!isa<BinaryOperator, UnaryOperator, CastInst, CmpInst,
6141 SelectInst, FreezeInst>(Inst)) {
6142 return false;
6143 }
6144
6145 // Reject operations that change the element-count.
6146 // E.g., bitcast <vscale x 4 x i16> %v to <vscale x 8 x i8>
6147 for (unsigned Op = 0, E = GetNumDataOperands(Inst); Op != E; ++Op) {
6148 auto *OperandTy = dyn_cast<VectorType>(Inst->getOperand(Op)->getType());
6149 if (OperandTy &&
6150 OperandTy->getElementCount() != ResultTy->getElementCount())
6151 return false;
6152 }
6153
6154 return true;
6155 };
6156
6157 // Traverse the Factor use chains with a breadth-first search.
6158 // At each level, expect every chain to perform the same operation with the
6159 // preceding chain value at the same operand position, until they all reach
6160 // the matching interleave.
6161 while (NumVisited + Factor <= MaxInstrsToScan) {
6162 NumVisited += Factor;
6163
6164 for (Use *&CurrentUse : CurrentUses) {
6165 Use *NextUse = CurrentUse->getUser()->getSingleUndroppableUse();
6166 auto *Next =
6167 NextUse ? dyn_cast<Instruction>(NextUse->getUser()) : nullptr;
6168 if (!Next)
6169 return false;
6170
6171 CurrentUse = NextUse;
6172 }
6173
6174 // Check whether every chain has reached the same interleave.
6175 if (auto *II = dyn_cast<IntrinsicInst>(CurrentUses.front()->getUser());
6176 II && II->getIntrinsicID() == ExpectedInterleaveIID) {
6177 if (II->hasOperandBundles())
6178 return false;
6179
6180 for (unsigned Index = 0; Index != Factor; ++Index)
6181 if (CurrentUses[Index]->getUser() != II ||
6182 CurrentUses[Index]->getOperandNo() != Index)
6183 return false;
6184
6185 Interleave = II;
6186 break;
6187 }
6188
6189 auto *FirstInst = cast<Instruction>(CurrentUses.front()->getUser());
6190 if (!IsSupportedElementwise(FirstInst))
6191 return false;
6192
6193 unsigned ChainOperand = CurrentUses.front()->getOperandNo();
6194 bool MismatchedUse = any_of(CurrentUses, [&](Use *U) {
6195 auto *Inst = cast<Instruction>(U->getUser());
6196 return Inst != FirstInst && (U->getOperandNo() != ChainOperand ||
6197 !FirstInst->isSameOperationAs(
6199 });
6200 if (MismatchedUse)
6201 return false;
6202
6203 auto GetSplatOrScalar = [](Value *V) {
6204 return isa<VectorType>(V->getType()) ? getSplatValue(V) : V;
6205 };
6206
6207 // Non-chain operands must be either the same scalar or splats of that
6208 // scalar. This intentionally rejects differing poison/undef or non-splat
6209 // vector operands between chains.
6210 for (unsigned Op = 0, E = GetNumDataOperands(FirstInst); Op != E; ++Op) {
6211 if (Op == ChainOperand)
6212 continue;
6213
6214 Value *CommonValue = GetSplatOrScalar(FirstInst->getOperand(Op));
6215 if (!CommonValue || any_of(CurrentUses, [&](Use *U) {
6216 Instruction *Inst = cast<Instruction>(U->getUser());
6217 return Inst != FirstInst &&
6218 GetSplatOrScalar(Inst->getOperand(Op)) != CommonValue;
6219 }))
6220 return false;
6221 }
6222
6223 Steps.push_back(CurrentUses);
6224 }
6225
6226 if (!Interleave)
6227 return false;
6228
6229 // Rebuild the matched elementwise chain at the original vector width.
6230 Value *WideValue = Deinterleave->getArgOperand(0);
6231 ElementCount WideEC =
6232 cast<VectorType>(WideValue->getType())->getElementCount();
6233
6234 auto CreateWideInstruction = [&](Instruction *NarrowInst,
6235 ArrayRef<Value *> NewOperands,
6236 VectorType *WideResultTy) -> Value * {
6237 assert(IsSupportedElementwise(NarrowInst) &&
6238 "Expected supported elementwise");
6239 if (isa<BinaryOperator, UnaryOperator>(NarrowInst))
6240 return Builder.CreateNAryOp(NarrowInst->getOpcode(), NewOperands);
6241 if (auto *Cast = dyn_cast<CastInst>(NarrowInst))
6242 return Builder.CreateCast(Cast->getOpcode(), NewOperands[0],
6243 WideResultTy);
6244 if (auto *Cmp = dyn_cast<CmpInst>(NarrowInst))
6245 return Builder.CreateCmp(Cmp->getPredicate(), NewOperands[0],
6246 NewOperands[1]);
6247 if (isa<SelectInst>(NarrowInst))
6248 return Builder.CreateSelect(
6249 NewOperands[0], NewOperands[1], NewOperands[2], /*Name=*/"",
6250 ProfcheckDisableMetadataFixes ? nullptr : NarrowInst);
6251 if (isa<FreezeInst>(NarrowInst))
6252 return Builder.CreateFreeze(NewOperands[0]);
6253 if (auto *II = dyn_cast<IntrinsicInst>(NarrowInst))
6254 return Builder.CreateIntrinsic(WideResultTy, II->getIntrinsicID(),
6255 NewOperands);
6256 llvm_unreachable("Unsupported instruction");
6257 };
6258
6259 // The BFS has succeeded and collected multiple levels of instructions that
6260 // can be SLP-widened into a chain of wider instructions.
6261 for (const ElementwiseStep &Step : Steps) {
6262 Instruction *NarrowInst = cast<Instruction>(Step.front()->getUser());
6263 unsigned ChainOperand = Step.front()->getOperandNo();
6264
6265 Builder.SetInsertPoint(NarrowInst);
6266 Builder.SetCurrentDebugLocation(NarrowInst->getDebugLoc());
6267
6268 unsigned NumOperands = GetNumDataOperands(NarrowInst);
6269 SmallVector<Value *, 4> NewOperands;
6270 NewOperands.reserve(NumOperands);
6271
6272 for (unsigned Op = 0; Op != NumOperands; ++Op) {
6273 Value *Operand = NarrowInst->getOperand(Op);
6274
6275 if (Op == ChainOperand)
6276 Operand = WideValue;
6277 else if (isa<VectorType>(Operand->getType()))
6278 Operand = Builder.CreateVectorSplat(WideEC, getSplatValue(Operand));
6279 NewOperands.push_back(Operand);
6280 }
6281
6282 auto *WideResultTy =
6283 VectorType::get(NarrowInst->getType()->getScalarType(), WideEC);
6284 Value *NewValue =
6285 CreateWideInstruction(NarrowInst, NewOperands, WideResultTy);
6286
6287 SmallVector<Value *> NarrowInsts =
6288 map_to_vector(Step, [](Use *U) { return cast<Value>(U->getUser()); });
6289 propagateIRFlags(NewValue, NarrowInsts);
6290
6291 if (auto *NewInst = dyn_cast<Instruction>(NewValue))
6292 propagateMetadata(NewInst, NarrowInsts);
6293
6294 WideValue = NewValue;
6295 }
6296
6297 assert(WideValue->getType() == Interleave->getType());
6298 replaceValue(*Interleave, *WideValue);
6299 return true;
6300}
6301
6302/// If we're interleaving 2 constant splats, for instance `<vscale x 8 x i32>
6303/// <splat of 666>` and `<vscale x 8 x i32> <splat of 777>`, we can create a
6304/// larger splat `<vscale x 8 x i64> <splat of ((777 << 32) | 666)>` first
6305/// before casting it back into `<vscale x 16 x i32>`.
6306bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
6307 const APInt *SplatVal0, *SplatVal1;
6309 m_APInt(SplatVal0), m_APInt(SplatVal1))))
6310 return false;
6311
6312 LLVM_DEBUG(dbgs() << "VC: Folding interleave2 with two splats: " << I
6313 << "\n");
6314
6315 auto *VTy =
6316 cast<VectorType>(cast<IntrinsicInst>(I).getArgOperand(0)->getType());
6317 auto *ExtVTy = VectorType::getExtendedElementVectorType(VTy);
6318 unsigned Width = VTy->getElementType()->getIntegerBitWidth();
6319
6320 // Just in case the cost of interleave2 intrinsic and bitcast are both
6321 // invalid, in which case we want to bail out, we use <= rather
6322 // than < here. Even they both have valid and equal costs, it's probably
6323 // not a good idea to emit a high-cost constant splat.
6325 TTI.getCastInstrCost(Instruction::BitCast, I.getType(), ExtVTy,
6327 LLVM_DEBUG(dbgs() << "VC: The cost to cast from " << *ExtVTy << " to "
6328 << *I.getType() << " is too high.\n");
6329 return false;
6330 }
6331
6332 APInt NewSplatVal = SplatVal1->zext(Width * 2);
6333 NewSplatVal <<= Width;
6334 NewSplatVal |= SplatVal0->zext(Width * 2);
6335 auto *NewSplat = ConstantVector::getSplat(
6336 ExtVTy->getElementCount(), ConstantInt::get(F.getContext(), NewSplatVal));
6337
6338 IRBuilder<> Builder(&I);
6339 replaceValue(I, *Builder.CreateBitCast(NewSplat, I.getType()));
6340 return true;
6341}
6342
6343/// Given this sequence:
6344/// ```
6345/// %d = llvm.vector.deinterleave2 <vscale x 16 x i32> %v
6346/// %f0 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 0
6347/// %f1 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 1
6348///
6349/// %low0 = and <vscale x 8 x i32> %f0, splat (i32 65535)
6350/// %low1 = shl <vscale x 8 x i32> %f1, splat (i32 16)
6351/// %merge0 = or disjoint <vscale x 8 x i32> %low0, %low1
6352///
6353/// %high0 = and <vscale x 8 x i32> %f1, splat (i32 -65536)
6354/// %high1 = lshr <vscale x 8 x i32> %f0, splat (i32 16)
6355/// %merge1 = or disjoint <vscale x 8 x i32> %high0, %high1
6356/// ```
6357/// It is actually just de-interleaving a 16-bit vector with double the
6358/// vector length. More generally speaking, it's de-interleaving on a vector
6359/// with half the element width as the original vector.
6360///
6361/// Therefore, we can turn it into:
6362/// ```
6363/// %narrow.v = bitcast <vscale x 16 x i32> %v to <vscale x 32 x i16>
6364/// %d = llvm.vector.deinterleave2 <vscale x 32 x i16> %narrow.v
6365/// %f0 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 0
6366/// %f1 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 1
6367///
6368/// %merge0 = bitcast <vscale x 16 x i16> %f0 to <vscale x 8 x i32>
6369/// %merge1 = bitcast <vscale x 16 x i16> %f1 to <vscale x 8 x i32>
6370/// ```
6371bool VectorCombine::foldDeinterleaveIntrinsics(Instruction &I) {
6372 if (foldDeinterleaveInterleavePair(I))
6373 return true;
6374
6375 // This pattern involves bitcast that is not compatible with big endian.
6376 if (DL->isBigEndian())
6377 return false;
6378
6379 using namespace PatternMatch;
6380 Value *DeinterleavedVal;
6381 if (!match(&I, m_Deinterleave2(m_Value(DeinterleavedVal))))
6382 return false;
6383
6384 VectorType *VecTy = cast<VectorType>(DeinterleavedVal->getType());
6385 IntegerType *ElementTy = dyn_cast<IntegerType>(VecTy->getElementType());
6386 if (!ElementTy)
6387 return false;
6388 unsigned ElementWidth = ElementTy->getBitWidth();
6389 if (ElementWidth < 2 || !isPowerOf2_32(ElementWidth))
6390 return false;
6391 unsigned HalfElementWidth = ElementWidth / 2;
6392
6393 if (!I.hasNUses(2))
6394 return false;
6395 std::array<ExtractValueInst *, 2> OrigFields{};
6396 for (User *Usr : I.users()) {
6397 auto *E = dyn_cast<ExtractValueInst>(Usr);
6398 // The deinterleave result can only be used by extractions.
6399 if (!E || E->getNumIndices() != 1)
6400 return false;
6401 unsigned Idx = *E->idx_begin();
6402 // A single field cannot be extracted more than once.
6403 if (Idx >= 2 || OrigFields[Idx] || !E->hasNUses(2))
6404 return false;
6405 OrigFields[Idx] = E;
6406 }
6407
6408 // Find the merge instruction (i.e. OR) first.
6409 SmallVector<Instruction *, 2> MergeInsts;
6410 for (auto *FieldUsr : OrigFields[0]->users()) {
6411 if (!FieldUsr->hasOneUse() || !isa<Instruction>(FieldUsr->user_back()))
6412 return false;
6413 MergeInsts.push_back(cast<Instruction>(FieldUsr->user_back()));
6414 }
6415 assert(MergeInsts.size() == 2);
6416
6417 // Pattern match bottom-up from the merge instructions.
6418 auto MatchMerge = [&](void) -> bool {
6419 APInt LoMask = APInt::getLowBitsSet(ElementWidth, HalfElementWidth);
6420 APInt HiMask = APInt::getHighBitsSet(ElementWidth, HalfElementWidth);
6421 return match(MergeInsts[0],
6422 m_c_Or(m_And(m_Specific(OrigFields[0]), m_SpecificInt(LoMask)),
6423 m_Shl(m_Specific(OrigFields[1]),
6424 m_SpecificInt(HalfElementWidth)))) &&
6425 match(MergeInsts[1],
6426 m_c_Or(m_And(m_Specific(OrigFields[1]), m_SpecificInt(HiMask)),
6427 m_LShr(m_Specific(OrigFields[0]),
6428 m_SpecificInt(HalfElementWidth))));
6429 };
6430 if (!MatchMerge()) {
6431 std::swap(MergeInsts[0], MergeInsts[1]);
6432 if (!MatchMerge())
6433 return false;
6434 }
6435
6436 // Profitability check.
6437 InstructionCost OldCost =
6438 TTI.getInstructionCost(MergeInsts[0], CostKind) +
6439 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(0)),
6440 CostKind) +
6441 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(1)),
6442 CostKind);
6443 // There are two fields (assuming SHL has the same cost as LSHR).
6444 OldCost *= 2;
6445
6446 auto *NewFieldTy = VecTy->getWithNewBitWidth(HalfElementWidth);
6447 auto *NewVecTy =
6448 VectorType::getDoubleElementsVectorType(cast<VectorType>(NewFieldTy));
6449 InstructionCost NewCost =
6450 TTI.getCastInstrCost(Instruction::BitCast, VecTy, NewVecTy,
6452 TTI.getCastInstrCost(Instruction::BitCast, NewFieldTy,
6453 MergeInsts[0]->getType(), TTI::CastContextHint::None,
6454 CostKind) *
6455 2;
6456 if (OldCost <= NewCost || !NewCost.isValid()) {
6457 LLVM_DEBUG(
6458 dbgs() << "VC: New deinterleave2 sequence cost (" << NewCost << ")"
6459 << " is higher than that of the old one (" << OldCost << ")\n");
6460 return false;
6461 }
6462
6463 // Do the replacement.
6464 IRBuilder<> Builder(&I);
6465 Value *NewVecCast = Builder.CreateBitCast(DeinterleavedVal, NewVecTy);
6466 Value *NewDeinterleave = Builder.CreateIntrinsic(
6467 Intrinsic::vector_deinterleave2, {NewVecTy}, {NewVecCast});
6468 for (auto [Idx, MergeInst] : enumerate(MergeInsts)) {
6469 Value *NewField = Builder.CreateExtractValue(NewDeinterleave, Idx);
6470 NewField = Builder.CreateBitCast(NewField, MergeInst->getType());
6471 replaceValue(*MergeInst, *NewField);
6472 }
6473
6474 return true;
6475}
6476
6477bool VectorCombine::foldBitcastOfVPLoad(Instruction &I) {
6478 const DataLayout &DL = I.getDataLayout();
6479 auto *Cast = dyn_cast<CastInst>(&I);
6480 if (!Cast || !Cast->isNoopCast(DL) || !isa<VectorType>(Cast->getDestTy()))
6481 return false;
6482
6483 // Fold away bit casts of the loaded value by loading the desired type,
6484 // if the mask is all-ones.
6485 Value *EVL;
6486 auto *II = dyn_cast<VPIntrinsic>(I.getOperand(0));
6488 m_Value(), m_AllOnes(), m_Value(EVL)))))
6489 return false;
6490
6491 VectorType *OrigVecTy = cast<VectorType>(II->getType());
6492 Align OrigAlign =
6493 DL.getValueOrABITypeAlignment(II->getPointerAlignment(), OrigVecTy);
6494 ElementCount OrigVecCnt = OrigVecTy->getElementCount();
6495 VectorType *NewVecTy = cast<VectorType>(Cast->getDestTy());
6496 ElementCount NewVecCnt = NewVecTy->getElementCount();
6497
6498 // Right now we only support cases where the NewVec is longer, because for
6499 // cases where it's shorter, we have to be sure that EVL can be exactly
6500 // divided, otherwise it might yield incorrect results or even page faults
6501 // (if we round-up during the division).
6502 if (!(OrigVecCnt.isScalable() == NewVecCnt.isScalable() &&
6503 NewVecCnt.hasKnownScalarFactor(OrigVecCnt)))
6504 return false;
6505
6506 InstructionCost OldCost =
6507 TTI.getMemIntrinsicInstrCost({Intrinsic::vp_load, OrigVecTy,
6508 II->getMemoryPointerParam(), false,
6509 OrigAlign},
6510 CostKind) +
6511 TTI.getCastInstrCost(Instruction::BitCast, Cast->getType(), OrigVecTy,
6514 {Intrinsic::vp_load, NewVecTy, II->getMemoryPointerParam(), false,
6515 OrigAlign},
6516 CostKind);
6517 LLVM_DEBUG(dbgs() << "foldBitcastOfVPLoad: OldCost=" << OldCost
6518 << " NewCost=" << NewCost << "\n");
6519 if (NewCost > OldCost || !NewCost.isValid())
6520 return false;
6521
6522 Builder.SetInsertPoint(II);
6523 unsigned Factor = NewVecCnt.getKnownScalarFactor(OrigVecCnt);
6524 Value *NewEVL = Builder.CreateNUWMul(EVL, Builder.getInt32(Factor));
6525 Value *NewMask = Builder.CreateVectorSplat(NewVecCnt, Builder.getTrue());
6526 CallInst *NewVP = Builder.CreateIntrinsicWithoutFolding(
6527 NewVecTy, Intrinsic::vp_load,
6528 {II->getMemoryPointerParam(), NewMask, NewEVL});
6529 // Preserve the original alignment.
6530 NewVP->addParamAttrs(
6531 0, AttrBuilder(II->getContext()).addAlignmentAttr(OrigAlign));
6532 replaceValue(*Cast, *NewVP);
6533 return true;
6534}
6535/// Fold the following cases into a single byte-level bit-reverse operation
6536/// and accepts bswap and bitreverse intrinsics:
6537/// bswap(bitreverse(x)) --> bitcast(bitreverse(bitcast(x)))
6538/// bitreverse(bswap(x)) <--> bitcast(bitreverse(bitcast(x)))
6539/// The direction of the fold is cost-model driven.
6540/// Also supports:
6541/// bitcast(bitreverse(bitcast(x))) --> bitreverse(fshl(x))
6542bool VectorCombine::foldBitOrderReverseAndSwap(Instruction &I) {
6543 Value *X;
6544
6546 Type *Ty = X->getType();
6547 Type *VecTy = I.getOperand(0)->getType();
6548 // Detect the case when bitreversing every octet in X individually. Then we
6549 // can use bswap to reorder the octets before doing a single bitreverse.
6550 bool CanUseBswap =
6551 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6552 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy(8) &&
6553 Ty->getIntegerBitWidth() % 16 == 0;
6554 // Detect the case when bitreversing upper and lower half of X
6555 // individually. Then we can use fshl as a rotate operation, to swap the
6556 // halves before doing a single bitreverse.
6557 bool CanUseFshl =
6558 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6559 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy() &&
6560 cast<FixedVectorType>(VecTy)->getNumElements() == 2;
6561 if (CanUseBswap || CanUseFshl) {
6562 auto *InnerCall = dyn_cast<Instruction>(I.getOperand(0));
6563 if (!InnerCall)
6564 return false;
6565 auto *InnerBitCast = dyn_cast<BitCastInst>(InnerCall->getOperand(0));
6566 if (!InnerBitCast)
6567 return false;
6568 Constant *HalfBW = ConstantInt::get(Ty, Ty->getIntegerBitWidth() / 2);
6569 InstructionCost OldCost = TTI.getInstructionCost(InnerBitCast, CostKind) +
6570 TTI.getInstructionCost(InnerCall, CostKind) +
6572 IntrinsicCostAttributes ICABSwap(Intrinsic::bswap, Ty, {Ty});
6573 IntrinsicCostAttributes ICABFshl(Intrinsic::fshl, Ty, {X, X, HalfBW},
6574 {Ty, Ty, Ty});
6575 IntrinsicCostAttributes ICABRev(Intrinsic::bitreverse, Ty, {Ty});
6576 InstructionCost NewCost =
6577 TTI.getIntrinsicInstrCost(CanUseBswap ? ICABSwap : ICABFshl,
6578 CostKind) +
6580 if (!InnerCall->hasOneUse())
6581 NewCost += TTI.getInstructionCost(InnerCall, CostKind) +
6582 TTI.getInstructionCost(InnerBitCast, CostKind);
6583 else if (!InnerBitCast->hasOneUse())
6584 NewCost += TTI.getInstructionCost(InnerBitCast, CostKind);
6585 LLVM_DEBUG(dbgs() << "Found bitreverse vector roundtrip: " << I
6586 << "\n OldCost: " << OldCost
6587 << " vs NewCost: " << NewCost << "\n");
6588 if (NewCost.isValid() && NewCost < OldCost) {
6589 Builder.SetInsertPoint(&I);
6590 Value *Swap =
6591 CanUseBswap
6592 ? Builder.CreateUnaryIntrinsic(Intrinsic::bswap, X)
6593 : Builder.CreateIntrinsic(Ty, Intrinsic::fshl, {X, X, HalfBW});
6594 Worklist.pushValue(Swap);
6595 Value *BRev = Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, Swap);
6596 replaceValue(I, *BRev);
6597 return true;
6598 }
6599 }
6600 }
6601
6602 if (!match(&I, m_BitReverse(m_BSwap(m_Value(X)))) &&
6604 return false;
6605 Type *Ty = I.getType();
6606 Type *I8Ty = Builder.getInt8Ty();
6607 TypeSize ElementSize = DL->getTypeStoreSize(Ty);
6608 ElementCount NewVecCnt = ElementCount::get(ElementSize.getKnownMinValue(),
6609 ElementSize.isScalable());
6610 Type *NewVecTy = VectorType::get(I8Ty, NewVecCnt);
6611 auto *II = cast<IntrinsicInst>(&I);
6612 auto *InnerII = cast<IntrinsicInst>(II->getArgOperand(0));
6613 // OldCost = cost of bitreverse/bswap + cost of bswap/bitreverse
6616 // NewCost = cost of bitcast to byte vector +
6617 // cost of bitreverse/bswap on byte vector +
6618 // cost of bitcast back to original type
6619 InstructionCost CastToVecCost = TTI.getCastInstrCost(
6620 Instruction::BitCast, NewVecTy, Ty, TTI::CastContextHint::None, CostKind);
6621 InstructionCost CastToOrigCost = TTI.getCastInstrCost(
6622 Instruction::BitCast, Ty, NewVecTy, TTI::CastContextHint::None, CostKind);
6623 IntrinsicCostAttributes ICANew(Intrinsic::bitreverse, NewVecTy, {NewVecTy});
6624 InstructionCost NewIntrinsicCost =
6626 InstructionCost NewCost = CastToVecCost + NewIntrinsicCost + CastToOrigCost;
6627 if (!InnerII->hasOneUse())
6628 NewCost += TTI.getInstructionCost(InnerII, CostKind);
6629 LLVM_DEBUG(dbgs() << "Found bitorder reverse and swap: " << I
6630 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6631 << "\n");
6632 if (!NewCost.isValid() || NewCost >= OldCost)
6633 return false;
6634 // Perform transform: bitcast(arg, <N x i8>), bitreverse, bitcast back
6635 Builder.SetInsertPoint(II);
6636 Value *CastToVec = Builder.CreateBitCast(X, NewVecTy);
6637 Value *NewCall =
6638 Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, CastToVec);
6639 Value *CastToOrig = Builder.CreateBitCast(NewCall, Ty);
6640 replaceValue(I, *CastToOrig);
6641 return true;
6642}
6643
6644/// Given the maximum shuffle index and load vector type, compute the number of
6645/// elements for the shrunk load, rounding up to the next full vector register
6646/// boundary to avoid scalar remainders that legalize poorly.
6647static unsigned getAlignedNumElements(unsigned MaxIdx, FixedVectorType *LoadTy,
6648 const TargetTransformInfo &TTI,
6649 const DataLayout &DL) {
6650 unsigned RawNumElements = MaxIdx + 1u;
6651 Type *ElemTy = LoadTy->getElementType();
6652 // Skip alignment for illegal element types.
6653 if (!TTI.isTypeLegal(ElemTy))
6654 return RawNumElements;
6655
6656 TypeSize ElemSize = DL.getTypeSizeInBits(ElemTy);
6657 if (ElemSize.isScalable() || ElemSize.isZero())
6658 return RawNumElements;
6659
6662 if (RegSize.isScalable() || RegSize.isZero())
6663 return RawNumElements;
6664
6665 unsigned ElemsPerReg = RegSize.getFixedValue() / ElemSize.getFixedValue();
6666 // If the load already fits in a register, keep the exact size.
6667 // Otherwise round up to the next full register boundary.
6668 if (ElemsPerReg == 0 || RawNumElements <= ElemsPerReg)
6669 return RawNumElements;
6670
6671 return alignTo(RawNumElements, ElemsPerReg);
6672}
6673
6674// Attempt to shrink loads that are only used by shufflevector instructions.
6675bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
6676 auto *OldLoad = dyn_cast<LoadInst>(&I);
6677 if (!OldLoad || !OldLoad->isSimple())
6678 return false;
6679
6680 auto *OldLoadTy = dyn_cast<FixedVectorType>(OldLoad->getType());
6681 if (!OldLoadTy)
6682 return false;
6683
6684 unsigned const OldNumElements = OldLoadTy->getNumElements();
6685
6686 // Search all uses of load. If all uses are shufflevector instructions, and
6687 // the second operands are all poison values, find the minimum and maximum
6688 // indices of the vector elements referenced by all shuffle masks.
6689 // Otherwise return `std::nullopt`.
6690 using IndexRange = std::pair<int, int>;
6691 auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
6692 IndexRange OutputRange = IndexRange(OldNumElements, -1);
6693 for (llvm::Use &Use : I.uses()) {
6694 // Ensure all uses match the required pattern.
6695 User *Shuffle = Use.getUser();
6696 ArrayRef<int> Mask;
6697
6698 if (!match(Shuffle,
6699 m_Shuffle(m_Specific(OldLoad), m_Undef(), m_Mask(Mask))))
6700 return std::nullopt;
6701
6702 // Ignore shufflevector instructions that have no uses.
6703 if (Shuffle->use_empty())
6704 continue;
6705
6706 // Find the min and max indices used by the shufflevector instruction.
6707 for (int Index : Mask) {
6708 if (Index >= 0 && Index < static_cast<int>(OldNumElements)) {
6709 OutputRange.first = std::min(Index, OutputRange.first);
6710 OutputRange.second = std::max(Index, OutputRange.second);
6711 }
6712 }
6713 }
6714
6715 if (OutputRange.second < OutputRange.first)
6716 return std::nullopt;
6717
6718 return OutputRange;
6719 };
6720
6721 // Get the range of vector elements used by shufflevector instructions.
6722 if (std::optional<IndexRange> Indices = GetIndexRangeInShuffles()) {
6723 unsigned const NewNumElements =
6724 getAlignedNumElements(Indices->second, OldLoadTy, TTI, *DL);
6725
6726 // If the range of vector elements is smaller than the full load, attempt
6727 // to create a smaller load.
6728 if (NewNumElements < OldNumElements) {
6729 IRBuilder Builder(&I);
6730 Builder.SetCurrentDebugLocation(I.getDebugLoc());
6731
6732 // Calculate costs of old and new ops.
6733 Type *ElemTy = OldLoadTy->getElementType();
6734 FixedVectorType *NewLoadTy = FixedVectorType::get(ElemTy, NewNumElements);
6735 Value *PtrOp = OldLoad->getPointerOperand();
6736
6738 Instruction::Load, OldLoad->getType(), OldLoad->getAlign(),
6739 OldLoad->getPointerAddressSpace(), CostKind);
6740 InstructionCost NewCost =
6741 TTI.getMemoryOpCost(Instruction::Load, NewLoadTy, OldLoad->getAlign(),
6742 OldLoad->getPointerAddressSpace(), CostKind);
6743
6744 using UseEntry = std::pair<ShuffleVectorInst *, std::vector<int>>;
6746 unsigned const MaxIndex = NewNumElements * 2u;
6747
6748 for (llvm::Use &Use : I.uses()) {
6749 auto *Shuffle = cast<ShuffleVectorInst>(Use.getUser());
6750
6751 // Ignore shufflevector instructions that have no uses.
6752 if (Shuffle->use_empty())
6753 continue;
6754
6755 ArrayRef<int> OldMask = Shuffle->getShuffleMask();
6756
6757 // Create entry for new use.
6758 NewUses.push_back({Shuffle, OldMask});
6759
6760 // Validate mask indices.
6761 for (int Index : OldMask) {
6762 if (Index >= static_cast<int>(MaxIndex))
6763 return false;
6764 }
6765
6766 // Update costs.
6767 OldCost +=
6769 OldLoadTy, CostKind, OldMask);
6770 NewCost +=
6772 NewLoadTy, CostKind, OldMask);
6773 }
6774
6775 LLVM_DEBUG(
6776 dbgs() << "Found a load used only by shufflevector instructions: "
6777 << I << "\n OldCost: " << OldCost
6778 << " vs NewCost: " << NewCost << "\n");
6779
6780 if (OldCost < NewCost || !NewCost.isValid())
6781 return false;
6782
6783 // Create new load of smaller vector.
6784 auto *NewLoad = cast<LoadInst>(
6785 Builder.CreateAlignedLoad(NewLoadTy, PtrOp, OldLoad->getAlign()));
6786 NewLoad->copyMetadata(I);
6787
6788 // Replace all uses.
6789 for (UseEntry &Use : NewUses) {
6790 ShuffleVectorInst *Shuffle = Use.first;
6791 std::vector<int> &NewMask = Use.second;
6792
6793 Builder.SetInsertPoint(Shuffle);
6794 Builder.SetCurrentDebugLocation(Shuffle->getDebugLoc());
6795 Value *NewShuffle = Builder.CreateShuffleVector(
6796 NewLoad, PoisonValue::get(NewLoadTy), NewMask);
6797
6798 replaceValue(*Shuffle, *NewShuffle, false);
6799 }
6800
6801 return true;
6802 }
6803 }
6804 return false;
6805}
6806
6807// Attempt to narrow a phi of shufflevector instructions where the two incoming
6808// values have the same operands but different masks. If the two shuffle masks
6809// are offsets of one another we can use one branch to rotate the incoming
6810// vector and perform one larger shuffle after the phi.
6811bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
6812 auto *Phi = dyn_cast<PHINode>(&I);
6813 if (!Phi || Phi->getNumIncomingValues() != 2u)
6814 return false;
6815
6816 Value *Op = nullptr;
6817 ArrayRef<int> Mask0;
6818 ArrayRef<int> Mask1;
6819
6820 if (!match(Phi->getOperand(0u),
6821 m_OneUse(m_Shuffle(m_Value(Op), m_Poison(), m_Mask(Mask0)))) ||
6822 !match(Phi->getOperand(1u),
6823 m_OneUse(m_Shuffle(m_Specific(Op), m_Poison(), m_Mask(Mask1)))))
6824 return false;
6825
6826 auto *Shuf = cast<ShuffleVectorInst>(Phi->getOperand(0u));
6827
6828 // Ensure result vectors are wider than the argument vector.
6829 auto *InputVT = cast<FixedVectorType>(Op->getType());
6830 auto *ResultVT = cast<FixedVectorType>(Shuf->getType());
6831 auto const InputNumElements = InputVT->getNumElements();
6832
6833 if (InputNumElements >= ResultVT->getNumElements())
6834 return false;
6835
6836 // Take the difference of the two shuffle masks at each index. Ignore poison
6837 // values at the same index in both masks.
6838 SmallVector<int, 16> NewMask;
6839 NewMask.reserve(Mask0.size());
6840
6841 for (auto [M0, M1] : zip(Mask0, Mask1)) {
6842 if (M0 >= 0 && M1 >= 0)
6843 NewMask.push_back(M0 - M1);
6844 else if (M0 == -1 && M1 == -1)
6845 continue;
6846 else
6847 return false;
6848 }
6849
6850 // Ensure all elements of the new mask are equal. If the difference between
6851 // the incoming mask elements is the same, the two must be constant offsets
6852 // of one another.
6853 if (NewMask.empty() || !all_equal(NewMask))
6854 return false;
6855
6856 // Create new mask using difference of the two incoming masks.
6857 int MaskOffset = NewMask[0u];
6858 unsigned Index = (InputNumElements + MaskOffset) % InputNumElements;
6859 NewMask.clear();
6860
6861 for (unsigned I = 0u; I < InputNumElements; ++I) {
6862 NewMask.push_back(Index);
6863 Index = (Index + 1u) % InputNumElements;
6864 }
6865
6866 // Calculate costs for worst cases and compare.
6867 auto const Kind = TTI::SK_PermuteSingleSrc;
6868 auto OldCost =
6869 std::max(TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask0),
6870 TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask1));
6871 auto NewCost = TTI.getShuffleCost(Kind, InputVT, InputVT, CostKind, NewMask) +
6872 TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask1);
6873
6874 LLVM_DEBUG(dbgs() << "Found a phi of mergeable shuffles: " << I
6875 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6876 << "\n");
6877
6878 if (NewCost > OldCost)
6879 return false;
6880
6881 // Create new shuffles and narrowed phi.
6882 auto Builder = IRBuilder(Shuf);
6883 Builder.SetCurrentDebugLocation(Shuf->getDebugLoc());
6884 auto *PoisonVal = PoisonValue::get(InputVT);
6885 auto *NewShuf0 = Builder.CreateShuffleVector(Op, PoisonVal, NewMask);
6886 Worklist.push(cast<Instruction>(NewShuf0));
6887
6888 Builder.SetInsertPoint(Phi);
6889 Builder.SetCurrentDebugLocation(Phi->getDebugLoc());
6890 auto *NewPhi = Builder.CreatePHI(NewShuf0->getType(), 2u);
6891 NewPhi->addIncoming(NewShuf0, Phi->getIncomingBlock(0u));
6892 NewPhi->addIncoming(Op, Phi->getIncomingBlock(1u));
6893
6894 Builder.SetInsertPoint(*NewPhi->getInsertionPointAfterDef());
6895 PoisonVal = PoisonValue::get(NewPhi->getType());
6896 auto *NewShuf1 = Builder.CreateShuffleVector(NewPhi, PoisonVal, Mask1);
6897
6898 replaceValue(*Phi, *NewShuf1);
6899 return true;
6900}
6901
6902/// This is the entry point for all transforms. Pass manager differences are
6903/// handled in the callers of this function.
6904bool VectorCombine::run() {
6906 return false;
6907
6908 // Don't attempt vectorization if the target does not support vectors.
6909 if (!TTI.getNumberOfRegisters(TTI.getRegisterClassForType(/*Vector*/ true)))
6910 return false;
6911
6912 LLVM_DEBUG(dbgs() << "\n\nVECTORCOMBINE on " << F.getName() << "\n");
6913
6914 auto FoldInst = [this](Instruction &I) {
6915 Builder.SetInsertPoint(&I);
6916 bool IsVectorType = isa<VectorType>(I.getType());
6917 bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
6918 auto Opcode = I.getOpcode();
6919
6920 LLVM_DEBUG(dbgs() << "VC: Visiting: " << I << '\n');
6921
6922 // These folds should be beneficial regardless of when this pass is run
6923 // in the optimization pipeline.
6924 // The type checking is for run-time efficiency. We can avoid wasting time
6925 // dispatching to folding functions if there's no chance of matching.
6926 if (IsFixedVectorType) {
6927 switch (Opcode) {
6928 case Instruction::InsertElement:
6929 if (vectorizeLoadInsert(I))
6930 return true;
6931 break;
6932 case Instruction::ShuffleVector:
6933 if (widenSubvectorLoad(I))
6934 return true;
6935 break;
6936 default:
6937 break;
6938 }
6939 }
6940
6941 // This transform works with scalable and fixed vectors
6942 // TODO: Identify and allow other scalable transforms
6943 if (IsVectorType) {
6944 if (scalarizeOpOrCmp(I))
6945 return true;
6946 if (scalarizeLoad(I))
6947 return true;
6948 if (scalarizeExtExtract(I))
6949 return true;
6950 if (foldInterleaveIntrinsics(I))
6951 return true;
6952 if (foldBitcastOfVPLoad(I))
6953 return true;
6954 }
6955
6956 if (foldDeinterleaveIntrinsics(I))
6957 return true;
6958
6959 if (Opcode == Instruction::Store)
6960 if (foldInsertElementsToStores(I))
6961 return true;
6962
6963 // If this is an early pipeline invocation of this pass, we are done.
6964 if (TryEarlyFoldsOnly)
6965 return false;
6966
6967 if (Opcode == Instruction::Call)
6968 if (foldBitOrderReverseAndSwap(I))
6969 return true;
6970 if (Opcode == Instruction::BitCast)
6971 if (foldBitOrderReverseAndSwap(I))
6972 return true;
6973
6974 // Otherwise, try folds that improve codegen but may interfere with
6975 // early IR canonicalizations.
6976 // The type checking is for run-time efficiency. We can avoid wasting time
6977 // dispatching to folding functions if there's no chance of matching.
6978 if (IsFixedVectorType) {
6979 switch (Opcode) {
6980 case Instruction::InsertElement:
6981 if (foldInsExtFNeg(I))
6982 return true;
6983 if (foldInsExtBinop(I))
6984 return true;
6985 if (foldInsExtVectorToShuffle(I))
6986 return true;
6987 break;
6988 case Instruction::ShuffleVector:
6989 if (foldPermuteOfBinops(I))
6990 return true;
6991 if (foldShuffleOfBinops(I))
6992 return true;
6993 if (foldShuffleOfSelects(I))
6994 return true;
6995 if (foldShuffleOfCastops(I))
6996 return true;
6997 if (foldShuffleOfShuffles(I))
6998 return true;
6999 if (foldPermuteOfIntrinsic(I))
7000 return true;
7001 if (foldShufflesOfLengthChangingShuffles(I))
7002 return true;
7003 if (foldShuffleOfIntrinsics(I))
7004 return true;
7005 if (foldSelectShuffle(I))
7006 return true;
7007 if (foldShuffleToIdentity(I))
7008 return true;
7009 break;
7010 case Instruction::Load:
7011 if (shrinkLoadForShuffles(I))
7012 return true;
7013 break;
7014 case Instruction::BitCast:
7015 if (foldBitcastShuffle(I))
7016 return true;
7017 if (foldSelectsFromBitcast(I))
7018 return true;
7019 break;
7020 case Instruction::And:
7021 case Instruction::Or:
7022 case Instruction::Xor:
7023 if (foldBitOpOfCastops(I))
7024 return true;
7025 if (foldBitOpOfCastConstant(I))
7026 return true;
7027 break;
7028 case Instruction::PHI:
7029 if (shrinkPhiOfShuffles(I))
7030 return true;
7031 break;
7032 default:
7033 if (shrinkType(I))
7034 return true;
7035 break;
7036 }
7037 } else {
7038 switch (Opcode) {
7039 case Instruction::Call:
7040 if (foldShuffleFromReductions(I))
7041 return true;
7042 if (foldCastFromReductions(I))
7043 return true;
7044 break;
7045 case Instruction::ExtractElement:
7046 if (foldShuffleChainsToReduce(I))
7047 return true;
7048 break;
7049 case Instruction::ICmp:
7050 if (foldSignBitReductionCmp(I))
7051 return true;
7052 if (foldICmpEqZeroVectorReduce(I))
7053 return true;
7054 if (foldReductionZeroTest(I))
7055 return true;
7056 if (foldEquivalentReductionCmp(I))
7057 return true;
7058 if (foldReduceAddCmpZero(I))
7059 return true;
7060 [[fallthrough]];
7061 case Instruction::FCmp:
7062 if (foldExtractExtract(I))
7063 return true;
7064 break;
7065 case Instruction::Or:
7066 if (foldConcatOfBoolMasks(I))
7067 return true;
7068 [[fallthrough]];
7069 default:
7070 if (Instruction::isBinaryOp(Opcode)) {
7071 if (foldExtractExtract(I))
7072 return true;
7073 if (foldExtractedCmps(I))
7074 return true;
7075 if (foldBinopOfReductions(I))
7076 return true;
7077 }
7078 break;
7079 }
7080 }
7081 return false;
7082 };
7083
7084 bool MadeChange = false;
7085 for (BasicBlock &BB : F) {
7086 // Ignore unreachable basic blocks.
7087 if (!DT.isReachableFromEntry(&BB))
7088 continue;
7089 // Use early increment range so that we can erase instructions in loop.
7090 // make_early_inc_range is not applicable here, as the next iterator may
7091 // be invalidated by RecursivelyDeleteTriviallyDeadInstructions.
7092 // We manually maintain the next instruction and update it when it is about
7093 // to be deleted.
7094 Instruction *I = &BB.front();
7095 while (I) {
7096 NextInst = I->getNextNode();
7097 if (!I->isDebugOrPseudoInst())
7098 MadeChange |= FoldInst(*I);
7099 I = NextInst;
7100 }
7101 }
7102
7103 NextInst = nullptr;
7104
7105 while (!Worklist.isEmpty()) {
7106 Instruction *I = Worklist.removeOne();
7107 if (!I)
7108 continue;
7109
7112 continue;
7113 }
7114
7115 MadeChange |= FoldInst(*I);
7116 }
7117
7118 return MadeChange;
7119}
7120
7123 auto &AC = FAM.getResult<AssumptionAnalysis>(F);
7125 DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
7126 AAResults &AA = FAM.getResult<AAManager>(F);
7127 const DataLayout *DL = &F.getDataLayout();
7130 VectorCombine Combiner(F, TTI, DT, AA, AC, DL, CostKind, TryEarlyFoldsOnly);
7131 if (!Combiner.run())
7132 return PreservedAnalyses::all();
7135 return PA;
7136}
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:857
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:1226
#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 Value * materializeScalarizedGEPIndex(Value *Idx, IntegerType *GEPIndexTy, IRBuilderBase &Builder)
Materialize an index for a scalarized GEP after profitability is known.
static Align computeAlignmentAfterScalarization(Align VectorAlignment, Type *ScalarType, Value *Idx, const DataLayout &DL)
The memory operation on a vector of ScalarType had alignment of VectorAlignment.
static bool feedsIntoVectorReduction(ShuffleVectorInst *SVI)
Returns true if this ShuffleVectorInst eventually feeds into a vector reduction intrinsic (e....
static 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 IntegerType * getScalarizedGEPIndexInfo(VectorType *VecTy, Value *Idx, Type *PtrTy, const DataLayout &DL)
Return the GEP index type if the unsigned vector index Idx can be represented by an inbounds GEP.
static Value * translateExtract(ExtractElementInst *ExtElt, unsigned NewIndex, IRBuilderBase &Builder)
Given an extract element instruction with constant index operand, shuffle the source vector (shift th...
static ScalarizationResult canScalarizeAccess(VectorType *VecTy, Value *Idx, const SimplifyQuery &SQ)
Check if it is legal to scalarize a memory access to VecTy at index Idx.
static 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:1057
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition APInt.h:1186
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
unsigned countl_one() const
Count the number of leading one bits.
Definition APInt.h:1635
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1030
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:292
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:385
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1225
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
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
bool empty() const
Definition DenseMap.h:732
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:782
iterator end()
Definition DenseMap.h:702
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:809
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:872
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:311
This instruction extracts a single (scalar) element from a VectorType value.
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
bool noSignedZeros() const
Definition FMF.h:67
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * getDoubleElementsVectorType(FixedVectorType *VTy)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
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:1456
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2661
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2649
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1926
Value * CreateNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, bool IsNUW, bool IsNSW, const Twine &Name="")
Definition IRBuilder.h:1735
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:2708
ConstantInt * getTrue()
Get the constant value for i1 true.
Definition IRBuilder.h:436
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:2727
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Definition IRBuilder.h:220
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1519
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Definition IRBuilder.h:2276
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
Definition IRBuilder.h:2765
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition IRBuilder.h:2011
Value * CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2301
Value * CreateFCmpFMF(CmpInst::Predicate P, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2502
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:461
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:456
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2508
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2539
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Definition IRBuilder.h:144
Value * CreateBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1724
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Definition IRBuilder.h:2760
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2235
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:1898
Value * CreateUnOpFMF(Instruction::UnaryOps Opc, Value *V, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1851
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1498
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:2113
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition IRBuilder.h:2683
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1557
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:1917
Value * CreateExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, bool IsExact, const Twine &Name="")
Definition IRBuilder.h:1747
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2099
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:556
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1718
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:179
Value * CreateFNegFMF(Value *V, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1831
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2484
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1579
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:503
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...
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
@ CompareCallTargets
Check for equivalence by comparing call targets.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isIdempotent() const
Return true if the instruction is idempotent:
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
bool isIntDivRem() const
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
void setAlignment(Align Align)
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
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void setAlignment(Align Align)
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI CastContextHint getCastContextHint(const Instruction *I)
Calculates a CastContextHint from I.
LLVM_ABI InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TargetCostKind CostKind, Type *AccessType=nullptr) const
Estimate the cost of a GEP operation when lowered.
LLVM_ABI TypeSize getRegisterBitWidth(RegisterKind K) const
LLVM_ABI InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, OperandValueInfo OpdInfo={OK_AnyValue, OP_None}, const Instruction *I=nullptr) const
static LLVM_ABI OperandValueInfo commonOperandInfo(const Value *X, const Value *Y)
Collect common data between two OperandValueInfo inputs.
LLVM_ABI bool allowVectorElementIndexingUsingGEP() const
Returns true if GEP should not be used to index into vectors for this target.
LLVM_ABI InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const
LLVM_ABI InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index=-1, const Value *Op0=nullptr, const Value *Op1=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
LLVM_ABI InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, OperandValueInfo Op1Info={OK_AnyValue, OP_None}, OperandValueInfo Op2Info={OK_AnyValue, OP_None}, const Instruction *I=nullptr) const
LLVM_ABI InstructionCost getShuffleCost(ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask={}, int Index=0, VectorType *SubTp=nullptr, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
LLVM_ABI InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const
LLVM_ABI unsigned getRegisterClassForType(bool Vector, Type *Ty=nullptr) const
LLVM_ABI InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const
Calculate the cost of vector reduction intrinsics.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
LLVM_ABI InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
LLVM_ABI InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const
LLVM_ABI unsigned getMinVectorRegisterBitWidth() const
LLVM_ABI InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const
LLVM_ABI unsigned getNumberOfRegisters(unsigned ClassID) const
LLVM_ABI InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, const TargetLibraryInfo *TLibInfo=nullptr) const
This is an approximation of reciprocal throughput of a math/logic op.
LLVM_ABI InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TargetCostKind CostKind) const
Estimate the cost of a given IR user when lowered.
LLVM_ABI InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
Estimate the overhead of scalarizing an instruction.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
@ 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:277
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
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:257
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
Definition Value.h:729
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
Definition Value.cpp:163
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition Value.cpp:1002
unsigned getValueID() const
Return an ID for the concrete type of this object.
Definition Value.h:545
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
Definition Value.cpp:147
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:712
bool use_empty() const
Definition Value.h:348
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
bool user_empty() const
Definition Value.h:391
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h: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*X will result in a value whose quantity matches our ...
Definition TypeSize.h:265
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS*X will result in a value whose quantity matches our own.
Definition TypeSize.h:273
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:2274
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition APInt.h:2279
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
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)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:339
@ Offset
Definition DWP.cpp:577
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition STLExtras.h:846
void stable_sort(R &&Range)
Definition STLExtras.h:2132
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
Definition LoopInfo.cpp: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:1748
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:522
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI Value * simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q)
Given operand for a UnaryOperator, fold the result or return null.
scope_exit(Callable) -> scope_exit< Callable >
@ Load
The value being inserted comes from a load (InsertElement only).
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:2224
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
LLVM_ABI Value * simplifyCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)
Given a callsite, callee, and arguments, fold the result or return null.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI bool mustSuppressSpeculation(const LoadInst &LI)
Return true if speculation of the given load must be suppressed to avoid ordering or interfering with...
Definition Loads.cpp:452
LLVM_ABI bool widenShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Try to transform a shuffle mask by replacing elements with the scaled index for an equivalent mask of...
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
LLVM_ABI Instruction * propagateMetadata(Instruction *I, ArrayRef< Value * > VL)
Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath, MD_nontemporal,...
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
unsigned M1(unsigned Val)
Definition VE.h: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:1762
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition Local.cpp:402
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI bool programUndefinedIfPoison(const Instruction *Inst)
LLVM_ABI unsigned getDeinterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.deinterleaveN intrinsics.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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
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 bool willNotFreeBetween(const Instruction *Assume, const Instruction *CtxI, const DominatorTree *DT=nullptr)
Returns true, if no instruction between Assume and CtxI may free (including through synchronization).
constexpr unsigned BitWidth
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
LLVM_ABI bool isSafeToLoadUnconditionally(Value *V, Align Alignment, const APInt &Size, const SimplifyQuery &SQ)
Return true if we know that executing a load from this value cannot trap.
Definition Loads.cpp:456
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h: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:2182
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicID(Intrinsic::ID IID)
Returns the llvm.vector.reduce min/max intrinsic that corresponds to the intrinsic op.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
LLVM_ABI AAMDNodes adjustForAccess(unsigned AccessSize)
Create a new AAMDNode for accessing AccessSize bytes of this AAMDNode.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
Definition KnownBits.h:310
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
Definition KnownBits.h:262
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Definition KnownBits.h:146
const DataLayout & DL
const DominatorTree * DT
SimplifyQuery getWithInstruction(const Instruction *I) const
AssumptionCache * AC
const Instruction * CtxI