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 if (!isa<FixedVectorType>(VecTy))
2304 return false;
2305
2306 Type *TargetScalarType = nullptr;
2307 unsigned VecBitWidth = DL->getTypeSizeInBits(VecTy);
2308
2309 for (User *U : LI->users()) {
2310 auto *BC = cast<BitCastInst>(U);
2311
2312 Type *DestTy = BC->getDestTy();
2313 if (!DestTy->isIntegerTy() && !DestTy->isFloatingPointTy())
2314 return false;
2315
2316 unsigned DestBitWidth = DL->getTypeSizeInBits(DestTy);
2317 if (DestBitWidth != VecBitWidth)
2318 return false;
2319
2320 // All bitcasts must target the same scalar type.
2321 if (!TargetScalarType)
2322 TargetScalarType = DestTy;
2323 else if (TargetScalarType != DestTy)
2324 return false;
2325
2326 OriginalCost +=
2327 TTI.getCastInstrCost(Instruction::BitCast, TargetScalarType, VecTy,
2329 }
2330
2331 if (!TargetScalarType)
2332 return false;
2333
2334 assert(!LI->user_empty() && "Unexpected load without bitcast users");
2335 InstructionCost ScalarizedCost =
2336 TTI.getMemoryOpCost(Instruction::Load, TargetScalarType, LI->getAlign(),
2338
2339 LLVM_DEBUG(dbgs() << "Found vector load feeding only bitcasts: " << *LI
2340 << "\n OriginalCost: " << OriginalCost
2341 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2342
2343 if (ScalarizedCost >= OriginalCost)
2344 return false;
2345
2346 // Ensure we add the load back to the worklist BEFORE its users so they can
2347 // erased in the correct order.
2348 Worklist.push(LI);
2349
2350 Builder.SetInsertPoint(LI);
2351 auto *ScalarLoad =
2352 Builder.CreateLoad(TargetScalarType, Ptr, LI->getName() + ".scalar");
2353 ScalarLoad->setAlignment(LI->getAlign());
2354 ScalarLoad->copyMetadata(*LI);
2355
2356 // Replace all bitcast users with the scalar load.
2357 for (User *U : LI->users()) {
2358 auto *BC = cast<BitCastInst>(U);
2359 replaceValue(*BC, *ScalarLoad, false);
2360 }
2361
2362 return true;
2363}
2364
2365bool VectorCombine::scalarizeExtExtract(Instruction &I) {
2367 return false;
2368 auto *Ext = dyn_cast<ZExtInst>(&I);
2369 if (!Ext)
2370 return false;
2371
2372 // Try to convert a vector zext feeding only extracts to a set of scalar
2373 // (Src << ExtIdx *Size) & (Size -1)
2374 // if profitable .
2375 auto *SrcTy = dyn_cast<FixedVectorType>(Ext->getOperand(0)->getType());
2376 if (!SrcTy)
2377 return false;
2378 auto *DstTy = cast<FixedVectorType>(Ext->getType());
2379
2380 Type *ScalarDstTy = DstTy->getElementType();
2381 if (DL->getTypeSizeInBits(SrcTy) != DL->getTypeSizeInBits(ScalarDstTy))
2382 return false;
2383
2384 InstructionCost VectorCost =
2385 TTI.getCastInstrCost(Instruction::ZExt, DstTy, SrcTy,
2387 unsigned ExtCnt = 0;
2388 bool ExtLane0 = false;
2389 for (User *U : Ext->users()) {
2390 uint64_t Idx;
2391 if (!match(U, m_ExtractElt(m_Value(), m_ConstantInt(Idx))))
2392 return false;
2393 // An out-of-bounds extractelement produces poison; bail out rather
2394 // than computing a shift amount that overflows the packed type.
2395 if (Idx >= SrcTy->getNumElements())
2396 return false;
2397 if (cast<Instruction>(U)->use_empty())
2398 continue;
2399 ExtCnt += 1;
2400 ExtLane0 |= !Idx;
2401 VectorCost += TTI.getVectorInstrCost(Instruction::ExtractElement, DstTy,
2402 CostKind, Idx, U);
2403 }
2404
2405 InstructionCost ScalarCost =
2406 ExtCnt * TTI.getArithmeticInstrCost(
2407 Instruction::And, ScalarDstTy, CostKind,
2410 (ExtCnt - ExtLane0) *
2412 Instruction::LShr, ScalarDstTy, CostKind,
2415 if (ScalarCost > VectorCost)
2416 return false;
2417
2418 Value *ScalarV = Ext->getOperand(0);
2419 if (!isGuaranteedNotToBePoison(ScalarV, SQ.AC, dyn_cast<Instruction>(ScalarV),
2420 SQ.DT)) {
2421 // Check wether all lanes are extracted, all extracts trigger UB
2422 // on poison, and the last extract (and hence all previous ones)
2423 // are guaranteed to execute if Ext executes. If so, we do not
2424 // need to insert a freeze.
2425 SmallDenseSet<ConstantInt *, 8> ExtractedLanes;
2426 bool AllExtractsTriggerUB = true;
2427 ExtractElementInst *LastExtract = nullptr;
2428 BasicBlock *ExtBB = Ext->getParent();
2429 for (User *U : Ext->users()) {
2430 auto *Extract = cast<ExtractElementInst>(U);
2431 if (Extract->getParent() != ExtBB || !programUndefinedIfPoison(Extract)) {
2432 AllExtractsTriggerUB = false;
2433 break;
2434 }
2435 ExtractedLanes.insert(cast<ConstantInt>(Extract->getIndexOperand()));
2436 if (!LastExtract || LastExtract->comesBefore(Extract))
2437 LastExtract = Extract;
2438 }
2439 if (ExtractedLanes.size() != DstTy->getNumElements() ||
2440 !AllExtractsTriggerUB ||
2442 LastExtract->getIterator()))
2443 ScalarV = Builder.CreateFreeze(ScalarV);
2444 }
2445 ScalarV = Builder.CreateBitCast(
2446 ScalarV,
2447 IntegerType::get(SrcTy->getContext(), DL->getTypeSizeInBits(SrcTy)));
2448 uint64_t SrcEltSizeInBits = DL->getTypeSizeInBits(SrcTy->getElementType());
2449 uint64_t TotalBits = DL->getTypeSizeInBits(SrcTy);
2450 APInt EltBitMask = APInt::getLowBitsSet(TotalBits, SrcEltSizeInBits);
2451 Type *PackedTy = IntegerType::get(SrcTy->getContext(), TotalBits);
2452 Value *Mask = ConstantInt::get(PackedTy, EltBitMask);
2453 for (User *U : Ext->users()) {
2454 auto *Extract = cast<ExtractElementInst>(U);
2455 uint64_t Idx =
2456 cast<ConstantInt>(Extract->getIndexOperand())->getZExtValue();
2457 uint64_t ShiftAmt =
2458 DL->isBigEndian()
2459 ? (TotalBits - SrcEltSizeInBits - Idx * SrcEltSizeInBits)
2460 : (Idx * SrcEltSizeInBits);
2461 Value *LShr = Builder.CreateLShr(ScalarV, ShiftAmt);
2462 Value *And = Builder.CreateAnd(LShr, Mask);
2463 U->replaceAllUsesWith(And);
2464 }
2465 return true;
2466}
2467
2468/// Try to fold "(or (zext (bitcast X)), (shl (zext (bitcast Y)), C))"
2469/// to "(bitcast (concat X, Y))"
2470/// where X/Y are bitcasted from i1 mask vectors.
2471bool VectorCombine::foldConcatOfBoolMasks(Instruction &I) {
2472 Type *Ty = I.getType();
2473 if (!Ty->isIntegerTy())
2474 return false;
2475
2476 // TODO: Add big endian test coverage
2477 if (DL->isBigEndian())
2478 return false;
2479
2480 // Restrict to disjoint cases so the mask vectors aren't overlapping.
2481 Instruction *X, *Y;
2483 return false;
2484
2485 // Allow both sources to contain shl, to handle more generic pattern:
2486 // "(or (shl (zext (bitcast X)), C1), (shl (zext (bitcast Y)), C2))"
2487 Value *SrcX;
2488 uint64_t ShAmtX = 0;
2489 if (!match(X, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcX)))))) &&
2490 !match(X, m_OneUse(
2492 m_ConstantInt(ShAmtX)))))
2493 return false;
2494
2495 Value *SrcY;
2496 uint64_t ShAmtY = 0;
2497 if (!match(Y, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcY)))))) &&
2498 !match(Y, m_OneUse(
2500 m_ConstantInt(ShAmtY)))))
2501 return false;
2502
2503 // Canonicalize larger shift to the RHS.
2504 if (ShAmtX > ShAmtY) {
2505 std::swap(X, Y);
2506 std::swap(SrcX, SrcY);
2507 std::swap(ShAmtX, ShAmtY);
2508 }
2509
2510 // Ensure both sources are matching vXi1 bool mask types, and that the shift
2511 // difference is the mask width so they can be easily concatenated together.
2512 uint64_t ShAmtDiff = ShAmtY - ShAmtX;
2513 unsigned NumSHL = (ShAmtX > 0) + (ShAmtY > 0);
2514 unsigned BitWidth = Ty->getPrimitiveSizeInBits();
2515 auto *MaskTy = dyn_cast<FixedVectorType>(SrcX->getType());
2516 if (!MaskTy || SrcX->getType() != SrcY->getType() ||
2517 !MaskTy->getElementType()->isIntegerTy(1) ||
2518 MaskTy->getNumElements() != ShAmtDiff ||
2519 MaskTy->getNumElements() > (BitWidth / 2))
2520 return false;
2521
2522 auto *ConcatTy = FixedVectorType::getDoubleElementsVectorType(MaskTy);
2523 auto *ConcatIntTy =
2524 Type::getIntNTy(Ty->getContext(), ConcatTy->getNumElements());
2525 auto *MaskIntTy = Type::getIntNTy(Ty->getContext(), ShAmtDiff);
2526
2527 SmallVector<int, 32> ConcatMask(ConcatTy->getNumElements());
2528 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
2529
2530 // TODO: Is it worth supporting multi use cases?
2531 InstructionCost OldCost = 0;
2532 OldCost += TTI.getArithmeticInstrCost(Instruction::Or, Ty, CostKind);
2533 OldCost +=
2534 NumSHL * TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2535 OldCost += 2 * TTI.getCastInstrCost(Instruction::ZExt, Ty, MaskIntTy,
2537 OldCost += 2 * TTI.getCastInstrCost(Instruction::BitCast, MaskIntTy, MaskTy,
2539
2540 InstructionCost NewCost = 0;
2542 MaskTy, CostKind, ConcatMask);
2543 NewCost += TTI.getCastInstrCost(Instruction::BitCast, ConcatIntTy, ConcatTy,
2545 if (Ty != ConcatIntTy)
2546 NewCost += TTI.getCastInstrCost(Instruction::ZExt, Ty, ConcatIntTy,
2548 if (ShAmtX > 0)
2549 NewCost += TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2550
2551 LLVM_DEBUG(dbgs() << "Found a concatenation of bitcasted bool masks: " << I
2552 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2553 << "\n");
2554
2555 if (NewCost > OldCost)
2556 return false;
2557
2558 // Build bool mask concatenation, bitcast back to scalar integer, and perform
2559 // any residual zero-extension or shifting.
2560 Value *Concat = Builder.CreateShuffleVector(SrcX, SrcY, ConcatMask);
2561 Worklist.pushValue(Concat);
2562
2563 Value *Result = Builder.CreateBitCast(Concat, ConcatIntTy);
2564
2565 if (Ty != ConcatIntTy) {
2566 Worklist.pushValue(Result);
2567 Result = Builder.CreateZExt(Result, Ty);
2568 }
2569
2570 if (ShAmtX > 0) {
2571 Worklist.pushValue(Result);
2572 Result = Builder.CreateShl(Result, ShAmtX);
2573 }
2574
2575 replaceValue(I, *Result);
2576 return true;
2577}
2578
2579/// Try to convert "shuffle (binop (shuffle, shuffle)), undef"
2580/// --> "binop (shuffle), (shuffle)".
2581bool VectorCombine::foldPermuteOfBinops(Instruction &I) {
2582 BinaryOperator *BinOp;
2583 ArrayRef<int> OuterMask;
2584 if (!match(&I, m_Shuffle(m_BinOp(BinOp), m_Undef(), m_Mask(OuterMask))))
2585 return false;
2586
2587 // Don't introduce poison into div/rem.
2588 if (BinOp->isIntDivRem() && llvm::is_contained(OuterMask, PoisonMaskElem))
2589 return false;
2590
2591 Value *Op00, *Op01, *Op10, *Op11;
2592 ArrayRef<int> Mask0, Mask1;
2593 bool Match0 = match(BinOp->getOperand(0),
2594 m_Shuffle(m_Value(Op00), m_Value(Op01), m_Mask(Mask0)));
2595 bool Match1 = match(BinOp->getOperand(1),
2596 m_Shuffle(m_Value(Op10), m_Value(Op11), m_Mask(Mask1)));
2597 if (!Match0 && !Match1)
2598 return false;
2599
2600 Op00 = Match0 ? Op00 : BinOp->getOperand(0);
2601 Op01 = Match0 ? Op01 : BinOp->getOperand(0);
2602 Op10 = Match1 ? Op10 : BinOp->getOperand(1);
2603 Op11 = Match1 ? Op11 : BinOp->getOperand(1);
2604
2605 Instruction::BinaryOps Opcode = BinOp->getOpcode();
2606 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2607 auto *BinOpTy = dyn_cast<FixedVectorType>(BinOp->getType());
2608 auto *Op0Ty = dyn_cast<FixedVectorType>(Op00->getType());
2609 auto *Op1Ty = dyn_cast<FixedVectorType>(Op10->getType());
2610 if (!ShuffleDstTy || !BinOpTy || !Op0Ty || !Op1Ty)
2611 return false;
2612
2613 unsigned NumSrcElts = BinOpTy->getNumElements();
2614
2615 // Don't accept shuffles that reference the second operand in
2616 // div/rem or if its an undef arg.
2617 if ((BinOp->isIntDivRem() || !isa<PoisonValue>(I.getOperand(1))) &&
2618 any_of(OuterMask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
2619 return false;
2620
2621 // Merge outer / inner (or identity if no match) shuffles.
2622 SmallVector<int> NewMask0, NewMask1;
2623 for (int M : OuterMask) {
2624 if (M < 0 || M >= (int)NumSrcElts) {
2625 NewMask0.push_back(PoisonMaskElem);
2626 NewMask1.push_back(PoisonMaskElem);
2627 } else {
2628 NewMask0.push_back(Match0 ? Mask0[M] : M);
2629 NewMask1.push_back(Match1 ? Mask1[M] : M);
2630 }
2631 }
2632
2633 unsigned NumOpElts = Op0Ty->getNumElements();
2634 bool IsIdentity0 = ShuffleDstTy == Op0Ty &&
2635 all_of(NewMask0, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2636 ShuffleVectorInst::isIdentityMask(NewMask0, NumOpElts);
2637 bool IsIdentity1 = ShuffleDstTy == Op1Ty &&
2638 all_of(NewMask1, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2639 ShuffleVectorInst::isIdentityMask(NewMask1, NumOpElts);
2640
2641 InstructionCost NewCost = 0;
2642 // Try to merge shuffles across the binop if the new shuffles are not costly.
2643 InstructionCost BinOpCost =
2644 TTI.getArithmeticInstrCost(Opcode, BinOpTy, CostKind);
2645 InstructionCost OldCost =
2647 ShuffleDstTy, BinOpTy, CostKind, OuterMask,
2648 0, nullptr, {BinOp}, &I);
2649 if (!BinOp->hasOneUse())
2650 NewCost += BinOpCost;
2651
2652 if (Match0) {
2654 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op0Ty, CostKind, Mask0,
2655 0, nullptr, {Op00, Op01}, cast<Instruction>(BinOp->getOperand(0)));
2656 OldCost += Shuf0Cost;
2657 if (!BinOp->hasOneUse() || !BinOp->getOperand(0)->hasOneUse())
2658 NewCost += Shuf0Cost;
2659 }
2660 if (Match1) {
2662 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op1Ty, CostKind, Mask1,
2663 0, nullptr, {Op10, Op11}, cast<Instruction>(BinOp->getOperand(1)));
2664 OldCost += Shuf1Cost;
2665 if (!BinOp->hasOneUse() || !BinOp->getOperand(1)->hasOneUse())
2666 NewCost += Shuf1Cost;
2667 }
2668
2669 NewCost += TTI.getArithmeticInstrCost(Opcode, ShuffleDstTy, CostKind);
2670
2671 if (!IsIdentity0)
2672 NewCost +=
2674 Op0Ty, CostKind, NewMask0, 0, nullptr, {Op00, Op01});
2675 if (!IsIdentity1)
2676 NewCost +=
2678 Op1Ty, CostKind, NewMask1, 0, nullptr, {Op10, Op11});
2679
2680 LLVM_DEBUG(dbgs() << "Found a shuffle feeding a shuffled binop: " << I
2681 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2682 << "\n");
2683
2684 // If costs are equal, still fold as we reduce instruction count.
2685 if (NewCost > OldCost)
2686 return false;
2687
2688 Value *LHS =
2689 IsIdentity0 ? Op00 : Builder.CreateShuffleVector(Op00, Op01, NewMask0);
2690 Value *RHS =
2691 IsIdentity1 ? Op10 : Builder.CreateShuffleVector(Op10, Op11, NewMask1);
2692 Value *NewBO = Builder.CreateBinOp(Opcode, LHS, RHS);
2693
2694 // Intersect flags from the old binops.
2695 if (auto *NewInst = dyn_cast<Instruction>(NewBO))
2696 NewInst->copyIRFlags(BinOp);
2697
2698 Worklist.pushValue(LHS);
2699 Worklist.pushValue(RHS);
2700 replaceValue(I, *NewBO);
2701 return true;
2702}
2703
2704/// Try to convert "shuffle (binop), (binop)" into "binop (shuffle), (shuffle)".
2705/// Try to convert "shuffle (cmpop), (cmpop)" into "cmpop (shuffle), (shuffle)".
2706bool VectorCombine::foldShuffleOfBinops(Instruction &I) {
2707 ArrayRef<int> OldMask;
2708 Instruction *LHS, *RHS;
2710 m_Mask(OldMask))))
2711 return false;
2712
2713 // TODO: Add support for addlike etc.
2714 if (LHS->getOpcode() != RHS->getOpcode())
2715 return false;
2716
2717 Value *X, *Y, *Z, *W;
2718 bool IsCommutative = false;
2719 CmpPredicate PredLHS = CmpInst::BAD_ICMP_PREDICATE;
2720 CmpPredicate PredRHS = CmpInst::BAD_ICMP_PREDICATE;
2721 if (match(LHS, m_BinOp(m_Value(X), m_Value(Y))) &&
2722 match(RHS, m_BinOp(m_Value(Z), m_Value(W)))) {
2723 auto *BO = cast<BinaryOperator>(LHS);
2724 // Don't introduce poison into div/rem.
2725 if (llvm::is_contained(OldMask, PoisonMaskElem) && BO->isIntDivRem())
2726 return false;
2727 IsCommutative = BinaryOperator::isCommutative(BO->getOpcode());
2728 } else if (match(LHS, m_Cmp(PredLHS, m_Value(X), m_Value(Y))) &&
2729 match(RHS, m_Cmp(PredRHS, m_Value(Z), m_Value(W))) &&
2730 (CmpInst::Predicate)PredLHS == (CmpInst::Predicate)PredRHS) {
2731 IsCommutative = cast<CmpInst>(LHS)->isCommutative();
2732 } else
2733 return false;
2734
2735 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2736 auto *BinResTy = dyn_cast<FixedVectorType>(LHS->getType());
2737 auto *BinOpTy = dyn_cast<FixedVectorType>(X->getType());
2738 if (!ShuffleDstTy || !BinResTy || !BinOpTy || X->getType() != Z->getType())
2739 return false;
2740
2741 bool SameBinOp = LHS == RHS;
2742 unsigned NumSrcElts = BinOpTy->getNumElements();
2743
2744 // If we have something like "add X, Y" and "add Z, X", swap ops to match.
2745 if (IsCommutative && X != Z && Y != W && (X == W || Y == Z))
2746 std::swap(X, Y);
2747
2748 auto ConvertToUnary = [NumSrcElts](int &M) {
2749 if (M >= (int)NumSrcElts)
2750 M -= NumSrcElts;
2751 };
2752
2753 SmallVector<int> NewMask0(OldMask);
2755 TTI::OperandValueInfo Op0Info = TTI.commonOperandInfo(X, Z);
2756 if (X == Z) {
2757 llvm::for_each(NewMask0, ConvertToUnary);
2759 Z = PoisonValue::get(BinOpTy);
2760 }
2761
2762 SmallVector<int> NewMask1(OldMask);
2764 TTI::OperandValueInfo Op1Info = TTI.commonOperandInfo(Y, W);
2765 if (Y == W) {
2766 llvm::for_each(NewMask1, ConvertToUnary);
2768 W = PoisonValue::get(BinOpTy);
2769 }
2770
2771 // Try to replace a binop with a shuffle if the shuffle is not costly.
2772 // When SameBinOp, only count the binop cost once.
2775
2776 InstructionCost OldCost = LHSCost;
2777 if (!SameBinOp) {
2778 OldCost += RHSCost;
2779 }
2781 ShuffleDstTy, BinResTy, CostKind, OldMask, 0,
2782 nullptr, {LHS, RHS}, &I);
2783
2784 // Handle shuffle(binop(shuffle(x),y),binop(z,shuffle(w))) style patterns
2785 // where one use shuffles have gotten split across the binop/cmp. These
2786 // often allow a major reduction in total cost that wouldn't happen as
2787 // individual folds.
2788 auto MergeInner = [&](Value *&Op, int Offset, MutableArrayRef<int> Mask,
2789 TTI::TargetCostKind CostKind) -> bool {
2790 Value *InnerOp;
2791 ArrayRef<int> InnerMask;
2792 if (match(Op, m_OneUse(m_Shuffle(m_Value(InnerOp), m_Undef(),
2793 m_Mask(InnerMask)))) &&
2794 InnerOp->getType() == Op->getType() &&
2795 all_of(InnerMask,
2796 [NumSrcElts](int M) { return M < (int)NumSrcElts; })) {
2797 for (int &M : Mask)
2798 if (Offset <= M && M < (int)(Offset + NumSrcElts)) {
2799 M = InnerMask[M - Offset];
2800 M = 0 <= M ? M + Offset : M;
2801 }
2803 Op = InnerOp;
2804 return true;
2805 }
2806 return false;
2807 };
2808 bool ReducedInstCount = false;
2809 ReducedInstCount |= MergeInner(X, 0, NewMask0, CostKind);
2810 ReducedInstCount |= MergeInner(Y, 0, NewMask1, CostKind);
2811 ReducedInstCount |= MergeInner(Z, NumSrcElts, NewMask0, CostKind);
2812 ReducedInstCount |= MergeInner(W, NumSrcElts, NewMask1, CostKind);
2813 bool SingleSrcBinOp = (X == Y) && (Z == W) && (NewMask0 == NewMask1);
2814 // SingleSrcBinOp only reduces instruction count if we also eliminate the
2815 // original binop(s). If binops have multiple uses, they won't be eliminated.
2816 ReducedInstCount |= SingleSrcBinOp && LHS->hasOneUser() && RHS->hasOneUser();
2817
2818 // For concat shuffles of i1 vectors where both binops are one-use, the
2819 // transform keeps the same instruction count but canonicalises to a single
2820 // wider binop, enabling downstream folds (e.g. NOT(XOR(concat(a,b),
2821 // concat(c,d))) -> XNOR(concat(a,b),concat(c,d)) on AVX-512 mask regs).
2822 // Restrict to BinaryOperator (not CmpInst) since narrow comparisons may
2823 // be cheaper than wide ones on some targets (e.g. AVX-512 vpcmpeq).
2824 ReducedInstCount |= cast<ShuffleVectorInst>(&I)->isConcat() &&
2825 I.getType()->getScalarType()->isIntegerTy(1) &&
2827 RHS->hasOneUser();
2828
2829 auto *ShuffleCmpTy =
2830 FixedVectorType::get(BinOpTy->getElementType(), ShuffleDstTy);
2832 SK0, ShuffleCmpTy, BinOpTy, CostKind, NewMask0, 0, nullptr, {X, Z});
2833 if (!SingleSrcBinOp)
2834 NewCost += TTI.getShuffleCost(SK1, ShuffleCmpTy, BinOpTy, CostKind,
2835 NewMask1, 0, nullptr, {Y, W});
2836
2837 if (PredLHS == CmpInst::BAD_ICMP_PREDICATE) {
2838 NewCost += TTI.getArithmeticInstrCost(LHS->getOpcode(), ShuffleDstTy,
2839 CostKind, Op0Info, Op1Info);
2840 } else {
2841 NewCost +=
2842 TTI.getCmpSelInstrCost(LHS->getOpcode(), ShuffleCmpTy, ShuffleDstTy,
2843 PredLHS, CostKind, Op0Info, Op1Info);
2844 }
2845 // If LHS/RHS have other uses, we need to account for the cost of keeping
2846 // the original instructions. When SameBinOp, only add the cost once.
2847 if (!LHS->hasOneUser())
2848 NewCost += LHSCost;
2849 if (!SameBinOp && !RHS->hasOneUser())
2850 NewCost += RHSCost;
2851
2852 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two binops: " << I
2853 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2854 << "\n");
2855
2856 // If either shuffle will constant fold away, then fold for the same cost as
2857 // we will reduce the instruction count.
2858 ReducedInstCount |= (isa<Constant>(X) && isa<Constant>(Z)) ||
2859 (isa<Constant>(Y) && isa<Constant>(W));
2860 if (ReducedInstCount ? (NewCost > OldCost) : (NewCost >= OldCost))
2861 return false;
2862
2863 Value *Shuf0 = Builder.CreateShuffleVector(X, Z, NewMask0);
2864 Value *Shuf1 =
2865 SingleSrcBinOp ? Shuf0 : Builder.CreateShuffleVector(Y, W, NewMask1);
2866 Value *NewBO = PredLHS == CmpInst::BAD_ICMP_PREDICATE
2867 ? Builder.CreateBinOp(
2868 cast<BinaryOperator>(LHS)->getOpcode(), Shuf0, Shuf1)
2869 : Builder.CreateCmp(PredLHS, Shuf0, Shuf1);
2870
2871 // Intersect flags from the old binops.
2872 if (auto *NewInst = dyn_cast<Instruction>(NewBO)) {
2873 NewInst->copyIRFlags(LHS);
2874 NewInst->andIRFlags(RHS);
2875 }
2876
2877 Worklist.pushValue(Shuf0);
2878 Worklist.pushValue(Shuf1);
2879 replaceValue(I, *NewBO);
2880 return true;
2881}
2882
2883/// Try to convert,
2884/// (shuffle(select(c1,t1,f1)), (select(c2,t2,f2)), m) into
2885/// (select (shuffle c1,c2,m), (shuffle t1,t2,m), (shuffle f1,f2,m))
2886bool VectorCombine::foldShuffleOfSelects(Instruction &I) {
2887 ArrayRef<int> Mask;
2888 Value *C1, *T1, *F1, *C2, *T2, *F2;
2889 if (!match(&I, m_Shuffle(m_Select(m_Value(C1), m_Value(T1), m_Value(F1)),
2890 m_Select(m_Value(C2), m_Value(T2), m_Value(F2)),
2891 m_Mask(Mask))))
2892 return false;
2893
2894 auto *Sel1 = cast<Instruction>(I.getOperand(0));
2895 auto *Sel2 = cast<Instruction>(I.getOperand(1));
2896
2897 auto *C1VecTy = dyn_cast<FixedVectorType>(C1->getType());
2898 auto *C2VecTy = dyn_cast<FixedVectorType>(C2->getType());
2899 if (!C1VecTy || !C2VecTy || C1VecTy != C2VecTy)
2900 return false;
2901
2902 auto *SI0FOp = dyn_cast<FPMathOperator>(I.getOperand(0));
2903 auto *SI1FOp = dyn_cast<FPMathOperator>(I.getOperand(1));
2904 // SelectInsts must have the same FMF.
2905 if (((SI0FOp == nullptr) != (SI1FOp == nullptr)) ||
2906 ((SI0FOp != nullptr) &&
2907 (SI0FOp->getFastMathFlags() != SI1FOp->getFastMathFlags())))
2908 return false;
2909
2910 auto *SrcVecTy = cast<FixedVectorType>(T1->getType());
2911 auto *DstVecTy = cast<FixedVectorType>(I.getType());
2913 auto SelOp = Instruction::Select;
2914
2916 SelOp, SrcVecTy, C1VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2918 SelOp, SrcVecTy, C2VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2919
2920 InstructionCost OldCost =
2921 CostSel1 + CostSel2 +
2922 TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0, nullptr,
2923 {I.getOperand(0), I.getOperand(1)}, &I);
2924
2926 SK, FixedVectorType::get(C1VecTy->getScalarType(), Mask.size()), C1VecTy,
2927 CostKind, Mask, 0, nullptr, {C1, C2});
2928 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0,
2929 nullptr, {T1, T2});
2930 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, CostKind, Mask, 0,
2931 nullptr, {F1, F2});
2932 auto *C1C2ShuffledVecTy = FixedVectorType::get(
2933 Type::getInt1Ty(I.getContext()), DstVecTy->getNumElements());
2934 NewCost += TTI.getCmpSelInstrCost(SelOp, DstVecTy, C1C2ShuffledVecTy,
2936
2937 if (!Sel1->hasOneUse())
2938 NewCost += CostSel1;
2939 if (!Sel2->hasOneUse())
2940 NewCost += CostSel2;
2941
2942 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two selects: " << I
2943 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2944 << "\n");
2945 if (NewCost > OldCost)
2946 return false;
2947
2948 Value *ShuffleCmp = Builder.CreateShuffleVector(C1, C2, Mask);
2949 Value *ShuffleTrue = Builder.CreateShuffleVector(T1, T2, Mask);
2950 Value *ShuffleFalse = Builder.CreateShuffleVector(F1, F2, Mask);
2951 Value *NewSel;
2952 // We presuppose that the SelectInsts have the same FMF.
2953 if (SI0FOp)
2954 NewSel = Builder.CreateSelectFMF(ShuffleCmp, ShuffleTrue, ShuffleFalse,
2955 SI0FOp->getFastMathFlags());
2956 else
2957 NewSel = Builder.CreateSelect(ShuffleCmp, ShuffleTrue, ShuffleFalse);
2958
2959 Worklist.pushValue(ShuffleCmp);
2960 Worklist.pushValue(ShuffleTrue);
2961 Worklist.pushValue(ShuffleFalse);
2962 replaceValue(I, *NewSel);
2963 return true;
2964}
2965
2966/// Try to convert "shuffle (castop), (castop)" with a shared castop operand
2967/// into "castop (shuffle)".
2968bool VectorCombine::foldShuffleOfCastops(Instruction &I) {
2969 Value *V0, *V1;
2970 ArrayRef<int> OldMask;
2971 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
2972 return false;
2973
2974 // Check whether this is a binary shuffle.
2975 bool IsBinaryShuffle = !isa<UndefValue>(V1);
2976
2977 auto *C0 = dyn_cast<CastInst>(V0);
2978 auto *C1 = dyn_cast<CastInst>(V1);
2979 if (!C0 || (IsBinaryShuffle && !C1))
2980 return false;
2981
2982 Instruction::CastOps Opcode = C0->getOpcode();
2983
2984 // If this is allowed, foldShuffleOfCastops can get stuck in a loop
2985 // with foldBitcastOfShuffle. Reject in favor of foldBitcastOfShuffle.
2986 if (!IsBinaryShuffle && Opcode == Instruction::BitCast)
2987 return false;
2988
2989 if (IsBinaryShuffle) {
2990 if (C0->getSrcTy() != C1->getSrcTy())
2991 return false;
2992 // Handle shuffle(zext_nneg(x), sext(y)) -> sext(shuffle(x,y)) folds.
2993 if (Opcode != C1->getOpcode()) {
2994 if (match(C0, m_SExtLike(m_Value())) && match(C1, m_SExtLike(m_Value())))
2995 Opcode = Instruction::SExt;
2996 else
2997 return false;
2998 }
2999 }
3000
3001 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3002 auto *CastDstTy = dyn_cast<FixedVectorType>(C0->getDestTy());
3003 auto *CastSrcTy = dyn_cast<FixedVectorType>(C0->getSrcTy());
3004 if (!ShuffleDstTy || !CastDstTy || !CastSrcTy)
3005 return false;
3006
3007 unsigned NumSrcElts = CastSrcTy->getNumElements();
3008 unsigned NumDstElts = CastDstTy->getNumElements();
3009 assert((NumDstElts == NumSrcElts || Opcode == Instruction::BitCast) &&
3010 "Only bitcasts expected to alter src/dst element counts");
3011
3012 // Check for bitcasting of unscalable vector types.
3013 // e.g. <32 x i40> -> <40 x i32>
3014 if (NumDstElts != NumSrcElts && (NumSrcElts % NumDstElts) != 0 &&
3015 (NumDstElts % NumSrcElts) != 0)
3016 return false;
3017
3018 SmallVector<int, 16> NewMask;
3019 if (NumSrcElts >= NumDstElts) {
3020 // The bitcast is from wide to narrow/equal elements. The shuffle mask can
3021 // always be expanded to the equivalent form choosing narrower elements.
3022 assert(NumSrcElts % NumDstElts == 0 && "Unexpected shuffle mask");
3023 unsigned ScaleFactor = NumSrcElts / NumDstElts;
3024 narrowShuffleMaskElts(ScaleFactor, OldMask, NewMask);
3025 } else {
3026 // The bitcast is from narrow elements to wide elements. The shuffle mask
3027 // must choose consecutive elements to allow casting first.
3028 assert(NumDstElts % NumSrcElts == 0 && "Unexpected shuffle mask");
3029 unsigned ScaleFactor = NumDstElts / NumSrcElts;
3030 if (!widenShuffleMaskElts(ScaleFactor, OldMask, NewMask))
3031 return false;
3032 }
3033
3034 auto *NewShuffleDstTy =
3035 FixedVectorType::get(CastSrcTy->getScalarType(), NewMask.size());
3036
3037 // Try to replace a castop with a shuffle if the shuffle is not costly.
3038 InstructionCost CostC0 =
3039 TTI.getCastInstrCost(C0->getOpcode(), CastDstTy, CastSrcTy,
3041
3043 if (IsBinaryShuffle)
3045 else
3047
3048 InstructionCost OldCost = CostC0;
3049 OldCost += TTI.getShuffleCost(ShuffleKind, ShuffleDstTy, CastDstTy, CostKind,
3050 OldMask, 0, nullptr, {}, &I);
3051
3052 InstructionCost NewCost = TTI.getShuffleCost(ShuffleKind, NewShuffleDstTy,
3053 CastSrcTy, CostKind, NewMask);
3054 NewCost += TTI.getCastInstrCost(Opcode, ShuffleDstTy, NewShuffleDstTy,
3056 if (!C0->hasOneUse())
3057 NewCost += CostC0;
3058 if (IsBinaryShuffle) {
3059 InstructionCost CostC1 =
3060 TTI.getCastInstrCost(C1->getOpcode(), CastDstTy, CastSrcTy,
3062 OldCost += CostC1;
3063 if (!C1->hasOneUse())
3064 NewCost += CostC1;
3065 }
3066
3067 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two casts: " << I
3068 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3069 << "\n");
3070 if (NewCost > OldCost)
3071 return false;
3072
3073 Value *Shuf;
3074 if (IsBinaryShuffle)
3075 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), C1->getOperand(0),
3076 NewMask);
3077 else
3078 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), NewMask);
3079
3080 Value *Cast = Builder.CreateCast(Opcode, Shuf, ShuffleDstTy);
3081
3082 // Intersect flags from the old casts.
3083 if (auto *NewInst = dyn_cast<Instruction>(Cast)) {
3084 NewInst->copyIRFlags(C0);
3085 if (IsBinaryShuffle)
3086 NewInst->andIRFlags(C1);
3087 }
3088
3089 Worklist.pushValue(Shuf);
3090 replaceValue(I, *Cast);
3091 return true;
3092}
3093
3094/// Try to convert any of:
3095/// "shuffle (shuffle x, y), (shuffle y, x)"
3096/// "shuffle (shuffle x, undef), (shuffle y, undef)"
3097/// "shuffle (shuffle x, undef), y"
3098/// "shuffle x, (shuffle y, undef)"
3099/// into "shuffle x, y".
3100bool VectorCombine::foldShuffleOfShuffles(Instruction &I) {
3101 ArrayRef<int> OuterMask;
3102 Value *OuterV0, *OuterV1;
3103 if (!match(&I,
3104 m_Shuffle(m_Value(OuterV0), m_Value(OuterV1), m_Mask(OuterMask))))
3105 return false;
3106
3107 ArrayRef<int> InnerMask0, InnerMask1;
3108 Value *X0, *X1, *Y0, *Y1;
3109 bool Match0 =
3110 match(OuterV0, m_Shuffle(m_Value(X0), m_Value(Y0), m_Mask(InnerMask0)));
3111 bool Match1 =
3112 match(OuterV1, m_Shuffle(m_Value(X1), m_Value(Y1), m_Mask(InnerMask1)));
3113 if (!Match0 && !Match1)
3114 return false;
3115
3116 // If the outer shuffle is a permute, then create a fake inner all-poison
3117 // shuffle. This is easier than accounting for length-changing shuffles below.
3118 SmallVector<int, 16> PoisonMask1;
3119 if (!Match1 && isa<PoisonValue>(OuterV1)) {
3120 X1 = X0;
3121 Y1 = Y0;
3122 PoisonMask1.append(InnerMask0.size(), PoisonMaskElem);
3123 InnerMask1 = PoisonMask1;
3124 Match1 = true; // fake match
3125 }
3126
3127 X0 = Match0 ? X0 : OuterV0;
3128 Y0 = Match0 ? Y0 : OuterV0;
3129 X1 = Match1 ? X1 : OuterV1;
3130 Y1 = Match1 ? Y1 : OuterV1;
3131 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3132 auto *ShuffleSrcTy = dyn_cast<FixedVectorType>(X0->getType());
3133 auto *ShuffleImmTy = dyn_cast<FixedVectorType>(OuterV0->getType());
3134 if (!ShuffleDstTy || !ShuffleSrcTy || !ShuffleImmTy ||
3135 X0->getType() != X1->getType())
3136 return false;
3137
3138 unsigned NumSrcElts = ShuffleSrcTy->getNumElements();
3139 unsigned NumImmElts = ShuffleImmTy->getNumElements();
3140
3141 // Attempt to merge shuffles, matching upto 2 source operands.
3142 // Replace index to a poison arg with PoisonMaskElem.
3143 // Bail if either inner masks reference an undef arg.
3144 SmallVector<int, 16> NewMask(OuterMask);
3145 Value *NewX = nullptr, *NewY = nullptr;
3146 for (int &M : NewMask) {
3147 Value *Src = nullptr;
3148 if (0 <= M && M < (int)NumImmElts) {
3149 Src = OuterV0;
3150 if (Match0) {
3151 M = InnerMask0[M];
3152 Src = M >= (int)NumSrcElts ? Y0 : X0;
3153 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3154 }
3155 } else if (M >= (int)NumImmElts) {
3156 Src = OuterV1;
3157 M -= NumImmElts;
3158 if (Match1) {
3159 M = InnerMask1[M];
3160 Src = M >= (int)NumSrcElts ? Y1 : X1;
3161 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3162 }
3163 }
3164 if (Src && M != PoisonMaskElem) {
3165 assert(0 <= M && M < (int)NumSrcElts && "Unexpected shuffle mask index");
3166 if (isa<UndefValue>(Src)) {
3167 // We've referenced an undef element - if its poison, update the shuffle
3168 // mask, else bail.
3169 if (!isa<PoisonValue>(Src))
3170 return false;
3171 M = PoisonMaskElem;
3172 continue;
3173 }
3174 if (!NewX || NewX == Src) {
3175 NewX = Src;
3176 continue;
3177 }
3178 if (!NewY || NewY == Src) {
3179 M += NumSrcElts;
3180 NewY = Src;
3181 continue;
3182 }
3183 return false;
3184 }
3185 }
3186
3187 if (!NewX) {
3188 replaceValue(I, *PoisonValue::get(ShuffleDstTy));
3189 return true;
3190 }
3191
3192 if (!NewY)
3193 NewY = PoisonValue::get(ShuffleSrcTy);
3194
3195 // Have we folded to an Identity shuffle?
3196 if (ShuffleVectorInst::isIdentityMask(NewMask, NumSrcElts)) {
3197 replaceValue(I, *NewX);
3198 return true;
3199 }
3200
3201 // Try to merge the shuffles if the new shuffle is not costly.
3202 InstructionCost InnerCost0 = 0;
3203 if (Match0)
3204 InnerCost0 = TTI.getInstructionCost(cast<User>(OuterV0), CostKind);
3205
3206 InstructionCost InnerCost1 = 0;
3207 if (Match1)
3208 InnerCost1 = TTI.getInstructionCost(cast<User>(OuterV1), CostKind);
3209
3211
3212 InstructionCost OldCost = InnerCost0 + InnerCost1 + OuterCost;
3213
3214 bool IsUnary = all_of(NewMask, [&](int M) { return M < (int)NumSrcElts; });
3218 InstructionCost NewCost =
3219 TTI.getShuffleCost(SK, ShuffleDstTy, ShuffleSrcTy, CostKind, NewMask, 0,
3220 nullptr, {NewX, NewY});
3221 if (!OuterV0->hasOneUse())
3222 NewCost += InnerCost0;
3223 if (!OuterV1->hasOneUse())
3224 NewCost += InnerCost1;
3225
3226 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two shuffles: " << I
3227 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3228 << "\n");
3229 if (NewCost > OldCost)
3230 return false;
3231
3232 Value *Shuf = Builder.CreateShuffleVector(NewX, NewY, NewMask);
3233 replaceValue(I, *Shuf);
3234 return true;
3235}
3236
3237/// Try to convert a chain of length-preserving shuffles that are fed by
3238/// length-changing shuffles from the same source, e.g. a chain of length 3:
3239///
3240/// "shuffle (shuffle (shuffle x, (shuffle y, undef)),
3241/// (shuffle y, undef)),
3242// (shuffle y, undef)"
3243///
3244/// into a single shuffle fed by a length-changing shuffle:
3245///
3246/// "shuffle x, (shuffle y, undef)"
3247///
3248/// Such chains arise e.g. from folding extract/insert sequences.
3249bool VectorCombine::foldShufflesOfLengthChangingShuffles(Instruction &I) {
3250 FixedVectorType *TrunkType = dyn_cast<FixedVectorType>(I.getType());
3251 if (!TrunkType)
3252 return false;
3253
3254 unsigned ChainLength = 0;
3255 SmallVector<int> Mask;
3256 SmallVector<int> YMask;
3257 InstructionCost OldCost = 0;
3258 InstructionCost NewCost = 0;
3259 Value *Trunk = &I;
3260 unsigned NumTrunkElts = TrunkType->getNumElements();
3261 Value *Y = nullptr;
3262
3263 for (;;) {
3264 // Match the current trunk against (commutations of) the pattern
3265 // "shuffle trunk', (shuffle y, undef)"
3266 ArrayRef<int> OuterMask;
3267 Value *OuterV0, *OuterV1;
3268 if (ChainLength != 0 && !Trunk->hasOneUse())
3269 break;
3270 if (!match(Trunk, m_Shuffle(m_Value(OuterV0), m_Value(OuterV1),
3271 m_Mask(OuterMask))))
3272 break;
3273 if (OuterV0->getType() != TrunkType) {
3274 // This shuffle is not length-preserving, so it cannot be part of the
3275 // chain.
3276 break;
3277 }
3278
3279 ArrayRef<int> InnerMask0, InnerMask1;
3280 Value *A0, *A1, *B0, *B1;
3281 bool Match0 =
3282 match(OuterV0, m_Shuffle(m_Value(A0), m_Value(B0), m_Mask(InnerMask0)));
3283 bool Match1 =
3284 match(OuterV1, m_Shuffle(m_Value(A1), m_Value(B1), m_Mask(InnerMask1)));
3285 bool Match0Leaf = Match0 && A0->getType() != I.getType();
3286 bool Match1Leaf = Match1 && A1->getType() != I.getType();
3287 if (Match0Leaf == Match1Leaf) {
3288 // Only handle the case of exactly one leaf in each step. The "two leaves"
3289 // case is handled by foldShuffleOfShuffles.
3290 break;
3291 }
3292
3293 SmallVector<int> CommutedOuterMask;
3294 if (Match0Leaf) {
3295 std::swap(OuterV0, OuterV1);
3296 std::swap(InnerMask0, InnerMask1);
3297 std::swap(A0, A1);
3298 std::swap(B0, B1);
3299 llvm::append_range(CommutedOuterMask, OuterMask);
3300 for (int &M : CommutedOuterMask) {
3301 if (M == PoisonMaskElem)
3302 continue;
3303 if (M < (int)NumTrunkElts)
3304 M += NumTrunkElts;
3305 else
3306 M -= NumTrunkElts;
3307 }
3308 OuterMask = CommutedOuterMask;
3309 }
3310 if (!OuterV1->hasOneUse())
3311 break;
3312
3313 if (!isa<UndefValue>(A1)) {
3314 if (!Y)
3315 Y = A1;
3316 else if (Y != A1)
3317 break;
3318 }
3319 if (!isa<UndefValue>(B1)) {
3320 if (!Y)
3321 Y = B1;
3322 else if (Y != B1)
3323 break;
3324 }
3325
3326 auto *YType = cast<FixedVectorType>(A1->getType());
3327 int NumLeafElts = YType->getNumElements();
3328 SmallVector<int> LocalYMask(InnerMask1);
3329 for (int &M : LocalYMask) {
3330 if (M >= NumLeafElts)
3331 M -= NumLeafElts;
3332 }
3333
3334 InstructionCost LocalOldCost =
3337
3338 // Handle the initial (start of chain) case.
3339 if (!ChainLength) {
3340 Mask.assign(OuterMask);
3341 YMask.assign(LocalYMask);
3342 OldCost = NewCost = LocalOldCost;
3343 Trunk = OuterV0;
3344 ChainLength++;
3345 continue;
3346 }
3347
3348 // For the non-root case, first attempt to combine masks.
3349 SmallVector<int> NewYMask(YMask);
3350 bool Valid = true;
3351 for (auto [CombinedM, LeafM] : llvm::zip(NewYMask, LocalYMask)) {
3352 if (LeafM == -1 || CombinedM == LeafM)
3353 continue;
3354 if (CombinedM == -1) {
3355 CombinedM = LeafM;
3356 } else {
3357 Valid = false;
3358 break;
3359 }
3360 }
3361 if (!Valid)
3362 break;
3363
3364 SmallVector<int> NewMask;
3365 NewMask.reserve(NumTrunkElts);
3366 for (int M : Mask) {
3367 if (M < 0 || M >= static_cast<int>(NumTrunkElts))
3368 NewMask.push_back(M);
3369 else
3370 NewMask.push_back(OuterMask[M]);
3371 }
3372
3373 // Break the chain if adding this new step complicates the shuffles such
3374 // that it would increase the new cost by more than the old cost of this
3375 // step.
3376 InstructionCost LocalNewCost =
3378 YType, CostKind, NewYMask) +
3380 TrunkType, CostKind, NewMask);
3381
3382 if (LocalNewCost >= NewCost && LocalOldCost < LocalNewCost - NewCost)
3383 break;
3384
3385 LLVM_DEBUG({
3386 if (ChainLength == 1) {
3387 dbgs() << "Found chain of shuffles fed by length-changing shuffles: "
3388 << I << '\n';
3389 }
3390 dbgs() << " next chain link: " << *Trunk << '\n'
3391 << " old cost: " << (OldCost + LocalOldCost)
3392 << " new cost: " << LocalNewCost << '\n';
3393 });
3394
3395 Mask = NewMask;
3396 YMask = NewYMask;
3397 OldCost += LocalOldCost;
3398 NewCost = LocalNewCost;
3399 Trunk = OuterV0;
3400 ChainLength++;
3401 }
3402 if (ChainLength <= 1)
3403 return false;
3404
3405 // Bail out if all leaves were poison.
3406 if (!Y)
3407 return false;
3408
3409 if (llvm::all_of(Mask, [&](int M) {
3410 return M < 0 || M >= static_cast<int>(NumTrunkElts);
3411 })) {
3412 // Produce a canonical simplified form if all elements are sourced from Y.
3413 for (int &M : Mask) {
3414 if (M >= static_cast<int>(NumTrunkElts))
3415 M = YMask[M - NumTrunkElts];
3416 }
3417 Value *Root =
3418 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), Mask);
3419 replaceValue(I, *Root);
3420 return true;
3421 }
3422
3423 Value *Leaf =
3424 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), YMask);
3425 Value *Root = Builder.CreateShuffleVector(Trunk, Leaf, Mask);
3426 replaceValue(I, *Root);
3427 return true;
3428}
3429
3430/// Try to convert
3431/// "shuffle (intrinsic), (intrinsic)" into "intrinsic (shuffle), (shuffle)".
3432bool VectorCombine::foldShuffleOfIntrinsics(Instruction &I) {
3433 Value *V0, *V1;
3434 ArrayRef<int> OldMask;
3435 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
3436 return false;
3437
3438 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3439 auto *II1 = dyn_cast<IntrinsicInst>(V1);
3440 if (!II0 || !II1)
3441 return false;
3442
3443 Intrinsic::ID IID = II0->getIntrinsicID();
3444 if (IID != II1->getIntrinsicID())
3445 return false;
3446 InstructionCost CostII0 =
3447 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3448 InstructionCost CostII1 =
3449 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II1), CostKind);
3450
3451 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3452 auto *II0Ty = dyn_cast<FixedVectorType>(II0->getType());
3453 if (!ShuffleDstTy || !II0Ty)
3454 return false;
3455
3456 if (!isTriviallyVectorizable(IID))
3457 return false;
3458
3459 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3460 Value *Arg0 = II0->getArgOperand(Idx);
3461 Value *Arg1 = II1->getArgOperand(Idx);
3462 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3463 // Scalar operands must be identical.
3464 if (Arg0 != Arg1)
3465 return false;
3466 } else if (Arg0->getType() != Arg1->getType()) {
3467 // The corresponding vector operands are shuffled together, so they must
3468 // share the same type. For intrinsics overloaded on their operand type
3469 // (e.g. llvm.fptosi.sat), two calls can produce the same result type
3470 // from different operand types; shuffling those would be invalid.
3471 return false;
3472 }
3473 }
3474
3475 InstructionCost OldCost =
3476 CostII0 + CostII1 +
3478 II0Ty, CostKind, OldMask, 0, nullptr, {II0, II1}, &I);
3479
3480 SmallVector<Type *> NewArgsTy;
3481 InstructionCost NewCost = 0;
3482 SmallDenseSet<std::pair<Value *, Value *>> SeenOperandPairs;
3483 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3484 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3485 NewArgsTy.push_back(II0->getArgOperand(Idx)->getType());
3486 } else {
3487 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(Idx)->getType());
3488 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3489 ShuffleDstTy->getNumElements());
3490 NewArgsTy.push_back(ArgTy);
3491 std::pair<Value *, Value *> OperandPair =
3492 std::make_pair(II0->getArgOperand(Idx), II1->getArgOperand(Idx));
3493 if (!SeenOperandPairs.insert(OperandPair).second) {
3494 // We've already computed the cost for this operand pair.
3495 continue;
3496 }
3497 NewCost += TTI.getShuffleCost(
3499 OldMask, 0, nullptr,
3500 {II0->getArgOperand(Idx), II1->getArgOperand(Idx)});
3501 }
3502 }
3503 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3504
3505 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3506 if (!II0->hasOneUse())
3507 NewCost += CostII0;
3508 if (II1 != II0 && !II1->hasOneUse())
3509 NewCost += CostII1;
3510
3511 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two intrinsics: " << I
3512 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3513 << "\n");
3514
3515 if (NewCost > OldCost)
3516 return false;
3517
3518 SmallVector<Value *> NewArgs;
3519 SmallDenseMap<std::pair<Value *, Value *>, Value *> ShuffleCache;
3520 for (unsigned Idx = 0, E = II0->arg_size(); Idx != E; ++Idx) {
3521 if (isVectorIntrinsicWithScalarOpAtArg(IID, Idx, &TTI)) {
3522 NewArgs.push_back(II0->getArgOperand(Idx));
3523 } else {
3524 std::pair<Value *, Value *> OperandPair =
3525 std::make_pair(II0->getArgOperand(Idx), II1->getArgOperand(Idx));
3526 auto It = ShuffleCache.find(OperandPair);
3527 if (It != ShuffleCache.end()) {
3528 // Reuse previously created shuffle for this operand pair.
3529 NewArgs.push_back(It->second);
3530 continue;
3531 }
3532 Value *Shuf = Builder.CreateShuffleVector(
3533 II0->getArgOperand(Idx), II1->getArgOperand(Idx), OldMask);
3534 ShuffleCache[OperandPair] = Shuf;
3535 NewArgs.push_back(Shuf);
3536 Worklist.pushValue(Shuf);
3537 }
3538 }
3539 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3540
3541 // Intersect flags from the old intrinsics.
3542 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic)) {
3543 NewInst->copyIRFlags(II0);
3544 NewInst->andIRFlags(II1);
3545 }
3546
3547 replaceValue(I, *NewIntrinsic);
3548 return true;
3549}
3550
3551/// Try to convert
3552/// "shuffle (intrinsic), (poison/undef)" into "intrinsic (shuffle)".
3553bool VectorCombine::foldPermuteOfIntrinsic(Instruction &I) {
3554 Value *V0;
3555 ArrayRef<int> Mask;
3556 if (!match(&I, m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask))))
3557 return false;
3558
3559 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3560 if (!II0)
3561 return false;
3562
3563 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3564 auto *IntrinsicSrcTy = dyn_cast<FixedVectorType>(II0->getType());
3565 if (!ShuffleDstTy || !IntrinsicSrcTy)
3566 return false;
3567
3568 // Validate it's a pure permute, mask should only reference the first vector
3569 unsigned NumSrcElts = IntrinsicSrcTy->getNumElements();
3570 if (any_of(Mask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
3571 return false;
3572
3573 Intrinsic::ID IID = II0->getIntrinsicID();
3574 if (!isTriviallyVectorizable(IID))
3575 return false;
3576
3577 // Cost analysis
3579 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3580 InstructionCost OldCost =
3583 IntrinsicSrcTy, CostKind, Mask, 0, nullptr, {V0}, &I);
3584
3585 SmallVector<Type *> NewArgsTy;
3586 InstructionCost NewCost = 0;
3587 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3589 NewArgsTy.push_back(II0->getArgOperand(I)->getType());
3590 } else {
3591 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(I)->getType());
3592 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3593 ShuffleDstTy->getNumElements());
3594 NewArgsTy.push_back(ArgTy);
3596 ArgTy, VecTy, CostKind, Mask, 0, nullptr,
3597 {II0->getArgOperand(I)});
3598 }
3599 }
3600 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3601 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3602
3603 // If the intrinsic has multiple uses, we need to account for the cost of
3604 // keeping the original intrinsic around.
3605 if (!II0->hasOneUse())
3606 NewCost += IntrinsicCost;
3607
3608 LLVM_DEBUG(dbgs() << "Found a permute of intrinsic: " << I << "\n OldCost: "
3609 << OldCost << " vs NewCost: " << NewCost << "\n");
3610
3611 if (NewCost > OldCost)
3612 return false;
3613
3614 // Transform
3615 SmallVector<Value *> NewArgs;
3616 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3618 NewArgs.push_back(II0->getArgOperand(I));
3619 } else {
3620 Value *Shuf = Builder.CreateShuffleVector(II0->getArgOperand(I), Mask);
3621 NewArgs.push_back(Shuf);
3622 Worklist.pushValue(Shuf);
3623 }
3624 }
3625
3626 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3627
3628 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic))
3629 NewInst->copyIRFlags(II0);
3630
3631 replaceValue(I, *NewIntrinsic);
3632 return true;
3633}
3634
3635using InstLane = std::pair<Value *, int>;
3636
3637static InstLane lookThroughShuffles(Value *V, int Lane) {
3638 while (auto *SV = dyn_cast<ShuffleVectorInst>(V)) {
3639 unsigned NumElts =
3640 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
3641 int M = SV->getMaskValue(Lane);
3642 if (M < 0)
3643 return {nullptr, PoisonMaskElem};
3644 if (static_cast<unsigned>(M) < NumElts) {
3645 V = SV->getOperand(0);
3646 Lane = M;
3647 } else {
3648 V = SV->getOperand(1);
3649 Lane = M - NumElts;
3650 }
3651 }
3652 return InstLane{V, Lane};
3653}
3654
3658 for (InstLane IL : Item) {
3659 auto [U, Lane] = IL;
3660 InstLane OpLane =
3661 U ? lookThroughShuffles(cast<Instruction>(U)->getOperand(Op), Lane)
3662 : InstLane{nullptr, PoisonMaskElem};
3663 NItem.emplace_back(OpLane);
3664 }
3665 return NItem;
3666}
3667
3668/// Detect concat of multiple values into a vector
3670 const TargetTransformInfo &TTI) {
3671 auto *Ty = cast<FixedVectorType>(Item.front().first->getType());
3672 unsigned NumElts = Ty->getNumElements();
3673 if (Item.size() == NumElts || NumElts == 1 || Item.size() % NumElts != 0)
3674 return false;
3675
3676 // Check that the concat is free, usually meaning that the type will be split
3677 // during legalization.
3678 SmallVector<int, 16> ConcatMask(NumElts * 2);
3679 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
3680 if (TTI.getShuffleCost(TTI::SK_PermuteTwoSrc,
3681 FixedVectorType::get(Ty->getScalarType(), NumElts * 2),
3682 Ty, CostKind, ConcatMask) != 0)
3683 return false;
3684
3685 unsigned NumSlices = Item.size() / NumElts;
3686 // Currently we generate a tree of shuffles for the concats, which limits us
3687 // to a power2.
3688 if (!isPowerOf2_32(NumSlices))
3689 return false;
3690 for (unsigned Slice = 0; Slice < NumSlices; ++Slice) {
3691 Value *SliceV = Item[Slice * NumElts].first;
3692 if (!SliceV || SliceV->getType() != Ty)
3693 return false;
3694 for (unsigned Elt = 0; Elt < NumElts; ++Elt) {
3695 auto [V, Lane] = Item[Slice * NumElts + Elt];
3696 if (Lane != static_cast<int>(Elt) || SliceV != V)
3697 return false;
3698 }
3699 }
3700 return true;
3701}
3702
3703static Value *
3705 const DenseSet<std::pair<Value *, Use *>> &IdentityLeafs,
3706 const DenseSet<std::pair<Value *, Use *>> &SplatLeafs,
3707 const DenseSet<std::pair<Value *, Use *>> &ConcatLeafs,
3708 IRBuilderBase &Builder, InstructionWorklist &WorkList,
3709 const TargetTransformInfo *TTI) {
3710 auto [FrontV, FrontLane] = Item.front();
3711
3712 if (IdentityLeafs.contains(std::make_pair(FrontV, From))) {
3713 return FrontV;
3714 }
3715 if (SplatLeafs.contains(std::make_pair(FrontV, From))) {
3716 SmallVector<int, 16> Mask(Item.size(), FrontLane);
3717 return Builder.CreateShuffleVector(FrontV, Mask);
3718 }
3719 if (ConcatLeafs.contains(std::make_pair(FrontV, From))) {
3720 unsigned NumElts =
3721 cast<FixedVectorType>(FrontV->getType())->getNumElements();
3722 SmallVector<Value *> Values(Item.size() / NumElts, nullptr);
3723 for (unsigned S = 0; S < Values.size(); ++S)
3724 Values[S] = Item[S * NumElts].first;
3725
3726 while (Values.size() > 1) {
3727 NumElts *= 2;
3728 SmallVector<int, 16> Mask(NumElts, 0);
3729 std::iota(Mask.begin(), Mask.end(), 0);
3730 SmallVector<Value *> NewValues(Values.size() / 2, nullptr);
3731 for (unsigned S = 0; S < NewValues.size(); ++S)
3732 NewValues[S] =
3733 Builder.CreateShuffleVector(Values[S * 2], Values[S * 2 + 1], Mask);
3734 Values = NewValues;
3735 }
3736 return Values[0];
3737 }
3738
3739 auto *I = cast<Instruction>(FrontV);
3740
3741 // Handle vector bitcasts that change element count. We cannot use
3742 // generateInstLaneVectorFromOperand for these because the lane indices
3743 // don't map 1:1 through the bitcast.
3744 if (auto *BitCast = dyn_cast<BitCastInst>(I)) {
3745 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3746 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3747 if (BCDstTy && BCSrcTy &&
3748 BCDstTy->getElementCount() != BCSrcTy->getElementCount()) {
3749 unsigned DstElts = BCDstTy->getNumElements();
3750 unsigned SrcElts = BCSrcTy->getNumElements();
3751 SmallVector<InstLane> NewItem;
3752 if (DstElts > SrcElts) {
3753 // Widening: compress operand Item.
3754 unsigned R = DstElts / SrcElts;
3755 if (Item.size() % R != 0)
3756 return nullptr;
3757 for (unsigned Idx = 0, E = Item.size(); Idx < E; Idx += R) {
3758 auto [V, Lane] = Item[Idx];
3759 if (!V) {
3760 NewItem.push_back({nullptr, PoisonMaskElem});
3761 continue;
3762 }
3763 NewItem.push_back(
3764 lookThroughShuffles(cast<Operator>(V)->getOperand(0), Lane / R));
3765 }
3766 } else {
3767 // Narrowing: expand operand Item.
3768 unsigned R = SrcElts / DstElts;
3769 for (auto [V, Lane] : Item) {
3770 if (!V) {
3771 NewItem.append(R, {nullptr, PoisonMaskElem});
3772 continue;
3773 }
3774 Value *Op = cast<Operator>(V)->getOperand(0);
3775 for (unsigned J = 0; J < R; ++J)
3776 NewItem.push_back(lookThroughShuffles(Op, Lane * R + J));
3777 }
3778 }
3779 Value *Op = generateNewInstTree(NewItem, &BitCast->getOperandUse(0),
3780 IdentityLeafs, SplatLeafs, ConcatLeafs,
3781 Builder, WorkList, TTI);
3782 WorkList.pushValue(Op);
3783 return Builder.CreateBitCast(
3784 Op, FixedVectorType::get(BCDstTy->getScalarType(), Item.size()));
3785 }
3786 }
3787 auto *II = dyn_cast<IntrinsicInst>(I);
3788 unsigned NumOps = I->getNumOperands() - (II ? 1 : 0);
3790 for (unsigned Idx = 0; Idx < NumOps; Idx++) {
3791 if (II &&
3792 isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Idx, TTI)) {
3793 Ops[Idx] = II->getOperand(Idx);
3794 continue;
3795 }
3796 Ops[Idx] = generateNewInstTree(
3797 generateInstLaneVectorFromOperand(Item, Idx), &I->getOperandUse(Idx),
3798 IdentityLeafs, SplatLeafs, ConcatLeafs, Builder, WorkList, TTI);
3799 // Don't re-queue the operand of a bitcast we just regenerated. Doing so
3800 // lets foldBitcastShuffle sink the bitcast back into a shuffle(bitcast),
3801 // which foldShuffleToIdentity then re-matches as the same superfluous
3802 // identity - an infinite loop between the two folds.
3803 if (!isa<BitCastInst>(I))
3804 WorkList.pushValue(Ops[Idx]);
3805 }
3806
3807 SmallVector<Value *, 8> ValueList;
3808 for (const auto &Lane : Item)
3809 if (Lane.first)
3810 ValueList.push_back(Lane.first);
3811
3812 Type *DstTy =
3813 FixedVectorType::get(I->getType()->getScalarType(), Item.size());
3814 if (auto *BI = dyn_cast<BinaryOperator>(I)) {
3815 auto *Value = Builder.CreateBinOp((Instruction::BinaryOps)BI->getOpcode(),
3816 Ops[0], Ops[1]);
3817 propagateIRFlags(Value, ValueList);
3818 return Value;
3819 }
3820 if (auto *CI = dyn_cast<CmpInst>(I)) {
3821 auto *Value = Builder.CreateCmp(CI->getPredicate(), Ops[0], Ops[1]);
3822 propagateIRFlags(Value, ValueList);
3823 return Value;
3824 }
3825 if (auto *SI = dyn_cast<SelectInst>(I)) {
3826 auto *Value = Builder.CreateSelect(Ops[0], Ops[1], Ops[2], "", SI);
3827 propagateIRFlags(Value, ValueList);
3828 return Value;
3829 }
3830 if (auto *CI = dyn_cast<CastInst>(I)) {
3831 auto *Value = Builder.CreateCast(CI->getOpcode(), Ops[0], DstTy);
3832 propagateIRFlags(Value, ValueList);
3833 return Value;
3834 }
3835 if (II) {
3836 auto *Value = Builder.CreateIntrinsic(DstTy, II->getIntrinsicID(), Ops);
3837 propagateIRFlags(Value, ValueList);
3838 return Value;
3839 }
3840 assert(isa<UnaryInstruction>(I) && "Unexpected instruction type in Generate");
3841 auto *Value =
3842 Builder.CreateUnOp((Instruction::UnaryOps)I->getOpcode(), Ops[0]);
3843 propagateIRFlags(Value, ValueList);
3844 return Value;
3845}
3846
3847// Starting from a shuffle, look up through operands tracking the shuffled index
3848// of each lane. If we can simplify away the shuffles to identities then
3849// do so.
3850bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
3851 auto *Ty = dyn_cast<FixedVectorType>(I.getType());
3852 if (!Ty || I.use_empty())
3853 return false;
3854
3855 SmallVector<InstLane> Start(Ty->getNumElements());
3856 for (unsigned M = 0, E = Ty->getNumElements(); M < E; ++M)
3857 Start[M] = lookThroughShuffles(&I, M);
3858
3860 Candidates.push_back(std::make_pair(Start, &*I.use_begin()));
3861 DenseSet<std::pair<Value *, Use *>> IdentityLeafs, SplatLeafs, ConcatLeafs;
3862 unsigned NumVisited = 0;
3863 bool TraversedElCountChangingBitcast = false;
3864
3865 while (!Candidates.empty()) {
3866 if (++NumVisited > MaxInstrsToScan)
3867 return false;
3868
3869 auto ItemFrom = Candidates.pop_back_val();
3870 auto Item = ItemFrom.first;
3871 auto From = ItemFrom.second;
3872 auto [FrontV, FrontLane] = Item.front();
3873
3874 // If we found an undef first lane then bail out to keep things simple.
3875 if (!FrontV)
3876 return false;
3877
3878 // Look for an identity value.
3879 if (FrontLane == 0 &&
3880 cast<FixedVectorType>(FrontV->getType())->getNumElements() ==
3881 Item.size() &&
3882 all_of(drop_begin(enumerate(Item)), [Item](const auto &E) {
3883 Value *FrontV = Item.front().first;
3884 return !E.value().first || (isEquivBitcast(E.value().first, FrontV) &&
3885 E.value().second == (int)E.index());
3886 })) {
3887 IdentityLeafs.insert(std::make_pair(FrontV, From));
3888 continue;
3889 }
3890 // Look for constants, for the moment only supporting constant splats.
3891 if (auto *C = dyn_cast<Constant>(FrontV);
3892 C && C->getSplatValue() &&
3893 all_of(drop_begin(Item), [Item](InstLane &IL) {
3894 Value *FrontV = Item.front().first;
3895 Value *V = IL.first;
3896 return !V || (isa<Constant>(V) &&
3897 cast<Constant>(V)->getSplatValue() ==
3898 cast<Constant>(FrontV)->getSplatValue());
3899 })) {
3900 SplatLeafs.insert(std::make_pair(FrontV, From));
3901 continue;
3902 }
3903 // Look for a splat value.
3904 if (all_of(drop_begin(Item), [Item](InstLane &IL) {
3905 auto [FrontV, FrontLane] = Item.front();
3906 auto [V, Lane] = IL;
3907 return !V || (V == FrontV && Lane == FrontLane);
3908 })) {
3909 SplatLeafs.insert(std::make_pair(FrontV, From));
3910 continue;
3911 }
3912
3913 // We need each element to be the same type of value, and check that each
3914 // element has a single use.
3915 auto CheckLaneIsEquivalentToFirst = [Item](InstLane IL) {
3916 Value *FrontV = Item.front().first;
3917 if (!IL.first)
3918 return true;
3919 Value *V = IL.first;
3920 if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUser())
3921 return false;
3922 if (V->getValueID() != FrontV->getValueID())
3923 return false;
3924 if (auto *CI = dyn_cast<CmpInst>(V))
3925 if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
3926 return false;
3927 if (auto *CI = dyn_cast<CastInst>(V))
3928 if (CI->getSrcTy()->getScalarType() !=
3929 cast<CastInst>(FrontV)->getSrcTy()->getScalarType())
3930 return false;
3931 if (auto *SI = dyn_cast<SelectInst>(V))
3932 if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
3933 SI->getOperand(0)->getType() !=
3934 cast<SelectInst>(FrontV)->getOperand(0)->getType())
3935 return false;
3936 if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
3937 return false;
3938 auto *II = dyn_cast<IntrinsicInst>(V);
3939 return !II || (isa<IntrinsicInst>(FrontV) &&
3940 II->getIntrinsicID() ==
3941 cast<IntrinsicInst>(FrontV)->getIntrinsicID() &&
3942 !II->hasOperandBundles());
3943 };
3944 if (all_of(drop_begin(Item), CheckLaneIsEquivalentToFirst)) {
3945 // Check the operator is one that we support.
3946 if (isa<BinaryOperator, CmpInst>(FrontV)) {
3947 // We exclude div/rem in case they hit UB from poison lanes.
3948 if (auto *BO = dyn_cast<BinaryOperator>(FrontV);
3949 BO && BO->isIntDivRem())
3950 return false;
3952 &cast<Instruction>(FrontV)->getOperandUse(0));
3954 &cast<Instruction>(FrontV)->getOperandUse(1));
3955 continue;
3956 } else if (isa<UnaryOperator, TruncInst, ZExtInst, SExtInst, FPToSIInst,
3957 FPToUIInst, SIToFPInst, UIToFPInst>(FrontV)) {
3959 &cast<Instruction>(FrontV)->getOperandUse(0));
3960 continue;
3961 } else if (auto *BitCast = dyn_cast<BitCastInst>(FrontV)) {
3962 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3963 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3964 if (BCDstTy && BCSrcTy) {
3965 ElementCount DstEC = BCDstTy->getElementCount();
3966 ElementCount SrcEC = BCSrcTy->getElementCount();
3967 if (DstEC == SrcEC) {
3968 // Same element count - simple pass-through.
3970 &BitCast->getOperandUse(0));
3971 continue;
3972 }
3973 unsigned DstElts = DstEC.getFixedValue();
3974 unsigned SrcElts = SrcEC.getFixedValue();
3975 if (DstElts > SrcElts && DstElts % SrcElts == 0) {
3976 // Widening bitcast (e.g. <2 x i32> -> <4 x i16>). Compress
3977 // consecutive groups of R destination lanes into one source
3978 // lane.
3979 unsigned R = DstElts / SrcElts;
3981 bool Valid = Item.size() % R == 0;
3982 for (unsigned Idx = 0, E = Item.size(); Valid && Idx < E;
3983 Idx += R) {
3984 auto [V0, L0] = Item[Idx];
3985 if (!V0) {
3986 if (any_of(ArrayRef(Item).slice(Idx + 1, R - 1),
3987 [](InstLane IL) { return IL.first != nullptr; })) {
3988 Valid = false;
3989 break;
3990 }
3991 NItem.push_back({nullptr, PoisonMaskElem});
3992 continue;
3993 }
3994 if (L0 % R != 0) {
3995 Valid = false;
3996 break;
3997 }
3998 for (unsigned J = 1; J < R; ++J) {
3999 auto [VJ, LJ] = Item[Idx + J];
4000 if (!VJ || VJ != V0 || LJ != L0 + (int)J) {
4001 Valid = false;
4002 break;
4003 }
4004 }
4005 if (!Valid)
4006 break;
4008 cast<Operator>(V0)->getOperand(0), L0 / R));
4009 }
4010 if (Valid) {
4011 TraversedElCountChangingBitcast = true;
4012 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
4013 continue;
4014 }
4015 } else if (SrcElts > DstElts && SrcElts % DstElts == 0) {
4016 // Narrowing bitcast (e.g. <4 x i16> -> <2 x i32>). Expand
4017 // each destination lane into R source lanes.
4018 unsigned R = SrcElts / DstElts;
4020 for (auto [V, Lane] : Item) {
4021 if (!V) {
4022 NItem.append(R, {nullptr, PoisonMaskElem});
4023 continue;
4024 }
4025 Value *Op = cast<Operator>(V)->getOperand(0);
4026 for (unsigned J = 0; J < R; ++J)
4027 NItem.push_back(lookThroughShuffles(Op, Lane * R + J));
4028 }
4029 TraversedElCountChangingBitcast = true;
4030 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
4031 continue;
4032 }
4033 }
4034 } else if (auto *Sel = dyn_cast<SelectInst>(FrontV)) {
4036 &Sel->getOperandUse(0));
4038 &Sel->getOperandUse(1));
4040 &Sel->getOperandUse(2));
4041 continue;
4042 } else if (auto *II = dyn_cast<IntrinsicInst>(FrontV);
4043 II && isTriviallyVectorizable(II->getIntrinsicID()) &&
4044 !II->hasOperandBundles()) {
4045 for (unsigned Op = 0, E = II->getNumOperands() - 1; Op < E; Op++) {
4046 if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Op,
4047 &TTI)) {
4048 if (!all_of(drop_begin(Item), [Item, Op](InstLane &IL) {
4049 Value *FrontV = Item.front().first;
4050 Value *V = IL.first;
4051 return !V || (cast<Instruction>(V)->getOperand(Op) ==
4052 cast<Instruction>(FrontV)->getOperand(Op));
4053 }))
4054 return false;
4055 continue;
4056 }
4057 Candidates.emplace_back(
4059 &cast<Instruction>(FrontV)->getOperandUse(Op));
4060 }
4061 continue;
4062 }
4063 }
4064
4065 if (isFreeConcat(Item, CostKind, TTI)) {
4066 ConcatLeafs.insert(std::make_pair(FrontV, From));
4067 continue;
4068 }
4069
4070 return false;
4071 }
4072
4073 if (NumVisited <= 1)
4074 return false;
4075
4076 // If the only non-leaf node traversed was a single bitcast that changes
4077 // element count, the fold would just commute the bitcast and shuffle.
4078 // foldBitcastShuffle does the reverse transform, causing an infinite loop.
4079 if (NumVisited == 2 && TraversedElCountChangingBitcast)
4080 return false;
4081
4082 LLVM_DEBUG(dbgs() << "Found a superfluous identity shuffle: " << I << "\n");
4083
4084 // If we got this far, we know the shuffles are superfluous and can be
4085 // removed. Scan through again and generate the new tree of instructions.
4086 Builder.SetInsertPoint(&I);
4087 Value *V =
4088 generateNewInstTree(Start, &*I.use_begin(), IdentityLeafs, SplatLeafs,
4089 ConcatLeafs, Builder, Worklist, &TTI);
4090 replaceValue(I, *V);
4091 return true;
4092}
4093
4094/// Given a commutative reduction, the order of the input lanes does not alter
4095/// the results. We can use this to remove certain shuffles feeding the
4096/// reduction, removing the need to shuffle at all.
4097bool VectorCombine::foldShuffleFromReductions(Instruction &I) {
4098 auto *II = dyn_cast<IntrinsicInst>(&I);
4099 if (!II)
4100 return false;
4101 switch (II->getIntrinsicID()) {
4102 case Intrinsic::vector_reduce_add:
4103 case Intrinsic::vector_reduce_mul:
4104 case Intrinsic::vector_reduce_and:
4105 case Intrinsic::vector_reduce_or:
4106 case Intrinsic::vector_reduce_xor:
4107 case Intrinsic::vector_reduce_smin:
4108 case Intrinsic::vector_reduce_smax:
4109 case Intrinsic::vector_reduce_umin:
4110 case Intrinsic::vector_reduce_umax:
4111 break;
4112 default:
4113 return false;
4114 }
4115
4116 // Find all the inputs when looking through operations that do not alter the
4117 // lane order (binops, for example). Currently we look for a single shuffle,
4118 // and can ignore splat values.
4119 std::queue<Value *> Worklist;
4120 SmallPtrSet<Value *, 4> Visited;
4121 ShuffleVectorInst *Shuffle = nullptr;
4122 if (auto *Op = dyn_cast<Instruction>(I.getOperand(0)))
4123 Worklist.push(Op);
4124
4125 while (!Worklist.empty()) {
4126 Value *CV = Worklist.front();
4127 Worklist.pop();
4128 if (Visited.contains(CV))
4129 continue;
4130
4131 // Splats don't change the order, so can be safely ignored.
4132 if (isSplatValue(CV))
4133 continue;
4134
4135 Visited.insert(CV);
4136
4137 if (auto *CI = dyn_cast<Instruction>(CV)) {
4138 if (CI->isBinaryOp()) {
4139 for (auto *Op : CI->operand_values())
4140 Worklist.push(Op);
4141 continue;
4142 } else if (auto *SV = dyn_cast<ShuffleVectorInst>(CI)) {
4143 if (Shuffle && Shuffle != SV)
4144 return false;
4145 Shuffle = SV;
4146 continue;
4147 }
4148 }
4149
4150 // Anything else is currently an unknown node.
4151 return false;
4152 }
4153
4154 if (!Shuffle)
4155 return false;
4156
4157 // Check all uses of the binary ops and shuffles are also included in the
4158 // lane-invariant operations (Visited should be the list of lanewise
4159 // instructions, including the shuffle that we found).
4160 for (auto *V : Visited)
4161 for (auto *U : V->users())
4162 if (!Visited.contains(U) && U != &I)
4163 return false;
4164
4165 FixedVectorType *VecType =
4166 dyn_cast<FixedVectorType>(II->getOperand(0)->getType());
4167 if (!VecType)
4168 return false;
4169 FixedVectorType *ShuffleInputType =
4171 if (!ShuffleInputType)
4172 return false;
4173 unsigned NumInputElts = ShuffleInputType->getNumElements();
4174
4175 // Find the mask from sorting the lanes into order. This is most likely to
4176 // become a identity or concat mask. Undef elements are pushed to the end.
4177 SmallVector<int> ConcatMask;
4178 Shuffle->getShuffleMask(ConcatMask);
4179 sort(ConcatMask, [](int X, int Y) { return (unsigned)X < (unsigned)Y; });
4180 bool UsesSecondVec =
4181 any_of(ConcatMask, [&](int M) { return M >= (int)NumInputElts; });
4182
4184 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4185 ShuffleInputType, CostKind, Shuffle->getShuffleMask());
4187 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4188 ShuffleInputType, CostKind, ConcatMask);
4189
4190 LLVM_DEBUG(dbgs() << "Found a reduction feeding from a shuffle: " << *Shuffle
4191 << "\n");
4192 LLVM_DEBUG(dbgs() << " OldCost: " << OldCost << " vs NewCost: " << NewCost
4193 << "\n");
4194 bool MadeChanges = false;
4195 if (NewCost < OldCost) {
4196 Builder.SetInsertPoint(Shuffle);
4197 Value *NewShuffle = Builder.CreateShuffleVector(
4198 Shuffle->getOperand(0), Shuffle->getOperand(1), ConcatMask);
4199 LLVM_DEBUG(dbgs() << "Created new shuffle: " << *NewShuffle << "\n");
4200 replaceValue(*Shuffle, *NewShuffle);
4201 return true;
4202 }
4203
4204 // See if we can re-use foldSelectShuffle, getting it to reduce the size of
4205 // the shuffle into a nicer order, as it can ignore the order of the shuffles.
4206 MadeChanges |= foldSelectShuffle(*Shuffle, true);
4207 return MadeChanges;
4208}
4209
4210/// Try to fold a chain of shuffles and ops feeding extractelement(..., 0)
4211/// into llvm.vector.reduce.*, by tracking which lanes contribute to the
4212/// extracted lane and reducing the widest vector whose lanes each contribute
4213/// once.
4214///
4215/// For example:
4216///
4217/// %lo = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 0, i32 1>
4218/// %hi = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 2, i32 3>
4219/// %s = add <2 x i32> %lo, %hi
4220/// %sh = shufflevector <2 x i32> %s, poison, <2 x i32> <i32 1, i32 poison>
4221/// %r = add <2 x i32> %s, %sh
4222/// %e = extractelement <2 x i32> %r, i64 0
4223///
4224/// transforms to:
4225///
4226/// %e = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
4227bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
4228 Value *VecOpEE;
4229 if (!match(&I, m_ExtractElt(m_Value(VecOpEE), m_Zero())))
4230 return false;
4231
4232 auto *FVT = dyn_cast<FixedVectorType>(VecOpEE->getType());
4233 if (!FVT)
4234 return false;
4235
4236 if (FVT->getNumElements() < 2)
4237 return false;
4238
4239 std::optional<Instruction::BinaryOps> CommonBinOp;
4240 std::optional<Intrinsic::ID> CommonCallOp;
4241
4242 if (auto *BO = dyn_cast<BinaryOperator>(VecOpEE)) {
4243 if (!getReductionForBinop(BO->getOpcode()))
4244 return false;
4245 CommonBinOp = BO->getOpcode();
4246 } else if (auto *MMI = dyn_cast<MinMaxIntrinsic>(VecOpEE)) {
4247 CommonCallOp = MMI->getIntrinsicID();
4248 } else {
4249 return false;
4250 }
4251
4252 // For floating-point reductions, track FMF intersection across all binops.
4253 FastMathFlags CommonFMF;
4254 bool IsFloatReduction = false;
4255
4256 // A chain node is one we walk through, either a matching-opcode binop/min-max
4257 // or a single-source shuffle. Anything else is a leaf source.
4258 auto IsChainNode = [&](Value *V) {
4259 if (auto *BO = dyn_cast<BinaryOperator>(V))
4260 return CommonBinOp && BO->getOpcode() == *CommonBinOp;
4261 if (auto *MMI = dyn_cast<MinMaxIntrinsic>(V))
4262 return CommonCallOp && MMI->getIntrinsicID() == *CommonCallOp;
4263 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V))
4264 return isa<PoisonValue>(SVI->getOperand(1));
4265 return false;
4266 };
4267
4268 // Collect the chain, building Nodes in postorder. Bail if the chain is empty
4269 // or exceeds MaxChainNodes.
4270 constexpr unsigned MaxChainNodes = 32;
4271 SmallSetVector<Value *, 16> Nodes;
4272 SmallSetVector<Value *, 4> Sources;
4273 unsigned NumVisited = 0;
4274 auto AddSource = [&](Value *V) {
4275 if (!isa<FixedVectorType>(V->getType()))
4276 return false;
4277 Sources.insert(V);
4278 return true;
4279 };
4280 auto Walk = [&](Value *V, auto &&Walk) -> bool {
4281 if (Nodes.contains(V) || Sources.contains(V))
4282 return true;
4283 if (++NumVisited > MaxChainNodes)
4284 return false;
4285 if (!IsChainNode(V))
4286 return AddSource(V);
4287 // Chain shuffles always have poison as op1, so only op0 matters.
4288 auto *U = cast<Instruction>(V);
4289 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4290 for (unsigned I = 0; I != NumOps; ++I)
4291 if (!Walk(U->getOperand(I), Walk))
4292 return false;
4293 if (isa<ShuffleVectorInst>(U) || Nodes.contains(U->getOperand(0)) ||
4294 Nodes.contains(U->getOperand(1))) {
4295 Nodes.insert(V);
4296 return true;
4297 }
4298 // Both operands are leaves so treat this binop as a source rather than
4299 // walking into it.
4300 return AddSource(V);
4301 };
4302 if (!Walk(VecOpEE, Walk) || Nodes.empty())
4303 return false;
4304
4305 bool IsIdempotent =
4306 CommonCallOp || (CommonBinOp && Instruction::isIdempotent(*CommonBinOp));
4307
4308 // For FP reductions, require reassoc on every binop and collect FMF.
4309 for (Value *V : Nodes) {
4310 auto *BinOp = dyn_cast<BinaryOperator>(V);
4311 if (!BinOp || !BinOp->getType()->isFPOrFPVectorTy())
4312 continue;
4313 if (!BinOp->hasAllowReassoc())
4314 return false;
4315 if (!IsFloatReduction) {
4316 CommonFMF = BinOp->getFastMathFlags();
4317 IsFloatReduction = true;
4318 } else {
4319 CommonFMF &= BinOp->getFastMathFlags();
4320 }
4321 }
4322
4323 // Top-down demanded elements. For each chain value, track which lanes feed
4324 // the extracted lane 0 and which feed it more than once. Reverse postorder
4325 // visits every use before its value. A binop forwards its demand to both
4326 // operands and a shuffle follows its mask back to the source lane.
4327 struct Demand {
4328 APInt Lanes;
4329 APInt Duplicates;
4330 };
4331 DenseMap<Value *, Demand> Demands;
4332 auto DemandOf = [&](Value *V) -> Demand & {
4333 unsigned N = cast<FixedVectorType>(V->getType())->getNumElements();
4334 Demand &D = Demands[V];
4335 if (D.Lanes.getBitWidth() != N)
4336 D.Lanes = D.Duplicates = APInt::getZero(N);
4337 return D;
4338 };
4339 DemandOf(VecOpEE).Lanes.setBit(0);
4340 for (Value *V : reverse(Nodes)) {
4341 Demand DV = Demands.lookup(V);
4342 if (DV.Lanes.isZero())
4343 continue;
4344 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V)) {
4345 ArrayRef<int> Mask = SVI->getShuffleMask();
4346 Demand &DS = DemandOf(SVI->getOperand(0));
4347 for (unsigned I = 0, E = Mask.size(); I != E; ++I) {
4348 // Skip lanes that are undemanded or map to poison.
4349 if (!DV.Lanes[I] || Mask[I] < 0 ||
4350 (unsigned)Mask[I] >= DS.Lanes.getBitWidth())
4351 continue;
4352 if (DS.Lanes[Mask[I]] || DV.Duplicates[I])
4353 DS.Duplicates.setBit(Mask[I]);
4354 DS.Lanes.setBit(Mask[I]);
4355 }
4356 } else {
4357 auto *U = cast<User>(V);
4358 for (Value *Op : {U->getOperand(0), U->getOperand(1)}) {
4359 Demand &DOp = DemandOf(Op);
4360 // Lanes demanded through more than one path accumulate in Duplicates.
4361 DOp.Duplicates |= DV.Duplicates | (DOp.Lanes & DV.Lanes);
4362 DOp.Lanes |= DV.Lanes;
4363 }
4364 }
4365 }
4366
4367 // Reducing V replaces the entire chain, so every contribution to the result
4368 // must flow through V. Reject if anything above V reads outside the chain.
4369 auto CoversChain = [&](Value *V) {
4370 SmallVector<Value *, 8> Worklist(1, VecOpEE);
4371 SmallPtrSet<Value *, 8> Seen;
4372 Seen.insert(VecOpEE);
4373 while (!Worklist.empty()) {
4374 auto *U = cast<Instruction>(Worklist.pop_back_val());
4375 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4376 for (unsigned I = 0; I != NumOps; ++I) {
4377 Value *Op = U->getOperand(I);
4378 if (Op == V || !Seen.insert(Op).second)
4379 continue;
4380 if (!Nodes.contains(Op))
4381 return false;
4382 Worklist.push_back(Op);
4383 }
4384 }
4385 return true;
4386 };
4387
4388 // Reduce a single cleanly demanded source if there is one, otherwise the
4389 // deepest intermediate that covers the chain.
4390 struct ReductionCut {
4391 Value *Src;
4392 APInt Elts;
4393 };
4394 std::optional<ReductionCut> Cut;
4395 for (Value *S : Sources) {
4396 auto It = Demands.find(S);
4397 if (It == Demands.end() || It->second.Lanes.isZero())
4398 continue;
4399 if (!IsIdempotent && !It->second.Duplicates.isZero()) {
4400 Cut.reset();
4401 break;
4402 }
4403 if (!Cut) {
4404 Cut = ReductionCut{S, It->second.Lanes};
4405 continue;
4406 }
4407 if (!isEquivBitcast(Cut->Src, S)) {
4408 Cut.reset();
4409 break;
4410 }
4411 if (!IsIdempotent && !(Cut->Elts & It->second.Lanes).isZero()) {
4412 Cut.reset();
4413 break;
4414 }
4415 Cut->Elts |= It->second.Lanes;
4416 }
4417 if (!Cut) {
4418 for (Value *V : Nodes) {
4420 continue;
4421 auto It = Demands.find(V);
4422 if (It == Demands.end() || !It->second.Lanes.isAllOnes())
4423 continue;
4424 if (!IsIdempotent && !It->second.Duplicates.isZero())
4425 continue;
4426 if (!CoversChain(V))
4427 continue;
4428 Cut = ReductionCut{V, It->second.Lanes};
4429 break;
4430 }
4431 }
4432 // Reducing one lane is just an extract and can refold forever.
4433 if (!Cut || Cut->Elts.popcount() < 2)
4434 return false;
4435
4436 Intrinsic::ID ReducedOp =
4437 (CommonCallOp ? getMinMaxReductionIntrinsicID(*CommonCallOp)
4438 : getReductionForBinop(*CommonBinOp));
4439 if (!ReducedOp)
4440 return false;
4441
4442 InstructionCost OrigCost = 0;
4443 for (Value *V : Nodes)
4445
4446 auto *SrcVT = cast<FixedVectorType>(Cut->Src->getType());
4447 bool IsPartialReduction = !Cut->Elts.isAllOnes();
4448 FixedVectorType *ReduceVecTy =
4449 IsPartialReduction
4450 ? FixedVectorType::get(FVT->getElementType(), Cut->Elts.popcount())
4451 : SrcVT;
4452
4453 SmallVector<int> ExtractMask;
4454 InstructionCost NewCost = 0;
4455 if (IsPartialReduction) {
4456 for (unsigned I = 0, E = Cut->Elts.getBitWidth(); I != E; ++I)
4457 if (Cut->Elts[I])
4458 ExtractMask.push_back(I);
4459 unsigned SubIdx = 0, SubLen;
4460 auto SK = Cut->Elts.isShiftedMask(SubIdx, SubLen)
4463 NewCost += TTI.getShuffleCost(SK, ReduceVecTy, SrcVT, CostKind, ExtractMask,
4464 SubIdx, ReduceVecTy);
4465 }
4466
4467 IntrinsicCostAttributes ICA(
4468 ReducedOp, ReduceVecTy->getElementType(),
4469 IsFloatReduction
4470 ? SmallVector<Type *, 2>{ReduceVecTy->getElementType(), ReduceVecTy}
4471 : SmallVector<Type *, 2>{ReduceVecTy},
4472 IsFloatReduction ? CommonFMF : FastMathFlags());
4473 NewCost += TTI.getIntrinsicInstrCost(ICA, CostKind);
4474
4475 LLVM_DEBUG(dbgs() << "Found reduction shuffle chain: " << I << "\n OldCost : "
4476 << OrigCost << " vs NewCost: " << NewCost << "\n");
4477
4478 if (!OrigCost.isValid() || !NewCost.isValid())
4479 return false;
4480
4481 if (VecOpEE->hasOneUse() ? (NewCost > OrigCost) : (NewCost >= OrigCost))
4482 return false;
4483
4484 Value *ReduceInput = Cut->Src;
4485 if (IsPartialReduction)
4486 ReduceInput = Builder.CreateShuffleVector(Cut->Src, ExtractMask);
4487
4488 Value *ReducedResult;
4489 if (IsFloatReduction) {
4491 *CommonBinOp, ReduceVecTy->getElementType(), /*AllowRHSConstant=*/false,
4492 CommonFMF.noSignedZeros());
4493 ReducedResult = Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy},
4494 {Identity, ReduceInput}, CommonFMF);
4495 } else {
4496 ReducedResult =
4497 Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy}, {ReduceInput});
4498 }
4499 replaceValue(I, *ReducedResult);
4500
4501 return true;
4502}
4503
4504/// Determine if its more efficient to fold:
4505/// reduce(trunc(x)) -> trunc(reduce(x)).
4506/// reduce(sext(x)) -> sext(reduce(x)).
4507/// reduce(zext(x)) -> zext(reduce(x)).
4508bool VectorCombine::foldCastFromReductions(Instruction &I) {
4509 auto *II = dyn_cast<IntrinsicInst>(&I);
4510 if (!II)
4511 return false;
4512
4513 bool TruncOnly = false;
4514 Intrinsic::ID IID = II->getIntrinsicID();
4515 switch (IID) {
4516 case Intrinsic::vector_reduce_add:
4517 case Intrinsic::vector_reduce_mul:
4518 TruncOnly = true;
4519 break;
4520 case Intrinsic::vector_reduce_and:
4521 case Intrinsic::vector_reduce_or:
4522 case Intrinsic::vector_reduce_xor:
4523 break;
4524 default:
4525 return false;
4526 }
4527
4528 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
4529 Value *ReductionSrc = I.getOperand(0);
4530
4531 Value *Src;
4532 if (!match(ReductionSrc, m_OneUse(m_Trunc(m_Value(Src)))) &&
4533 (TruncOnly || !match(ReductionSrc, m_OneUse(m_ZExtOrSExt(m_Value(Src))))))
4534 return false;
4535
4536 auto CastOpc =
4537 (Instruction::CastOps)cast<Instruction>(ReductionSrc)->getOpcode();
4538
4539 auto *SrcTy = cast<VectorType>(Src->getType());
4540 auto *ReductionSrcTy = cast<VectorType>(ReductionSrc->getType());
4541 Type *ResultTy = I.getType();
4542
4544 ReductionOpc, ReductionSrcTy, std::nullopt, CostKind);
4545 OldCost += TTI.getCastInstrCost(CastOpc, ReductionSrcTy, SrcTy,
4547 cast<CastInst>(ReductionSrc));
4548 InstructionCost NewCost =
4549 TTI.getArithmeticReductionCost(ReductionOpc, SrcTy, std::nullopt,
4550 CostKind) +
4551 TTI.getCastInstrCost(CastOpc, ResultTy, ReductionSrcTy->getScalarType(),
4553
4554 if (OldCost <= NewCost || !NewCost.isValid())
4555 return false;
4556
4557 Value *NewReduction = Builder.CreateIntrinsic(SrcTy->getScalarType(),
4558 II->getIntrinsicID(), {Src});
4559 Value *NewCast = Builder.CreateCast(CastOpc, NewReduction, ResultTy);
4560 replaceValue(I, *NewCast);
4561 return true;
4562}
4563
4564/// Fold:
4565/// icmp pred (reduce.{add,or,and,umax,umin}(signbit_extract(x))), C
4566/// into:
4567/// icmp sgt/slt (reduce.{or,umax,and,umin}(x)), -1/0
4568///
4569/// Sign-bit reductions produce values with known semantics:
4570/// - reduce.{or,umax}: 0 if no element is negative, 1 if any is
4571/// - reduce.{and,umin}: 1 if all elements are negative, 0 if any isn't
4572/// - reduce.add: count of negative elements (0 to NumElts)
4573///
4574/// Both lshr and ashr are supported:
4575/// - lshr produces 0 or 1, so reduce.add range is [0, N]
4576/// - ashr produces 0 or -1, so reduce.add range is [-N, 0]
4577///
4578/// The fold generalizes to multiple source vectors combined with the same
4579/// operation as the reduction. For example:
4580/// reduce.or(or(shr A, shr B)) conceptually extends the vector
4581/// For reduce.add, this changes the count to M*N where M is the number of
4582/// source vectors.
4583///
4584/// We transform to a direct sign check on the original vector using
4585/// reduce.{or,umax} or reduce.{and,umin}.
4586///
4587/// In spirit, it's similar to foldSignBitCheck in InstCombine.
4588bool VectorCombine::foldSignBitReductionCmp(Instruction &I) {
4589 CmpPredicate Pred;
4590 IntrinsicInst *ReduceOp;
4591 const APInt *CmpVal;
4592 if (!match(&I,
4593 m_ICmp(Pred, m_OneUse(m_AnyIntrinsic(ReduceOp)), m_APInt(CmpVal))))
4594 return false;
4595
4596 Intrinsic::ID OrigIID = ReduceOp->getIntrinsicID();
4597 switch (OrigIID) {
4598 case Intrinsic::vector_reduce_or:
4599 case Intrinsic::vector_reduce_umax:
4600 case Intrinsic::vector_reduce_and:
4601 case Intrinsic::vector_reduce_umin:
4602 case Intrinsic::vector_reduce_add:
4603 break;
4604 default:
4605 return false;
4606 }
4607
4608 Value *ReductionSrc = ReduceOp->getArgOperand(0);
4609 auto *VecTy = dyn_cast<FixedVectorType>(ReductionSrc->getType());
4610 if (!VecTy)
4611 return false;
4612
4613 unsigned BitWidth = VecTy->getScalarSizeInBits();
4614 if (BitWidth == 1)
4615 return false;
4616
4617 unsigned NumElts = VecTy->getNumElements();
4618
4619 // Determine the expected tree opcode for multi-vector patterns.
4620 // The tree opcode must match the reduction's underlying operation.
4621 //
4622 // TODO: for pairs of equivalent operators, we should match both,
4623 // not only the most common.
4624 Instruction::BinaryOps TreeOpcode;
4625 switch (OrigIID) {
4626 case Intrinsic::vector_reduce_or:
4627 case Intrinsic::vector_reduce_umax:
4628 TreeOpcode = Instruction::Or;
4629 break;
4630 case Intrinsic::vector_reduce_and:
4631 case Intrinsic::vector_reduce_umin:
4632 TreeOpcode = Instruction::And;
4633 break;
4634 case Intrinsic::vector_reduce_add:
4635 TreeOpcode = Instruction::Add;
4636 break;
4637 default:
4638 llvm_unreachable("Unexpected intrinsic");
4639 }
4640
4641 // Collect sign-bit extraction leaves from an associative tree of TreeOpcode.
4642 // The tree conceptually extends the vector being reduced.
4643 SmallVector<Value *, 8> Worklist;
4644 SmallVector<Value *, 8> Sources; // Original vectors (X in shr X, BW-1)
4645 Worklist.push_back(ReductionSrc);
4646 std::optional<bool> IsAShr;
4647 constexpr unsigned MaxSources = 8;
4648
4649 // Calculate old cost: all shifts + tree ops + reduction
4650 InstructionCost OldCost = TTI.getInstructionCost(ReduceOp, CostKind);
4651
4652 while (!Worklist.empty() && Worklist.size() <= MaxSources &&
4653 Sources.size() <= MaxSources) {
4654 Value *V = Worklist.pop_back_val();
4655
4656 // Try to match sign-bit extraction: shr X, (bitwidth-1)
4657 Value *X;
4658 if (match(V, m_OneUse(m_Shr(m_Value(X), m_SpecificInt(BitWidth - 1))))) {
4659 auto *Shr = cast<Instruction>(V);
4660
4661 // All shifts must be the same type (all lshr or all ashr)
4662 bool ThisIsAShr = Shr->getOpcode() == Instruction::AShr;
4663 if (!IsAShr)
4664 IsAShr = ThisIsAShr;
4665 else if (*IsAShr != ThisIsAShr)
4666 return false;
4667
4668 Sources.push_back(X);
4669
4670 // As part of the fold, we remove all of the shifts, so we need to keep
4671 // track of their costs.
4672 OldCost += TTI.getInstructionCost(Shr, CostKind);
4673
4674 continue;
4675 }
4676
4677 // Try to extend through a tree node of the expected opcode
4678 Value *A, *B;
4679 if (!match(V, m_OneUse(m_BinOp(TreeOpcode, m_Value(A), m_Value(B)))))
4680 return false;
4681
4682 // We are potentially replacing these operations as well, so we add them
4683 // to the costs.
4685
4686 Worklist.push_back(A);
4687 Worklist.push_back(B);
4688 }
4689
4690 // Must have at least one source and not exceed limit
4691 if (Sources.empty() || Sources.size() > MaxSources ||
4692 Worklist.size() > MaxSources || !IsAShr)
4693 return false;
4694
4695 unsigned NumSources = Sources.size();
4696
4697 // For reduce.add, the total count must fit as a signed integer.
4698 // Range is [0, M*N] for lshr or [-M*N, 0] for ashr.
4699 if (OrigIID == Intrinsic::vector_reduce_add &&
4700 !isIntN(BitWidth, NumSources * NumElts))
4701 return false;
4702
4703 // Compute the boundary value when all elements are negative:
4704 // - Per-element contribution: 1 for lshr, -1 for ashr
4705 // - For add: M*N (total elements across all sources); for others: just 1
4706 unsigned Count =
4707 (OrigIID == Intrinsic::vector_reduce_add) ? NumSources * NumElts : 1;
4708 APInt NegativeVal(CmpVal->getBitWidth(), Count);
4709 if (*IsAShr)
4710 NegativeVal.negate();
4711
4712 // Range is [min(0, AllNegVal), max(0, AllNegVal)]
4713 APInt Zero = APInt::getZero(CmpVal->getBitWidth());
4714 APInt RangeLow = APIntOps::smin(Zero, NegativeVal);
4715 APInt RangeHigh = APIntOps::smax(Zero, NegativeVal);
4716
4717 // Determine comparison semantics:
4718 // - IsEq: true for equality test, false for inequality
4719 // - TestsNegative: true if testing against AllNegVal, false for zero
4720 //
4721 // In addition to EQ/NE against 0 or AllNegVal, we support inequalities
4722 // that fold to boundary tests given the narrow value range:
4723 // < RangeHigh -> != RangeHigh
4724 // > RangeHigh-1 -> == RangeHigh
4725 // > RangeLow -> != RangeLow
4726 // < RangeLow+1 -> == RangeLow
4727 //
4728 // For inequalities, we work with signed predicates only. Unsigned predicates
4729 // are canonicalized to signed when the range is non-negative (where they are
4730 // equivalent). When the range includes negative values, unsigned predicates
4731 // would have different semantics due to wrap-around, so we reject them.
4732 if (!ICmpInst::isEquality(Pred) && !ICmpInst::isSigned(Pred)) {
4733 if (RangeLow.isNegative())
4734 return false;
4735 Pred = ICmpInst::getSignedPredicate(Pred);
4736 }
4737
4738 bool IsEq;
4739 bool TestsNegative;
4740 if (ICmpInst::isEquality(Pred)) {
4741 if (CmpVal->isZero()) {
4742 TestsNegative = false;
4743 } else if (*CmpVal == NegativeVal) {
4744 TestsNegative = true;
4745 } else {
4746 return false;
4747 }
4748 IsEq = Pred == ICmpInst::ICMP_EQ;
4749 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeHigh) {
4750 IsEq = false;
4751 TestsNegative = (RangeHigh == NegativeVal);
4752 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeHigh - 1) {
4753 IsEq = true;
4754 TestsNegative = (RangeHigh == NegativeVal);
4755 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeLow) {
4756 IsEq = false;
4757 TestsNegative = (RangeLow == NegativeVal);
4758 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeLow + 1) {
4759 IsEq = true;
4760 TestsNegative = (RangeLow == NegativeVal);
4761 } else {
4762 return false;
4763 }
4764
4765 // For this fold we support four types of checks:
4766 //
4767 // 1. All lanes are negative - AllNeg
4768 // 2. All lanes are non-negative - AllNonNeg
4769 // 3. At least one negative lane - AnyNeg
4770 // 4. At least one non-negative lane - AnyNonNeg
4771 //
4772 // For each case, we can generate the following code:
4773 //
4774 // 1. AllNeg - reduce.and/umin(X) < 0
4775 // 2. AllNonNeg - reduce.or/umax(X) > -1
4776 // 3. AnyNeg - reduce.or/umax(X) < 0
4777 // 4. AnyNonNeg - reduce.and/umin(X) > -1
4778 //
4779 // The table below shows the aggregation of all supported cases
4780 // using these four cases.
4781 //
4782 // Reduction | == 0 | != 0 | == MAX | != MAX
4783 // ------------+-----------+-----------+-----------+-----------
4784 // or/umax | AllNonNeg | AnyNeg | AnyNeg | AllNonNeg
4785 // and/umin | AnyNonNeg | AllNeg | AllNeg | AnyNonNeg
4786 // add | AllNonNeg | AnyNeg | AllNeg | AnyNonNeg
4787 //
4788 // NOTE: MAX = 1 for or/and/umax/umin, and the vector size N for add
4789 //
4790 // For easier codegen and check inversion, we use the following encoding:
4791 //
4792 // 1. Bit-3 === requires or/umax (1) or and/umin (0) check
4793 // 2. Bit-2 === checks < 0 (1) or > -1 (0)
4794 // 3. Bit-1 === universal (1) or existential (0) check
4795 //
4796 // AnyNeg = 0b110: uses or/umax, checks negative, any-check
4797 // AllNonNeg = 0b101: uses or/umax, checks non-neg, all-check
4798 // AnyNonNeg = 0b000: uses and/umin, checks non-neg, any-check
4799 // AllNeg = 0b011: uses and/umin, checks negative, all-check
4800 //
4801 // XOR with 0b011 inverts the check (swaps all/any and neg/non-neg).
4802 //
4803 enum CheckKind : unsigned {
4804 AnyNonNeg = 0b000,
4805 AllNeg = 0b011,
4806 AllNonNeg = 0b101,
4807 AnyNeg = 0b110,
4808 };
4809 // Return true if we fold this check into or/umax and false for and/umin
4810 auto RequiresOr = [](CheckKind C) -> bool { return C & 0b100; };
4811 // Return true if we should check if result is negative and false otherwise
4812 auto IsNegativeCheck = [](CheckKind C) -> bool { return C & 0b010; };
4813 // Logically invert the check
4814 auto Invert = [](CheckKind C) { return CheckKind(C ^ 0b011); };
4815
4816 CheckKind Base;
4817 switch (OrigIID) {
4818 case Intrinsic::vector_reduce_or:
4819 case Intrinsic::vector_reduce_umax:
4820 Base = TestsNegative ? AnyNeg : AllNonNeg;
4821 break;
4822 case Intrinsic::vector_reduce_and:
4823 case Intrinsic::vector_reduce_umin:
4824 Base = TestsNegative ? AllNeg : AnyNonNeg;
4825 break;
4826 case Intrinsic::vector_reduce_add:
4827 Base = TestsNegative ? AllNeg : AllNonNeg;
4828 break;
4829 default:
4830 llvm_unreachable("Unexpected intrinsic");
4831 }
4832
4833 CheckKind Check = IsEq ? Base : Invert(Base);
4834
4835 auto PickCheaper = [&](Intrinsic::ID Arith, Intrinsic::ID MinMax) {
4836 InstructionCost ArithCost =
4838 VecTy, std::nullopt, CostKind);
4839 InstructionCost MinMaxCost =
4841 FastMathFlags(), CostKind);
4842 return ArithCost <= MinMaxCost ? std::make_pair(Arith, ArithCost)
4843 : std::make_pair(MinMax, MinMaxCost);
4844 };
4845
4846 // Choose output reduction based on encoding's MSB
4847 auto [NewIID, NewCost] = RequiresOr(Check)
4848 ? PickCheaper(Intrinsic::vector_reduce_or,
4849 Intrinsic::vector_reduce_umax)
4850 : PickCheaper(Intrinsic::vector_reduce_and,
4851 Intrinsic::vector_reduce_umin);
4852
4853 // Add cost of combining multiple sources with or/and
4854 if (NumSources > 1) {
4855 unsigned CombineOpc =
4856 RequiresOr(Check) ? Instruction::Or : Instruction::And;
4857 NewCost += TTI.getArithmeticInstrCost(CombineOpc, VecTy, CostKind) *
4858 (NumSources - 1);
4859 }
4860
4861 LLVM_DEBUG(dbgs() << "Found sign-bit reduction cmp: " << I << "\n OldCost: "
4862 << OldCost << " vs NewCost: " << NewCost << "\n");
4863
4864 if (NewCost > OldCost)
4865 return false;
4866
4867 // Generate the combined input and reduction
4868 Builder.SetInsertPoint(&I);
4869 Type *ScalarTy = VecTy->getScalarType();
4870
4871 Value *Input;
4872 if (NumSources == 1) {
4873 Input = Sources[0];
4874 } else {
4875 // Combine sources with or/and based on check type
4876 Input = RequiresOr(Check) ? Builder.CreateOr(Sources)
4877 : Builder.CreateAnd(Sources);
4878 }
4879
4880 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, NewIID, {Input});
4881 Value *NewCmp = IsNegativeCheck(Check) ? Builder.CreateIsNeg(NewReduce)
4882 : Builder.CreateIsNotNeg(NewReduce);
4883 replaceValue(I, *NewCmp);
4884 return true;
4885}
4886
4887/// Fold a zero test of reduce.or or reduce.umax into a boolean reduction.
4888///
4889/// Vectorization may produce IR that compares the result of a scalar reduction
4890/// with zero. Depending on the target, lowering a reduction and a scalar
4891/// comparison separately can cost more than reducing lane-wise comparison
4892/// results. This fold creates the latter form only when it is not costlier.
4893///
4894/// Before:
4895/// %r = call iT @llvm.vector.reduce.or.vNiT(<N x iT> %x)
4896/// %cmp = icmp ne iT %r, 0
4897///
4898/// After:
4899/// %lane.cmp = icmp ne <N x iT> %x, zeroinitializer
4900/// %cmp = call i1 @llvm.vector.reduce.or.vNi1(<N x i1> %lane.cmp)
4901///
4902/// `reduce.or` and `reduce.umax` are non-zero when at least one lane is
4903/// non-zero. Therefore, `icmp ne` uses the existential `reduce.or` test.
4904/// Conversely, `icmp eq` must check that every lane is zero, so it uses the
4905/// universal `reduce.and` test.
4906///
4907/// Before:
4908/// %r = call iT @llvm.vector.reduce.umax.vNiT(<N x iT> %x)
4909/// %cmp = icmp eq iT %r, 0
4910///
4911/// After:
4912/// %lane.cmp = icmp eq <N x iT> %x, zeroinitializer
4913/// %cmp = call i1 @llvm.vector.reduce.and.vNi1(<N x i1> %lane.cmp)
4914bool VectorCombine::foldReductionZeroTest(Instruction &I) {
4915 CmpPredicate Pred;
4916 Value *Op;
4917
4918 if (!match(&I, m_c_ICmp(Pred, m_Value(Op), m_Zero())) ||
4919 !ICmpInst::isEquality(Pred))
4920 return false;
4921
4922 auto *II = dyn_cast<IntrinsicInst>(Op);
4923 if (!II || !II->hasOneUse())
4924 return false;
4925
4926 auto ReduceID = II->getIntrinsicID();
4927 if (ReduceID != Intrinsic::vector_reduce_or &&
4928 ReduceID != Intrinsic::vector_reduce_umax)
4929 return false;
4930
4931 Value *Vec = II->getArgOperand(0);
4932 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
4933 if (!VecTy || !VecTy->getElementType()->isIntegerTy())
4934 return false;
4935
4936 // Map the scalar zero test to an any-lane or all-lane boolean reduction.
4937 Intrinsic::ID NewIID = (Pred == ICmpInst::ICMP_NE)
4938 ? Intrinsic::vector_reduce_or
4939 : Intrinsic::vector_reduce_and;
4940
4941 // This is not an unconditional canonicalization: compare the cost of the
4942 // original scalar reduction and compare with the vector compare and i1
4943 // reduction replacement for both reduce.or and reduce.umax.
4946
4947 auto *CmpTy = cast<VectorType>(CmpInst::makeCmpResultType(VecTy));
4948 InstructionCost NewCost =
4949 TTI.getCmpSelInstrCost(Instruction::ICmp, VecTy, CmpTy, Pred, CostKind);
4951 getArithmeticReductionInstruction(NewIID), CmpTy, std::nullopt, CostKind);
4952
4953 LLVM_DEBUG(dbgs() << "Found a reduction zero test: " << I << "\n OldCost: "
4954 << OldCost << " vs NewCost: " << NewCost << "\n");
4955
4956 if (!OldCost.isValid() || !NewCost.isValid() || NewCost > OldCost)
4957 return false;
4958
4959 Builder.SetInsertPoint(&I);
4960 Value *NewCmp = Builder.CreateICmp(Pred, Vec, Constant::getNullValue(VecTy));
4961 Value *NewReduce = Builder.CreateIntrinsic(NewIID, {CmpTy}, {NewCmp});
4962 replaceValue(I, *NewReduce);
4963 return true;
4964}
4965
4966/// vector.reduce.OP f(X_i) == 0 -> vector.reduce.OP X_i == 0
4967///
4968/// We can prove it for cases when:
4969///
4970/// 1. OP X_i == 0 <=> \forall i \in [1, N] X_i == 0
4971/// 1'. OP X_i == 0 <=> \exists j \in [1, N] X_j == 0
4972/// 2. f(x) == 0 <=> x == 0
4973///
4974/// From 1 and 2 (or 1' and 2), we can infer that
4975///
4976/// OP f(X_i) == 0 <=> OP X_i == 0.
4977///
4978/// (1)
4979/// OP f(X_i) == 0 <=> \forall i \in [1, N] f(X_i) == 0
4980/// (2)
4981/// <=> \forall i \in [1, N] X_i == 0
4982/// (1)
4983/// <=> OP(X_i) == 0
4984///
4985/// For some of the OP's and f's, we need to have domain constraints on X
4986/// to ensure properties 1 (or 1') and 2.
4987bool VectorCombine::foldICmpEqZeroVectorReduce(Instruction &I) {
4988 CmpPredicate Pred;
4989 Value *Op;
4990 if (!match(&I, m_ICmp(Pred, m_Value(Op), m_Zero())) ||
4991 !ICmpInst::isEquality(Pred))
4992 return false;
4993
4994 auto *II = dyn_cast<IntrinsicInst>(Op);
4995 if (!II)
4996 return false;
4997
4998 switch (II->getIntrinsicID()) {
4999 case Intrinsic::vector_reduce_add:
5000 case Intrinsic::vector_reduce_or:
5001 case Intrinsic::vector_reduce_umin:
5002 case Intrinsic::vector_reduce_umax:
5003 case Intrinsic::vector_reduce_smin:
5004 case Intrinsic::vector_reduce_smax:
5005 break;
5006 default:
5007 return false;
5008 }
5009
5010 Value *InnerOp = II->getArgOperand(0);
5011
5012 // TODO: fixed vector type might be too restrictive
5013 if (!II->hasOneUse() || !isa<FixedVectorType>(InnerOp->getType()))
5014 return false;
5015
5016 Value *X = nullptr;
5017
5018 // Check for zero-preserving operations where f(x) = 0 <=> x = 0
5019 //
5020 // 1. f(x) = shl nuw x, y for arbitrary y
5021 // 2. f(x) = mul nuw x, c for defined c != 0
5022 // 3. f(x) = zext x
5023 // 4. f(x) = sext x
5024 // 5. f(x) = neg x
5025 //
5026 if (!(match(InnerOp, m_NUWShl(m_Value(X), m_Value())) || // Case 1
5027 match(InnerOp, m_NUWMul(m_Value(X), m_NonZeroInt())) || // Case 2
5028 match(InnerOp, m_ZExt(m_Value(X))) || // Case 3
5029 match(InnerOp, m_SExt(m_Value(X))) || // Case 4
5030 match(InnerOp, m_Neg(m_Value(X))) // Case 5
5031 ))
5032 return false;
5033
5034 SimplifyQuery S = SQ.getWithInstruction(&I);
5035 auto *XTy = cast<FixedVectorType>(X->getType());
5036
5037 // Check for domain constraints for all supported reductions.
5038 //
5039 // a. OR X_i - has property 1 for every X
5040 // b. UMAX X_i - has property 1 for every X
5041 // c. UMIN X_i - has property 1' for every X
5042 // d. SMAX X_i - has property 1 for X >= 0
5043 // e. SMIN X_i - has property 1' for X >= 0
5044 // f. ADD X_i - has property 1 for X >= 0 && ADD X_i doesn't sign wrap
5045 //
5046 // In order for the proof to work, we need 1 (or 1') to be true for both
5047 // OP f(X_i) and OP X_i and that's why below we check constraints twice.
5048 //
5049 // NOTE: ADD X_i holds property 1 for a mirror case as well, i.e. when
5050 // X <= 0 && ADD X_i doesn't sign wrap. However, due to the nature
5051 // of known bits, we can't reasonably hold knowledge of "either 0
5052 // or negative".
5053 switch (II->getIntrinsicID()) {
5054 case Intrinsic::vector_reduce_add: {
5055 // We need to check that both X_i and f(X_i) have enough leading
5056 // zeros to not overflow.
5057 KnownBits KnownX = computeKnownBits(X, S);
5058 KnownBits KnownFX = computeKnownBits(InnerOp, S);
5059 unsigned NumElems = XTy->getNumElements();
5060 // Adding N elements loses at most ceil(log2(N)) leading bits.
5061 unsigned LostBits = Log2_32_Ceil(NumElems);
5062 unsigned LeadingZerosX = KnownX.countMinLeadingZeros();
5063 unsigned LeadingZerosFX = KnownFX.countMinLeadingZeros();
5064 // Need at least one leading zero left after summation to ensure no overflow
5065 if (LeadingZerosX <= LostBits || LeadingZerosFX <= LostBits)
5066 return false;
5067
5068 // We are not checking whether X or f(X) are positive explicitly because
5069 // we implicitly checked for it when we checked if both cases have enough
5070 // leading zeros to not wrap addition.
5071 break;
5072 }
5073 case Intrinsic::vector_reduce_smin:
5074 case Intrinsic::vector_reduce_smax:
5075 // Check whether X >= 0 and f(X) >= 0
5076 if (!isKnownNonNegative(InnerOp, S) || !isKnownNonNegative(X, S))
5077 return false;
5078
5079 break;
5080 default:
5081 break;
5082 };
5083
5084 LLVM_DEBUG(dbgs() << "Found a reduction to 0 comparison with removable op: "
5085 << *II << "\n");
5086
5087 // For zext/sext, check if the transform is profitable using cost model.
5088 // For other operations (shl, mul, neg), we're removing an instruction
5089 // while keeping the same reduction type, so it's always profitable.
5090 if (isa<ZExtInst>(InnerOp) || isa<SExtInst>(InnerOp)) {
5091 auto *FXTy = cast<FixedVectorType>(InnerOp->getType());
5092 Intrinsic::ID IID = II->getIntrinsicID();
5093
5095 cast<CastInst>(InnerOp)->getOpcode(), FXTy, XTy,
5097
5098 InstructionCost OldReduceCost, NewReduceCost;
5099 switch (IID) {
5100 case Intrinsic::vector_reduce_add:
5101 case Intrinsic::vector_reduce_or:
5102 OldReduceCost = TTI.getArithmeticReductionCost(
5103 getArithmeticReductionInstruction(IID), FXTy, std::nullopt, CostKind);
5104 NewReduceCost = TTI.getArithmeticReductionCost(
5105 getArithmeticReductionInstruction(IID), XTy, std::nullopt, CostKind);
5106 break;
5107 case Intrinsic::vector_reduce_umin:
5108 case Intrinsic::vector_reduce_umax:
5109 case Intrinsic::vector_reduce_smin:
5110 case Intrinsic::vector_reduce_smax:
5111 OldReduceCost = TTI.getMinMaxReductionCost(
5112 getMinMaxReductionIntrinsicOp(IID), FXTy, FastMathFlags(), CostKind);
5113 NewReduceCost = TTI.getMinMaxReductionCost(
5114 getMinMaxReductionIntrinsicOp(IID), XTy, FastMathFlags(), CostKind);
5115 break;
5116 default:
5117 llvm_unreachable("Unexpected reduction");
5118 }
5119
5120 InstructionCost OldCost = OldReduceCost + ExtCost;
5121 InstructionCost NewCost =
5122 NewReduceCost + (InnerOp->hasOneUse() ? 0 : ExtCost);
5123
5124 LLVM_DEBUG(dbgs() << "Found a removable extension before reduction: "
5125 << *InnerOp << "\n OldCost: " << OldCost
5126 << " vs NewCost: " << NewCost << "\n");
5127
5128 // We consider transformation to still be potentially beneficial even
5129 // when the costs are the same because we might remove a use from f(X)
5130 // and unlock other optimizations. Equal costs would just mean that we
5131 // didn't make it worse in the worst case.
5132 if (NewCost > OldCost)
5133 return false;
5134 }
5135
5136 // Since we support zext and sext as f, we might change the scalar type
5137 // of the intrinsic.
5138 Type *Ty = XTy->getScalarType();
5139 Value *NewReduce = Builder.CreateIntrinsic(Ty, II->getIntrinsicID(), {X});
5140 Value *NewCmp =
5141 Builder.CreateICmp(Pred, NewReduce, ConstantInt::getNullValue(Ty));
5142 replaceValue(I, *NewCmp);
5143 return true;
5144}
5145
5146/// Fold comparisons of reduce.or/reduce.and with reduce.umax/reduce.umin
5147/// based on cost, preserving the comparison semantics.
5148///
5149/// We use two fundamental properties for each pair:
5150///
5151/// 1. or(X) == 0 <=> umax(X) == 0
5152/// 2. or(X) == 1 <=> umax(X) == 1
5153/// 3. sign(or(X)) == sign(umax(X))
5154///
5155/// 1. and(X) == -1 <=> umin(X) == -1
5156/// 2. and(X) == -2 <=> umin(X) == -2
5157/// 3. sign(and(X)) == sign(umin(X))
5158///
5159/// From these we can infer the following transformations:
5160/// a. or(X) ==/!= 0 <-> umax(X) ==/!= 0
5161/// b. or(X) s< 0 <-> umax(X) s< 0
5162/// c. or(X) s> -1 <-> umax(X) s> -1
5163/// d. or(X) s< 1 <-> umax(X) s< 1
5164/// e. or(X) ==/!= 1 <-> umax(X) ==/!= 1
5165/// f. or(X) s< 2 <-> umax(X) s< 2
5166/// g. and(X) ==/!= -1 <-> umin(X) ==/!= -1
5167/// h. and(X) s< 0 <-> umin(X) s< 0
5168/// i. and(X) s> -1 <-> umin(X) s> -1
5169/// j. and(X) s> -2 <-> umin(X) s> -2
5170/// k. and(X) ==/!= -2 <-> umin(X) ==/!= -2
5171/// l. and(X) s> -3 <-> umin(X) s> -3
5172///
5173bool VectorCombine::foldEquivalentReductionCmp(Instruction &I) {
5174 CmpPredicate Pred;
5175 Value *ReduceOp;
5176 const APInt *CmpVal;
5177 if (!match(&I, m_ICmp(Pred, m_Value(ReduceOp), m_APInt(CmpVal))))
5178 return false;
5179
5180 auto *II = dyn_cast<IntrinsicInst>(ReduceOp);
5181 if (!II || !II->hasOneUse())
5182 return false;
5183
5184 const auto IsValidOrUmaxCmp = [&]() {
5185 // or === umax for i1
5186 if (CmpVal->getBitWidth() == 1)
5187 return true;
5188
5189 // Cases a and e
5190 bool IsEquality =
5191 (CmpVal->isZero() || CmpVal->isOne()) && ICmpInst::isEquality(Pred);
5192 // Case c
5193 bool IsPositive = CmpVal->isAllOnes() && Pred == ICmpInst::ICMP_SGT;
5194 // Cases b, d, and f
5195 bool IsNegative = (CmpVal->isZero() || CmpVal->isOne() || *CmpVal == 2) &&
5196 Pred == ICmpInst::ICMP_SLT;
5197 return IsEquality || IsPositive || IsNegative;
5198 };
5199
5200 const auto IsValidAndUminCmp = [&]() {
5201 // and === umin for i1
5202 if (CmpVal->getBitWidth() == 1)
5203 return true;
5204
5205 const auto LeadingOnes = CmpVal->countl_one();
5206
5207 // Cases g and k
5208 bool IsEquality =
5209 (CmpVal->isAllOnes() || LeadingOnes + 1 == CmpVal->getBitWidth()) &&
5211 // Case h
5212 bool IsNegative = CmpVal->isZero() && Pred == ICmpInst::ICMP_SLT;
5213 // Cases i, j, and l
5214 bool IsPositive =
5215 // if the number has at least N - 2 leading ones
5216 // and the two LSBs are:
5217 // - 1 x 1 -> -1
5218 // - 1 x 0 -> -2
5219 // - 0 x 1 -> -3
5220 LeadingOnes + 2 >= CmpVal->getBitWidth() &&
5221 ((*CmpVal)[0] || (*CmpVal)[1]) && Pred == ICmpInst::ICMP_SGT;
5222 return IsEquality || IsNegative || IsPositive;
5223 };
5224
5225 Intrinsic::ID OriginalIID = II->getIntrinsicID();
5226 Intrinsic::ID AlternativeIID;
5227
5228 // Check if this is a valid comparison pattern and determine the alternate
5229 // reduction intrinsic.
5230 switch (OriginalIID) {
5231 case Intrinsic::vector_reduce_or:
5232 if (!IsValidOrUmaxCmp())
5233 return false;
5234 AlternativeIID = Intrinsic::vector_reduce_umax;
5235 break;
5236 case Intrinsic::vector_reduce_umax:
5237 if (!IsValidOrUmaxCmp())
5238 return false;
5239 AlternativeIID = Intrinsic::vector_reduce_or;
5240 break;
5241 case Intrinsic::vector_reduce_and:
5242 if (!IsValidAndUminCmp())
5243 return false;
5244 AlternativeIID = Intrinsic::vector_reduce_umin;
5245 break;
5246 case Intrinsic::vector_reduce_umin:
5247 if (!IsValidAndUminCmp())
5248 return false;
5249 AlternativeIID = Intrinsic::vector_reduce_and;
5250 break;
5251 default:
5252 return false;
5253 }
5254
5255 Value *X = II->getArgOperand(0);
5256 auto *VecTy = dyn_cast<FixedVectorType>(X->getType());
5257 if (!VecTy)
5258 return false;
5259
5260 const auto GetReductionCost = [&](Intrinsic::ID IID) -> InstructionCost {
5261 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
5262 if (ReductionOpc != Instruction::ICmp)
5263 return TTI.getArithmeticReductionCost(ReductionOpc, VecTy, std::nullopt,
5264 CostKind);
5266 FastMathFlags(), CostKind);
5267 };
5268
5269 InstructionCost OrigCost = GetReductionCost(OriginalIID);
5270 InstructionCost AltCost = GetReductionCost(AlternativeIID);
5271
5272 LLVM_DEBUG(dbgs() << "Found equivalent reduction cmp: " << I
5273 << "\n OrigCost: " << OrigCost
5274 << " vs AltCost: " << AltCost << "\n");
5275
5276 if (AltCost >= OrigCost)
5277 return false;
5278
5279 Builder.SetInsertPoint(&I);
5280 Type *ScalarTy = VecTy->getScalarType();
5281 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, AlternativeIID, {X});
5282 Value *NewCmp =
5283 Builder.CreateICmp(Pred, NewReduce, ConstantInt::get(ScalarTy, *CmpVal));
5284
5285 replaceValue(I, *NewCmp);
5286 return true;
5287}
5288
5289/// Used by foldReduceAddCmpZero to check if we can prove that a value is
5290/// non-positive.
5291/// KnownBits cannot see sext <? x i1> as non-positive: each top bit equals a
5292/// single unknown input bit, which a per-bit lattice cannot track. The fold's
5293/// target shape is popcount-style sums of <N x i1> valid/invalid masks (e.g.
5294/// ray-intersection hits) tested for any-hit.
5295/// Previous attempts to approximate the known bits of such expressions were
5296/// using a fully recursive value tracking approach to infer a constant range
5297/// but ultimately turned to be too expensive in compile time.
5298static bool isKnownNonPositive(const Value *V, const SimplifyQuery &SQ,
5299 unsigned Depth = 0) {
5300 constexpr unsigned MaxLocalDepth = 2;
5301 if (Depth > MaxLocalDepth)
5302 return false;
5303
5304 auto NumSignBits = [&](const Value *X) {
5305 return ComputeNumSignBits(X, SQ.DL, SQ.AC, SQ.CxtI, SQ.DT);
5306 };
5307 if (NumSignBits(V) == V->getType()->getScalarSizeInBits())
5308 return true;
5309
5310 Value *A, *B;
5311 if (match(V, m_Add(m_Value(A), m_Value(B))))
5312 return NumSignBits(A) >= 2 && NumSignBits(B) >= 2 &&
5313 isKnownNonPositive(A, SQ, Depth + 1) &&
5314 isKnownNonPositive(B, SQ, Depth + 1);
5315
5316 return computeKnownBits(V, SQ).isNonPositive();
5317}
5318
5319/// Fold (icmp pred (reduce.add X), 0) to (icmp pred' (reduce.or X), 0) when X
5320/// has lanes known to all be non-negative or all non-positive, so that
5321/// sum == 0 iff every lane is 0. Falls back to reduce.umax if reduce.or is
5322/// more expensive on the target.
5323bool VectorCombine::foldReduceAddCmpZero(Instruction &I) {
5324 CmpPredicate Pred;
5325 Value *Vec;
5326 if (!match(&I, m_ICmp(Pred,
5328 m_Value(Vec))),
5329 m_Zero())))
5330 return false;
5331
5332 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
5333 if (!VecTy || VecTy->getNumElements() < 2)
5334 return false;
5335
5336 SimplifyQuery Q = SQ.getWithInstruction(&I);
5337 bool IsNonNegative = isKnownNonNegative(Vec, Q);
5338 bool IsNonPositive = !IsNonNegative && isKnownNonPositive(Vec, Q);
5339 if (!IsNonNegative && !IsNonPositive)
5340 return false;
5341
5342 // Summing NumElts lanes can consume up to log2(NumElts) sign bits. Require
5343 // strictly more headroom than that so the sum cannot wrap to zero.
5344 unsigned NumElts = VecTy->getNumElements();
5345 unsigned NumSignBits = ComputeNumSignBits(Vec, *DL, SQ.AC, &I, &DT);
5346 if (Log2_32(NumElts) >= NumSignBits)
5347 return false;
5348
5349 ICmpInst::Predicate NewPred;
5350 switch (Pred) {
5351 case ICmpInst::ICMP_EQ:
5352 case ICmpInst::ICMP_ULE:
5353 case ICmpInst::ICMP_SLE:
5354 case ICmpInst::ICMP_SGE:
5355 NewPred = ICmpInst::ICMP_EQ;
5356 break;
5357 case ICmpInst::ICMP_NE:
5358 case ICmpInst::ICMP_UGT:
5359 case ICmpInst::ICMP_SGT:
5360 case ICmpInst::ICMP_SLT:
5361 NewPred = ICmpInst::ICMP_NE;
5362 break;
5363 default:
5364 return false;
5365 }
5366
5367 // SGT and SLE on a non-positive tree, and SLT and SGE on a non-negative
5368 // tree, are tautologies (always true or always false). Leave those to
5369 // InstCombine rather than mapping them here. Remaining signed inequalities
5370 // also need one extra sign bit so the sum cannot flip sign.
5371 if (!IsNonNegative &&
5372 (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE))
5373 return false;
5374 if (!IsNonPositive &&
5375 (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE))
5376 return false;
5377 if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE ||
5378 Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) &&
5379 Log2_32(NumElts) >= NumSignBits - 1)
5380 return false;
5381
5383 Instruction::Add, VecTy, std::nullopt, CostKind);
5385 Instruction::Or, VecTy, std::nullopt, CostKind);
5387 Intrinsic::umax, VecTy, FastMathFlags(), CostKind);
5388 if (!OrCost.isValid() && !UmaxCost.isValid())
5389 return false;
5390 bool UseOr = OrCost.isValid() && (!UmaxCost.isValid() || OrCost <= UmaxCost);
5391 InstructionCost AltCost = UseOr ? OrCost : UmaxCost;
5392 if (AltCost > OrigCost)
5393 return false;
5394
5395 Builder.SetInsertPoint(&I);
5396 Value *NewReduce = UseOr ? Builder.CreateOrReduce(Vec)
5397 : Builder.CreateIntrinsic(
5398 Intrinsic::vector_reduce_umax, {VecTy}, {Vec});
5399 Worklist.pushValue(NewReduce);
5400 Value *NewCmp = Builder.CreateICmp(
5401 NewPred, NewReduce, ConstantInt::getNullValue(VecTy->getScalarType()));
5402 replaceValue(I, *NewCmp);
5403 return true;
5404}
5405
5406/// Returns true if this ShuffleVectorInst eventually feeds into a
5407/// vector reduction intrinsic (e.g., vector_reduce_add) by only following
5408/// chains of shuffles and binary operators (in any combination/order).
5409/// The search does not go deeper than the given Depth.
5411 constexpr unsigned MaxVisited = 32;
5414 bool FoundReduction = false;
5415
5416 WorkList.push_back(SVI);
5417 while (!WorkList.empty()) {
5418 Instruction *I = WorkList.pop_back_val();
5419 for (User *U : I->users()) {
5420 auto *UI = cast<Instruction>(U);
5421 if (!UI || !Visited.insert(UI).second)
5422 continue;
5423 if (Visited.size() > MaxVisited)
5424 return false;
5425 if (auto *II = dyn_cast<IntrinsicInst>(UI)) {
5426 // More than one reduction reached
5427 if (FoundReduction)
5428 return false;
5429 switch (II->getIntrinsicID()) {
5430 case Intrinsic::vector_reduce_add:
5431 case Intrinsic::vector_reduce_mul:
5432 case Intrinsic::vector_reduce_and:
5433 case Intrinsic::vector_reduce_or:
5434 case Intrinsic::vector_reduce_xor:
5435 case Intrinsic::vector_reduce_smin:
5436 case Intrinsic::vector_reduce_smax:
5437 case Intrinsic::vector_reduce_umin:
5438 case Intrinsic::vector_reduce_umax:
5439 FoundReduction = true;
5440 continue;
5441 default:
5442 return false;
5443 }
5444 }
5445
5447 return false;
5448
5449 WorkList.emplace_back(UI);
5450 }
5451 }
5452 return FoundReduction;
5453}
5454
5455/// This method looks for groups of shuffles acting on binops, of the form:
5456/// %x = shuffle ...
5457/// %y = shuffle ...
5458/// %a = binop %x, %y
5459/// %b = binop %x, %y
5460/// shuffle %a, %b, selectmask
5461/// We may, especially if the shuffle is wider than legal, be able to convert
5462/// the shuffle to a form where only parts of a and b need to be computed. On
5463/// architectures with no obvious "select" shuffle, this can reduce the total
5464/// number of operations if the target reports them as cheaper.
5465bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
5466 auto *SVI = cast<ShuffleVectorInst>(&I);
5467 auto *VT = cast<FixedVectorType>(I.getType());
5468 auto *Op0 = dyn_cast<Instruction>(SVI->getOperand(0));
5469 auto *Op1 = dyn_cast<Instruction>(SVI->getOperand(1));
5470 if (!Op0 || !Op1 || Op0 == Op1 || !Op0->isBinaryOp() || !Op1->isBinaryOp() ||
5471 VT != Op0->getType())
5472 return false;
5473
5474 auto *SVI0A = dyn_cast<Instruction>(Op0->getOperand(0));
5475 auto *SVI0B = dyn_cast<Instruction>(Op0->getOperand(1));
5476 auto *SVI1A = dyn_cast<Instruction>(Op1->getOperand(0));
5477 auto *SVI1B = dyn_cast<Instruction>(Op1->getOperand(1));
5478 SmallPtrSet<Instruction *, 4> InputShuffles({SVI0A, SVI0B, SVI1A, SVI1B});
5479 auto checkSVNonOpUses = [&](Instruction *I) {
5480 if (!I || I->getOperand(0)->getType() != VT)
5481 return true;
5482 return any_of(I->users(), [&](User *U) {
5483 return U != Op0 && U != Op1 &&
5484 !(isa<ShuffleVectorInst>(U) &&
5485 (InputShuffles.contains(cast<Instruction>(U)) ||
5486 isInstructionTriviallyDead(cast<Instruction>(U))));
5487 });
5488 };
5489 if (checkSVNonOpUses(SVI0A) || checkSVNonOpUses(SVI0B) ||
5490 checkSVNonOpUses(SVI1A) || checkSVNonOpUses(SVI1B))
5491 return false;
5492
5493 // Collect all the uses that are shuffles that we can transform together. We
5494 // may not have a single shuffle, but a group that can all be transformed
5495 // together profitably.
5497 auto collectShuffles = [&](Instruction *I) {
5498 for (auto *U : I->users()) {
5500 if (!SV || SV->getType() != VT)
5501 return false;
5502 if ((SV->getOperand(0) != Op0 && SV->getOperand(0) != Op1) ||
5503 (SV->getOperand(1) != Op0 && SV->getOperand(1) != Op1))
5504 return false;
5505 if (!llvm::is_contained(Shuffles, SV))
5506 Shuffles.push_back(SV);
5507 }
5508 return true;
5509 };
5510 if (!collectShuffles(Op0) || !collectShuffles(Op1))
5511 return false;
5512 // From a reduction, we need to be processing a single shuffle, otherwise the
5513 // other uses will not be lane-invariant.
5514 if (FromReduction && Shuffles.size() > 1)
5515 return false;
5516
5517 // Add any shuffle uses for the shuffles we have found, to include them in our
5518 // cost calculations.
5519 if (!FromReduction) {
5520 for (size_t Idx = 0, E = Shuffles.size(); Idx != E; ++Idx) {
5521 for (auto *U : Shuffles[Idx]->users()) {
5522 ShuffleVectorInst *SSV = dyn_cast<ShuffleVectorInst>(U);
5523 if (SSV && isa<UndefValue>(SSV->getOperand(1)) && SSV->getType() == VT)
5524 Shuffles.push_back(SSV);
5525 }
5526 }
5527 }
5528
5529 // For each of the output shuffles, we try to sort all the first vector
5530 // elements to the beginning, followed by the second array elements at the
5531 // end. If the binops are legalized to smaller vectors, this may reduce total
5532 // number of binops. We compute the ReconstructMask mask needed to convert
5533 // back to the original lane order.
5535 SmallVector<SmallVector<int>> OrigReconstructMasks;
5536 int MaxV1Elt = 0, MaxV2Elt = 0;
5537 unsigned NumElts = VT->getNumElements();
5538 for (ShuffleVectorInst *SVN : Shuffles) {
5539 SmallVector<int> Mask;
5540 SVN->getShuffleMask(Mask);
5541
5542 // Check the operands are the same as the original, or reversed (in which
5543 // case we need to commute the mask).
5544 Value *SVOp0 = SVN->getOperand(0);
5545 Value *SVOp1 = SVN->getOperand(1);
5546 if (isa<UndefValue>(SVOp1)) {
5547 auto *SSV = cast<ShuffleVectorInst>(SVOp0);
5548 SVOp0 = SSV->getOperand(0);
5549 SVOp1 = SSV->getOperand(1);
5550 for (int &Elem : Mask) {
5551 if (Elem >= static_cast<int>(SSV->getShuffleMask().size()))
5552 return false;
5553 Elem = Elem < 0 ? Elem : SSV->getMaskValue(Elem);
5554 }
5555 }
5556 if (SVOp0 == Op1 && SVOp1 == Op0) {
5557 std::swap(SVOp0, SVOp1);
5559 }
5560 if (SVOp0 != Op0 || SVOp1 != Op1)
5561 return false;
5562
5563 // Calculate the reconstruction mask for this shuffle, as the mask needed to
5564 // take the packed values from Op0/Op1 and reconstructing to the original
5565 // order.
5566 SmallVector<int> ReconstructMask;
5567 for (unsigned I = 0; I < Mask.size(); I++) {
5568 if (Mask[I] < 0) {
5569 ReconstructMask.push_back(-1);
5570 } else if (Mask[I] < static_cast<int>(NumElts)) {
5571 MaxV1Elt = std::max(MaxV1Elt, Mask[I]);
5572 auto It = find_if(V1, [&](const std::pair<int, int> &A) {
5573 return Mask[I] == A.first;
5574 });
5575 if (It != V1.end())
5576 ReconstructMask.push_back(It - V1.begin());
5577 else {
5578 ReconstructMask.push_back(V1.size());
5579 V1.emplace_back(Mask[I], V1.size());
5580 }
5581 } else {
5582 MaxV2Elt = std::max<int>(MaxV2Elt, Mask[I] - NumElts);
5583 auto It = find_if(V2, [&](const std::pair<int, int> &A) {
5584 return Mask[I] - static_cast<int>(NumElts) == A.first;
5585 });
5586 if (It != V2.end())
5587 ReconstructMask.push_back(NumElts + It - V2.begin());
5588 else {
5589 ReconstructMask.push_back(NumElts + V2.size());
5590 V2.emplace_back(Mask[I] - NumElts, NumElts + V2.size());
5591 }
5592 }
5593 }
5594
5595 // For reductions, we know that the lane ordering out doesn't alter the
5596 // result. In-order can help simplify the shuffle away.
5597 if (FromReduction)
5598 sort(ReconstructMask);
5599 OrigReconstructMasks.push_back(std::move(ReconstructMask));
5600 }
5601
5602 // If the Maximum element used from V1 and V2 are not larger than the new
5603 // vectors, the vectors are already packes and performing the optimization
5604 // again will likely not help any further. This also prevents us from getting
5605 // stuck in a cycle in case the costs do not also rule it out.
5606 if (V1.empty() || V2.empty() ||
5607 (MaxV1Elt == static_cast<int>(V1.size()) - 1 &&
5608 MaxV2Elt == static_cast<int>(V2.size()) - 1))
5609 return false;
5610
5611 // GetBaseMaskValue takes one of the inputs, which may either be a shuffle, a
5612 // shuffle of another shuffle, or not a shuffle (that is treated like a
5613 // identity shuffle).
5614 auto GetBaseMaskValue = [&](Instruction *I, int M) {
5616 if (!SV)
5617 return M;
5618 if (isa<UndefValue>(SV->getOperand(1)))
5619 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5620 if (InputShuffles.contains(SSV))
5621 return SSV->getMaskValue(SV->getMaskValue(M));
5622 return SV->getMaskValue(M);
5623 };
5624
5625 // Attempt to sort the inputs my ascending mask values to make simpler input
5626 // shuffles and push complex shuffles down to the uses. We sort on the first
5627 // of the two input shuffle orders, to try and get at least one input into a
5628 // nice order.
5629 auto SortBase = [&](Instruction *A, std::pair<int, int> X,
5630 std::pair<int, int> Y) {
5631 int MXA = GetBaseMaskValue(A, X.first);
5632 int MYA = GetBaseMaskValue(A, Y.first);
5633 return MXA < MYA;
5634 };
5635 stable_sort(V1, [&](std::pair<int, int> A, std::pair<int, int> B) {
5636 return SortBase(SVI0A, A, B);
5637 });
5638 stable_sort(V2, [&](std::pair<int, int> A, std::pair<int, int> B) {
5639 return SortBase(SVI1A, A, B);
5640 });
5641 // Calculate our ReconstructMasks from the OrigReconstructMasks and the
5642 // modified order of the input shuffles.
5643 SmallVector<SmallVector<int>> ReconstructMasks;
5644 for (const auto &Mask : OrigReconstructMasks) {
5645 SmallVector<int> ReconstructMask;
5646 for (int M : Mask) {
5647 auto FindIndex = [](const SmallVector<std::pair<int, int>> &V, int M) {
5648 auto It = find_if(V, [M](auto A) { return A.second == M; });
5649 assert(It != V.end() && "Expected all entries in Mask");
5650 return std::distance(V.begin(), It);
5651 };
5652 if (M < 0)
5653 ReconstructMask.push_back(-1);
5654 else if (M < static_cast<int>(NumElts)) {
5655 ReconstructMask.push_back(FindIndex(V1, M));
5656 } else {
5657 ReconstructMask.push_back(NumElts + FindIndex(V2, M));
5658 }
5659 }
5660 ReconstructMasks.push_back(std::move(ReconstructMask));
5661 }
5662
5663 // Calculate the masks needed for the new input shuffles, which get padded
5664 // with undef
5665 SmallVector<int> V1A, V1B, V2A, V2B;
5666 for (unsigned I = 0; I < V1.size(); I++) {
5667 V1A.push_back(GetBaseMaskValue(SVI0A, V1[I].first));
5668 V1B.push_back(GetBaseMaskValue(SVI0B, V1[I].first));
5669 }
5670 for (unsigned I = 0; I < V2.size(); I++) {
5671 V2A.push_back(GetBaseMaskValue(SVI1A, V2[I].first));
5672 V2B.push_back(GetBaseMaskValue(SVI1B, V2[I].first));
5673 }
5674 while (V1A.size() < NumElts) {
5677 }
5678 while (V2A.size() < NumElts) {
5681 }
5682
5683 auto AddShuffleCost = [&](InstructionCost C, Instruction *I) {
5685 if (!SV)
5686 return C;
5687 return C + TTI.getShuffleCost(isa<UndefValue>(SV->getOperand(1))
5690 VT, VT, CostKind, SV->getShuffleMask());
5691 };
5692 auto AddShuffleMaskCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5693 return C +
5695 };
5696
5697 unsigned ElementSize = VT->getElementType()->getPrimitiveSizeInBits();
5698 unsigned MaxVectorSize =
5700 unsigned MaxElementsInVector = MaxVectorSize / ElementSize;
5701 if (MaxElementsInVector == 0)
5702 return false;
5703 // When there are multiple shufflevector operations on the same input,
5704 // especially when the vector length is larger than the register size,
5705 // identical shuffle patterns may occur across different groups of elements.
5706 // To avoid overestimating the cost by counting these repeated shuffles more
5707 // than once, we only account for unique shuffle patterns. This adjustment
5708 // prevents inflated costs in the cost model for wide vectors split into
5709 // several register-sized groups.
5710 std::set<SmallVector<int, 4>> UniqueShuffles;
5711 auto AddShuffleMaskAdjustedCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5712 // Compute the cost for performing the shuffle over the full vector.
5713 auto ShuffleCost =
5715 unsigned NumFullVectors = Mask.size() / MaxElementsInVector;
5716 if (NumFullVectors < 2)
5717 return C + ShuffleCost;
5718 SmallVector<int, 4> SubShuffle(MaxElementsInVector);
5719 unsigned NumUniqueGroups = 0;
5720 unsigned NumGroups = Mask.size() / MaxElementsInVector;
5721 // For each group of MaxElementsInVector contiguous elements,
5722 // collect their shuffle pattern and insert into the set of unique patterns.
5723 for (unsigned I = 0; I < NumFullVectors; ++I) {
5724 for (unsigned J = 0; J < MaxElementsInVector; ++J)
5725 SubShuffle[J] = Mask[MaxElementsInVector * I + J];
5726 if (UniqueShuffles.insert(SubShuffle).second)
5727 NumUniqueGroups += 1;
5728 }
5729 return C + ShuffleCost * NumUniqueGroups / NumGroups;
5730 };
5731 auto AddShuffleAdjustedCost = [&](InstructionCost C, Instruction *I) {
5733 if (!SV)
5734 return C;
5735 SmallVector<int, 16> Mask;
5736 SV->getShuffleMask(Mask);
5737 return AddShuffleMaskAdjustedCost(C, Mask);
5738 };
5739 // Check that input consists of ShuffleVectors applied to the same input
5740 auto AllShufflesHaveSameOperands =
5741 [](SmallPtrSetImpl<Instruction *> &InputShuffles) {
5742 if (InputShuffles.size() < 2)
5743 return false;
5744 ShuffleVectorInst *FirstSV =
5745 dyn_cast<ShuffleVectorInst>(*InputShuffles.begin());
5746 if (!FirstSV)
5747 return false;
5748
5749 Value *In0 = FirstSV->getOperand(0), *In1 = FirstSV->getOperand(1);
5750 return std::all_of(
5751 std::next(InputShuffles.begin()), InputShuffles.end(),
5752 [&](Instruction *I) {
5753 ShuffleVectorInst *SV = dyn_cast<ShuffleVectorInst>(I);
5754 return SV && SV->getOperand(0) == In0 && SV->getOperand(1) == In1;
5755 });
5756 };
5757
5758 // Get the costs of the shuffles + binops before and after with the new
5759 // shuffle masks.
5760 InstructionCost CostBefore =
5761 TTI.getArithmeticInstrCost(Op0->getOpcode(), VT, CostKind) +
5762 TTI.getArithmeticInstrCost(Op1->getOpcode(), VT, CostKind);
5763 CostBefore += std::accumulate(Shuffles.begin(), Shuffles.end(),
5764 InstructionCost(0), AddShuffleCost);
5765 if (AllShufflesHaveSameOperands(InputShuffles)) {
5766 UniqueShuffles.clear();
5767 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5768 InstructionCost(0), AddShuffleAdjustedCost);
5769 } else {
5770 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5771 InstructionCost(0), AddShuffleCost);
5772 }
5773
5774 // The new binops will be unused for lanes past the used shuffle lengths.
5775 // These types attempt to get the correct cost for that from the target.
5776 FixedVectorType *Op0SmallVT =
5777 FixedVectorType::get(VT->getScalarType(), V1.size());
5778 FixedVectorType *Op1SmallVT =
5779 FixedVectorType::get(VT->getScalarType(), V2.size());
5780 InstructionCost CostAfter =
5781 TTI.getArithmeticInstrCost(Op0->getOpcode(), Op0SmallVT, CostKind) +
5782 TTI.getArithmeticInstrCost(Op1->getOpcode(), Op1SmallVT, CostKind);
5783 UniqueShuffles.clear();
5784 CostAfter += std::accumulate(ReconstructMasks.begin(), ReconstructMasks.end(),
5785 InstructionCost(0), AddShuffleMaskAdjustedCost);
5786 std::set<SmallVector<int>> OutputShuffleMasks({V1A, V1B, V2A, V2B});
5787 CostAfter +=
5788 std::accumulate(OutputShuffleMasks.begin(), OutputShuffleMasks.end(),
5789 InstructionCost(0), AddShuffleMaskCost);
5790
5791 LLVM_DEBUG(dbgs() << "Found a binop select shuffle pattern: " << I << "\n");
5792 LLVM_DEBUG(dbgs() << " CostBefore: " << CostBefore
5793 << " vs CostAfter: " << CostAfter << "\n");
5794 if (CostBefore < CostAfter ||
5795 (CostBefore == CostAfter && !feedsIntoVectorReduction(SVI)))
5796 return false;
5797
5798 // The cost model has passed, create the new instructions.
5799 auto GetShuffleOperand = [&](Instruction *I, unsigned Op) -> Value * {
5801 if (!SV)
5802 return I;
5803 if (isa<UndefValue>(SV->getOperand(1)))
5804 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5805 if (InputShuffles.contains(SSV))
5806 return SSV->getOperand(Op);
5807 return SV->getOperand(Op);
5808 };
5809 Builder.SetInsertPoint(*SVI0A->getInsertionPointAfterDef());
5810 Value *NSV0A = Builder.CreateShuffleVector(GetShuffleOperand(SVI0A, 0),
5811 GetShuffleOperand(SVI0A, 1), V1A);
5812 Builder.SetInsertPoint(*SVI0B->getInsertionPointAfterDef());
5813 Value *NSV0B = Builder.CreateShuffleVector(GetShuffleOperand(SVI0B, 0),
5814 GetShuffleOperand(SVI0B, 1), V1B);
5815 Builder.SetInsertPoint(*SVI1A->getInsertionPointAfterDef());
5816 Value *NSV1A = Builder.CreateShuffleVector(GetShuffleOperand(SVI1A, 0),
5817 GetShuffleOperand(SVI1A, 1), V2A);
5818 Builder.SetInsertPoint(*SVI1B->getInsertionPointAfterDef());
5819 Value *NSV1B = Builder.CreateShuffleVector(GetShuffleOperand(SVI1B, 0),
5820 GetShuffleOperand(SVI1B, 1), V2B);
5821 Builder.SetInsertPoint(Op0);
5822 Value *NOp0 = Builder.CreateBinOp((Instruction::BinaryOps)Op0->getOpcode(),
5823 NSV0A, NSV0B);
5824 if (auto *I = dyn_cast<Instruction>(NOp0))
5825 I->copyIRFlags(Op0, true);
5826 Builder.SetInsertPoint(Op1);
5827 Value *NOp1 = Builder.CreateBinOp((Instruction::BinaryOps)Op1->getOpcode(),
5828 NSV1A, NSV1B);
5829 if (auto *I = dyn_cast<Instruction>(NOp1))
5830 I->copyIRFlags(Op1, true);
5831
5832 for (int S = 0, E = ReconstructMasks.size(); S != E; S++) {
5833 Builder.SetInsertPoint(Shuffles[S]);
5834 Value *NSV = Builder.CreateShuffleVector(NOp0, NOp1, ReconstructMasks[S]);
5835 replaceValue(*Shuffles[S], *NSV, false);
5836 }
5837
5838 Worklist.pushValue(NSV0A);
5839 Worklist.pushValue(NSV0B);
5840 Worklist.pushValue(NSV1A);
5841 Worklist.pushValue(NSV1B);
5842 return true;
5843}
5844
5845/// Check if instruction depends on ZExt and this ZExt can be moved after the
5846/// instruction. Move ZExt if it is profitable. For example:
5847/// logic(zext(x),y) -> zext(logic(x,trunc(y)))
5848/// lshr((zext(x),y) -> zext(lshr(x,trunc(y)))
5849/// Cost model calculations takes into account if zext(x) has other users and
5850/// whether it can be propagated through them too.
5851bool VectorCombine::shrinkType(Instruction &I) {
5852 Value *ZExted, *OtherOperand;
5853 if (!match(&I, m_c_BitwiseLogic(m_ZExt(m_Value(ZExted)),
5854 m_Value(OtherOperand))) &&
5855 !match(&I, m_LShr(m_ZExt(m_Value(ZExted)), m_Value(OtherOperand))))
5856 return false;
5857
5858 Value *ZExtOperand = I.getOperand(I.getOperand(0) == OtherOperand ? 1 : 0);
5859
5860 auto *BigTy = cast<FixedVectorType>(I.getType());
5861 auto *SmallTy = cast<FixedVectorType>(ZExted->getType());
5862 unsigned BW = SmallTy->getElementType()->getPrimitiveSizeInBits();
5863
5864 if (I.getOpcode() == Instruction::LShr) {
5865 // Check that the shift amount is less than the number of bits in the
5866 // smaller type. Otherwise, the smaller lshr will return a poison value.
5867 KnownBits ShAmtKB = computeKnownBits(I.getOperand(1), *DL);
5868 if (ShAmtKB.getMaxValue().uge(BW))
5869 return false;
5870 } else {
5871 // Check that the expression overall uses at most the same number of bits as
5872 // ZExted
5873 KnownBits KB = computeKnownBits(&I, *DL);
5874 if (KB.countMaxActiveBits() > BW)
5875 return false;
5876 }
5877
5878 // Calculate costs of leaving current IR as it is and moving ZExt operation
5879 // later, along with adding truncates if needed
5881 Instruction::ZExt, BigTy, SmallTy,
5882 TargetTransformInfo::CastContextHint::None, CostKind);
5883 InstructionCost CurrentCost = ZExtCost;
5884 InstructionCost ShrinkCost = 0;
5885
5886 // Calculate total cost and check that we can propagate through all ZExt users
5887 for (User *U : ZExtOperand->users()) {
5888 auto *UI = cast<Instruction>(U);
5889 if (UI == &I) {
5890 CurrentCost +=
5891 TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5892 ShrinkCost +=
5893 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5894 ShrinkCost += ZExtCost;
5895 continue;
5896 }
5897
5898 if (!Instruction::isBinaryOp(UI->getOpcode()))
5899 return false;
5900
5901 // Check if we can propagate ZExt through its other users
5902 KnownBits KB = computeKnownBits(UI, *DL);
5903 if (KB.countMaxActiveBits() > BW)
5904 return false;
5905
5906 CurrentCost += TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5907 ShrinkCost +=
5908 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5909 ShrinkCost += ZExtCost;
5910 }
5911
5912 // If the other instruction operand is not a constant, we'll need to
5913 // generate a truncate instruction. So we have to adjust cost
5914 if (!isa<Constant>(OtherOperand))
5915 ShrinkCost += TTI.getCastInstrCost(
5916 Instruction::Trunc, SmallTy, BigTy,
5917 TargetTransformInfo::CastContextHint::None, CostKind);
5918
5919 // If the cost of shrinking types and leaving the IR is the same, we'll lean
5920 // towards modifying the IR because shrinking opens opportunities for other
5921 // shrinking optimisations.
5922 if (ShrinkCost > CurrentCost)
5923 return false;
5924
5925 Builder.SetInsertPoint(&I);
5926 Value *Op0 = ZExted;
5927 Value *Op1 = Builder.CreateTrunc(OtherOperand, SmallTy);
5928 // Keep the order of operands the same
5929 if (I.getOperand(0) == OtherOperand)
5930 std::swap(Op0, Op1);
5931 Value *NewBinOp =
5932 Builder.CreateBinOp((Instruction::BinaryOps)I.getOpcode(), Op0, Op1);
5933 if (auto *NewBinOpI = dyn_cast<Instruction>(NewBinOp)) {
5934 NewBinOpI->copyIRFlags(&I);
5935 NewBinOpI->copyMetadata(I);
5936 }
5937 Value *NewZExtr = Builder.CreateZExt(NewBinOp, BigTy);
5938 replaceValue(I, *NewZExtr);
5939 return true;
5940}
5941
5942/// insert (DstVec, (extract SrcVec, ExtIdx), InsIdx) -->
5943/// shuffle (DstVec, SrcVec, Mask)
5944bool VectorCombine::foldInsExtVectorToShuffle(Instruction &I) {
5945 Value *DstVec, *SrcVec;
5946 uint64_t ExtIdx, InsIdx;
5947 if (!match(&I,
5948 m_InsertElt(m_Value(DstVec),
5949 m_ExtractElt(m_Value(SrcVec), m_ConstantInt(ExtIdx)),
5950 m_ConstantInt(InsIdx))))
5951 return false;
5952
5953 auto *DstVecTy = dyn_cast<FixedVectorType>(I.getType());
5954 auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcVec->getType());
5955 // We can try combining vectors with different element sizes.
5956 if (!DstVecTy || !SrcVecTy ||
5957 SrcVecTy->getElementType() != DstVecTy->getElementType())
5958 return false;
5959
5960 unsigned NumDstElts = DstVecTy->getNumElements();
5961 unsigned NumSrcElts = SrcVecTy->getNumElements();
5962 if (InsIdx >= NumDstElts || ExtIdx >= NumSrcElts || NumDstElts == 1)
5963 return false;
5964
5965 // Insertion into poison is a cheaper single operand shuffle.
5967 SmallVector<int> Mask(NumDstElts, PoisonMaskElem);
5968
5969 bool NeedExpOrNarrow = NumSrcElts != NumDstElts;
5970 bool NeedDstSrcSwap = isa<PoisonValue>(DstVec) && !isa<UndefValue>(SrcVec);
5971 if (NeedDstSrcSwap) {
5973 Mask[InsIdx] = ExtIdx % NumDstElts;
5974 std::swap(DstVec, SrcVec);
5975 } else {
5977 std::iota(Mask.begin(), Mask.end(), 0);
5978 Mask[InsIdx] = (ExtIdx % NumDstElts) + NumDstElts;
5979 }
5980
5981 // Cost
5982 auto *Ins = cast<InsertElementInst>(&I);
5983 auto *Ext = cast<ExtractElementInst>(I.getOperand(1));
5984 InstructionCost InsCost =
5985 TTI.getVectorInstrCost(*Ins, DstVecTy, CostKind, InsIdx);
5986 InstructionCost ExtCost =
5987 TTI.getVectorInstrCost(*Ext, DstVecTy, CostKind, ExtIdx);
5988 InstructionCost OldCost = ExtCost + InsCost;
5989
5990 InstructionCost NewCost = 0;
5991 SmallVector<int> ExtToVecMask;
5992 if (!NeedExpOrNarrow) {
5993 // Ignore 'free' identity insertion shuffle.
5994 // TODO: getShuffleCost should return TCC_Free for Identity shuffles.
5995 if (!ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts))
5996 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, CostKind, Mask, 0,
5997 nullptr, {DstVec, SrcVec});
5998 } else {
5999 // When creating a length-changing-vector, always try to keep the relevant
6000 // element in an equivalent position, so that bulk shuffles are more likely
6001 // to be useful.
6002 ExtToVecMask.assign(NumDstElts, PoisonMaskElem);
6003 ExtToVecMask[ExtIdx % NumDstElts] = ExtIdx;
6004 // Add cost for expanding or narrowing
6006 DstVecTy, SrcVecTy, CostKind, ExtToVecMask);
6007 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, CostKind, Mask);
6008 }
6009
6010 if (!Ext->hasOneUse())
6011 NewCost += ExtCost;
6012
6013 LLVM_DEBUG(dbgs() << "Found a insert/extract shuffle-like pair: " << I
6014 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6015 << "\n");
6016
6017 if (OldCost < NewCost)
6018 return false;
6019
6020 if (NeedExpOrNarrow) {
6021 if (!NeedDstSrcSwap)
6022 SrcVec = Builder.CreateShuffleVector(SrcVec, ExtToVecMask);
6023 else
6024 DstVec = Builder.CreateShuffleVector(DstVec, ExtToVecMask);
6025 }
6026
6027 // Canonicalize undef param to RHS to help further folds.
6028 if (isa<UndefValue>(DstVec) && !isa<UndefValue>(SrcVec)) {
6029 ShuffleVectorInst::commuteShuffleMask(Mask, NumDstElts);
6030 std::swap(DstVec, SrcVec);
6031 }
6032
6033 Value *Shuf = Builder.CreateShuffleVector(DstVec, SrcVec, Mask);
6034 replaceValue(I, *Shuf);
6035
6036 return true;
6037}
6038
6039/// Fold away a matched pair of vector.deinterleave/interleave intrinsics
6040/// with a chain of elementwise operations on each between the
6041/// deinterleave and interleave.
6042///
6043/// For example:
6044/// ```
6045/// %d = call { <2 x i16>, <2 x i16> } @deinterleave2.v4i16(<4 x i16> %v)
6046/// %f0 = extractvalue { <2 x i16>, <2 x i16> } %d, 0
6047/// %f1 = extractvalue { <2 x i16>, <2 x i16> } %d, 1
6048///
6049/// %u0 = add <2 x i16> %f0, splat (i16 3)
6050/// %u1 = add <2 x i16> %f1, splat (i16 3)
6051///
6052/// %r = call <4 x i16> @interleave2.v4i16(<2 x i16> %u0, <2 x i16> %u1)
6053/// ```
6054/// Folds to:
6055/// ```
6056/// %r = add <4 x i16> %v, splat (i16 3)
6057/// ```
6058bool VectorCombine::foldDeinterleaveInterleavePair(Instruction &I) {
6060 if (!Deinterleave)
6061 return false;
6062
6063 unsigned Factor =
6065 if (!Factor || Deinterleave->hasOperandBundles() ||
6066 !Deinterleave->hasNUndroppableUses(Factor))
6067 return false;
6068
6069 const Intrinsic::ID ExpectedInterleaveIID =
6071
6072 // Collect one extract for each deinterleaved field.
6073 SmallVector<Use *, 8> CurrentUses(Factor, nullptr);
6074 for (Use &U : Deinterleave->uses()) {
6075 if (U.getUser()->isDroppable())
6076 continue;
6077
6078 auto *Extract = dyn_cast<ExtractValueInst>(U.getUser());
6079 if (!Extract || Extract->getNumIndices() != 1)
6080 return false;
6081
6082 unsigned Index = *Extract->idx_begin();
6083 if (Index >= Factor || CurrentUses[Index])
6084 return false;
6085
6086 CurrentUses[Index] = &U;
6087 }
6088
6089 using ElementwiseStep = SmallVector<Use *, 8>;
6091 IntrinsicInst *Interleave = nullptr;
6092 unsigned NumVisited = 0;
6093
6094 auto GetNumDataOperands = [](Instruction *Inst) {
6095 if (auto *CB = dyn_cast<CallBase>(Inst))
6096 return CB->arg_size(); // Exclude callee operand and bundles.
6097 return Inst->getNumOperands();
6098 };
6099
6100 auto IsSupportedElementwise = [&](Instruction *Inst) {
6101 auto *ResultTy = dyn_cast<VectorType>(Inst->getType());
6102 if (!ResultTy || !isSafeToSpeculativelyExecute(Inst))
6103 return false;
6104
6105 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
6106 if (II->hasOperandBundles() ||
6107 !isTriviallyVectorizable(II->getIntrinsicID()))
6108 return false;
6109 } else if (!isa<BinaryOperator, UnaryOperator, CastInst, CmpInst,
6110 SelectInst, FreezeInst>(Inst)) {
6111 return false;
6112 }
6113
6114 // Reject operations that change the element-count.
6115 // E.g., bitcast <vscale x 4 x i16> %v to <vscale x 8 x i8>
6116 for (unsigned Op = 0, E = GetNumDataOperands(Inst); Op != E; ++Op) {
6117 auto *OperandTy = dyn_cast<VectorType>(Inst->getOperand(Op)->getType());
6118 if (OperandTy &&
6119 OperandTy->getElementCount() != ResultTy->getElementCount())
6120 return false;
6121 }
6122
6123 return true;
6124 };
6125
6126 // Traverse the Factor use chains with a breadth-first search.
6127 // At each level, expect every chain to perform the same operation with the
6128 // preceding chain value at the same operand position, until they all reach
6129 // the matching interleave.
6130 while (NumVisited + Factor <= MaxInstrsToScan) {
6131 NumVisited += Factor;
6132
6133 for (Use *&CurrentUse : CurrentUses) {
6134 Use *NextUse = CurrentUse->getUser()->getSingleUndroppableUse();
6135 auto *Next =
6136 NextUse ? dyn_cast<Instruction>(NextUse->getUser()) : nullptr;
6137 if (!Next)
6138 return false;
6139
6140 CurrentUse = NextUse;
6141 }
6142
6143 // Check whether every chain has reached the same interleave.
6144 if (auto *II = dyn_cast<IntrinsicInst>(CurrentUses.front()->getUser());
6145 II && II->getIntrinsicID() == ExpectedInterleaveIID) {
6146 if (II->hasOperandBundles())
6147 return false;
6148
6149 for (unsigned Index = 0; Index != Factor; ++Index)
6150 if (CurrentUses[Index]->getUser() != II ||
6151 CurrentUses[Index]->getOperandNo() != Index)
6152 return false;
6153
6154 Interleave = II;
6155 break;
6156 }
6157
6158 auto *FirstInst = cast<Instruction>(CurrentUses.front()->getUser());
6159 if (!IsSupportedElementwise(FirstInst))
6160 return false;
6161
6162 unsigned ChainOperand = CurrentUses.front()->getOperandNo();
6163 bool MismatchedUse = any_of(CurrentUses, [&](Use *U) {
6164 auto *Inst = cast<Instruction>(U->getUser());
6165 return Inst != FirstInst && (U->getOperandNo() != ChainOperand ||
6166 !FirstInst->isSameOperationAs(
6168 });
6169 if (MismatchedUse)
6170 return false;
6171
6172 auto GetSplatOrScalar = [](Value *V) {
6173 return isa<VectorType>(V->getType()) ? getSplatValue(V) : V;
6174 };
6175
6176 // Non-chain operands must be either the same scalar or splats of that
6177 // scalar. This intentionally rejects differing poison/undef or non-splat
6178 // vector operands between chains.
6179 for (unsigned Op = 0, E = GetNumDataOperands(FirstInst); Op != E; ++Op) {
6180 if (Op == ChainOperand)
6181 continue;
6182
6183 Value *CommonValue = GetSplatOrScalar(FirstInst->getOperand(Op));
6184 if (!CommonValue || any_of(CurrentUses, [&](Use *U) {
6185 Instruction *Inst = cast<Instruction>(U->getUser());
6186 return Inst != FirstInst &&
6187 GetSplatOrScalar(Inst->getOperand(Op)) != CommonValue;
6188 }))
6189 return false;
6190 }
6191
6192 Steps.push_back(CurrentUses);
6193 }
6194
6195 if (!Interleave)
6196 return false;
6197
6198 // Rebuild the matched elementwise chain at the original vector width.
6199 Value *WideValue = Deinterleave->getArgOperand(0);
6200 ElementCount WideEC =
6201 cast<VectorType>(WideValue->getType())->getElementCount();
6202
6203 auto CreateWideInstruction = [&](Instruction *NarrowInst,
6204 ArrayRef<Value *> NewOperands,
6205 VectorType *WideResultTy) -> Value * {
6206 assert(IsSupportedElementwise(NarrowInst) &&
6207 "Expected supported elementwise");
6208 if (isa<BinaryOperator, UnaryOperator>(NarrowInst))
6209 return Builder.CreateNAryOp(NarrowInst->getOpcode(), NewOperands);
6210 if (auto *Cast = dyn_cast<CastInst>(NarrowInst))
6211 return Builder.CreateCast(Cast->getOpcode(), NewOperands[0],
6212 WideResultTy);
6213 if (auto *Cmp = dyn_cast<CmpInst>(NarrowInst))
6214 return Builder.CreateCmp(Cmp->getPredicate(), NewOperands[0],
6215 NewOperands[1]);
6216 if (isa<SelectInst>(NarrowInst))
6217 return Builder.CreateSelect(
6218 NewOperands[0], NewOperands[1], NewOperands[2], /*Name=*/"",
6219 ProfcheckDisableMetadataFixes ? nullptr : NarrowInst);
6220 if (isa<FreezeInst>(NarrowInst))
6221 return Builder.CreateFreeze(NewOperands[0]);
6222 if (auto *II = dyn_cast<IntrinsicInst>(NarrowInst))
6223 return Builder.CreateIntrinsic(WideResultTy, II->getIntrinsicID(),
6224 NewOperands);
6225 llvm_unreachable("Unsupported instruction");
6226 };
6227
6228 // The BFS has succeeded and collected multiple levels of instructions that
6229 // can be SLP-widened into a chain of wider instructions.
6230 for (const ElementwiseStep &Step : Steps) {
6231 Instruction *NarrowInst = cast<Instruction>(Step.front()->getUser());
6232 unsigned ChainOperand = Step.front()->getOperandNo();
6233
6234 Builder.SetInsertPoint(NarrowInst);
6235 Builder.SetCurrentDebugLocation(NarrowInst->getDebugLoc());
6236
6237 unsigned NumOperands = GetNumDataOperands(NarrowInst);
6238 SmallVector<Value *, 4> NewOperands;
6239 NewOperands.reserve(NumOperands);
6240
6241 for (unsigned Op = 0; Op != NumOperands; ++Op) {
6242 Value *Operand = NarrowInst->getOperand(Op);
6243
6244 if (Op == ChainOperand)
6245 Operand = WideValue;
6246 else if (isa<VectorType>(Operand->getType()))
6247 Operand = Builder.CreateVectorSplat(WideEC, getSplatValue(Operand));
6248 NewOperands.push_back(Operand);
6249 }
6250
6251 auto *WideResultTy =
6252 VectorType::get(NarrowInst->getType()->getScalarType(), WideEC);
6253 Value *NewValue =
6254 CreateWideInstruction(NarrowInst, NewOperands, WideResultTy);
6255
6256 SmallVector<Value *> NarrowInsts =
6257 map_to_vector(Step, [](Use *U) { return cast<Value>(U->getUser()); });
6258 propagateIRFlags(NewValue, NarrowInsts);
6259
6260 if (auto *NewInst = dyn_cast<Instruction>(NewValue))
6261 propagateMetadata(NewInst, NarrowInsts);
6262
6263 WideValue = NewValue;
6264 }
6265
6266 assert(WideValue->getType() == Interleave->getType());
6267 replaceValue(*Interleave, *WideValue);
6268 return true;
6269}
6270
6271/// If we're interleaving 2 constant splats, for instance `<vscale x 8 x i32>
6272/// <splat of 666>` and `<vscale x 8 x i32> <splat of 777>`, we can create a
6273/// larger splat `<vscale x 8 x i64> <splat of ((777 << 32) | 666)>` first
6274/// before casting it back into `<vscale x 16 x i32>`.
6275bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
6276 const APInt *SplatVal0, *SplatVal1;
6278 m_APInt(SplatVal0), m_APInt(SplatVal1))))
6279 return false;
6280
6281 LLVM_DEBUG(dbgs() << "VC: Folding interleave2 with two splats: " << I
6282 << "\n");
6283
6284 auto *VTy =
6285 cast<VectorType>(cast<IntrinsicInst>(I).getArgOperand(0)->getType());
6286 auto *ExtVTy = VectorType::getExtendedElementVectorType(VTy);
6287 unsigned Width = VTy->getElementType()->getIntegerBitWidth();
6288
6289 // Just in case the cost of interleave2 intrinsic and bitcast are both
6290 // invalid, in which case we want to bail out, we use <= rather
6291 // than < here. Even they both have valid and equal costs, it's probably
6292 // not a good idea to emit a high-cost constant splat.
6294 TTI.getCastInstrCost(Instruction::BitCast, I.getType(), ExtVTy,
6296 LLVM_DEBUG(dbgs() << "VC: The cost to cast from " << *ExtVTy << " to "
6297 << *I.getType() << " is too high.\n");
6298 return false;
6299 }
6300
6301 APInt NewSplatVal = SplatVal1->zext(Width * 2);
6302 NewSplatVal <<= Width;
6303 NewSplatVal |= SplatVal0->zext(Width * 2);
6304 auto *NewSplat = ConstantVector::getSplat(
6305 ExtVTy->getElementCount(), ConstantInt::get(F.getContext(), NewSplatVal));
6306
6307 IRBuilder<> Builder(&I);
6308 replaceValue(I, *Builder.CreateBitCast(NewSplat, I.getType()));
6309 return true;
6310}
6311
6312/// Given this sequence:
6313/// ```
6314/// %d = llvm.vector.deinterleave2 <vscale x 16 x i32> %v
6315/// %f0 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 0
6316/// %f1 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 1
6317///
6318/// %low0 = and <vscale x 8 x i32> %f0, splat (i32 65535)
6319/// %low1 = shl <vscale x 8 x i32> %f1, splat (i32 16)
6320/// %merge0 = or disjoint <vscale x 8 x i32> %low0, %low1
6321///
6322/// %high0 = and <vscale x 8 x i32> %f1, splat (i32 -65536)
6323/// %high1 = lshr <vscale x 8 x i32> %f0, splat (i32 16)
6324/// %merge1 = or disjoint <vscale x 8 x i32> %high0, %high1
6325/// ```
6326/// It is actually just de-interleaving a 16-bit vector with double the
6327/// vector length. More generally speaking, it's de-interleaving on a vector
6328/// with half the element width as the original vector.
6329///
6330/// Therefore, we can turn it into:
6331/// ```
6332/// %narrow.v = bitcast <vscale x 16 x i32> %v to <vscale x 32 x i16>
6333/// %d = llvm.vector.deinterleave2 <vscale x 32 x i16> %narrow.v
6334/// %f0 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 0
6335/// %f1 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 1
6336///
6337/// %merge0 = bitcast <vscale x 16 x i16> %f0 to <vscale x 8 x i32>
6338/// %merge1 = bitcast <vscale x 16 x i16> %f1 to <vscale x 8 x i32>
6339/// ```
6340bool VectorCombine::foldDeinterleaveIntrinsics(Instruction &I) {
6341 if (foldDeinterleaveInterleavePair(I))
6342 return true;
6343
6344 // This pattern involves bitcast that is not compatible with big endian.
6345 if (DL->isBigEndian())
6346 return false;
6347
6348 using namespace PatternMatch;
6349 Value *DeinterleavedVal;
6350 if (!match(&I, m_Deinterleave2(m_Value(DeinterleavedVal))))
6351 return false;
6352
6353 VectorType *VecTy = cast<VectorType>(DeinterleavedVal->getType());
6354 IntegerType *ElementTy = dyn_cast<IntegerType>(VecTy->getElementType());
6355 if (!ElementTy)
6356 return false;
6357 unsigned ElementWidth = ElementTy->getBitWidth();
6358 if (ElementWidth < 2 || !isPowerOf2_32(ElementWidth))
6359 return false;
6360 unsigned HalfElementWidth = ElementWidth / 2;
6361
6362 if (!I.hasNUses(2))
6363 return false;
6364 std::array<ExtractValueInst *, 2> OrigFields{};
6365 for (User *Usr : I.users()) {
6366 auto *E = dyn_cast<ExtractValueInst>(Usr);
6367 // The deinterleave result can only be used by extractions.
6368 if (!E || E->getNumIndices() != 1)
6369 return false;
6370 unsigned Idx = *E->idx_begin();
6371 // A single field cannot be extracted more than once.
6372 if (Idx >= 2 || OrigFields[Idx] || !E->hasNUses(2))
6373 return false;
6374 OrigFields[Idx] = E;
6375 }
6376
6377 // Find the merge instruction (i.e. OR) first.
6378 SmallVector<Instruction *, 2> MergeInsts;
6379 for (auto *FieldUsr : OrigFields[0]->users()) {
6380 if (!FieldUsr->hasOneUse() || !isa<Instruction>(FieldUsr->user_back()))
6381 return false;
6382 MergeInsts.push_back(cast<Instruction>(FieldUsr->user_back()));
6383 }
6384 assert(MergeInsts.size() == 2);
6385
6386 // Pattern match bottom-up from the merge instructions.
6387 auto MatchMerge = [&](void) -> bool {
6388 APInt LoMask = APInt::getLowBitsSet(ElementWidth, HalfElementWidth);
6389 APInt HiMask = APInt::getHighBitsSet(ElementWidth, HalfElementWidth);
6390 return match(MergeInsts[0],
6391 m_c_Or(m_And(m_Specific(OrigFields[0]), m_SpecificInt(LoMask)),
6392 m_Shl(m_Specific(OrigFields[1]),
6393 m_SpecificInt(HalfElementWidth)))) &&
6394 match(MergeInsts[1],
6395 m_c_Or(m_And(m_Specific(OrigFields[1]), m_SpecificInt(HiMask)),
6396 m_LShr(m_Specific(OrigFields[0]),
6397 m_SpecificInt(HalfElementWidth))));
6398 };
6399 if (!MatchMerge()) {
6400 std::swap(MergeInsts[0], MergeInsts[1]);
6401 if (!MatchMerge())
6402 return false;
6403 }
6404
6405 // Profitability check.
6406 InstructionCost OldCost =
6407 TTI.getInstructionCost(MergeInsts[0], CostKind) +
6408 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(0)),
6409 CostKind) +
6410 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(1)),
6411 CostKind);
6412 // There are two fields (assuming SHL has the same cost as LSHR).
6413 OldCost *= 2;
6414
6415 auto *NewFieldTy = VecTy->getWithNewBitWidth(HalfElementWidth);
6416 auto *NewVecTy =
6417 VectorType::getDoubleElementsVectorType(cast<VectorType>(NewFieldTy));
6418 InstructionCost NewCost =
6419 TTI.getCastInstrCost(Instruction::BitCast, VecTy, NewVecTy,
6421 TTI.getCastInstrCost(Instruction::BitCast, NewFieldTy,
6422 MergeInsts[0]->getType(), TTI::CastContextHint::None,
6423 CostKind) *
6424 2;
6425 if (OldCost <= NewCost || !NewCost.isValid()) {
6426 LLVM_DEBUG(
6427 dbgs() << "VC: New deinterleave2 sequence cost (" << NewCost << ")"
6428 << " is higher than that of the old one (" << OldCost << ")\n");
6429 return false;
6430 }
6431
6432 // Do the replacement.
6433 IRBuilder<> Builder(&I);
6434 Value *NewVecCast = Builder.CreateBitCast(DeinterleavedVal, NewVecTy);
6435 Value *NewDeinterleave = Builder.CreateIntrinsic(
6436 Intrinsic::vector_deinterleave2, {NewVecTy}, {NewVecCast});
6437 for (auto [Idx, MergeInst] : enumerate(MergeInsts)) {
6438 Value *NewField = Builder.CreateExtractValue(NewDeinterleave, Idx);
6439 NewField = Builder.CreateBitCast(NewField, MergeInst->getType());
6440 replaceValue(*MergeInst, *NewField);
6441 }
6442
6443 return true;
6444}
6445
6446bool VectorCombine::foldBitcastOfVPLoad(Instruction &I) {
6447 const DataLayout &DL = I.getDataLayout();
6448 auto *Cast = dyn_cast<CastInst>(&I);
6449 if (!Cast || !Cast->isNoopCast(DL) || !isa<VectorType>(Cast->getDestTy()))
6450 return false;
6451
6452 // Fold away bit casts of the loaded value by loading the desired type,
6453 // if the mask is all-ones.
6454 Value *EVL;
6455 auto *II = dyn_cast<VPIntrinsic>(I.getOperand(0));
6457 m_Value(), m_AllOnes(), m_Value(EVL)))))
6458 return false;
6459
6460 VectorType *OrigVecTy = cast<VectorType>(II->getType());
6461 Align OrigAlign =
6462 DL.getValueOrABITypeAlignment(II->getPointerAlignment(), OrigVecTy);
6463 ElementCount OrigVecCnt = OrigVecTy->getElementCount();
6464 VectorType *NewVecTy = cast<VectorType>(Cast->getDestTy());
6465 ElementCount NewVecCnt = NewVecTy->getElementCount();
6466
6467 // Right now we only support cases where the NewVec is longer, because for
6468 // cases where it's shorter, we have to be sure that EVL can be exactly
6469 // divided, otherwise it might yield incorrect results or even page faults
6470 // (if we round-up during the division).
6471 if (!(OrigVecCnt.isScalable() == NewVecCnt.isScalable() &&
6472 NewVecCnt.hasKnownScalarFactor(OrigVecCnt)))
6473 return false;
6474
6475 InstructionCost OldCost =
6476 TTI.getMemIntrinsicInstrCost({Intrinsic::vp_load, OrigVecTy,
6477 II->getMemoryPointerParam(), false,
6478 OrigAlign},
6479 CostKind) +
6480 TTI.getCastInstrCost(Instruction::BitCast, Cast->getType(), OrigVecTy,
6483 {Intrinsic::vp_load, NewVecTy, II->getMemoryPointerParam(), false,
6484 OrigAlign},
6485 CostKind);
6486 LLVM_DEBUG(dbgs() << "foldBitcastOfVPLoad: OldCost=" << OldCost
6487 << " NewCost=" << NewCost << "\n");
6488 if (NewCost > OldCost || !NewCost.isValid())
6489 return false;
6490
6491 Builder.SetInsertPoint(II);
6492 unsigned Factor = NewVecCnt.getKnownScalarFactor(OrigVecCnt);
6493 Value *NewEVL = Builder.CreateNUWMul(EVL, Builder.getInt32(Factor));
6494 Value *NewMask = Builder.CreateVectorSplat(NewVecCnt, Builder.getTrue());
6495 CallInst *NewVP = Builder.CreateIntrinsicWithoutFolding(
6496 NewVecTy, Intrinsic::vp_load,
6497 {II->getMemoryPointerParam(), NewMask, NewEVL});
6498 // Preserve the original alignment.
6499 NewVP->addParamAttrs(
6500 0, AttrBuilder(II->getContext()).addAlignmentAttr(OrigAlign));
6501 replaceValue(*Cast, *NewVP);
6502 return true;
6503}
6504/// Fold the following cases into a single byte-level bit-reverse operation
6505/// and accepts bswap and bitreverse intrinsics:
6506/// bswap(bitreverse(x)) --> bitcast(bitreverse(bitcast(x)))
6507/// bitreverse(bswap(x)) <--> bitcast(bitreverse(bitcast(x)))
6508/// The direction of the fold is cost-model driven.
6509/// Also supports:
6510/// bitcast(bitreverse(bitcast(x))) --> bitreverse(fshl(x))
6511bool VectorCombine::foldBitOrderReverseAndSwap(Instruction &I) {
6512 Value *X;
6513
6515 Type *Ty = X->getType();
6516 Type *VecTy = I.getOperand(0)->getType();
6517 // Detect the case when bitreversing every octet in X individually. Then we
6518 // can use bswap to reorder the octets before doing a single bitreverse.
6519 bool CanUseBswap =
6520 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6521 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy(8) &&
6522 Ty->getIntegerBitWidth() % 16 == 0;
6523 // Detect the case when bitreversing upper and lower half of X
6524 // individually. Then we can use fshl as a rotate operation, to swap the
6525 // halves before doing a single bitreverse.
6526 bool CanUseFshl =
6527 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6528 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy() &&
6529 cast<FixedVectorType>(VecTy)->getNumElements() == 2;
6530 if (CanUseBswap || CanUseFshl) {
6531 auto *InnerCall = dyn_cast<Instruction>(I.getOperand(0));
6532 if (!InnerCall)
6533 return false;
6534 auto *InnerBitCast = dyn_cast<BitCastInst>(InnerCall->getOperand(0));
6535 if (!InnerBitCast)
6536 return false;
6537 Constant *HalfBW = ConstantInt::get(Ty, Ty->getIntegerBitWidth() / 2);
6538 InstructionCost OldCost = TTI.getInstructionCost(InnerBitCast, CostKind) +
6539 TTI.getInstructionCost(InnerCall, CostKind) +
6541 IntrinsicCostAttributes ICABSwap(Intrinsic::bswap, Ty, {Ty});
6542 IntrinsicCostAttributes ICABFshl(Intrinsic::fshl, Ty, {X, X, HalfBW},
6543 {Ty, Ty, Ty});
6544 IntrinsicCostAttributes ICABRev(Intrinsic::bitreverse, Ty, {Ty});
6545 InstructionCost NewCost =
6546 TTI.getIntrinsicInstrCost(CanUseBswap ? ICABSwap : ICABFshl,
6547 CostKind) +
6549 if (!InnerCall->hasOneUse())
6550 NewCost += TTI.getInstructionCost(InnerCall, CostKind) +
6551 TTI.getInstructionCost(InnerBitCast, CostKind);
6552 else if (!InnerBitCast->hasOneUse())
6553 NewCost += TTI.getInstructionCost(InnerBitCast, CostKind);
6554 LLVM_DEBUG(dbgs() << "Found bitreverse vector roundtrip: " << I
6555 << "\n OldCost: " << OldCost
6556 << " vs NewCost: " << NewCost << "\n");
6557 if (NewCost.isValid() && NewCost < OldCost) {
6558 Builder.SetInsertPoint(&I);
6559 Value *Swap =
6560 CanUseBswap
6561 ? Builder.CreateUnaryIntrinsic(Intrinsic::bswap, X)
6562 : Builder.CreateIntrinsic(Ty, Intrinsic::fshl, {X, X, HalfBW});
6563 Worklist.pushValue(Swap);
6564 Value *BRev = Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, Swap);
6565 replaceValue(I, *BRev);
6566 return true;
6567 }
6568 }
6569 }
6570
6571 if (!match(&I, m_BitReverse(m_BSwap(m_Value(X)))) &&
6573 return false;
6574 Type *Ty = I.getType();
6575 Type *I8Ty = Builder.getInt8Ty();
6576 TypeSize ElementSize = DL->getTypeStoreSize(Ty);
6577 ElementCount NewVecCnt = ElementCount::get(ElementSize.getKnownMinValue(),
6578 ElementSize.isScalable());
6579 Type *NewVecTy = VectorType::get(I8Ty, NewVecCnt);
6580 auto *II = cast<IntrinsicInst>(&I);
6581 auto *InnerII = cast<IntrinsicInst>(II->getArgOperand(0));
6582 // OldCost = cost of bitreverse/bswap + cost of bswap/bitreverse
6585 // NewCost = cost of bitcast to byte vector +
6586 // cost of bitreverse/bswap on byte vector +
6587 // cost of bitcast back to original type
6588 InstructionCost CastToVecCost = TTI.getCastInstrCost(
6589 Instruction::BitCast, NewVecTy, Ty, TTI::CastContextHint::None, CostKind);
6590 InstructionCost CastToOrigCost = TTI.getCastInstrCost(
6591 Instruction::BitCast, Ty, NewVecTy, TTI::CastContextHint::None, CostKind);
6592 IntrinsicCostAttributes ICANew(Intrinsic::bitreverse, NewVecTy, {NewVecTy});
6593 InstructionCost NewIntrinsicCost =
6595 InstructionCost NewCost = CastToVecCost + NewIntrinsicCost + CastToOrigCost;
6596 if (!InnerII->hasOneUse())
6597 NewCost += TTI.getInstructionCost(InnerII, CostKind);
6598 LLVM_DEBUG(dbgs() << "Found bitorder reverse and swap: " << I
6599 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6600 << "\n");
6601 if (!NewCost.isValid() || NewCost >= OldCost)
6602 return false;
6603 // Perform transform: bitcast(arg, <N x i8>), bitreverse, bitcast back
6604 Builder.SetInsertPoint(II);
6605 Value *CastToVec = Builder.CreateBitCast(X, NewVecTy);
6606 Value *NewCall =
6607 Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, CastToVec);
6608 Value *CastToOrig = Builder.CreateBitCast(NewCall, Ty);
6609 replaceValue(I, *CastToOrig);
6610 return true;
6611}
6612
6613/// Given the maximum shuffle index and load vector type, compute the number of
6614/// elements for the shrunk load, rounding up to the next full vector register
6615/// boundary to avoid scalar remainders that legalize poorly.
6616static unsigned getAlignedNumElements(unsigned MaxIdx, FixedVectorType *LoadTy,
6617 const TargetTransformInfo &TTI,
6618 const DataLayout &DL) {
6619 unsigned RawNumElements = MaxIdx + 1u;
6620 Type *ElemTy = LoadTy->getElementType();
6621 // Skip alignment for illegal element types.
6622 if (!TTI.isTypeLegal(ElemTy))
6623 return RawNumElements;
6624
6625 TypeSize ElemSize = DL.getTypeSizeInBits(ElemTy);
6626 if (ElemSize.isScalable() || ElemSize.isZero())
6627 return RawNumElements;
6628
6631 if (RegSize.isScalable() || RegSize.isZero())
6632 return RawNumElements;
6633
6634 unsigned ElemsPerReg = RegSize.getFixedValue() / ElemSize.getFixedValue();
6635 // If the load already fits in a register, keep the exact size.
6636 // Otherwise round up to the next full register boundary.
6637 if (ElemsPerReg == 0 || RawNumElements <= ElemsPerReg)
6638 return RawNumElements;
6639
6640 return alignTo(RawNumElements, ElemsPerReg);
6641}
6642
6643// Attempt to shrink loads that are only used by shufflevector instructions.
6644bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
6645 auto *OldLoad = dyn_cast<LoadInst>(&I);
6646 if (!OldLoad || !OldLoad->isSimple())
6647 return false;
6648
6649 auto *OldLoadTy = dyn_cast<FixedVectorType>(OldLoad->getType());
6650 if (!OldLoadTy)
6651 return false;
6652
6653 unsigned const OldNumElements = OldLoadTy->getNumElements();
6654
6655 // Search all uses of load. If all uses are shufflevector instructions, and
6656 // the second operands are all poison values, find the minimum and maximum
6657 // indices of the vector elements referenced by all shuffle masks.
6658 // Otherwise return `std::nullopt`.
6659 using IndexRange = std::pair<int, int>;
6660 auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
6661 IndexRange OutputRange = IndexRange(OldNumElements, -1);
6662 for (llvm::Use &Use : I.uses()) {
6663 // Ensure all uses match the required pattern.
6664 User *Shuffle = Use.getUser();
6665 ArrayRef<int> Mask;
6666
6667 if (!match(Shuffle,
6668 m_Shuffle(m_Specific(OldLoad), m_Undef(), m_Mask(Mask))))
6669 return std::nullopt;
6670
6671 // Ignore shufflevector instructions that have no uses.
6672 if (Shuffle->use_empty())
6673 continue;
6674
6675 // Find the min and max indices used by the shufflevector instruction.
6676 for (int Index : Mask) {
6677 if (Index >= 0 && Index < static_cast<int>(OldNumElements)) {
6678 OutputRange.first = std::min(Index, OutputRange.first);
6679 OutputRange.second = std::max(Index, OutputRange.second);
6680 }
6681 }
6682 }
6683
6684 if (OutputRange.second < OutputRange.first)
6685 return std::nullopt;
6686
6687 return OutputRange;
6688 };
6689
6690 // Get the range of vector elements used by shufflevector instructions.
6691 if (std::optional<IndexRange> Indices = GetIndexRangeInShuffles()) {
6692 unsigned const NewNumElements =
6693 getAlignedNumElements(Indices->second, OldLoadTy, TTI, *DL);
6694
6695 // If the range of vector elements is smaller than the full load, attempt
6696 // to create a smaller load.
6697 if (NewNumElements < OldNumElements) {
6698 IRBuilder Builder(&I);
6699 Builder.SetCurrentDebugLocation(I.getDebugLoc());
6700
6701 // Calculate costs of old and new ops.
6702 Type *ElemTy = OldLoadTy->getElementType();
6703 FixedVectorType *NewLoadTy = FixedVectorType::get(ElemTy, NewNumElements);
6704 Value *PtrOp = OldLoad->getPointerOperand();
6705
6707 Instruction::Load, OldLoad->getType(), OldLoad->getAlign(),
6708 OldLoad->getPointerAddressSpace(), CostKind);
6709 InstructionCost NewCost =
6710 TTI.getMemoryOpCost(Instruction::Load, NewLoadTy, OldLoad->getAlign(),
6711 OldLoad->getPointerAddressSpace(), CostKind);
6712
6713 using UseEntry = std::pair<ShuffleVectorInst *, std::vector<int>>;
6715 unsigned const MaxIndex = NewNumElements * 2u;
6716
6717 for (llvm::Use &Use : I.uses()) {
6718 auto *Shuffle = cast<ShuffleVectorInst>(Use.getUser());
6719
6720 // Ignore shufflevector instructions that have no uses.
6721 if (Shuffle->use_empty())
6722 continue;
6723
6724 ArrayRef<int> OldMask = Shuffle->getShuffleMask();
6725
6726 // Create entry for new use.
6727 NewUses.push_back({Shuffle, OldMask});
6728
6729 // Validate mask indices.
6730 for (int Index : OldMask) {
6731 if (Index >= static_cast<int>(MaxIndex))
6732 return false;
6733 }
6734
6735 // Update costs.
6736 OldCost +=
6738 OldLoadTy, CostKind, OldMask);
6739 NewCost +=
6741 NewLoadTy, CostKind, OldMask);
6742 }
6743
6744 LLVM_DEBUG(
6745 dbgs() << "Found a load used only by shufflevector instructions: "
6746 << I << "\n OldCost: " << OldCost
6747 << " vs NewCost: " << NewCost << "\n");
6748
6749 if (OldCost < NewCost || !NewCost.isValid())
6750 return false;
6751
6752 // Create new load of smaller vector.
6753 auto *NewLoad = cast<LoadInst>(
6754 Builder.CreateAlignedLoad(NewLoadTy, PtrOp, OldLoad->getAlign()));
6755 NewLoad->copyMetadata(I);
6756
6757 // Replace all uses.
6758 for (UseEntry &Use : NewUses) {
6759 ShuffleVectorInst *Shuffle = Use.first;
6760 std::vector<int> &NewMask = Use.second;
6761
6762 Builder.SetInsertPoint(Shuffle);
6763 Builder.SetCurrentDebugLocation(Shuffle->getDebugLoc());
6764 Value *NewShuffle = Builder.CreateShuffleVector(
6765 NewLoad, PoisonValue::get(NewLoadTy), NewMask);
6766
6767 replaceValue(*Shuffle, *NewShuffle, false);
6768 }
6769
6770 return true;
6771 }
6772 }
6773 return false;
6774}
6775
6776// Attempt to narrow a phi of shufflevector instructions where the two incoming
6777// values have the same operands but different masks. If the two shuffle masks
6778// are offsets of one another we can use one branch to rotate the incoming
6779// vector and perform one larger shuffle after the phi.
6780bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
6781 auto *Phi = dyn_cast<PHINode>(&I);
6782 if (!Phi || Phi->getNumIncomingValues() != 2u)
6783 return false;
6784
6785 Value *Op = nullptr;
6786 ArrayRef<int> Mask0;
6787 ArrayRef<int> Mask1;
6788
6789 if (!match(Phi->getOperand(0u),
6790 m_OneUse(m_Shuffle(m_Value(Op), m_Poison(), m_Mask(Mask0)))) ||
6791 !match(Phi->getOperand(1u),
6792 m_OneUse(m_Shuffle(m_Specific(Op), m_Poison(), m_Mask(Mask1)))))
6793 return false;
6794
6795 auto *Shuf = cast<ShuffleVectorInst>(Phi->getOperand(0u));
6796
6797 // Ensure result vectors are wider than the argument vector.
6798 auto *InputVT = cast<FixedVectorType>(Op->getType());
6799 auto *ResultVT = cast<FixedVectorType>(Shuf->getType());
6800 auto const InputNumElements = InputVT->getNumElements();
6801
6802 if (InputNumElements >= ResultVT->getNumElements())
6803 return false;
6804
6805 // Take the difference of the two shuffle masks at each index. Ignore poison
6806 // values at the same index in both masks.
6807 SmallVector<int, 16> NewMask;
6808 NewMask.reserve(Mask0.size());
6809
6810 for (auto [M0, M1] : zip(Mask0, Mask1)) {
6811 if (M0 >= 0 && M1 >= 0)
6812 NewMask.push_back(M0 - M1);
6813 else if (M0 == -1 && M1 == -1)
6814 continue;
6815 else
6816 return false;
6817 }
6818
6819 // Ensure all elements of the new mask are equal. If the difference between
6820 // the incoming mask elements is the same, the two must be constant offsets
6821 // of one another.
6822 if (NewMask.empty() || !all_equal(NewMask))
6823 return false;
6824
6825 // Create new mask using difference of the two incoming masks.
6826 int MaskOffset = NewMask[0u];
6827 unsigned Index = (InputNumElements + MaskOffset) % InputNumElements;
6828 NewMask.clear();
6829
6830 for (unsigned I = 0u; I < InputNumElements; ++I) {
6831 NewMask.push_back(Index);
6832 Index = (Index + 1u) % InputNumElements;
6833 }
6834
6835 // Calculate costs for worst cases and compare.
6836 auto const Kind = TTI::SK_PermuteSingleSrc;
6837 auto OldCost =
6838 std::max(TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask0),
6839 TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask1));
6840 auto NewCost = TTI.getShuffleCost(Kind, InputVT, InputVT, CostKind, NewMask) +
6841 TTI.getShuffleCost(Kind, ResultVT, InputVT, CostKind, Mask1);
6842
6843 LLVM_DEBUG(dbgs() << "Found a phi of mergeable shuffles: " << I
6844 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6845 << "\n");
6846
6847 if (NewCost > OldCost)
6848 return false;
6849
6850 // Create new shuffles and narrowed phi.
6851 auto Builder = IRBuilder(Shuf);
6852 Builder.SetCurrentDebugLocation(Shuf->getDebugLoc());
6853 auto *PoisonVal = PoisonValue::get(InputVT);
6854 auto *NewShuf0 = Builder.CreateShuffleVector(Op, PoisonVal, NewMask);
6855 Worklist.push(cast<Instruction>(NewShuf0));
6856
6857 Builder.SetInsertPoint(Phi);
6858 Builder.SetCurrentDebugLocation(Phi->getDebugLoc());
6859 auto *NewPhi = Builder.CreatePHI(NewShuf0->getType(), 2u);
6860 NewPhi->addIncoming(NewShuf0, Phi->getIncomingBlock(0u));
6861 NewPhi->addIncoming(Op, Phi->getIncomingBlock(1u));
6862
6863 Builder.SetInsertPoint(*NewPhi->getInsertionPointAfterDef());
6864 PoisonVal = PoisonValue::get(NewPhi->getType());
6865 auto *NewShuf1 = Builder.CreateShuffleVector(NewPhi, PoisonVal, Mask1);
6866
6867 replaceValue(*Phi, *NewShuf1);
6868 return true;
6869}
6870
6871/// This is the entry point for all transforms. Pass manager differences are
6872/// handled in the callers of this function.
6873bool VectorCombine::run() {
6875 return false;
6876
6877 // Don't attempt vectorization if the target does not support vectors.
6878 if (!TTI.getNumberOfRegisters(TTI.getRegisterClassForType(/*Vector*/ true)))
6879 return false;
6880
6881 LLVM_DEBUG(dbgs() << "\n\nVECTORCOMBINE on " << F.getName() << "\n");
6882
6883 auto FoldInst = [this](Instruction &I) {
6884 Builder.SetInsertPoint(&I);
6885 bool IsVectorType = isa<VectorType>(I.getType());
6886 bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
6887 auto Opcode = I.getOpcode();
6888
6889 LLVM_DEBUG(dbgs() << "VC: Visiting: " << I << '\n');
6890
6891 // These folds should be beneficial regardless of when this pass is run
6892 // in the optimization pipeline.
6893 // The type checking is for run-time efficiency. We can avoid wasting time
6894 // dispatching to folding functions if there's no chance of matching.
6895 if (IsFixedVectorType) {
6896 switch (Opcode) {
6897 case Instruction::InsertElement:
6898 if (vectorizeLoadInsert(I))
6899 return true;
6900 break;
6901 case Instruction::ShuffleVector:
6902 if (widenSubvectorLoad(I))
6903 return true;
6904 break;
6905 default:
6906 break;
6907 }
6908 }
6909
6910 // This transform works with scalable and fixed vectors
6911 // TODO: Identify and allow other scalable transforms
6912 if (IsVectorType) {
6913 if (scalarizeOpOrCmp(I))
6914 return true;
6915 if (scalarizeLoad(I))
6916 return true;
6917 if (scalarizeExtExtract(I))
6918 return true;
6919 if (foldInterleaveIntrinsics(I))
6920 return true;
6921 if (foldBitcastOfVPLoad(I))
6922 return true;
6923 }
6924
6925 if (foldDeinterleaveIntrinsics(I))
6926 return true;
6927
6928 if (Opcode == Instruction::Store)
6929 if (foldInsertElementsToStores(I))
6930 return true;
6931
6932 // If this is an early pipeline invocation of this pass, we are done.
6933 if (TryEarlyFoldsOnly)
6934 return false;
6935
6936 if (Opcode == Instruction::Call)
6937 if (foldBitOrderReverseAndSwap(I))
6938 return true;
6939 if (Opcode == Instruction::BitCast)
6940 if (foldBitOrderReverseAndSwap(I))
6941 return true;
6942
6943 // Otherwise, try folds that improve codegen but may interfere with
6944 // early IR canonicalizations.
6945 // The type checking is for run-time efficiency. We can avoid wasting time
6946 // dispatching to folding functions if there's no chance of matching.
6947 if (IsFixedVectorType) {
6948 switch (Opcode) {
6949 case Instruction::InsertElement:
6950 if (foldInsExtFNeg(I))
6951 return true;
6952 if (foldInsExtBinop(I))
6953 return true;
6954 if (foldInsExtVectorToShuffle(I))
6955 return true;
6956 break;
6957 case Instruction::ShuffleVector:
6958 if (foldPermuteOfBinops(I))
6959 return true;
6960 if (foldShuffleOfBinops(I))
6961 return true;
6962 if (foldShuffleOfSelects(I))
6963 return true;
6964 if (foldShuffleOfCastops(I))
6965 return true;
6966 if (foldShuffleOfShuffles(I))
6967 return true;
6968 if (foldPermuteOfIntrinsic(I))
6969 return true;
6970 if (foldShufflesOfLengthChangingShuffles(I))
6971 return true;
6972 if (foldShuffleOfIntrinsics(I))
6973 return true;
6974 if (foldSelectShuffle(I))
6975 return true;
6976 if (foldShuffleToIdentity(I))
6977 return true;
6978 break;
6979 case Instruction::Load:
6980 if (shrinkLoadForShuffles(I))
6981 return true;
6982 break;
6983 case Instruction::BitCast:
6984 if (foldBitcastShuffle(I))
6985 return true;
6986 if (foldSelectsFromBitcast(I))
6987 return true;
6988 break;
6989 case Instruction::And:
6990 case Instruction::Or:
6991 case Instruction::Xor:
6992 if (foldBitOpOfCastops(I))
6993 return true;
6994 if (foldBitOpOfCastConstant(I))
6995 return true;
6996 break;
6997 case Instruction::PHI:
6998 if (shrinkPhiOfShuffles(I))
6999 return true;
7000 break;
7001 default:
7002 if (shrinkType(I))
7003 return true;
7004 break;
7005 }
7006 } else {
7007 switch (Opcode) {
7008 case Instruction::Call:
7009 if (foldShuffleFromReductions(I))
7010 return true;
7011 if (foldCastFromReductions(I))
7012 return true;
7013 break;
7014 case Instruction::ExtractElement:
7015 if (foldShuffleChainsToReduce(I))
7016 return true;
7017 break;
7018 case Instruction::ICmp:
7019 if (foldSignBitReductionCmp(I))
7020 return true;
7021 if (foldICmpEqZeroVectorReduce(I))
7022 return true;
7023 if (foldReductionZeroTest(I))
7024 return true;
7025 if (foldEquivalentReductionCmp(I))
7026 return true;
7027 if (foldReduceAddCmpZero(I))
7028 return true;
7029 [[fallthrough]];
7030 case Instruction::FCmp:
7031 if (foldExtractExtract(I))
7032 return true;
7033 break;
7034 case Instruction::Or:
7035 if (foldConcatOfBoolMasks(I))
7036 return true;
7037 [[fallthrough]];
7038 default:
7039 if (Instruction::isBinaryOp(Opcode)) {
7040 if (foldExtractExtract(I))
7041 return true;
7042 if (foldExtractedCmps(I))
7043 return true;
7044 if (foldBinopOfReductions(I))
7045 return true;
7046 }
7047 break;
7048 }
7049 }
7050 return false;
7051 };
7052
7053 bool MadeChange = false;
7054 for (BasicBlock &BB : F) {
7055 // Ignore unreachable basic blocks.
7056 if (!DT.isReachableFromEntry(&BB))
7057 continue;
7058 // Use early increment range so that we can erase instructions in loop.
7059 // make_early_inc_range is not applicable here, as the next iterator may
7060 // be invalidated by RecursivelyDeleteTriviallyDeadInstructions.
7061 // We manually maintain the next instruction and update it when it is about
7062 // to be deleted.
7063 Instruction *I = &BB.front();
7064 while (I) {
7065 NextInst = I->getNextNode();
7066 if (!I->isDebugOrPseudoInst())
7067 MadeChange |= FoldInst(*I);
7068 I = NextInst;
7069 }
7070 }
7071
7072 NextInst = nullptr;
7073
7074 while (!Worklist.isEmpty()) {
7075 Instruction *I = Worklist.removeOne();
7076 if (!I)
7077 continue;
7078
7081 continue;
7082 }
7083
7084 MadeChange |= FoldInst(*I);
7085 }
7086
7087 return MadeChange;
7088}
7089
7092 auto &AC = FAM.getResult<AssumptionAnalysis>(F);
7094 DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
7095 AAResults &AA = FAM.getResult<AAManager>(F);
7096 const DataLayout *DL = &F.getDataLayout();
7099 VectorCombine Combiner(F, TTI, DT, AA, AC, DL, CostKind, TryEarlyFoldsOnly);
7100 if (!Combiner.run())
7101 return PreservedAnalyses::all();
7104 return PA;
7105}
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< unsigned > MaxInstrsToScan("aggressive-instcombine-max-scan-instrs", cl::init(64), cl::Hidden, cl::desc("Max number of instructions to scan for aggressive instcombine."))
This is the interface for LLVM's primary stateless and local alias analysis.
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
static cl::opt< IntrinsicCostStrategy > IntrinsicCost("intrinsic-cost-strategy", cl::desc("Costing strategy for intrinsic instructions"), cl::init(IntrinsicCostStrategy::InstructionCost), cl::values(clEnumValN(IntrinsicCostStrategy::InstructionCost, "instruction-cost", "Use TargetTransformInfo::getInstructionCost"), clEnumValN(IntrinsicCostStrategy::IntrinsicCost, "intrinsic-cost", "Use TargetTransformInfo::getIntrinsicInstrCost"), clEnumValN(IntrinsicCostStrategy::TypeBasedIntrinsicCost, "type-based-intrinsic-cost", "Calculate the intrinsic cost based only on argument types")))
This file defines the DenseMap class.
#define Check(C,...)
This is the interface for a simple mod/ref and alias analysis over globals.
Hexagon Common GEP
iv users
Definition IVUsers.cpp:48
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU)
Definition LICM.cpp:1226
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T1
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
if(PassOpts->AAPipeline)
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file contains some templates that are useful if you are working with the STL at all.
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines less commonly used SmallVector utilities.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
static bool isEquivBitcast(Value *X, Value *Y)
Helper to peek through bitcasts to the same value.
static bool isFreeConcat(ArrayRef< InstLane > Item, TTI::TargetCostKind CostKind, const TargetTransformInfo &TTI)
Detect concat of multiple values into a vector.
static void analyzeCostOfVecReduction(const IntrinsicInst &II, TTI::TargetCostKind CostKind, const TargetTransformInfo &TTI, InstructionCost &CostBeforeReduction, InstructionCost &CostAfterReduction)
static Value * generateNewInstTree(ArrayRef< InstLane > Item, Use *From, const DenseSet< std::pair< Value *, Use * > > &IdentityLeafs, const DenseSet< std::pair< Value *, Use * > > &SplatLeafs, const DenseSet< std::pair< Value *, Use * > > &ConcatLeafs, IRBuilderBase &Builder, InstructionWorklist &WorkList, const TargetTransformInfo *TTI)
static SmallVector< InstLane > generateInstLaneVectorFromOperand(ArrayRef< InstLane > Item, int Op)
static Value * createShiftShuffle(Value *Vec, unsigned OldIndex, unsigned NewIndex, IRBuilderBase &Builder)
Create a shuffle that translates (shifts) 1 element from the input vector to a new element location.
std::pair< Value *, int > InstLane
static bool isKnownNonPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Used by foldReduceAddCmpZero to check if we can prove that a value is non-positive.
static Value * materializeScalarizedGEPIndex(Value *Idx, IntegerType *GEPIndexTy, IRBuilderBase &Builder)
Materialize an index for a scalarized GEP after profitability is known.
static Align computeAlignmentAfterScalarization(Align VectorAlignment, Type *ScalarType, Value *Idx, const DataLayout &DL)
The memory operation on a vector of ScalarType had alignment of VectorAlignment.
static bool feedsIntoVectorReduction(ShuffleVectorInst *SVI)
Returns true if this ShuffleVectorInst eventually feeds into a vector reduction intrinsic (e....
static cl::opt< bool > DisableVectorCombine("disable-vector-combine", cl::init(false), cl::Hidden, cl::desc("Disable all vector combine transforms"))
static bool canWidenLoad(LoadInst *Load, const TargetTransformInfo &TTI)
static const unsigned InvalidIndex
static IntegerType * getScalarizedGEPIndexInfo(VectorType *VecTy, Value *Idx, Type *PtrTy, const DataLayout &DL)
Return the GEP index type if the unsigned vector index Idx can be represented by an inbounds GEP.
static Value * translateExtract(ExtractElementInst *ExtElt, unsigned NewIndex, IRBuilderBase &Builder)
Given an extract element instruction with constant index operand, shuffle the source vector (shift th...
static ScalarizationResult canScalarizeAccess(VectorType *VecTy, Value *Idx, const SimplifyQuery &SQ)
Check if it is legal to scalarize a memory access to VecTy at index Idx.
static cl::opt< unsigned > MaxInstrsToScan("vector-combine-max-scan-instrs", cl::init(30), cl::Hidden, cl::desc("Max number of instructions to scan for vector combining."))
static cl::opt< bool > DisableBinopExtractShuffle("disable-binop-extract-shuffle", cl::init(false), cl::Hidden, cl::desc("Disable binop extract to shuffle transforms"))
static unsigned getAlignedNumElements(unsigned MaxIdx, FixedVectorType *LoadTy, const TargetTransformInfo &TTI, const DataLayout &DL)
Given the maximum shuffle index and load vector type, compute the number of elements for the shrunk l...
static InstLane lookThroughShuffles(Value *V, int Lane)
static bool isMemModifiedBetween(BasicBlock::iterator Begin, BasicBlock::iterator End, const MemoryLocation &Loc, AAResults &AA)
static constexpr int Concat[]
Value * RHS
Value * LHS
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition APInt.h:1186
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
unsigned countl_one() const
Count the number of leading one bits.
Definition APInt.h:1635
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1030
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:292
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:385
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1225
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
size_t size() const
Get the array size.
Definition ArrayRef.h:141
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
BinaryOps getOpcode() const
Definition InstrTypes.h:409
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Value * getArgOperand(unsigned i) const
void addParamAttrs(unsigned ArgNo, const AttrBuilder &B)
Adds attributes to the indicated argument.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
bool isFPPredicate() const
Definition InstrTypes.h:845
static LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
Combiner implementation.
Definition Combiner.h:33
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This class represents a range of values.
LLVM_ABI ConstantRange urem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned remainder operation of...
LLVM_ABI ConstantRange binaryAnd(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-and of a value in this ra...
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
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:285
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:258
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:348
bool empty() const
Definition DenseMap.h:206
iterator end()
Definition DenseMap.h:176
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:311
This instruction extracts a single (scalar) element from a VectorType value.
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
bool noSignedZeros() const
Definition FMF.h:67
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * getDoubleElementsVectorType(FixedVectorType *VTy)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
Value * CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1477
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2677
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2665
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1942
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:2724
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:2743
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:1540
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Definition IRBuilder.h:2292
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
Definition IRBuilder.h:2767
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition IRBuilder.h:2027
Value * CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2317
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:2524
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2555
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:2762
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2251
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:1914
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1519
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:2129
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition IRBuilder.h:2699
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1578
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:1933
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2115
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:1739
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:1852
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2500
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1600
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...
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
@ CompareCallTargets
Check for equivalence by comparing call targets.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isIdempotent() const
Return true if the instruction is idempotent:
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
bool isIntDivRem() const
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
void setAlignment(Align Align)
Type * getPointerOperandType() const
Align getAlign() const
Return the alignment of the access that is being performed.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
const SDValue & getOperand(unsigned Num) const
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
This instruction constructs a fixed permutation of two input vectors.
int getMaskValue(unsigned Elt) const
Return the shuffle mask value of this instruction for the given element index.
VectorType * getType() const
Overload to return most specific vector type.
static LLVM_ABI void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
static void commuteShuffleMask(MutableArrayRef< int > Mask, unsigned InVecNumElts)
Change values in a shuffle permute mask assuming the two vector operands of length InVecNumElts have ...
size_type size() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void setAlignment(Align Align)
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI CastContextHint getCastContextHint(const Instruction *I)
Calculates a CastContextHint from I.
LLVM_ABI InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TargetCostKind CostKind, Type *AccessType=nullptr) const
Estimate the cost of a GEP operation when lowered.
LLVM_ABI TypeSize getRegisterBitWidth(RegisterKind K) const
LLVM_ABI InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, OperandValueInfo OpdInfo={OK_AnyValue, OP_None}, const Instruction *I=nullptr) const
static LLVM_ABI OperandValueInfo commonOperandInfo(const Value *X, const Value *Y)
Collect common data between two OperandValueInfo inputs.
LLVM_ABI bool allowVectorElementIndexingUsingGEP() const
Returns true if GEP should not be used to index into vectors for this target.
LLVM_ABI InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const
LLVM_ABI InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index=-1, const Value *Op0=nullptr, const Value *Op1=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
LLVM_ABI InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, OperandValueInfo Op1Info={OK_AnyValue, OP_None}, OperandValueInfo Op2Info={OK_AnyValue, OP_None}, const Instruction *I=nullptr) const
LLVM_ABI InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const
LLVM_ABI unsigned getRegisterClassForType(bool Vector, Type *Ty=nullptr) const
LLVM_ABI InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const
Calculate the cost of vector reduction intrinsics.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
LLVM_ABI InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
LLVM_ABI InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const
LLVM_ABI unsigned getMinVectorRegisterBitWidth() const
LLVM_ABI InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const
LLVM_ABI 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, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
LLVM_ABI unsigned getNumberOfRegisters(unsigned ClassID) const
LLVM_ABI InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TargetCostKind CostKind) const
Estimate the cost of a given IR user when lowered.
LLVM_ABI InstructionCost 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:277
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
Definition Value.h:729
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
Definition Value.cpp:163
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition Value.cpp:1002
unsigned getValueID() const
Return an ID for the concrete type of this object.
Definition Value.h:545
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
Definition Value.cpp:147
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:712
bool use_empty() const
Definition Value.h:348
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
bool user_empty() const
Definition Value.h:391
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
size_type size() const
Definition DenseSet.h:84
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS*X will result in a value whose quantity matches our ...
Definition TypeSize.h:265
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS*X will result in a value whose quantity matches our own.
Definition TypeSize.h:273
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
constexpr bool isZero() const
Definition TypeSize.h:153
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
Definition APInt.h:2274
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition APInt.h:2279
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h: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)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:339
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:577
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition STLExtras.h:846
void stable_sort(R &&Range)
Definition STLExtras.h:2132
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
Definition LoopInfo.cpp:60
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1748
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:522
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI Value * simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q)
Given operand for a UnaryOperator, fold the result or return null.
scope_exit(Callable) -> scope_exit< Callable >
@ Load
The value being inserted comes from a load (InsertElement only).
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI unsigned getArithmeticReductionInstruction(Intrinsic::ID RdxID)
Returns the arithmetic instruction opcode used when expanding a reduction.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
LLVM_ABI Value * simplifyCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)
Given a callsite, callee, and arguments, fold the result or return null.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
LLVM_ABI 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:1762
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition Local.cpp:402
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI 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:1788
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
LLVM_ABI bool isSafeToLoadUnconditionally(Value *V, Align Alignment, const APInt &Size, const SimplifyQuery &SQ)
Return true if we know that executing a load from this value cannot trap.
Definition Loads.cpp:456
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Definition STLExtras.h:2182
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicID(Intrinsic::ID IID)
Returns the llvm.vector.reduce min/max intrinsic that corresponds to the intrinsic op.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
LLVM_ABI AAMDNodes adjustForAccess(unsigned AccessSize)
Create a new AAMDNode for accessing AccessSize bytes of this AAMDNode.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
Definition KnownBits.h:310
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
Definition KnownBits.h:262
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Definition KnownBits.h:146
const DataLayout & DL
const Instruction * CxtI
const DominatorTree * DT
SimplifyQuery getWithInstruction(const Instruction *I) const
AssumptionCache * AC