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