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