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