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 // The new GEP may change the pointer operand, so !invariant.group cannot
2019 // be transferred to the scalar store.
2020 NSI->setMetadata(LLVMContext::MD_invariant_group, nullptr);
2021 Align ScalarOpAlignment = computeAlignmentAfterScalarization(
2022 std::max(SI->getAlign(), Load->getAlign()), NewElement->getType(), Idx,
2023 *DL);
2024 NSI->setAlignment(ScalarOpAlignment);
2025 replaceValue(I, *NSI);
2027 return true;
2028 }
2029
2030 return false;
2031}
2032
2033/// Try to scalarize vector loads feeding extractelement or bitcast
2034/// instructions.
2035bool VectorCombine::scalarizeLoad(Instruction &I) {
2036 Value *Ptr;
2037 if (!match(&I, m_Load(m_Value(Ptr))))
2038 return false;
2039
2040 auto *LI = cast<LoadInst>(&I);
2041 auto *VecTy = cast<VectorType>(LI->getType());
2042
2043 // The isSimple() check could be isUnordered(), but for now we cowardly
2044 // refuse to handle even unordered atomics.
2045 if (!LI->isSimple() || !DL->typeSizeEqualsStoreSize(VecTy->getScalarType()))
2046 return false;
2047
2048 bool AllExtracts = true;
2049 bool AllBitcasts = true;
2050 Instruction *LastCheckedInst = LI;
2051 unsigned NumInstChecked = 0;
2052
2053 // Check what type of users we have (must either all be extracts or
2054 // bitcasts) and ensure no memory modifications between the load and
2055 // its users.
2056 for (User *U : LI->users()) {
2057 auto *UI = dyn_cast<Instruction>(U);
2058 if (!UI || UI->getParent() != LI->getParent())
2059 return false;
2060
2061 // If any user is waiting to be erased, then bail out as this will
2062 // distort the cost calculation and possibly lead to infinite loops.
2063 if (UI->use_empty())
2064 return false;
2065
2066 if (!isa<ExtractElementInst>(UI))
2067 AllExtracts = false;
2068 if (!isa<BitCastInst>(UI))
2069 AllBitcasts = false;
2070
2071 // Check if any instruction between the load and the user may modify memory.
2072 if (LastCheckedInst->comesBefore(UI)) {
2073 for (Instruction &I :
2074 make_range(std::next(LI->getIterator()), UI->getIterator())) {
2075 // Bail out if we reached the check limit or the instruction may write
2076 // to memory.
2077 if (NumInstChecked == MaxInstrsToScan || I.mayWriteToMemory())
2078 return false;
2079 NumInstChecked++;
2080 }
2081 LastCheckedInst = UI;
2082 }
2083 }
2084
2085 if (AllExtracts)
2086 return scalarizeLoadExtract(LI, VecTy, Ptr);
2087 if (AllBitcasts)
2088 return scalarizeLoadBitcast(LI, VecTy, Ptr);
2089 return false;
2090}
2091
2092/// Try to scalarize vector loads feeding extractelement instructions.
2093bool VectorCombine::scalarizeLoadExtract(LoadInst *LI, VectorType *VecTy,
2094 Value *Ptr) {
2096 return false;
2097
2098 DenseMap<ExtractElementInst *, ScalarizationResult> NeedFreeze;
2099 llvm::scope_exit FailureGuard([&]() {
2100 // If the transform is aborted, discard the ScalarizationResults.
2101 for (auto &Pair : NeedFreeze)
2102 Pair.second.discard();
2103 });
2104
2105 InstructionCost OriginalCost =
2106 TTI.getMemoryOpCost(Instruction::Load, VecTy, LI->getAlign(),
2108 InstructionCost ScalarizedCost = 0;
2109
2110 for (User *U : LI->users()) {
2111 auto *UI = cast<ExtractElementInst>(U);
2112
2113 auto ScalarIdx = canScalarizeAccess(VecTy, UI->getIndexOperand(),
2114 SQ.getWithInstruction(LI));
2115 if (ScalarIdx.isUnsafe())
2116 return false;
2117 if (ScalarIdx.isSafeWithFreeze()) {
2118 NeedFreeze.try_emplace(UI, ScalarIdx);
2119 ScalarIdx.discard();
2120 }
2121
2122 auto *Index = dyn_cast<ConstantInt>(UI->getIndexOperand());
2123 OriginalCost +=
2124 TTI.getVectorInstrCost(Instruction::ExtractElement, VecTy, CostKind,
2125 Index ? Index->getZExtValue() : -1);
2126 ScalarizedCost +=
2127 TTI.getMemoryOpCost(Instruction::Load, VecTy->getElementType(),
2129 ScalarizedCost += TTI.getAddressComputationCost(LI->getPointerOperandType(),
2130 nullptr, nullptr, CostKind);
2131 }
2132
2133 LLVM_DEBUG(dbgs() << "Found all extractions of a vector load: " << *LI
2134 << "\n LoadExtractCost: " << OriginalCost
2135 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2136
2137 if (ScalarizedCost >= OriginalCost)
2138 return false;
2139
2140 // Ensure we add the load back to the worklist BEFORE its users so they can
2141 // erased in the correct order.
2142 Worklist.push(LI);
2143
2144 Type *ElemType = VecTy->getElementType();
2145
2146 // Replace extracts with narrow scalar loads.
2147 for (User *U : LI->users()) {
2148 auto *EI = cast<ExtractElementInst>(U);
2149 Value *Idx = EI->getIndexOperand();
2150
2151 // Insert 'freeze' for poison indexes.
2152 auto It = NeedFreeze.find(EI);
2153 if (It != NeedFreeze.end())
2154 It->second.freeze(Builder, *cast<Instruction>(Idx));
2155
2156 Builder.SetInsertPoint(EI);
2157 Value *GEP =
2158 Builder.CreateInBoundsGEP(VecTy, Ptr, {Builder.getInt32(0), Idx});
2159 auto *NewLoad = cast<LoadInst>(
2160 Builder.CreateLoad(ElemType, GEP, EI->getName() + ".scalar"));
2161
2162 Align ScalarOpAlignment =
2163 computeAlignmentAfterScalarization(LI->getAlign(), ElemType, Idx, *DL);
2164 NewLoad->setAlignment(ScalarOpAlignment);
2165
2166 if (auto *ConstIdx = dyn_cast<ConstantInt>(Idx)) {
2167 size_t Offset = ConstIdx->getZExtValue() * DL->getTypeStoreSize(ElemType);
2168 AAMDNodes OldAAMD = LI->getAAMetadata();
2169 NewLoad->setAAMetadata(OldAAMD.adjustForAccess(Offset, ElemType, *DL));
2170 }
2171
2172 replaceValue(*EI, *NewLoad, false);
2173 }
2174
2175 FailureGuard.release();
2176 return true;
2177}
2178
2179/// Try to scalarize vector loads feeding bitcast instructions.
2180bool VectorCombine::scalarizeLoadBitcast(LoadInst *LI, VectorType *VecTy,
2181 Value *Ptr) {
2182 InstructionCost OriginalCost =
2183 TTI.getMemoryOpCost(Instruction::Load, VecTy, LI->getAlign(),
2185
2186 Type *TargetScalarType = nullptr;
2187 unsigned VecBitWidth = DL->getTypeSizeInBits(VecTy);
2188
2189 for (User *U : LI->users()) {
2190 auto *BC = cast<BitCastInst>(U);
2191
2192 Type *DestTy = BC->getDestTy();
2193 if (!DestTy->isIntegerTy() && !DestTy->isFloatingPointTy())
2194 return false;
2195
2196 unsigned DestBitWidth = DL->getTypeSizeInBits(DestTy);
2197 if (DestBitWidth != VecBitWidth)
2198 return false;
2199
2200 // All bitcasts must target the same scalar type.
2201 if (!TargetScalarType)
2202 TargetScalarType = DestTy;
2203 else if (TargetScalarType != DestTy)
2204 return false;
2205
2206 OriginalCost +=
2207 TTI.getCastInstrCost(Instruction::BitCast, TargetScalarType, VecTy,
2209 }
2210
2211 if (!TargetScalarType)
2212 return false;
2213
2214 assert(!LI->user_empty() && "Unexpected load without bitcast users");
2215 InstructionCost ScalarizedCost =
2216 TTI.getMemoryOpCost(Instruction::Load, TargetScalarType, LI->getAlign(),
2218
2219 LLVM_DEBUG(dbgs() << "Found vector load feeding only bitcasts: " << *LI
2220 << "\n OriginalCost: " << OriginalCost
2221 << " vs ScalarizedCost: " << ScalarizedCost << "\n");
2222
2223 if (ScalarizedCost >= OriginalCost)
2224 return false;
2225
2226 // Ensure we add the load back to the worklist BEFORE its users so they can
2227 // erased in the correct order.
2228 Worklist.push(LI);
2229
2230 Builder.SetInsertPoint(LI);
2231 auto *ScalarLoad =
2232 Builder.CreateLoad(TargetScalarType, Ptr, LI->getName() + ".scalar");
2233 ScalarLoad->setAlignment(LI->getAlign());
2234 ScalarLoad->copyMetadata(*LI);
2235
2236 // Replace all bitcast users with the scalar load.
2237 for (User *U : LI->users()) {
2238 auto *BC = cast<BitCastInst>(U);
2239 replaceValue(*BC, *ScalarLoad, false);
2240 }
2241
2242 return true;
2243}
2244
2245bool VectorCombine::scalarizeExtExtract(Instruction &I) {
2247 return false;
2248 auto *Ext = dyn_cast<ZExtInst>(&I);
2249 if (!Ext)
2250 return false;
2251
2252 // Try to convert a vector zext feeding only extracts to a set of scalar
2253 // (Src << ExtIdx *Size) & (Size -1)
2254 // if profitable .
2255 auto *SrcTy = dyn_cast<FixedVectorType>(Ext->getOperand(0)->getType());
2256 if (!SrcTy)
2257 return false;
2258 auto *DstTy = cast<FixedVectorType>(Ext->getType());
2259
2260 Type *ScalarDstTy = DstTy->getElementType();
2261 if (DL->getTypeSizeInBits(SrcTy) != DL->getTypeSizeInBits(ScalarDstTy))
2262 return false;
2263
2264 InstructionCost VectorCost =
2265 TTI.getCastInstrCost(Instruction::ZExt, DstTy, SrcTy,
2267 unsigned ExtCnt = 0;
2268 bool ExtLane0 = false;
2269 for (User *U : Ext->users()) {
2270 uint64_t Idx;
2271 if (!match(U, m_ExtractElt(m_Value(), m_ConstantInt(Idx))))
2272 return false;
2273 if (cast<Instruction>(U)->use_empty())
2274 continue;
2275 ExtCnt += 1;
2276 ExtLane0 |= !Idx;
2277 VectorCost += TTI.getVectorInstrCost(Instruction::ExtractElement, DstTy,
2278 CostKind, Idx, U);
2279 }
2280
2281 InstructionCost ScalarCost =
2282 ExtCnt * TTI.getArithmeticInstrCost(
2283 Instruction::And, ScalarDstTy, CostKind,
2286 (ExtCnt - ExtLane0) *
2288 Instruction::LShr, ScalarDstTy, CostKind,
2291 if (ScalarCost > VectorCost)
2292 return false;
2293
2294 Value *ScalarV = Ext->getOperand(0);
2295 if (!isGuaranteedNotToBePoison(ScalarV, SQ.AC, dyn_cast<Instruction>(ScalarV),
2296 SQ.DT)) {
2297 // Check wether all lanes are extracted, all extracts trigger UB
2298 // on poison, and the last extract (and hence all previous ones)
2299 // are guaranteed to execute if Ext executes. If so, we do not
2300 // need to insert a freeze.
2301 SmallDenseSet<ConstantInt *, 8> ExtractedLanes;
2302 bool AllExtractsTriggerUB = true;
2303 ExtractElementInst *LastExtract = nullptr;
2304 BasicBlock *ExtBB = Ext->getParent();
2305 for (User *U : Ext->users()) {
2306 auto *Extract = cast<ExtractElementInst>(U);
2307 if (Extract->getParent() != ExtBB || !programUndefinedIfPoison(Extract)) {
2308 AllExtractsTriggerUB = false;
2309 break;
2310 }
2311 ExtractedLanes.insert(cast<ConstantInt>(Extract->getIndexOperand()));
2312 if (!LastExtract || LastExtract->comesBefore(Extract))
2313 LastExtract = Extract;
2314 }
2315 if (ExtractedLanes.size() != DstTy->getNumElements() ||
2316 !AllExtractsTriggerUB ||
2318 LastExtract->getIterator()))
2319 ScalarV = Builder.CreateFreeze(ScalarV);
2320 }
2321 ScalarV = Builder.CreateBitCast(
2322 ScalarV,
2323 IntegerType::get(SrcTy->getContext(), DL->getTypeSizeInBits(SrcTy)));
2324 uint64_t SrcEltSizeInBits = DL->getTypeSizeInBits(SrcTy->getElementType());
2325 uint64_t TotalBits = DL->getTypeSizeInBits(SrcTy);
2326 APInt EltBitMask = APInt::getLowBitsSet(TotalBits, SrcEltSizeInBits);
2327 Type *PackedTy = IntegerType::get(SrcTy->getContext(), TotalBits);
2328 Value *Mask = ConstantInt::get(PackedTy, EltBitMask);
2329 for (User *U : Ext->users()) {
2330 auto *Extract = cast<ExtractElementInst>(U);
2331 uint64_t Idx =
2332 cast<ConstantInt>(Extract->getIndexOperand())->getZExtValue();
2333 uint64_t ShiftAmt =
2334 DL->isBigEndian()
2335 ? (TotalBits - SrcEltSizeInBits - Idx * SrcEltSizeInBits)
2336 : (Idx * SrcEltSizeInBits);
2337 Value *LShr = Builder.CreateLShr(ScalarV, ShiftAmt);
2338 Value *And = Builder.CreateAnd(LShr, Mask);
2339 U->replaceAllUsesWith(And);
2340 }
2341 return true;
2342}
2343
2344/// Try to fold "(or (zext (bitcast X)), (shl (zext (bitcast Y)), C))"
2345/// to "(bitcast (concat X, Y))"
2346/// where X/Y are bitcasted from i1 mask vectors.
2347bool VectorCombine::foldConcatOfBoolMasks(Instruction &I) {
2348 Type *Ty = I.getType();
2349 if (!Ty->isIntegerTy())
2350 return false;
2351
2352 // TODO: Add big endian test coverage
2353 if (DL->isBigEndian())
2354 return false;
2355
2356 // Restrict to disjoint cases so the mask vectors aren't overlapping.
2357 Instruction *X, *Y;
2359 return false;
2360
2361 // Allow both sources to contain shl, to handle more generic pattern:
2362 // "(or (shl (zext (bitcast X)), C1), (shl (zext (bitcast Y)), C2))"
2363 Value *SrcX;
2364 uint64_t ShAmtX = 0;
2365 if (!match(X, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcX)))))) &&
2366 !match(X, m_OneUse(
2368 m_ConstantInt(ShAmtX)))))
2369 return false;
2370
2371 Value *SrcY;
2372 uint64_t ShAmtY = 0;
2373 if (!match(Y, m_OneUse(m_ZExt(m_OneUse(m_BitCast(m_Value(SrcY)))))) &&
2374 !match(Y, m_OneUse(
2376 m_ConstantInt(ShAmtY)))))
2377 return false;
2378
2379 // Canonicalize larger shift to the RHS.
2380 if (ShAmtX > ShAmtY) {
2381 std::swap(X, Y);
2382 std::swap(SrcX, SrcY);
2383 std::swap(ShAmtX, ShAmtY);
2384 }
2385
2386 // Ensure both sources are matching vXi1 bool mask types, and that the shift
2387 // difference is the mask width so they can be easily concatenated together.
2388 uint64_t ShAmtDiff = ShAmtY - ShAmtX;
2389 unsigned NumSHL = (ShAmtX > 0) + (ShAmtY > 0);
2390 unsigned BitWidth = Ty->getPrimitiveSizeInBits();
2391 auto *MaskTy = dyn_cast<FixedVectorType>(SrcX->getType());
2392 if (!MaskTy || SrcX->getType() != SrcY->getType() ||
2393 !MaskTy->getElementType()->isIntegerTy(1) ||
2394 MaskTy->getNumElements() != ShAmtDiff ||
2395 MaskTy->getNumElements() > (BitWidth / 2))
2396 return false;
2397
2398 auto *ConcatTy = FixedVectorType::getDoubleElementsVectorType(MaskTy);
2399 auto *ConcatIntTy =
2400 Type::getIntNTy(Ty->getContext(), ConcatTy->getNumElements());
2401 auto *MaskIntTy = Type::getIntNTy(Ty->getContext(), ShAmtDiff);
2402
2403 SmallVector<int, 32> ConcatMask(ConcatTy->getNumElements());
2404 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
2405
2406 // TODO: Is it worth supporting multi use cases?
2407 InstructionCost OldCost = 0;
2408 OldCost += TTI.getArithmeticInstrCost(Instruction::Or, Ty, CostKind);
2409 OldCost +=
2410 NumSHL * TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2411 OldCost += 2 * TTI.getCastInstrCost(Instruction::ZExt, Ty, MaskIntTy,
2413 OldCost += 2 * TTI.getCastInstrCost(Instruction::BitCast, MaskIntTy, MaskTy,
2415
2416 InstructionCost NewCost = 0;
2418 MaskTy, ConcatMask, CostKind);
2419 NewCost += TTI.getCastInstrCost(Instruction::BitCast, ConcatIntTy, ConcatTy,
2421 if (Ty != ConcatIntTy)
2422 NewCost += TTI.getCastInstrCost(Instruction::ZExt, Ty, ConcatIntTy,
2424 if (ShAmtX > 0)
2425 NewCost += TTI.getArithmeticInstrCost(Instruction::Shl, Ty, CostKind);
2426
2427 LLVM_DEBUG(dbgs() << "Found a concatenation of bitcasted bool masks: " << I
2428 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2429 << "\n");
2430
2431 if (NewCost > OldCost)
2432 return false;
2433
2434 // Build bool mask concatenation, bitcast back to scalar integer, and perform
2435 // any residual zero-extension or shifting.
2436 Value *Concat = Builder.CreateShuffleVector(SrcX, SrcY, ConcatMask);
2437 Worklist.pushValue(Concat);
2438
2439 Value *Result = Builder.CreateBitCast(Concat, ConcatIntTy);
2440
2441 if (Ty != ConcatIntTy) {
2442 Worklist.pushValue(Result);
2443 Result = Builder.CreateZExt(Result, Ty);
2444 }
2445
2446 if (ShAmtX > 0) {
2447 Worklist.pushValue(Result);
2448 Result = Builder.CreateShl(Result, ShAmtX);
2449 }
2450
2451 replaceValue(I, *Result);
2452 return true;
2453}
2454
2455/// Try to convert "shuffle (binop (shuffle, shuffle)), undef"
2456/// --> "binop (shuffle), (shuffle)".
2457bool VectorCombine::foldPermuteOfBinops(Instruction &I) {
2458 BinaryOperator *BinOp;
2459 ArrayRef<int> OuterMask;
2460 if (!match(&I, m_Shuffle(m_BinOp(BinOp), m_Undef(), m_Mask(OuterMask))))
2461 return false;
2462
2463 // Don't introduce poison into div/rem.
2464 if (BinOp->isIntDivRem() && llvm::is_contained(OuterMask, PoisonMaskElem))
2465 return false;
2466
2467 Value *Op00, *Op01, *Op10, *Op11;
2468 ArrayRef<int> Mask0, Mask1;
2469 bool Match0 = match(BinOp->getOperand(0),
2470 m_Shuffle(m_Value(Op00), m_Value(Op01), m_Mask(Mask0)));
2471 bool Match1 = match(BinOp->getOperand(1),
2472 m_Shuffle(m_Value(Op10), m_Value(Op11), m_Mask(Mask1)));
2473 if (!Match0 && !Match1)
2474 return false;
2475
2476 Op00 = Match0 ? Op00 : BinOp->getOperand(0);
2477 Op01 = Match0 ? Op01 : BinOp->getOperand(0);
2478 Op10 = Match1 ? Op10 : BinOp->getOperand(1);
2479 Op11 = Match1 ? Op11 : BinOp->getOperand(1);
2480
2481 Instruction::BinaryOps Opcode = BinOp->getOpcode();
2482 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2483 auto *BinOpTy = dyn_cast<FixedVectorType>(BinOp->getType());
2484 auto *Op0Ty = dyn_cast<FixedVectorType>(Op00->getType());
2485 auto *Op1Ty = dyn_cast<FixedVectorType>(Op10->getType());
2486 if (!ShuffleDstTy || !BinOpTy || !Op0Ty || !Op1Ty)
2487 return false;
2488
2489 unsigned NumSrcElts = BinOpTy->getNumElements();
2490
2491 // Don't accept shuffles that reference the second operand in
2492 // div/rem or if its an undef arg.
2493 if ((BinOp->isIntDivRem() || !isa<PoisonValue>(I.getOperand(1))) &&
2494 any_of(OuterMask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
2495 return false;
2496
2497 // Merge outer / inner (or identity if no match) shuffles.
2498 SmallVector<int> NewMask0, NewMask1;
2499 for (int M : OuterMask) {
2500 if (M < 0 || M >= (int)NumSrcElts) {
2501 NewMask0.push_back(PoisonMaskElem);
2502 NewMask1.push_back(PoisonMaskElem);
2503 } else {
2504 NewMask0.push_back(Match0 ? Mask0[M] : M);
2505 NewMask1.push_back(Match1 ? Mask1[M] : M);
2506 }
2507 }
2508
2509 unsigned NumOpElts = Op0Ty->getNumElements();
2510 bool IsIdentity0 = ShuffleDstTy == Op0Ty &&
2511 all_of(NewMask0, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2512 ShuffleVectorInst::isIdentityMask(NewMask0, NumOpElts);
2513 bool IsIdentity1 = ShuffleDstTy == Op1Ty &&
2514 all_of(NewMask1, [NumOpElts](int M) { return M < (int)NumOpElts; }) &&
2515 ShuffleVectorInst::isIdentityMask(NewMask1, NumOpElts);
2516
2517 InstructionCost NewCost = 0;
2518 // Try to merge shuffles across the binop if the new shuffles are not costly.
2519 InstructionCost BinOpCost =
2520 TTI.getArithmeticInstrCost(Opcode, BinOpTy, CostKind);
2521 InstructionCost OldCost =
2523 ShuffleDstTy, BinOpTy, OuterMask, CostKind,
2524 0, nullptr, {BinOp}, &I);
2525 if (!BinOp->hasOneUse())
2526 NewCost += BinOpCost;
2527
2528 if (Match0) {
2530 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op0Ty, Mask0, CostKind,
2531 0, nullptr, {Op00, Op01}, cast<Instruction>(BinOp->getOperand(0)));
2532 OldCost += Shuf0Cost;
2533 if (!BinOp->hasOneUse() || !BinOp->getOperand(0)->hasOneUse())
2534 NewCost += Shuf0Cost;
2535 }
2536 if (Match1) {
2538 TargetTransformInfo::SK_PermuteTwoSrc, BinOpTy, Op1Ty, Mask1, CostKind,
2539 0, nullptr, {Op10, Op11}, cast<Instruction>(BinOp->getOperand(1)));
2540 OldCost += Shuf1Cost;
2541 if (!BinOp->hasOneUse() || !BinOp->getOperand(1)->hasOneUse())
2542 NewCost += Shuf1Cost;
2543 }
2544
2545 NewCost += TTI.getArithmeticInstrCost(Opcode, ShuffleDstTy, CostKind);
2546
2547 if (!IsIdentity0)
2548 NewCost +=
2550 Op0Ty, NewMask0, CostKind, 0, nullptr, {Op00, Op01});
2551 if (!IsIdentity1)
2552 NewCost +=
2554 Op1Ty, NewMask1, CostKind, 0, nullptr, {Op10, Op11});
2555
2556 LLVM_DEBUG(dbgs() << "Found a shuffle feeding a shuffled binop: " << I
2557 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2558 << "\n");
2559
2560 // If costs are equal, still fold as we reduce instruction count.
2561 if (NewCost > OldCost)
2562 return false;
2563
2564 Value *LHS =
2565 IsIdentity0 ? Op00 : Builder.CreateShuffleVector(Op00, Op01, NewMask0);
2566 Value *RHS =
2567 IsIdentity1 ? Op10 : Builder.CreateShuffleVector(Op10, Op11, NewMask1);
2568 Value *NewBO = Builder.CreateBinOp(Opcode, LHS, RHS);
2569
2570 // Intersect flags from the old binops.
2571 if (auto *NewInst = dyn_cast<Instruction>(NewBO))
2572 NewInst->copyIRFlags(BinOp);
2573
2574 Worklist.pushValue(LHS);
2575 Worklist.pushValue(RHS);
2576 replaceValue(I, *NewBO);
2577 return true;
2578}
2579
2580/// Try to convert "shuffle (binop), (binop)" into "binop (shuffle), (shuffle)".
2581/// Try to convert "shuffle (cmpop), (cmpop)" into "cmpop (shuffle), (shuffle)".
2582bool VectorCombine::foldShuffleOfBinops(Instruction &I) {
2583 ArrayRef<int> OldMask;
2584 Instruction *LHS, *RHS;
2586 m_Mask(OldMask))))
2587 return false;
2588
2589 // TODO: Add support for addlike etc.
2590 if (LHS->getOpcode() != RHS->getOpcode())
2591 return false;
2592
2593 Value *X, *Y, *Z, *W;
2594 bool IsCommutative = false;
2595 CmpPredicate PredLHS = CmpInst::BAD_ICMP_PREDICATE;
2596 CmpPredicate PredRHS = CmpInst::BAD_ICMP_PREDICATE;
2597 if (match(LHS, m_BinOp(m_Value(X), m_Value(Y))) &&
2598 match(RHS, m_BinOp(m_Value(Z), m_Value(W)))) {
2599 auto *BO = cast<BinaryOperator>(LHS);
2600 // Don't introduce poison into div/rem.
2601 if (llvm::is_contained(OldMask, PoisonMaskElem) && BO->isIntDivRem())
2602 return false;
2603 IsCommutative = BinaryOperator::isCommutative(BO->getOpcode());
2604 } else if (match(LHS, m_Cmp(PredLHS, m_Value(X), m_Value(Y))) &&
2605 match(RHS, m_Cmp(PredRHS, m_Value(Z), m_Value(W))) &&
2606 (CmpInst::Predicate)PredLHS == (CmpInst::Predicate)PredRHS) {
2607 IsCommutative = cast<CmpInst>(LHS)->isCommutative();
2608 } else
2609 return false;
2610
2611 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2612 auto *BinResTy = dyn_cast<FixedVectorType>(LHS->getType());
2613 auto *BinOpTy = dyn_cast<FixedVectorType>(X->getType());
2614 if (!ShuffleDstTy || !BinResTy || !BinOpTy || X->getType() != Z->getType())
2615 return false;
2616
2617 bool SameBinOp = LHS == RHS;
2618 unsigned NumSrcElts = BinOpTy->getNumElements();
2619
2620 // If we have something like "add X, Y" and "add Z, X", swap ops to match.
2621 if (IsCommutative && X != Z && Y != W && (X == W || Y == Z))
2622 std::swap(X, Y);
2623
2624 auto ConvertToUnary = [NumSrcElts](int &M) {
2625 if (M >= (int)NumSrcElts)
2626 M -= NumSrcElts;
2627 };
2628
2629 SmallVector<int> NewMask0(OldMask);
2631 TTI::OperandValueInfo Op0Info = TTI.commonOperandInfo(X, Z);
2632 if (X == Z) {
2633 llvm::for_each(NewMask0, ConvertToUnary);
2635 Z = PoisonValue::get(BinOpTy);
2636 }
2637
2638 SmallVector<int> NewMask1(OldMask);
2640 TTI::OperandValueInfo Op1Info = TTI.commonOperandInfo(Y, W);
2641 if (Y == W) {
2642 llvm::for_each(NewMask1, ConvertToUnary);
2644 W = PoisonValue::get(BinOpTy);
2645 }
2646
2647 // Try to replace a binop with a shuffle if the shuffle is not costly.
2648 // When SameBinOp, only count the binop cost once.
2651
2652 InstructionCost OldCost = LHSCost;
2653 if (!SameBinOp) {
2654 OldCost += RHSCost;
2655 }
2657 ShuffleDstTy, BinResTy, OldMask, CostKind, 0,
2658 nullptr, {LHS, RHS}, &I);
2659
2660 // Handle shuffle(binop(shuffle(x),y),binop(z,shuffle(w))) style patterns
2661 // where one use shuffles have gotten split across the binop/cmp. These
2662 // often allow a major reduction in total cost that wouldn't happen as
2663 // individual folds.
2664 auto MergeInner = [&](Value *&Op, int Offset, MutableArrayRef<int> Mask,
2665 TTI::TargetCostKind CostKind) -> bool {
2666 Value *InnerOp;
2667 ArrayRef<int> InnerMask;
2668 if (match(Op, m_OneUse(m_Shuffle(m_Value(InnerOp), m_Undef(),
2669 m_Mask(InnerMask)))) &&
2670 InnerOp->getType() == Op->getType() &&
2671 all_of(InnerMask,
2672 [NumSrcElts](int M) { return M < (int)NumSrcElts; })) {
2673 for (int &M : Mask)
2674 if (Offset <= M && M < (int)(Offset + NumSrcElts)) {
2675 M = InnerMask[M - Offset];
2676 M = 0 <= M ? M + Offset : M;
2677 }
2679 Op = InnerOp;
2680 return true;
2681 }
2682 return false;
2683 };
2684 bool ReducedInstCount = false;
2685 ReducedInstCount |= MergeInner(X, 0, NewMask0, CostKind);
2686 ReducedInstCount |= MergeInner(Y, 0, NewMask1, CostKind);
2687 ReducedInstCount |= MergeInner(Z, NumSrcElts, NewMask0, CostKind);
2688 ReducedInstCount |= MergeInner(W, NumSrcElts, NewMask1, CostKind);
2689 bool SingleSrcBinOp = (X == Y) && (Z == W) && (NewMask0 == NewMask1);
2690 // SingleSrcBinOp only reduces instruction count if we also eliminate the
2691 // original binop(s). If binops have multiple uses, they won't be eliminated.
2692 ReducedInstCount |= SingleSrcBinOp && LHS->hasOneUser() && RHS->hasOneUser();
2693
2694 // For concat shuffles of i1 vectors where both binops are one-use, the
2695 // transform keeps the same instruction count but canonicalises to a single
2696 // wider binop, enabling downstream folds (e.g. NOT(XOR(concat(a,b),
2697 // concat(c,d))) -> XNOR(concat(a,b),concat(c,d)) on AVX-512 mask regs).
2698 // Restrict to BinaryOperator (not CmpInst) since narrow comparisons may
2699 // be cheaper than wide ones on some targets (e.g. AVX-512 vpcmpeq).
2700 ReducedInstCount |= cast<ShuffleVectorInst>(&I)->isConcat() &&
2701 I.getType()->getScalarType()->isIntegerTy(1) &&
2703 RHS->hasOneUser();
2704
2705 auto *ShuffleCmpTy =
2706 FixedVectorType::get(BinOpTy->getElementType(), ShuffleDstTy);
2708 SK0, ShuffleCmpTy, BinOpTy, NewMask0, CostKind, 0, nullptr, {X, Z});
2709 if (!SingleSrcBinOp)
2710 NewCost += TTI.getShuffleCost(SK1, ShuffleCmpTy, BinOpTy, NewMask1,
2711 CostKind, 0, nullptr, {Y, W});
2712
2713 if (PredLHS == CmpInst::BAD_ICMP_PREDICATE) {
2714 NewCost += TTI.getArithmeticInstrCost(LHS->getOpcode(), ShuffleDstTy,
2715 CostKind, Op0Info, Op1Info);
2716 } else {
2717 NewCost +=
2718 TTI.getCmpSelInstrCost(LHS->getOpcode(), ShuffleCmpTy, ShuffleDstTy,
2719 PredLHS, CostKind, Op0Info, Op1Info);
2720 }
2721 // If LHS/RHS have other uses, we need to account for the cost of keeping
2722 // the original instructions. When SameBinOp, only add the cost once.
2723 if (!LHS->hasOneUser())
2724 NewCost += LHSCost;
2725 if (!SameBinOp && !RHS->hasOneUser())
2726 NewCost += RHSCost;
2727
2728 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two binops: " << I
2729 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2730 << "\n");
2731
2732 // If either shuffle will constant fold away, then fold for the same cost as
2733 // we will reduce the instruction count.
2734 ReducedInstCount |= (isa<Constant>(X) && isa<Constant>(Z)) ||
2735 (isa<Constant>(Y) && isa<Constant>(W));
2736 if (ReducedInstCount ? (NewCost > OldCost) : (NewCost >= OldCost))
2737 return false;
2738
2739 Value *Shuf0 = Builder.CreateShuffleVector(X, Z, NewMask0);
2740 Value *Shuf1 =
2741 SingleSrcBinOp ? Shuf0 : Builder.CreateShuffleVector(Y, W, NewMask1);
2742 Value *NewBO = PredLHS == CmpInst::BAD_ICMP_PREDICATE
2743 ? Builder.CreateBinOp(
2744 cast<BinaryOperator>(LHS)->getOpcode(), Shuf0, Shuf1)
2745 : Builder.CreateCmp(PredLHS, Shuf0, Shuf1);
2746
2747 // Intersect flags from the old binops.
2748 if (auto *NewInst = dyn_cast<Instruction>(NewBO)) {
2749 NewInst->copyIRFlags(LHS);
2750 NewInst->andIRFlags(RHS);
2751 }
2752
2753 Worklist.pushValue(Shuf0);
2754 Worklist.pushValue(Shuf1);
2755 replaceValue(I, *NewBO);
2756 return true;
2757}
2758
2759/// Try to convert,
2760/// (shuffle(select(c1,t1,f1)), (select(c2,t2,f2)), m) into
2761/// (select (shuffle c1,c2,m), (shuffle t1,t2,m), (shuffle f1,f2,m))
2762bool VectorCombine::foldShuffleOfSelects(Instruction &I) {
2763 ArrayRef<int> Mask;
2764 Value *C1, *T1, *F1, *C2, *T2, *F2;
2765 if (!match(&I, m_Shuffle(m_Select(m_Value(C1), m_Value(T1), m_Value(F1)),
2766 m_Select(m_Value(C2), m_Value(T2), m_Value(F2)),
2767 m_Mask(Mask))))
2768 return false;
2769
2770 auto *Sel1 = cast<Instruction>(I.getOperand(0));
2771 auto *Sel2 = cast<Instruction>(I.getOperand(1));
2772
2773 auto *C1VecTy = dyn_cast<FixedVectorType>(C1->getType());
2774 auto *C2VecTy = dyn_cast<FixedVectorType>(C2->getType());
2775 if (!C1VecTy || !C2VecTy || C1VecTy != C2VecTy)
2776 return false;
2777
2778 auto *SI0FOp = dyn_cast<FPMathOperator>(I.getOperand(0));
2779 auto *SI1FOp = dyn_cast<FPMathOperator>(I.getOperand(1));
2780 // SelectInsts must have the same FMF.
2781 if (((SI0FOp == nullptr) != (SI1FOp == nullptr)) ||
2782 ((SI0FOp != nullptr) &&
2783 (SI0FOp->getFastMathFlags() != SI1FOp->getFastMathFlags())))
2784 return false;
2785
2786 auto *SrcVecTy = cast<FixedVectorType>(T1->getType());
2787 auto *DstVecTy = cast<FixedVectorType>(I.getType());
2789 auto SelOp = Instruction::Select;
2790
2792 SelOp, SrcVecTy, C1VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2794 SelOp, SrcVecTy, C2VecTy, CmpInst::BAD_ICMP_PREDICATE, CostKind);
2795
2796 InstructionCost OldCost =
2797 CostSel1 + CostSel2 +
2798 TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, Mask, CostKind, 0, nullptr,
2799 {I.getOperand(0), I.getOperand(1)}, &I);
2800
2802 SK, FixedVectorType::get(C1VecTy->getScalarType(), Mask.size()), C1VecTy,
2803 Mask, CostKind, 0, nullptr, {C1, C2});
2804 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, Mask, CostKind, 0,
2805 nullptr, {T1, T2});
2806 NewCost += TTI.getShuffleCost(SK, DstVecTy, SrcVecTy, Mask, CostKind, 0,
2807 nullptr, {F1, F2});
2808 auto *C1C2ShuffledVecTy = FixedVectorType::get(
2809 Type::getInt1Ty(I.getContext()), DstVecTy->getNumElements());
2810 NewCost += TTI.getCmpSelInstrCost(SelOp, DstVecTy, C1C2ShuffledVecTy,
2812
2813 if (!Sel1->hasOneUse())
2814 NewCost += CostSel1;
2815 if (!Sel2->hasOneUse())
2816 NewCost += CostSel2;
2817
2818 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two selects: " << I
2819 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2820 << "\n");
2821 if (NewCost > OldCost)
2822 return false;
2823
2824 Value *ShuffleCmp = Builder.CreateShuffleVector(C1, C2, Mask);
2825 Value *ShuffleTrue = Builder.CreateShuffleVector(T1, T2, Mask);
2826 Value *ShuffleFalse = Builder.CreateShuffleVector(F1, F2, Mask);
2827 Value *NewSel;
2828 // We presuppose that the SelectInsts have the same FMF.
2829 if (SI0FOp)
2830 NewSel = Builder.CreateSelectFMF(ShuffleCmp, ShuffleTrue, ShuffleFalse,
2831 SI0FOp->getFastMathFlags());
2832 else
2833 NewSel = Builder.CreateSelect(ShuffleCmp, ShuffleTrue, ShuffleFalse);
2834
2835 Worklist.pushValue(ShuffleCmp);
2836 Worklist.pushValue(ShuffleTrue);
2837 Worklist.pushValue(ShuffleFalse);
2838 replaceValue(I, *NewSel);
2839 return true;
2840}
2841
2842/// Try to convert "shuffle (castop), (castop)" with a shared castop operand
2843/// into "castop (shuffle)".
2844bool VectorCombine::foldShuffleOfCastops(Instruction &I) {
2845 Value *V0, *V1;
2846 ArrayRef<int> OldMask;
2847 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
2848 return false;
2849
2850 // Check whether this is a binary shuffle.
2851 bool IsBinaryShuffle = !isa<UndefValue>(V1);
2852
2853 auto *C0 = dyn_cast<CastInst>(V0);
2854 auto *C1 = dyn_cast<CastInst>(V1);
2855 if (!C0 || (IsBinaryShuffle && !C1))
2856 return false;
2857
2858 Instruction::CastOps Opcode = C0->getOpcode();
2859
2860 // If this is allowed, foldShuffleOfCastops can get stuck in a loop
2861 // with foldBitcastOfShuffle. Reject in favor of foldBitcastOfShuffle.
2862 if (!IsBinaryShuffle && Opcode == Instruction::BitCast)
2863 return false;
2864
2865 if (IsBinaryShuffle) {
2866 if (C0->getSrcTy() != C1->getSrcTy())
2867 return false;
2868 // Handle shuffle(zext_nneg(x), sext(y)) -> sext(shuffle(x,y)) folds.
2869 if (Opcode != C1->getOpcode()) {
2870 if (match(C0, m_SExtLike(m_Value())) && match(C1, m_SExtLike(m_Value())))
2871 Opcode = Instruction::SExt;
2872 else
2873 return false;
2874 }
2875 }
2876
2877 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
2878 auto *CastDstTy = dyn_cast<FixedVectorType>(C0->getDestTy());
2879 auto *CastSrcTy = dyn_cast<FixedVectorType>(C0->getSrcTy());
2880 if (!ShuffleDstTy || !CastDstTy || !CastSrcTy)
2881 return false;
2882
2883 unsigned NumSrcElts = CastSrcTy->getNumElements();
2884 unsigned NumDstElts = CastDstTy->getNumElements();
2885 assert((NumDstElts == NumSrcElts || Opcode == Instruction::BitCast) &&
2886 "Only bitcasts expected to alter src/dst element counts");
2887
2888 // Check for bitcasting of unscalable vector types.
2889 // e.g. <32 x i40> -> <40 x i32>
2890 if (NumDstElts != NumSrcElts && (NumSrcElts % NumDstElts) != 0 &&
2891 (NumDstElts % NumSrcElts) != 0)
2892 return false;
2893
2894 SmallVector<int, 16> NewMask;
2895 if (NumSrcElts >= NumDstElts) {
2896 // The bitcast is from wide to narrow/equal elements. The shuffle mask can
2897 // always be expanded to the equivalent form choosing narrower elements.
2898 assert(NumSrcElts % NumDstElts == 0 && "Unexpected shuffle mask");
2899 unsigned ScaleFactor = NumSrcElts / NumDstElts;
2900 narrowShuffleMaskElts(ScaleFactor, OldMask, NewMask);
2901 } else {
2902 // The bitcast is from narrow elements to wide elements. The shuffle mask
2903 // must choose consecutive elements to allow casting first.
2904 assert(NumDstElts % NumSrcElts == 0 && "Unexpected shuffle mask");
2905 unsigned ScaleFactor = NumDstElts / NumSrcElts;
2906 if (!widenShuffleMaskElts(ScaleFactor, OldMask, NewMask))
2907 return false;
2908 }
2909
2910 auto *NewShuffleDstTy =
2911 FixedVectorType::get(CastSrcTy->getScalarType(), NewMask.size());
2912
2913 // Try to replace a castop with a shuffle if the shuffle is not costly.
2914 InstructionCost CostC0 =
2915 TTI.getCastInstrCost(C0->getOpcode(), CastDstTy, CastSrcTy,
2917
2919 if (IsBinaryShuffle)
2921 else
2923
2924 InstructionCost OldCost = CostC0;
2925 OldCost += TTI.getShuffleCost(ShuffleKind, ShuffleDstTy, CastDstTy, OldMask,
2926 CostKind, 0, nullptr, {}, &I);
2927
2928 InstructionCost NewCost = TTI.getShuffleCost(ShuffleKind, NewShuffleDstTy,
2929 CastSrcTy, NewMask, CostKind);
2930 NewCost += TTI.getCastInstrCost(Opcode, ShuffleDstTy, NewShuffleDstTy,
2932 if (!C0->hasOneUse())
2933 NewCost += CostC0;
2934 if (IsBinaryShuffle) {
2935 InstructionCost CostC1 =
2936 TTI.getCastInstrCost(C1->getOpcode(), CastDstTy, CastSrcTy,
2938 OldCost += CostC1;
2939 if (!C1->hasOneUse())
2940 NewCost += CostC1;
2941 }
2942
2943 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two casts: " << I
2944 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
2945 << "\n");
2946 if (NewCost > OldCost)
2947 return false;
2948
2949 Value *Shuf;
2950 if (IsBinaryShuffle)
2951 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), C1->getOperand(0),
2952 NewMask);
2953 else
2954 Shuf = Builder.CreateShuffleVector(C0->getOperand(0), NewMask);
2955
2956 Value *Cast = Builder.CreateCast(Opcode, Shuf, ShuffleDstTy);
2957
2958 // Intersect flags from the old casts.
2959 if (auto *NewInst = dyn_cast<Instruction>(Cast)) {
2960 NewInst->copyIRFlags(C0);
2961 if (IsBinaryShuffle)
2962 NewInst->andIRFlags(C1);
2963 }
2964
2965 Worklist.pushValue(Shuf);
2966 replaceValue(I, *Cast);
2967 return true;
2968}
2969
2970/// Try to convert any of:
2971/// "shuffle (shuffle x, y), (shuffle y, x)"
2972/// "shuffle (shuffle x, undef), (shuffle y, undef)"
2973/// "shuffle (shuffle x, undef), y"
2974/// "shuffle x, (shuffle y, undef)"
2975/// into "shuffle x, y".
2976bool VectorCombine::foldShuffleOfShuffles(Instruction &I) {
2977 ArrayRef<int> OuterMask;
2978 Value *OuterV0, *OuterV1;
2979 if (!match(&I,
2980 m_Shuffle(m_Value(OuterV0), m_Value(OuterV1), m_Mask(OuterMask))))
2981 return false;
2982
2983 ArrayRef<int> InnerMask0, InnerMask1;
2984 Value *X0, *X1, *Y0, *Y1;
2985 bool Match0 =
2986 match(OuterV0, m_Shuffle(m_Value(X0), m_Value(Y0), m_Mask(InnerMask0)));
2987 bool Match1 =
2988 match(OuterV1, m_Shuffle(m_Value(X1), m_Value(Y1), m_Mask(InnerMask1)));
2989 if (!Match0 && !Match1)
2990 return false;
2991
2992 // If the outer shuffle is a permute, then create a fake inner all-poison
2993 // shuffle. This is easier than accounting for length-changing shuffles below.
2994 SmallVector<int, 16> PoisonMask1;
2995 if (!Match1 && isa<PoisonValue>(OuterV1)) {
2996 X1 = X0;
2997 Y1 = Y0;
2998 PoisonMask1.append(InnerMask0.size(), PoisonMaskElem);
2999 InnerMask1 = PoisonMask1;
3000 Match1 = true; // fake match
3001 }
3002
3003 X0 = Match0 ? X0 : OuterV0;
3004 Y0 = Match0 ? Y0 : OuterV0;
3005 X1 = Match1 ? X1 : OuterV1;
3006 Y1 = Match1 ? Y1 : OuterV1;
3007 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3008 auto *ShuffleSrcTy = dyn_cast<FixedVectorType>(X0->getType());
3009 auto *ShuffleImmTy = dyn_cast<FixedVectorType>(OuterV0->getType());
3010 if (!ShuffleDstTy || !ShuffleSrcTy || !ShuffleImmTy ||
3011 X0->getType() != X1->getType())
3012 return false;
3013
3014 unsigned NumSrcElts = ShuffleSrcTy->getNumElements();
3015 unsigned NumImmElts = ShuffleImmTy->getNumElements();
3016
3017 // Attempt to merge shuffles, matching upto 2 source operands.
3018 // Replace index to a poison arg with PoisonMaskElem.
3019 // Bail if either inner masks reference an undef arg.
3020 SmallVector<int, 16> NewMask(OuterMask);
3021 Value *NewX = nullptr, *NewY = nullptr;
3022 for (int &M : NewMask) {
3023 Value *Src = nullptr;
3024 if (0 <= M && M < (int)NumImmElts) {
3025 Src = OuterV0;
3026 if (Match0) {
3027 M = InnerMask0[M];
3028 Src = M >= (int)NumSrcElts ? Y0 : X0;
3029 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3030 }
3031 } else if (M >= (int)NumImmElts) {
3032 Src = OuterV1;
3033 M -= NumImmElts;
3034 if (Match1) {
3035 M = InnerMask1[M];
3036 Src = M >= (int)NumSrcElts ? Y1 : X1;
3037 M = M >= (int)NumSrcElts ? (M - NumSrcElts) : M;
3038 }
3039 }
3040 if (Src && M != PoisonMaskElem) {
3041 assert(0 <= M && M < (int)NumSrcElts && "Unexpected shuffle mask index");
3042 if (isa<UndefValue>(Src)) {
3043 // We've referenced an undef element - if its poison, update the shuffle
3044 // mask, else bail.
3045 if (!isa<PoisonValue>(Src))
3046 return false;
3047 M = PoisonMaskElem;
3048 continue;
3049 }
3050 if (!NewX || NewX == Src) {
3051 NewX = Src;
3052 continue;
3053 }
3054 if (!NewY || NewY == Src) {
3055 M += NumSrcElts;
3056 NewY = Src;
3057 continue;
3058 }
3059 return false;
3060 }
3061 }
3062
3063 if (!NewX) {
3064 replaceValue(I, *PoisonValue::get(ShuffleDstTy));
3065 return true;
3066 }
3067
3068 if (!NewY)
3069 NewY = PoisonValue::get(ShuffleSrcTy);
3070
3071 // Have we folded to an Identity shuffle?
3072 if (ShuffleVectorInst::isIdentityMask(NewMask, NumSrcElts)) {
3073 replaceValue(I, *NewX);
3074 return true;
3075 }
3076
3077 // Try to merge the shuffles if the new shuffle is not costly.
3078 InstructionCost InnerCost0 = 0;
3079 if (Match0)
3080 InnerCost0 = TTI.getInstructionCost(cast<User>(OuterV0), CostKind);
3081
3082 InstructionCost InnerCost1 = 0;
3083 if (Match1)
3084 InnerCost1 = TTI.getInstructionCost(cast<User>(OuterV1), CostKind);
3085
3087
3088 InstructionCost OldCost = InnerCost0 + InnerCost1 + OuterCost;
3089
3090 bool IsUnary = all_of(NewMask, [&](int M) { return M < (int)NumSrcElts; });
3094 InstructionCost NewCost =
3095 TTI.getShuffleCost(SK, ShuffleDstTy, ShuffleSrcTy, NewMask, CostKind, 0,
3096 nullptr, {NewX, NewY});
3097 if (!OuterV0->hasOneUse())
3098 NewCost += InnerCost0;
3099 if (!OuterV1->hasOneUse())
3100 NewCost += InnerCost1;
3101
3102 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two shuffles: " << I
3103 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3104 << "\n");
3105 if (NewCost > OldCost)
3106 return false;
3107
3108 Value *Shuf = Builder.CreateShuffleVector(NewX, NewY, NewMask);
3109 replaceValue(I, *Shuf);
3110 return true;
3111}
3112
3113/// Try to convert a chain of length-preserving shuffles that are fed by
3114/// length-changing shuffles from the same source, e.g. a chain of length 3:
3115///
3116/// "shuffle (shuffle (shuffle x, (shuffle y, undef)),
3117/// (shuffle y, undef)),
3118// (shuffle y, undef)"
3119///
3120/// into a single shuffle fed by a length-changing shuffle:
3121///
3122/// "shuffle x, (shuffle y, undef)"
3123///
3124/// Such chains arise e.g. from folding extract/insert sequences.
3125bool VectorCombine::foldShufflesOfLengthChangingShuffles(Instruction &I) {
3126 FixedVectorType *TrunkType = dyn_cast<FixedVectorType>(I.getType());
3127 if (!TrunkType)
3128 return false;
3129
3130 unsigned ChainLength = 0;
3131 SmallVector<int> Mask;
3132 SmallVector<int> YMask;
3133 InstructionCost OldCost = 0;
3134 InstructionCost NewCost = 0;
3135 Value *Trunk = &I;
3136 unsigned NumTrunkElts = TrunkType->getNumElements();
3137 Value *Y = nullptr;
3138
3139 for (;;) {
3140 // Match the current trunk against (commutations of) the pattern
3141 // "shuffle trunk', (shuffle y, undef)"
3142 ArrayRef<int> OuterMask;
3143 Value *OuterV0, *OuterV1;
3144 if (ChainLength != 0 && !Trunk->hasOneUse())
3145 break;
3146 if (!match(Trunk, m_Shuffle(m_Value(OuterV0), m_Value(OuterV1),
3147 m_Mask(OuterMask))))
3148 break;
3149 if (OuterV0->getType() != TrunkType) {
3150 // This shuffle is not length-preserving, so it cannot be part of the
3151 // chain.
3152 break;
3153 }
3154
3155 ArrayRef<int> InnerMask0, InnerMask1;
3156 Value *A0, *A1, *B0, *B1;
3157 bool Match0 =
3158 match(OuterV0, m_Shuffle(m_Value(A0), m_Value(B0), m_Mask(InnerMask0)));
3159 bool Match1 =
3160 match(OuterV1, m_Shuffle(m_Value(A1), m_Value(B1), m_Mask(InnerMask1)));
3161 bool Match0Leaf = Match0 && A0->getType() != I.getType();
3162 bool Match1Leaf = Match1 && A1->getType() != I.getType();
3163 if (Match0Leaf == Match1Leaf) {
3164 // Only handle the case of exactly one leaf in each step. The "two leaves"
3165 // case is handled by foldShuffleOfShuffles.
3166 break;
3167 }
3168
3169 SmallVector<int> CommutedOuterMask;
3170 if (Match0Leaf) {
3171 std::swap(OuterV0, OuterV1);
3172 std::swap(InnerMask0, InnerMask1);
3173 std::swap(A0, A1);
3174 std::swap(B0, B1);
3175 llvm::append_range(CommutedOuterMask, OuterMask);
3176 for (int &M : CommutedOuterMask) {
3177 if (M == PoisonMaskElem)
3178 continue;
3179 if (M < (int)NumTrunkElts)
3180 M += NumTrunkElts;
3181 else
3182 M -= NumTrunkElts;
3183 }
3184 OuterMask = CommutedOuterMask;
3185 }
3186 if (!OuterV1->hasOneUse())
3187 break;
3188
3189 if (!isa<UndefValue>(A1)) {
3190 if (!Y)
3191 Y = A1;
3192 else if (Y != A1)
3193 break;
3194 }
3195 if (!isa<UndefValue>(B1)) {
3196 if (!Y)
3197 Y = B1;
3198 else if (Y != B1)
3199 break;
3200 }
3201
3202 auto *YType = cast<FixedVectorType>(A1->getType());
3203 int NumLeafElts = YType->getNumElements();
3204 SmallVector<int> LocalYMask(InnerMask1);
3205 for (int &M : LocalYMask) {
3206 if (M >= NumLeafElts)
3207 M -= NumLeafElts;
3208 }
3209
3210 InstructionCost LocalOldCost =
3213
3214 // Handle the initial (start of chain) case.
3215 if (!ChainLength) {
3216 Mask.assign(OuterMask);
3217 YMask.assign(LocalYMask);
3218 OldCost = NewCost = LocalOldCost;
3219 Trunk = OuterV0;
3220 ChainLength++;
3221 continue;
3222 }
3223
3224 // For the non-root case, first attempt to combine masks.
3225 SmallVector<int> NewYMask(YMask);
3226 bool Valid = true;
3227 for (auto [CombinedM, LeafM] : llvm::zip(NewYMask, LocalYMask)) {
3228 if (LeafM == -1 || CombinedM == LeafM)
3229 continue;
3230 if (CombinedM == -1) {
3231 CombinedM = LeafM;
3232 } else {
3233 Valid = false;
3234 break;
3235 }
3236 }
3237 if (!Valid)
3238 break;
3239
3240 SmallVector<int> NewMask;
3241 NewMask.reserve(NumTrunkElts);
3242 for (int M : Mask) {
3243 if (M < 0 || M >= static_cast<int>(NumTrunkElts))
3244 NewMask.push_back(M);
3245 else
3246 NewMask.push_back(OuterMask[M]);
3247 }
3248
3249 // Break the chain if adding this new step complicates the shuffles such
3250 // that it would increase the new cost by more than the old cost of this
3251 // step.
3252 InstructionCost LocalNewCost =
3254 YType, NewYMask, CostKind) +
3256 TrunkType, NewMask, CostKind);
3257
3258 if (LocalNewCost >= NewCost && LocalOldCost < LocalNewCost - NewCost)
3259 break;
3260
3261 LLVM_DEBUG({
3262 if (ChainLength == 1) {
3263 dbgs() << "Found chain of shuffles fed by length-changing shuffles: "
3264 << I << '\n';
3265 }
3266 dbgs() << " next chain link: " << *Trunk << '\n'
3267 << " old cost: " << (OldCost + LocalOldCost)
3268 << " new cost: " << LocalNewCost << '\n';
3269 });
3270
3271 Mask = NewMask;
3272 YMask = NewYMask;
3273 OldCost += LocalOldCost;
3274 NewCost = LocalNewCost;
3275 Trunk = OuterV0;
3276 ChainLength++;
3277 }
3278 if (ChainLength <= 1)
3279 return false;
3280
3281 // Bail out if all leaves were poison.
3282 if (!Y)
3283 return false;
3284
3285 if (llvm::all_of(Mask, [&](int M) {
3286 return M < 0 || M >= static_cast<int>(NumTrunkElts);
3287 })) {
3288 // Produce a canonical simplified form if all elements are sourced from Y.
3289 for (int &M : Mask) {
3290 if (M >= static_cast<int>(NumTrunkElts))
3291 M = YMask[M - NumTrunkElts];
3292 }
3293 Value *Root =
3294 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), Mask);
3295 replaceValue(I, *Root);
3296 return true;
3297 }
3298
3299 Value *Leaf =
3300 Builder.CreateShuffleVector(Y, PoisonValue::get(Y->getType()), YMask);
3301 Value *Root = Builder.CreateShuffleVector(Trunk, Leaf, Mask);
3302 replaceValue(I, *Root);
3303 return true;
3304}
3305
3306/// Try to convert
3307/// "shuffle (intrinsic), (intrinsic)" into "intrinsic (shuffle), (shuffle)".
3308bool VectorCombine::foldShuffleOfIntrinsics(Instruction &I) {
3309 Value *V0, *V1;
3310 ArrayRef<int> OldMask;
3311 if (!match(&I, m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(OldMask))))
3312 return false;
3313
3314 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3315 auto *II1 = dyn_cast<IntrinsicInst>(V1);
3316 if (!II0 || !II1)
3317 return false;
3318
3319 Intrinsic::ID IID = II0->getIntrinsicID();
3320 if (IID != II1->getIntrinsicID())
3321 return false;
3322 InstructionCost CostII0 =
3323 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3324 InstructionCost CostII1 =
3325 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II1), CostKind);
3326
3327 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3328 auto *II0Ty = dyn_cast<FixedVectorType>(II0->getType());
3329 if (!ShuffleDstTy || !II0Ty)
3330 return false;
3331
3332 if (!isTriviallyVectorizable(IID))
3333 return false;
3334
3335 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3336 Value *Arg0 = II0->getArgOperand(I);
3337 Value *Arg1 = II1->getArgOperand(I);
3339 // Scalar operands must be identical.
3340 if (Arg0 != Arg1)
3341 return false;
3342 } else if (Arg0->getType() != Arg1->getType()) {
3343 // The corresponding vector operands are shuffled together, so they must
3344 // share the same type. For intrinsics overloaded on their operand type
3345 // (e.g. llvm.fptosi.sat), two calls can produce the same result type
3346 // from different operand types; shuffling those would be invalid.
3347 return false;
3348 }
3349 }
3350
3351 InstructionCost OldCost =
3352 CostII0 + CostII1 +
3354 II0Ty, OldMask, CostKind, 0, nullptr, {II0, II1}, &I);
3355
3356 SmallVector<Type *> NewArgsTy;
3357 InstructionCost NewCost = 0;
3358 SmallDenseSet<std::pair<Value *, Value *>> SeenOperandPairs;
3359 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3361 NewArgsTy.push_back(II0->getArgOperand(I)->getType());
3362 } else {
3363 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(I)->getType());
3364 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3365 ShuffleDstTy->getNumElements());
3366 NewArgsTy.push_back(ArgTy);
3367 std::pair<Value *, Value *> OperandPair =
3368 std::make_pair(II0->getArgOperand(I), II1->getArgOperand(I));
3369 if (!SeenOperandPairs.insert(OperandPair).second) {
3370 // We've already computed the cost for this operand pair.
3371 continue;
3372 }
3373 NewCost += TTI.getShuffleCost(
3374 TargetTransformInfo::SK_PermuteTwoSrc, ArgTy, VecTy, OldMask,
3375 CostKind, 0, nullptr, {II0->getArgOperand(I), II1->getArgOperand(I)});
3376 }
3377 }
3378 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3379
3380 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3381 if (!II0->hasOneUse())
3382 NewCost += CostII0;
3383 if (II1 != II0 && !II1->hasOneUse())
3384 NewCost += CostII1;
3385
3386 LLVM_DEBUG(dbgs() << "Found a shuffle feeding two intrinsics: " << I
3387 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
3388 << "\n");
3389
3390 if (NewCost > OldCost)
3391 return false;
3392
3393 SmallVector<Value *> NewArgs;
3394 SmallDenseMap<std::pair<Value *, Value *>, Value *> ShuffleCache;
3395 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I)
3397 NewArgs.push_back(II0->getArgOperand(I));
3398 } else {
3399 std::pair<Value *, Value *> OperandPair =
3400 std::make_pair(II0->getArgOperand(I), II1->getArgOperand(I));
3401 auto It = ShuffleCache.find(OperandPair);
3402 if (It != ShuffleCache.end()) {
3403 // Reuse previously created shuffle for this operand pair.
3404 NewArgs.push_back(It->second);
3405 continue;
3406 }
3407 Value *Shuf = Builder.CreateShuffleVector(II0->getArgOperand(I),
3408 II1->getArgOperand(I), OldMask);
3409 ShuffleCache[OperandPair] = Shuf;
3410 NewArgs.push_back(Shuf);
3411 Worklist.pushValue(Shuf);
3412 }
3413 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3414
3415 // Intersect flags from the old intrinsics.
3416 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic)) {
3417 NewInst->copyIRFlags(II0);
3418 NewInst->andIRFlags(II1);
3419 }
3420
3421 replaceValue(I, *NewIntrinsic);
3422 return true;
3423}
3424
3425/// Try to convert
3426/// "shuffle (intrinsic), (poison/undef)" into "intrinsic (shuffle)".
3427bool VectorCombine::foldPermuteOfIntrinsic(Instruction &I) {
3428 Value *V0;
3429 ArrayRef<int> Mask;
3430 if (!match(&I, m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask))))
3431 return false;
3432
3433 auto *II0 = dyn_cast<IntrinsicInst>(V0);
3434 if (!II0)
3435 return false;
3436
3437 auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
3438 auto *IntrinsicSrcTy = dyn_cast<FixedVectorType>(II0->getType());
3439 if (!ShuffleDstTy || !IntrinsicSrcTy)
3440 return false;
3441
3442 // Validate it's a pure permute, mask should only reference the first vector
3443 unsigned NumSrcElts = IntrinsicSrcTy->getNumElements();
3444 if (any_of(Mask, [NumSrcElts](int M) { return M >= (int)NumSrcElts; }))
3445 return false;
3446
3447 Intrinsic::ID IID = II0->getIntrinsicID();
3448 if (!isTriviallyVectorizable(IID))
3449 return false;
3450
3451 // Cost analysis
3453 TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind);
3454 InstructionCost OldCost =
3457 IntrinsicSrcTy, Mask, CostKind, 0, nullptr, {V0}, &I);
3458
3459 SmallVector<Type *> NewArgsTy;
3460 InstructionCost NewCost = 0;
3461 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3463 NewArgsTy.push_back(II0->getArgOperand(I)->getType());
3464 } else {
3465 auto *VecTy = cast<FixedVectorType>(II0->getArgOperand(I)->getType());
3466 auto *ArgTy = FixedVectorType::get(VecTy->getElementType(),
3467 ShuffleDstTy->getNumElements());
3468 NewArgsTy.push_back(ArgTy);
3470 ArgTy, VecTy, Mask, CostKind, 0, nullptr,
3471 {II0->getArgOperand(I)});
3472 }
3473 }
3474 IntrinsicCostAttributes NewAttr(IID, ShuffleDstTy, NewArgsTy);
3475 NewCost += TTI.getIntrinsicInstrCost(NewAttr, CostKind);
3476
3477 // If the intrinsic has multiple uses, we need to account for the cost of
3478 // keeping the original intrinsic around.
3479 if (!II0->hasOneUse())
3480 NewCost += IntrinsicCost;
3481
3482 LLVM_DEBUG(dbgs() << "Found a permute of intrinsic: " << I << "\n OldCost: "
3483 << OldCost << " vs NewCost: " << NewCost << "\n");
3484
3485 if (NewCost > OldCost)
3486 return false;
3487
3488 // Transform
3489 SmallVector<Value *> NewArgs;
3490 for (unsigned I = 0, E = II0->arg_size(); I != E; ++I) {
3492 NewArgs.push_back(II0->getArgOperand(I));
3493 } else {
3494 Value *Shuf = Builder.CreateShuffleVector(II0->getArgOperand(I), Mask);
3495 NewArgs.push_back(Shuf);
3496 Worklist.pushValue(Shuf);
3497 }
3498 }
3499
3500 Value *NewIntrinsic = Builder.CreateIntrinsic(ShuffleDstTy, IID, NewArgs);
3501
3502 if (auto *NewInst = dyn_cast<Instruction>(NewIntrinsic))
3503 NewInst->copyIRFlags(II0);
3504
3505 replaceValue(I, *NewIntrinsic);
3506 return true;
3507}
3508
3509using InstLane = std::pair<Value *, int>;
3510
3511static InstLane lookThroughShuffles(Value *V, int Lane) {
3512 while (auto *SV = dyn_cast<ShuffleVectorInst>(V)) {
3513 unsigned NumElts =
3514 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
3515 int M = SV->getMaskValue(Lane);
3516 if (M < 0)
3517 return {nullptr, PoisonMaskElem};
3518 if (static_cast<unsigned>(M) < NumElts) {
3519 V = SV->getOperand(0);
3520 Lane = M;
3521 } else {
3522 V = SV->getOperand(1);
3523 Lane = M - NumElts;
3524 }
3525 }
3526 return InstLane{V, Lane};
3527}
3528
3532 for (InstLane IL : Item) {
3533 auto [U, Lane] = IL;
3534 InstLane OpLane =
3535 U ? lookThroughShuffles(cast<Instruction>(U)->getOperand(Op), Lane)
3536 : InstLane{nullptr, PoisonMaskElem};
3537 NItem.emplace_back(OpLane);
3538 }
3539 return NItem;
3540}
3541
3542/// Detect concat of multiple values into a vector
3544 const TargetTransformInfo &TTI) {
3545 auto *Ty = cast<FixedVectorType>(Item.front().first->getType());
3546 unsigned NumElts = Ty->getNumElements();
3547 if (Item.size() == NumElts || NumElts == 1 || Item.size() % NumElts != 0)
3548 return false;
3549
3550 // Check that the concat is free, usually meaning that the type will be split
3551 // during legalization.
3552 SmallVector<int, 16> ConcatMask(NumElts * 2);
3553 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
3554 if (TTI.getShuffleCost(TTI::SK_PermuteTwoSrc,
3555 FixedVectorType::get(Ty->getScalarType(), NumElts * 2),
3556 Ty, ConcatMask, CostKind) != 0)
3557 return false;
3558
3559 unsigned NumSlices = Item.size() / NumElts;
3560 // Currently we generate a tree of shuffles for the concats, which limits us
3561 // to a power2.
3562 if (!isPowerOf2_32(NumSlices))
3563 return false;
3564 for (unsigned Slice = 0; Slice < NumSlices; ++Slice) {
3565 Value *SliceV = Item[Slice * NumElts].first;
3566 if (!SliceV || SliceV->getType() != Ty)
3567 return false;
3568 for (unsigned Elt = 0; Elt < NumElts; ++Elt) {
3569 auto [V, Lane] = Item[Slice * NumElts + Elt];
3570 if (Lane != static_cast<int>(Elt) || SliceV != V)
3571 return false;
3572 }
3573 }
3574 return true;
3575}
3576
3577static Value *
3579 const DenseSet<std::pair<Value *, Use *>> &IdentityLeafs,
3580 const DenseSet<std::pair<Value *, Use *>> &SplatLeafs,
3581 const DenseSet<std::pair<Value *, Use *>> &ConcatLeafs,
3582 IRBuilderBase &Builder, InstructionWorklist &WorkList,
3583 const TargetTransformInfo *TTI) {
3584 auto [FrontV, FrontLane] = Item.front();
3585
3586 if (IdentityLeafs.contains(std::make_pair(FrontV, From))) {
3587 return FrontV;
3588 }
3589 if (SplatLeafs.contains(std::make_pair(FrontV, From))) {
3590 SmallVector<int, 16> Mask(Item.size(), FrontLane);
3591 return Builder.CreateShuffleVector(FrontV, Mask);
3592 }
3593 if (ConcatLeafs.contains(std::make_pair(FrontV, From))) {
3594 unsigned NumElts =
3595 cast<FixedVectorType>(FrontV->getType())->getNumElements();
3596 SmallVector<Value *> Values(Item.size() / NumElts, nullptr);
3597 for (unsigned S = 0; S < Values.size(); ++S)
3598 Values[S] = Item[S * NumElts].first;
3599
3600 while (Values.size() > 1) {
3601 NumElts *= 2;
3602 SmallVector<int, 16> Mask(NumElts, 0);
3603 std::iota(Mask.begin(), Mask.end(), 0);
3604 SmallVector<Value *> NewValues(Values.size() / 2, nullptr);
3605 for (unsigned S = 0; S < NewValues.size(); ++S)
3606 NewValues[S] =
3607 Builder.CreateShuffleVector(Values[S * 2], Values[S * 2 + 1], Mask);
3608 Values = NewValues;
3609 }
3610 return Values[0];
3611 }
3612
3613 auto *I = cast<Instruction>(FrontV);
3614
3615 // Handle vector bitcasts that change element count. We cannot use
3616 // generateInstLaneVectorFromOperand for these because the lane indices
3617 // don't map 1:1 through the bitcast.
3618 if (auto *BitCast = dyn_cast<BitCastInst>(I)) {
3619 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3620 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3621 if (BCDstTy && BCSrcTy &&
3622 BCDstTy->getElementCount() != BCSrcTy->getElementCount()) {
3623 unsigned DstElts = BCDstTy->getNumElements();
3624 unsigned SrcElts = BCSrcTy->getNumElements();
3625 SmallVector<InstLane> NewItem;
3626 if (DstElts > SrcElts) {
3627 // Widening: compress operand Item.
3628 unsigned R = DstElts / SrcElts;
3629 if (Item.size() % R != 0)
3630 return nullptr;
3631 for (unsigned Idx = 0, E = Item.size(); Idx < E; Idx += R) {
3632 auto [V, Lane] = Item[Idx];
3633 if (!V) {
3634 NewItem.push_back({nullptr, PoisonMaskElem});
3635 continue;
3636 }
3637 NewItem.push_back(
3638 lookThroughShuffles(cast<Operator>(V)->getOperand(0), Lane / R));
3639 }
3640 } else {
3641 // Narrowing: expand operand Item.
3642 unsigned R = SrcElts / DstElts;
3643 for (auto [V, Lane] : Item) {
3644 if (!V) {
3645 NewItem.append(R, {nullptr, PoisonMaskElem});
3646 continue;
3647 }
3648 Value *Op = cast<Operator>(V)->getOperand(0);
3649 for (unsigned J = 0; J < R; ++J)
3650 NewItem.push_back(lookThroughShuffles(Op, Lane * R + J));
3651 }
3652 }
3653 Value *Op = generateNewInstTree(NewItem, &BitCast->getOperandUse(0),
3654 IdentityLeafs, SplatLeafs, ConcatLeafs,
3655 Builder, WorkList, TTI);
3656 WorkList.pushValue(Op);
3657 return Builder.CreateBitCast(
3658 Op, FixedVectorType::get(BCDstTy->getScalarType(), Item.size()));
3659 }
3660 }
3661 auto *II = dyn_cast<IntrinsicInst>(I);
3662 unsigned NumOps = I->getNumOperands() - (II ? 1 : 0);
3664 for (unsigned Idx = 0; Idx < NumOps; Idx++) {
3665 if (II &&
3666 isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Idx, TTI)) {
3667 Ops[Idx] = II->getOperand(Idx);
3668 continue;
3669 }
3670 Ops[Idx] = generateNewInstTree(
3671 generateInstLaneVectorFromOperand(Item, Idx), &I->getOperandUse(Idx),
3672 IdentityLeafs, SplatLeafs, ConcatLeafs, Builder, WorkList, TTI);
3673 // Don't re-queue the operand of a bitcast we just regenerated. Doing so
3674 // lets foldBitcastShuffle sink the bitcast back into a shuffle(bitcast),
3675 // which foldShuffleToIdentity then re-matches as the same superfluous
3676 // identity - an infinite loop between the two folds.
3677 if (!isa<BitCastInst>(I))
3678 WorkList.pushValue(Ops[Idx]);
3679 }
3680
3681 SmallVector<Value *, 8> ValueList;
3682 for (const auto &Lane : Item)
3683 if (Lane.first)
3684 ValueList.push_back(Lane.first);
3685
3686 Type *DstTy =
3687 FixedVectorType::get(I->getType()->getScalarType(), Item.size());
3688 if (auto *BI = dyn_cast<BinaryOperator>(I)) {
3689 auto *Value = Builder.CreateBinOp((Instruction::BinaryOps)BI->getOpcode(),
3690 Ops[0], Ops[1]);
3691 propagateIRFlags(Value, ValueList);
3692 return Value;
3693 }
3694 if (auto *CI = dyn_cast<CmpInst>(I)) {
3695 auto *Value = Builder.CreateCmp(CI->getPredicate(), Ops[0], Ops[1]);
3696 propagateIRFlags(Value, ValueList);
3697 return Value;
3698 }
3699 if (auto *SI = dyn_cast<SelectInst>(I)) {
3700 auto *Value = Builder.CreateSelect(Ops[0], Ops[1], Ops[2], "", SI);
3701 propagateIRFlags(Value, ValueList);
3702 return Value;
3703 }
3704 if (auto *CI = dyn_cast<CastInst>(I)) {
3705 auto *Value = Builder.CreateCast(CI->getOpcode(), Ops[0], DstTy);
3706 propagateIRFlags(Value, ValueList);
3707 return Value;
3708 }
3709 if (II) {
3710 auto *Value = Builder.CreateIntrinsic(DstTy, II->getIntrinsicID(), Ops);
3711 propagateIRFlags(Value, ValueList);
3712 return Value;
3713 }
3714 assert(isa<UnaryInstruction>(I) && "Unexpected instruction type in Generate");
3715 auto *Value =
3716 Builder.CreateUnOp((Instruction::UnaryOps)I->getOpcode(), Ops[0]);
3717 propagateIRFlags(Value, ValueList);
3718 return Value;
3719}
3720
3721// Starting from a shuffle, look up through operands tracking the shuffled index
3722// of each lane. If we can simplify away the shuffles to identities then
3723// do so.
3724bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
3725 auto *Ty = dyn_cast<FixedVectorType>(I.getType());
3726 if (!Ty || I.use_empty())
3727 return false;
3728
3729 SmallVector<InstLane> Start(Ty->getNumElements());
3730 for (unsigned M = 0, E = Ty->getNumElements(); M < E; ++M)
3731 Start[M] = lookThroughShuffles(&I, M);
3732
3734 Candidates.push_back(std::make_pair(Start, &*I.use_begin()));
3735 DenseSet<std::pair<Value *, Use *>> IdentityLeafs, SplatLeafs, ConcatLeafs;
3736 unsigned NumVisited = 0;
3737 bool TraversedElCountChangingBitcast = false;
3738
3739 while (!Candidates.empty()) {
3740 if (++NumVisited > MaxInstrsToScan)
3741 return false;
3742
3743 auto ItemFrom = Candidates.pop_back_val();
3744 auto Item = ItemFrom.first;
3745 auto From = ItemFrom.second;
3746 auto [FrontV, FrontLane] = Item.front();
3747
3748 // If we found an undef first lane then bail out to keep things simple.
3749 if (!FrontV)
3750 return false;
3751
3752 // Look for an identity value.
3753 if (FrontLane == 0 &&
3754 cast<FixedVectorType>(FrontV->getType())->getNumElements() ==
3755 Item.size() &&
3756 all_of(drop_begin(enumerate(Item)), [Item](const auto &E) {
3757 Value *FrontV = Item.front().first;
3758 return !E.value().first || (isEquivBitcast(E.value().first, FrontV) &&
3759 E.value().second == (int)E.index());
3760 })) {
3761 IdentityLeafs.insert(std::make_pair(FrontV, From));
3762 continue;
3763 }
3764 // Look for constants, for the moment only supporting constant splats.
3765 if (auto *C = dyn_cast<Constant>(FrontV);
3766 C && C->getSplatValue() &&
3767 all_of(drop_begin(Item), [Item](InstLane &IL) {
3768 Value *FrontV = Item.front().first;
3769 Value *V = IL.first;
3770 return !V || (isa<Constant>(V) &&
3771 cast<Constant>(V)->getSplatValue() ==
3772 cast<Constant>(FrontV)->getSplatValue());
3773 })) {
3774 SplatLeafs.insert(std::make_pair(FrontV, From));
3775 continue;
3776 }
3777 // Look for a splat value.
3778 if (all_of(drop_begin(Item), [Item](InstLane &IL) {
3779 auto [FrontV, FrontLane] = Item.front();
3780 auto [V, Lane] = IL;
3781 return !V || (V == FrontV && Lane == FrontLane);
3782 })) {
3783 SplatLeafs.insert(std::make_pair(FrontV, From));
3784 continue;
3785 }
3786
3787 // We need each element to be the same type of value, and check that each
3788 // element has a single use.
3789 auto CheckLaneIsEquivalentToFirst = [Item](InstLane IL) {
3790 Value *FrontV = Item.front().first;
3791 if (!IL.first)
3792 return true;
3793 Value *V = IL.first;
3794 if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUser())
3795 return false;
3796 if (V->getValueID() != FrontV->getValueID())
3797 return false;
3798 if (auto *CI = dyn_cast<CmpInst>(V))
3799 if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
3800 return false;
3801 if (auto *CI = dyn_cast<CastInst>(V))
3802 if (CI->getSrcTy()->getScalarType() !=
3803 cast<CastInst>(FrontV)->getSrcTy()->getScalarType())
3804 return false;
3805 if (auto *SI = dyn_cast<SelectInst>(V))
3806 if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
3807 SI->getOperand(0)->getType() !=
3808 cast<SelectInst>(FrontV)->getOperand(0)->getType())
3809 return false;
3810 if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
3811 return false;
3812 auto *II = dyn_cast<IntrinsicInst>(V);
3813 return !II || (isa<IntrinsicInst>(FrontV) &&
3814 II->getIntrinsicID() ==
3815 cast<IntrinsicInst>(FrontV)->getIntrinsicID() &&
3816 !II->hasOperandBundles());
3817 };
3818 if (all_of(drop_begin(Item), CheckLaneIsEquivalentToFirst)) {
3819 // Check the operator is one that we support.
3820 if (isa<BinaryOperator, CmpInst>(FrontV)) {
3821 // We exclude div/rem in case they hit UB from poison lanes.
3822 if (auto *BO = dyn_cast<BinaryOperator>(FrontV);
3823 BO && BO->isIntDivRem())
3824 return false;
3826 &cast<Instruction>(FrontV)->getOperandUse(0));
3828 &cast<Instruction>(FrontV)->getOperandUse(1));
3829 continue;
3830 } else if (isa<UnaryOperator, TruncInst, ZExtInst, SExtInst, FPToSIInst,
3831 FPToUIInst, SIToFPInst, UIToFPInst>(FrontV)) {
3833 &cast<Instruction>(FrontV)->getOperandUse(0));
3834 continue;
3835 } else if (auto *BitCast = dyn_cast<BitCastInst>(FrontV)) {
3836 auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
3837 auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
3838 if (BCDstTy && BCSrcTy) {
3839 ElementCount DstEC = BCDstTy->getElementCount();
3840 ElementCount SrcEC = BCSrcTy->getElementCount();
3841 if (DstEC == SrcEC) {
3842 // Same element count - simple pass-through.
3844 &BitCast->getOperandUse(0));
3845 continue;
3846 }
3847 unsigned DstElts = DstEC.getFixedValue();
3848 unsigned SrcElts = SrcEC.getFixedValue();
3849 if (DstElts > SrcElts && DstElts % SrcElts == 0) {
3850 // Widening bitcast (e.g. <2 x i32> -> <4 x i16>). Compress
3851 // consecutive groups of R destination lanes into one source
3852 // lane.
3853 unsigned R = DstElts / SrcElts;
3855 bool Valid = Item.size() % R == 0;
3856 for (unsigned Idx = 0, E = Item.size(); Valid && Idx < E;
3857 Idx += R) {
3858 auto [V0, L0] = Item[Idx];
3859 if (!V0) {
3860 if (any_of(ArrayRef(Item).slice(Idx + 1, R - 1),
3861 [](InstLane IL) { return IL.first != nullptr; })) {
3862 Valid = false;
3863 break;
3864 }
3865 NItem.push_back({nullptr, PoisonMaskElem});
3866 continue;
3867 }
3868 if (L0 % R != 0) {
3869 Valid = false;
3870 break;
3871 }
3872 for (unsigned J = 1; J < R; ++J) {
3873 auto [VJ, LJ] = Item[Idx + J];
3874 if (!VJ || VJ != V0 || LJ != L0 + (int)J) {
3875 Valid = false;
3876 break;
3877 }
3878 }
3879 if (!Valid)
3880 break;
3882 cast<Operator>(V0)->getOperand(0), L0 / R));
3883 }
3884 if (Valid) {
3885 TraversedElCountChangingBitcast = true;
3886 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
3887 continue;
3888 }
3889 } else if (SrcElts > DstElts && SrcElts % DstElts == 0) {
3890 // Narrowing bitcast (e.g. <4 x i16> -> <2 x i32>). Expand
3891 // each destination lane into R source lanes.
3892 unsigned R = SrcElts / DstElts;
3894 for (auto [V, Lane] : Item) {
3895 if (!V) {
3896 NItem.append(R, {nullptr, PoisonMaskElem});
3897 continue;
3898 }
3899 Value *Op = cast<Operator>(V)->getOperand(0);
3900 for (unsigned J = 0; J < R; ++J)
3901 NItem.push_back(lookThroughShuffles(Op, Lane * R + J));
3902 }
3903 TraversedElCountChangingBitcast = true;
3904 Candidates.emplace_back(NItem, &BitCast->getOperandUse(0));
3905 continue;
3906 }
3907 }
3908 } else if (auto *Sel = dyn_cast<SelectInst>(FrontV)) {
3910 &Sel->getOperandUse(0));
3912 &Sel->getOperandUse(1));
3914 &Sel->getOperandUse(2));
3915 continue;
3916 } else if (auto *II = dyn_cast<IntrinsicInst>(FrontV);
3917 II && isTriviallyVectorizable(II->getIntrinsicID()) &&
3918 !II->hasOperandBundles()) {
3919 for (unsigned Op = 0, E = II->getNumOperands() - 1; Op < E; Op++) {
3920 if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Op,
3921 &TTI)) {
3922 if (!all_of(drop_begin(Item), [Item, Op](InstLane &IL) {
3923 Value *FrontV = Item.front().first;
3924 Value *V = IL.first;
3925 return !V || (cast<Instruction>(V)->getOperand(Op) ==
3926 cast<Instruction>(FrontV)->getOperand(Op));
3927 }))
3928 return false;
3929 continue;
3930 }
3931 Candidates.emplace_back(
3933 &cast<Instruction>(FrontV)->getOperandUse(Op));
3934 }
3935 continue;
3936 }
3937 }
3938
3939 if (isFreeConcat(Item, CostKind, TTI)) {
3940 ConcatLeafs.insert(std::make_pair(FrontV, From));
3941 continue;
3942 }
3943
3944 return false;
3945 }
3946
3947 if (NumVisited <= 1)
3948 return false;
3949
3950 // If the only non-leaf node traversed was a single bitcast that changes
3951 // element count, the fold would just commute the bitcast and shuffle.
3952 // foldBitcastShuffle does the reverse transform, causing an infinite loop.
3953 if (NumVisited == 2 && TraversedElCountChangingBitcast)
3954 return false;
3955
3956 LLVM_DEBUG(dbgs() << "Found a superfluous identity shuffle: " << I << "\n");
3957
3958 // If we got this far, we know the shuffles are superfluous and can be
3959 // removed. Scan through again and generate the new tree of instructions.
3960 Builder.SetInsertPoint(&I);
3961 Value *V =
3962 generateNewInstTree(Start, &*I.use_begin(), IdentityLeafs, SplatLeafs,
3963 ConcatLeafs, Builder, Worklist, &TTI);
3964 replaceValue(I, *V);
3965 return true;
3966}
3967
3968/// Given a commutative reduction, the order of the input lanes does not alter
3969/// the results. We can use this to remove certain shuffles feeding the
3970/// reduction, removing the need to shuffle at all.
3971bool VectorCombine::foldShuffleFromReductions(Instruction &I) {
3972 auto *II = dyn_cast<IntrinsicInst>(&I);
3973 if (!II)
3974 return false;
3975 switch (II->getIntrinsicID()) {
3976 case Intrinsic::vector_reduce_add:
3977 case Intrinsic::vector_reduce_mul:
3978 case Intrinsic::vector_reduce_and:
3979 case Intrinsic::vector_reduce_or:
3980 case Intrinsic::vector_reduce_xor:
3981 case Intrinsic::vector_reduce_smin:
3982 case Intrinsic::vector_reduce_smax:
3983 case Intrinsic::vector_reduce_umin:
3984 case Intrinsic::vector_reduce_umax:
3985 break;
3986 default:
3987 return false;
3988 }
3989
3990 // Find all the inputs when looking through operations that do not alter the
3991 // lane order (binops, for example). Currently we look for a single shuffle,
3992 // and can ignore splat values.
3993 std::queue<Value *> Worklist;
3994 SmallPtrSet<Value *, 4> Visited;
3995 ShuffleVectorInst *Shuffle = nullptr;
3996 if (auto *Op = dyn_cast<Instruction>(I.getOperand(0)))
3997 Worklist.push(Op);
3998
3999 while (!Worklist.empty()) {
4000 Value *CV = Worklist.front();
4001 Worklist.pop();
4002 if (Visited.contains(CV))
4003 continue;
4004
4005 // Splats don't change the order, so can be safely ignored.
4006 if (isSplatValue(CV))
4007 continue;
4008
4009 Visited.insert(CV);
4010
4011 if (auto *CI = dyn_cast<Instruction>(CV)) {
4012 if (CI->isBinaryOp()) {
4013 for (auto *Op : CI->operand_values())
4014 Worklist.push(Op);
4015 continue;
4016 } else if (auto *SV = dyn_cast<ShuffleVectorInst>(CI)) {
4017 if (Shuffle && Shuffle != SV)
4018 return false;
4019 Shuffle = SV;
4020 continue;
4021 }
4022 }
4023
4024 // Anything else is currently an unknown node.
4025 return false;
4026 }
4027
4028 if (!Shuffle)
4029 return false;
4030
4031 // Check all uses of the binary ops and shuffles are also included in the
4032 // lane-invariant operations (Visited should be the list of lanewise
4033 // instructions, including the shuffle that we found).
4034 for (auto *V : Visited)
4035 for (auto *U : V->users())
4036 if (!Visited.contains(U) && U != &I)
4037 return false;
4038
4039 FixedVectorType *VecType =
4040 dyn_cast<FixedVectorType>(II->getOperand(0)->getType());
4041 if (!VecType)
4042 return false;
4043 FixedVectorType *ShuffleInputType =
4045 if (!ShuffleInputType)
4046 return false;
4047 unsigned NumInputElts = ShuffleInputType->getNumElements();
4048
4049 // Find the mask from sorting the lanes into order. This is most likely to
4050 // become a identity or concat mask. Undef elements are pushed to the end.
4051 SmallVector<int> ConcatMask;
4052 Shuffle->getShuffleMask(ConcatMask);
4053 sort(ConcatMask, [](int X, int Y) { return (unsigned)X < (unsigned)Y; });
4054 bool UsesSecondVec =
4055 any_of(ConcatMask, [&](int M) { return M >= (int)NumInputElts; });
4056
4058 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4059 ShuffleInputType, Shuffle->getShuffleMask(), CostKind);
4061 UsesSecondVec ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc, VecType,
4062 ShuffleInputType, ConcatMask, CostKind);
4063
4064 LLVM_DEBUG(dbgs() << "Found a reduction feeding from a shuffle: " << *Shuffle
4065 << "\n");
4066 LLVM_DEBUG(dbgs() << " OldCost: " << OldCost << " vs NewCost: " << NewCost
4067 << "\n");
4068 bool MadeChanges = false;
4069 if (NewCost < OldCost) {
4070 Builder.SetInsertPoint(Shuffle);
4071 Value *NewShuffle = Builder.CreateShuffleVector(
4072 Shuffle->getOperand(0), Shuffle->getOperand(1), ConcatMask);
4073 LLVM_DEBUG(dbgs() << "Created new shuffle: " << *NewShuffle << "\n");
4074 replaceValue(*Shuffle, *NewShuffle);
4075 return true;
4076 }
4077
4078 // See if we can re-use foldSelectShuffle, getting it to reduce the size of
4079 // the shuffle into a nicer order, as it can ignore the order of the shuffles.
4080 MadeChanges |= foldSelectShuffle(*Shuffle, true);
4081 return MadeChanges;
4082}
4083
4084/// Try to fold a chain of shuffles and ops feeding extractelement(..., 0)
4085/// into llvm.vector.reduce.*, by tracking which lanes contribute to the
4086/// extracted lane and reducing the widest vector whose lanes each contribute
4087/// once.
4088///
4089/// For example:
4090///
4091/// %lo = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 0, i32 1>
4092/// %hi = shufflevector <4 x i32> %a, poison, <2 x i32> <i32 2, i32 3>
4093/// %s = add <2 x i32> %lo, %hi
4094/// %sh = shufflevector <2 x i32> %s, poison, <2 x i32> <i32 1, i32 poison>
4095/// %r = add <2 x i32> %s, %sh
4096/// %e = extractelement <2 x i32> %r, i64 0
4097///
4098/// transforms to:
4099///
4100/// %e = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
4101bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
4102 Value *VecOpEE;
4103 if (!match(&I, m_ExtractElt(m_Value(VecOpEE), m_Zero())))
4104 return false;
4105
4106 auto *FVT = dyn_cast<FixedVectorType>(VecOpEE->getType());
4107 if (!FVT)
4108 return false;
4109
4110 if (FVT->getNumElements() < 2)
4111 return false;
4112
4113 std::optional<Instruction::BinaryOps> CommonBinOp;
4114 std::optional<Intrinsic::ID> CommonCallOp;
4115
4116 if (auto *BO = dyn_cast<BinaryOperator>(VecOpEE)) {
4117 if (!getReductionForBinop(BO->getOpcode()))
4118 return false;
4119 CommonBinOp = BO->getOpcode();
4120 } else if (auto *MMI = dyn_cast<MinMaxIntrinsic>(VecOpEE)) {
4121 CommonCallOp = MMI->getIntrinsicID();
4122 } else {
4123 return false;
4124 }
4125
4126 // For floating-point reductions, track FMF intersection across all binops.
4127 FastMathFlags CommonFMF;
4128 bool IsFloatReduction = false;
4129
4130 // A chain node is one we walk through, either a matching-opcode binop/min-max
4131 // or a single-source shuffle. Anything else is a leaf source.
4132 auto IsChainNode = [&](Value *V) {
4133 if (auto *BO = dyn_cast<BinaryOperator>(V))
4134 return CommonBinOp && BO->getOpcode() == *CommonBinOp;
4135 if (auto *MMI = dyn_cast<MinMaxIntrinsic>(V))
4136 return CommonCallOp && MMI->getIntrinsicID() == *CommonCallOp;
4137 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V))
4138 return isa<PoisonValue>(SVI->getOperand(1));
4139 return false;
4140 };
4141
4142 // Collect the chain, building Nodes in postorder. Bail if the chain is empty
4143 // or exceeds MaxChainNodes.
4144 constexpr unsigned MaxChainNodes = 32;
4145 SmallSetVector<Value *, 16> Nodes;
4146 SmallSetVector<Value *, 4> Sources;
4147 unsigned NumVisited = 0;
4148 auto AddSource = [&](Value *V) {
4149 if (!isa<FixedVectorType>(V->getType()))
4150 return false;
4151 Sources.insert(V);
4152 return true;
4153 };
4154 auto Walk = [&](Value *V, auto &&Walk) -> bool {
4155 if (Nodes.contains(V) || Sources.contains(V))
4156 return true;
4157 if (++NumVisited > MaxChainNodes)
4158 return false;
4159 if (!IsChainNode(V))
4160 return AddSource(V);
4161 // Chain shuffles always have poison as op1, so only op0 matters.
4162 auto *U = cast<Instruction>(V);
4163 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4164 for (unsigned I = 0; I != NumOps; ++I)
4165 if (!Walk(U->getOperand(I), Walk))
4166 return false;
4167 if (isa<ShuffleVectorInst>(U) || Nodes.contains(U->getOperand(0)) ||
4168 Nodes.contains(U->getOperand(1))) {
4169 Nodes.insert(V);
4170 return true;
4171 }
4172 // Both operands are leaves so treat this binop as a source rather than
4173 // walking into it.
4174 return AddSource(V);
4175 };
4176 if (!Walk(VecOpEE, Walk) || Nodes.empty())
4177 return false;
4178
4179 bool IsIdempotent =
4180 CommonCallOp || (CommonBinOp && Instruction::isIdempotent(*CommonBinOp));
4181
4182 // For FP reductions, require reassoc on every binop and collect FMF.
4183 for (Value *V : Nodes) {
4184 auto *BinOp = dyn_cast<BinaryOperator>(V);
4185 if (!BinOp || !BinOp->getType()->isFPOrFPVectorTy())
4186 continue;
4187 if (!BinOp->hasAllowReassoc())
4188 return false;
4189 if (!IsFloatReduction) {
4190 CommonFMF = BinOp->getFastMathFlags();
4191 IsFloatReduction = true;
4192 } else {
4193 CommonFMF &= BinOp->getFastMathFlags();
4194 }
4195 }
4196
4197 // Top-down demanded elements. For each chain value, track which lanes feed
4198 // the extracted lane 0 and which feed it more than once. Reverse postorder
4199 // visits every use before its value. A binop forwards its demand to both
4200 // operands and a shuffle follows its mask back to the source lane.
4201 struct Demand {
4202 APInt Lanes;
4203 APInt Duplicates;
4204 };
4205 DenseMap<Value *, Demand> Demands;
4206 auto DemandOf = [&](Value *V) -> Demand & {
4207 unsigned N = cast<FixedVectorType>(V->getType())->getNumElements();
4208 Demand &D = Demands[V];
4209 if (D.Lanes.getBitWidth() != N)
4210 D.Lanes = D.Duplicates = APInt::getZero(N);
4211 return D;
4212 };
4213 DemandOf(VecOpEE).Lanes.setBit(0);
4214 for (Value *V : reverse(Nodes)) {
4215 Demand DV = Demands.lookup(V);
4216 if (DV.Lanes.isZero())
4217 continue;
4218 if (auto *SVI = dyn_cast<ShuffleVectorInst>(V)) {
4219 ArrayRef<int> Mask = SVI->getShuffleMask();
4220 Demand &DS = DemandOf(SVI->getOperand(0));
4221 for (unsigned I = 0, E = Mask.size(); I != E; ++I) {
4222 // Skip lanes that are undemanded or map to poison.
4223 if (!DV.Lanes[I] || Mask[I] < 0 ||
4224 (unsigned)Mask[I] >= DS.Lanes.getBitWidth())
4225 continue;
4226 if (DS.Lanes[Mask[I]] || DV.Duplicates[I])
4227 DS.Duplicates.setBit(Mask[I]);
4228 DS.Lanes.setBit(Mask[I]);
4229 }
4230 } else {
4231 auto *U = cast<User>(V);
4232 for (Value *Op : {U->getOperand(0), U->getOperand(1)}) {
4233 Demand &DOp = DemandOf(Op);
4234 // Lanes demanded through more than one path accumulate in Duplicates.
4235 DOp.Duplicates |= DV.Duplicates | (DOp.Lanes & DV.Lanes);
4236 DOp.Lanes |= DV.Lanes;
4237 }
4238 }
4239 }
4240
4241 // Reducing V replaces the entire chain, so every contribution to the result
4242 // must flow through V. Reject if anything above V reads outside the chain.
4243 auto CoversChain = [&](Value *V) {
4244 SmallVector<Value *, 8> Worklist(1, VecOpEE);
4245 SmallPtrSet<Value *, 8> Seen;
4246 Seen.insert(VecOpEE);
4247 while (!Worklist.empty()) {
4248 auto *U = cast<Instruction>(Worklist.pop_back_val());
4249 unsigned NumOps = isa<ShuffleVectorInst>(U) ? 1 : 2;
4250 for (unsigned I = 0; I != NumOps; ++I) {
4251 Value *Op = U->getOperand(I);
4252 if (Op == V || !Seen.insert(Op).second)
4253 continue;
4254 if (!Nodes.contains(Op))
4255 return false;
4256 Worklist.push_back(Op);
4257 }
4258 }
4259 return true;
4260 };
4261
4262 // Reduce a single cleanly demanded source if there is one, otherwise the
4263 // deepest intermediate that covers the chain.
4264 struct ReductionCut {
4265 Value *Src;
4266 APInt Elts;
4267 };
4268 std::optional<ReductionCut> Cut;
4269 for (Value *S : Sources) {
4270 auto It = Demands.find(S);
4271 if (It == Demands.end() || It->second.Lanes.isZero())
4272 continue;
4273 if (!IsIdempotent && !It->second.Duplicates.isZero()) {
4274 Cut.reset();
4275 break;
4276 }
4277 if (!Cut) {
4278 Cut = ReductionCut{S, It->second.Lanes};
4279 continue;
4280 }
4281 if (!isEquivBitcast(Cut->Src, S)) {
4282 Cut.reset();
4283 break;
4284 }
4285 if (!IsIdempotent && !(Cut->Elts & It->second.Lanes).isZero()) {
4286 Cut.reset();
4287 break;
4288 }
4289 Cut->Elts |= It->second.Lanes;
4290 }
4291 if (!Cut) {
4292 for (Value *V : Nodes) {
4294 continue;
4295 auto It = Demands.find(V);
4296 if (It == Demands.end() || !It->second.Lanes.isAllOnes())
4297 continue;
4298 if (!IsIdempotent && !It->second.Duplicates.isZero())
4299 continue;
4300 if (!CoversChain(V))
4301 continue;
4302 Cut = ReductionCut{V, It->second.Lanes};
4303 break;
4304 }
4305 }
4306 // Reducing one lane is just an extract and can refold forever.
4307 if (!Cut || Cut->Elts.popcount() < 2)
4308 return false;
4309
4310 Intrinsic::ID ReducedOp =
4311 (CommonCallOp ? getMinMaxReductionIntrinsicID(*CommonCallOp)
4312 : getReductionForBinop(*CommonBinOp));
4313 if (!ReducedOp)
4314 return false;
4315
4316 InstructionCost OrigCost = 0;
4317 for (Value *V : Nodes)
4319
4320 auto *SrcVT = cast<FixedVectorType>(Cut->Src->getType());
4321 bool IsPartialReduction = !Cut->Elts.isAllOnes();
4322 FixedVectorType *ReduceVecTy =
4323 IsPartialReduction
4324 ? FixedVectorType::get(FVT->getElementType(), Cut->Elts.popcount())
4325 : SrcVT;
4326
4327 SmallVector<int> ExtractMask;
4328 InstructionCost NewCost = 0;
4329 if (IsPartialReduction) {
4330 for (unsigned I = 0, E = Cut->Elts.getBitWidth(); I != E; ++I)
4331 if (Cut->Elts[I])
4332 ExtractMask.push_back(I);
4333 unsigned SubIdx = 0, SubLen;
4334 auto SK = Cut->Elts.isShiftedMask(SubIdx, SubLen)
4337 NewCost += TTI.getShuffleCost(SK, ReduceVecTy, SrcVT, ExtractMask, CostKind,
4338 SubIdx, ReduceVecTy);
4339 }
4340
4341 IntrinsicCostAttributes ICA(
4342 ReducedOp, ReduceVecTy->getElementType(),
4343 IsFloatReduction
4344 ? SmallVector<Type *, 2>{ReduceVecTy->getElementType(), ReduceVecTy}
4345 : SmallVector<Type *, 2>{ReduceVecTy},
4346 IsFloatReduction ? CommonFMF : FastMathFlags());
4347 NewCost += TTI.getIntrinsicInstrCost(ICA, CostKind);
4348
4349 LLVM_DEBUG(dbgs() << "Found reduction shuffle chain: " << I << "\n OldCost : "
4350 << OrigCost << " vs NewCost: " << NewCost << "\n");
4351
4352 if (!OrigCost.isValid() || !NewCost.isValid())
4353 return false;
4354
4355 if (VecOpEE->hasOneUse() ? (NewCost > OrigCost) : (NewCost >= OrigCost))
4356 return false;
4357
4358 Value *ReduceInput = Cut->Src;
4359 if (IsPartialReduction)
4360 ReduceInput = Builder.CreateShuffleVector(Cut->Src, ExtractMask);
4361
4362 Value *ReducedResult;
4363 if (IsFloatReduction) {
4365 *CommonBinOp, ReduceVecTy->getElementType(), /*AllowRHSConstant=*/false,
4366 CommonFMF.noSignedZeros());
4367 ReducedResult = Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy},
4368 {Identity, ReduceInput}, CommonFMF);
4369 } else {
4370 ReducedResult =
4371 Builder.CreateIntrinsic(ReducedOp, {ReduceVecTy}, {ReduceInput});
4372 }
4373 replaceValue(I, *ReducedResult);
4374
4375 return true;
4376}
4377
4378/// Determine if its more efficient to fold:
4379/// reduce(trunc(x)) -> trunc(reduce(x)).
4380/// reduce(sext(x)) -> sext(reduce(x)).
4381/// reduce(zext(x)) -> zext(reduce(x)).
4382bool VectorCombine::foldCastFromReductions(Instruction &I) {
4383 auto *II = dyn_cast<IntrinsicInst>(&I);
4384 if (!II)
4385 return false;
4386
4387 bool TruncOnly = false;
4388 Intrinsic::ID IID = II->getIntrinsicID();
4389 switch (IID) {
4390 case Intrinsic::vector_reduce_add:
4391 case Intrinsic::vector_reduce_mul:
4392 TruncOnly = true;
4393 break;
4394 case Intrinsic::vector_reduce_and:
4395 case Intrinsic::vector_reduce_or:
4396 case Intrinsic::vector_reduce_xor:
4397 break;
4398 default:
4399 return false;
4400 }
4401
4402 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
4403 Value *ReductionSrc = I.getOperand(0);
4404
4405 Value *Src;
4406 if (!match(ReductionSrc, m_OneUse(m_Trunc(m_Value(Src)))) &&
4407 (TruncOnly || !match(ReductionSrc, m_OneUse(m_ZExtOrSExt(m_Value(Src))))))
4408 return false;
4409
4410 auto CastOpc =
4411 (Instruction::CastOps)cast<Instruction>(ReductionSrc)->getOpcode();
4412
4413 auto *SrcTy = cast<VectorType>(Src->getType());
4414 auto *ReductionSrcTy = cast<VectorType>(ReductionSrc->getType());
4415 Type *ResultTy = I.getType();
4416
4418 ReductionOpc, ReductionSrcTy, std::nullopt, CostKind);
4419 OldCost += TTI.getCastInstrCost(CastOpc, ReductionSrcTy, SrcTy,
4421 cast<CastInst>(ReductionSrc));
4422 InstructionCost NewCost =
4423 TTI.getArithmeticReductionCost(ReductionOpc, SrcTy, std::nullopt,
4424 CostKind) +
4425 TTI.getCastInstrCost(CastOpc, ResultTy, ReductionSrcTy->getScalarType(),
4427
4428 if (OldCost <= NewCost || !NewCost.isValid())
4429 return false;
4430
4431 Value *NewReduction = Builder.CreateIntrinsic(SrcTy->getScalarType(),
4432 II->getIntrinsicID(), {Src});
4433 Value *NewCast = Builder.CreateCast(CastOpc, NewReduction, ResultTy);
4434 replaceValue(I, *NewCast);
4435 return true;
4436}
4437
4438/// Fold:
4439/// icmp pred (reduce.{add,or,and,umax,umin}(signbit_extract(x))), C
4440/// into:
4441/// icmp sgt/slt (reduce.{or,umax,and,umin}(x)), -1/0
4442///
4443/// Sign-bit reductions produce values with known semantics:
4444/// - reduce.{or,umax}: 0 if no element is negative, 1 if any is
4445/// - reduce.{and,umin}: 1 if all elements are negative, 0 if any isn't
4446/// - reduce.add: count of negative elements (0 to NumElts)
4447///
4448/// Both lshr and ashr are supported:
4449/// - lshr produces 0 or 1, so reduce.add range is [0, N]
4450/// - ashr produces 0 or -1, so reduce.add range is [-N, 0]
4451///
4452/// The fold generalizes to multiple source vectors combined with the same
4453/// operation as the reduction. For example:
4454/// reduce.or(or(shr A, shr B)) conceptually extends the vector
4455/// For reduce.add, this changes the count to M*N where M is the number of
4456/// source vectors.
4457///
4458/// We transform to a direct sign check on the original vector using
4459/// reduce.{or,umax} or reduce.{and,umin}.
4460///
4461/// In spirit, it's similar to foldSignBitCheck in InstCombine.
4462bool VectorCombine::foldSignBitReductionCmp(Instruction &I) {
4463 CmpPredicate Pred;
4464 IntrinsicInst *ReduceOp;
4465 const APInt *CmpVal;
4466 if (!match(&I,
4467 m_ICmp(Pred, m_OneUse(m_AnyIntrinsic(ReduceOp)), m_APInt(CmpVal))))
4468 return false;
4469
4470 Intrinsic::ID OrigIID = ReduceOp->getIntrinsicID();
4471 switch (OrigIID) {
4472 case Intrinsic::vector_reduce_or:
4473 case Intrinsic::vector_reduce_umax:
4474 case Intrinsic::vector_reduce_and:
4475 case Intrinsic::vector_reduce_umin:
4476 case Intrinsic::vector_reduce_add:
4477 break;
4478 default:
4479 return false;
4480 }
4481
4482 Value *ReductionSrc = ReduceOp->getArgOperand(0);
4483 auto *VecTy = dyn_cast<FixedVectorType>(ReductionSrc->getType());
4484 if (!VecTy)
4485 return false;
4486
4487 unsigned BitWidth = VecTy->getScalarSizeInBits();
4488 if (BitWidth == 1)
4489 return false;
4490
4491 unsigned NumElts = VecTy->getNumElements();
4492
4493 // Determine the expected tree opcode for multi-vector patterns.
4494 // The tree opcode must match the reduction's underlying operation.
4495 //
4496 // TODO: for pairs of equivalent operators, we should match both,
4497 // not only the most common.
4498 Instruction::BinaryOps TreeOpcode;
4499 switch (OrigIID) {
4500 case Intrinsic::vector_reduce_or:
4501 case Intrinsic::vector_reduce_umax:
4502 TreeOpcode = Instruction::Or;
4503 break;
4504 case Intrinsic::vector_reduce_and:
4505 case Intrinsic::vector_reduce_umin:
4506 TreeOpcode = Instruction::And;
4507 break;
4508 case Intrinsic::vector_reduce_add:
4509 TreeOpcode = Instruction::Add;
4510 break;
4511 default:
4512 llvm_unreachable("Unexpected intrinsic");
4513 }
4514
4515 // Collect sign-bit extraction leaves from an associative tree of TreeOpcode.
4516 // The tree conceptually extends the vector being reduced.
4517 SmallVector<Value *, 8> Worklist;
4518 SmallVector<Value *, 8> Sources; // Original vectors (X in shr X, BW-1)
4519 Worklist.push_back(ReductionSrc);
4520 std::optional<bool> IsAShr;
4521 constexpr unsigned MaxSources = 8;
4522
4523 // Calculate old cost: all shifts + tree ops + reduction
4524 InstructionCost OldCost = TTI.getInstructionCost(ReduceOp, CostKind);
4525
4526 while (!Worklist.empty() && Worklist.size() <= MaxSources &&
4527 Sources.size() <= MaxSources) {
4528 Value *V = Worklist.pop_back_val();
4529
4530 // Try to match sign-bit extraction: shr X, (bitwidth-1)
4531 Value *X;
4532 if (match(V, m_OneUse(m_Shr(m_Value(X), m_SpecificInt(BitWidth - 1))))) {
4533 auto *Shr = cast<Instruction>(V);
4534
4535 // All shifts must be the same type (all lshr or all ashr)
4536 bool ThisIsAShr = Shr->getOpcode() == Instruction::AShr;
4537 if (!IsAShr)
4538 IsAShr = ThisIsAShr;
4539 else if (*IsAShr != ThisIsAShr)
4540 return false;
4541
4542 Sources.push_back(X);
4543
4544 // As part of the fold, we remove all of the shifts, so we need to keep
4545 // track of their costs.
4546 OldCost += TTI.getInstructionCost(Shr, CostKind);
4547
4548 continue;
4549 }
4550
4551 // Try to extend through a tree node of the expected opcode
4552 Value *A, *B;
4553 if (!match(V, m_OneUse(m_BinOp(TreeOpcode, m_Value(A), m_Value(B)))))
4554 return false;
4555
4556 // We are potentially replacing these operations as well, so we add them
4557 // to the costs.
4559
4560 Worklist.push_back(A);
4561 Worklist.push_back(B);
4562 }
4563
4564 // Must have at least one source and not exceed limit
4565 if (Sources.empty() || Sources.size() > MaxSources ||
4566 Worklist.size() > MaxSources || !IsAShr)
4567 return false;
4568
4569 unsigned NumSources = Sources.size();
4570
4571 // For reduce.add, the total count must fit as a signed integer.
4572 // Range is [0, M*N] for lshr or [-M*N, 0] for ashr.
4573 if (OrigIID == Intrinsic::vector_reduce_add &&
4574 !isIntN(BitWidth, NumSources * NumElts))
4575 return false;
4576
4577 // Compute the boundary value when all elements are negative:
4578 // - Per-element contribution: 1 for lshr, -1 for ashr
4579 // - For add: M*N (total elements across all sources); for others: just 1
4580 unsigned Count =
4581 (OrigIID == Intrinsic::vector_reduce_add) ? NumSources * NumElts : 1;
4582 APInt NegativeVal(CmpVal->getBitWidth(), Count);
4583 if (*IsAShr)
4584 NegativeVal.negate();
4585
4586 // Range is [min(0, AllNegVal), max(0, AllNegVal)]
4587 APInt Zero = APInt::getZero(CmpVal->getBitWidth());
4588 APInt RangeLow = APIntOps::smin(Zero, NegativeVal);
4589 APInt RangeHigh = APIntOps::smax(Zero, NegativeVal);
4590
4591 // Determine comparison semantics:
4592 // - IsEq: true for equality test, false for inequality
4593 // - TestsNegative: true if testing against AllNegVal, false for zero
4594 //
4595 // In addition to EQ/NE against 0 or AllNegVal, we support inequalities
4596 // that fold to boundary tests given the narrow value range:
4597 // < RangeHigh -> != RangeHigh
4598 // > RangeHigh-1 -> == RangeHigh
4599 // > RangeLow -> != RangeLow
4600 // < RangeLow+1 -> == RangeLow
4601 //
4602 // For inequalities, we work with signed predicates only. Unsigned predicates
4603 // are canonicalized to signed when the range is non-negative (where they are
4604 // equivalent). When the range includes negative values, unsigned predicates
4605 // would have different semantics due to wrap-around, so we reject them.
4606 if (!ICmpInst::isEquality(Pred) && !ICmpInst::isSigned(Pred)) {
4607 if (RangeLow.isNegative())
4608 return false;
4609 Pred = ICmpInst::getSignedPredicate(Pred);
4610 }
4611
4612 bool IsEq;
4613 bool TestsNegative;
4614 if (ICmpInst::isEquality(Pred)) {
4615 if (CmpVal->isZero()) {
4616 TestsNegative = false;
4617 } else if (*CmpVal == NegativeVal) {
4618 TestsNegative = true;
4619 } else {
4620 return false;
4621 }
4622 IsEq = Pred == ICmpInst::ICMP_EQ;
4623 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeHigh) {
4624 IsEq = false;
4625 TestsNegative = (RangeHigh == NegativeVal);
4626 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeHigh - 1) {
4627 IsEq = true;
4628 TestsNegative = (RangeHigh == NegativeVal);
4629 } else if (Pred == ICmpInst::ICMP_SGT && *CmpVal == RangeLow) {
4630 IsEq = false;
4631 TestsNegative = (RangeLow == NegativeVal);
4632 } else if (Pred == ICmpInst::ICMP_SLT && *CmpVal == RangeLow + 1) {
4633 IsEq = true;
4634 TestsNegative = (RangeLow == NegativeVal);
4635 } else {
4636 return false;
4637 }
4638
4639 // For this fold we support four types of checks:
4640 //
4641 // 1. All lanes are negative - AllNeg
4642 // 2. All lanes are non-negative - AllNonNeg
4643 // 3. At least one negative lane - AnyNeg
4644 // 4. At least one non-negative lane - AnyNonNeg
4645 //
4646 // For each case, we can generate the following code:
4647 //
4648 // 1. AllNeg - reduce.and/umin(X) < 0
4649 // 2. AllNonNeg - reduce.or/umax(X) > -1
4650 // 3. AnyNeg - reduce.or/umax(X) < 0
4651 // 4. AnyNonNeg - reduce.and/umin(X) > -1
4652 //
4653 // The table below shows the aggregation of all supported cases
4654 // using these four cases.
4655 //
4656 // Reduction | == 0 | != 0 | == MAX | != MAX
4657 // ------------+-----------+-----------+-----------+-----------
4658 // or/umax | AllNonNeg | AnyNeg | AnyNeg | AllNonNeg
4659 // and/umin | AnyNonNeg | AllNeg | AllNeg | AnyNonNeg
4660 // add | AllNonNeg | AnyNeg | AllNeg | AnyNonNeg
4661 //
4662 // NOTE: MAX = 1 for or/and/umax/umin, and the vector size N for add
4663 //
4664 // For easier codegen and check inversion, we use the following encoding:
4665 //
4666 // 1. Bit-3 === requires or/umax (1) or and/umin (0) check
4667 // 2. Bit-2 === checks < 0 (1) or > -1 (0)
4668 // 3. Bit-1 === universal (1) or existential (0) check
4669 //
4670 // AnyNeg = 0b110: uses or/umax, checks negative, any-check
4671 // AllNonNeg = 0b101: uses or/umax, checks non-neg, all-check
4672 // AnyNonNeg = 0b000: uses and/umin, checks non-neg, any-check
4673 // AllNeg = 0b011: uses and/umin, checks negative, all-check
4674 //
4675 // XOR with 0b011 inverts the check (swaps all/any and neg/non-neg).
4676 //
4677 enum CheckKind : unsigned {
4678 AnyNonNeg = 0b000,
4679 AllNeg = 0b011,
4680 AllNonNeg = 0b101,
4681 AnyNeg = 0b110,
4682 };
4683 // Return true if we fold this check into or/umax and false for and/umin
4684 auto RequiresOr = [](CheckKind C) -> bool { return C & 0b100; };
4685 // Return true if we should check if result is negative and false otherwise
4686 auto IsNegativeCheck = [](CheckKind C) -> bool { return C & 0b010; };
4687 // Logically invert the check
4688 auto Invert = [](CheckKind C) { return CheckKind(C ^ 0b011); };
4689
4690 CheckKind Base;
4691 switch (OrigIID) {
4692 case Intrinsic::vector_reduce_or:
4693 case Intrinsic::vector_reduce_umax:
4694 Base = TestsNegative ? AnyNeg : AllNonNeg;
4695 break;
4696 case Intrinsic::vector_reduce_and:
4697 case Intrinsic::vector_reduce_umin:
4698 Base = TestsNegative ? AllNeg : AnyNonNeg;
4699 break;
4700 case Intrinsic::vector_reduce_add:
4701 Base = TestsNegative ? AllNeg : AllNonNeg;
4702 break;
4703 default:
4704 llvm_unreachable("Unexpected intrinsic");
4705 }
4706
4707 CheckKind Check = IsEq ? Base : Invert(Base);
4708
4709 auto PickCheaper = [&](Intrinsic::ID Arith, Intrinsic::ID MinMax) {
4710 InstructionCost ArithCost =
4712 VecTy, std::nullopt, CostKind);
4713 InstructionCost MinMaxCost =
4715 FastMathFlags(), CostKind);
4716 return ArithCost <= MinMaxCost ? std::make_pair(Arith, ArithCost)
4717 : std::make_pair(MinMax, MinMaxCost);
4718 };
4719
4720 // Choose output reduction based on encoding's MSB
4721 auto [NewIID, NewCost] = RequiresOr(Check)
4722 ? PickCheaper(Intrinsic::vector_reduce_or,
4723 Intrinsic::vector_reduce_umax)
4724 : PickCheaper(Intrinsic::vector_reduce_and,
4725 Intrinsic::vector_reduce_umin);
4726
4727 // Add cost of combining multiple sources with or/and
4728 if (NumSources > 1) {
4729 unsigned CombineOpc =
4730 RequiresOr(Check) ? Instruction::Or : Instruction::And;
4731 NewCost += TTI.getArithmeticInstrCost(CombineOpc, VecTy, CostKind) *
4732 (NumSources - 1);
4733 }
4734
4735 LLVM_DEBUG(dbgs() << "Found sign-bit reduction cmp: " << I << "\n OldCost: "
4736 << OldCost << " vs NewCost: " << NewCost << "\n");
4737
4738 if (NewCost > OldCost)
4739 return false;
4740
4741 // Generate the combined input and reduction
4742 Builder.SetInsertPoint(&I);
4743 Type *ScalarTy = VecTy->getScalarType();
4744
4745 Value *Input;
4746 if (NumSources == 1) {
4747 Input = Sources[0];
4748 } else {
4749 // Combine sources with or/and based on check type
4750 Input = RequiresOr(Check) ? Builder.CreateOr(Sources)
4751 : Builder.CreateAnd(Sources);
4752 }
4753
4754 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, NewIID, {Input});
4755 Value *NewCmp = IsNegativeCheck(Check) ? Builder.CreateIsNeg(NewReduce)
4756 : Builder.CreateIsNotNeg(NewReduce);
4757 replaceValue(I, *NewCmp);
4758 return true;
4759}
4760
4761/// Fold a zero test of reduce.or or reduce.umax into a boolean reduction.
4762///
4763/// Vectorization may produce IR that compares the result of a scalar reduction
4764/// with zero. Depending on the target, lowering a reduction and a scalar
4765/// comparison separately can cost more than reducing lane-wise comparison
4766/// results. This fold creates the latter form only when it is not costlier.
4767///
4768/// Before:
4769/// %r = call iT @llvm.vector.reduce.or.vNiT(<N x iT> %x)
4770/// %cmp = icmp ne iT %r, 0
4771///
4772/// After:
4773/// %lane.cmp = icmp ne <N x iT> %x, zeroinitializer
4774/// %cmp = call i1 @llvm.vector.reduce.or.vNi1(<N x i1> %lane.cmp)
4775///
4776/// `reduce.or` and `reduce.umax` are non-zero when at least one lane is
4777/// non-zero. Therefore, `icmp ne` uses the existential `reduce.or` test.
4778/// Conversely, `icmp eq` must check that every lane is zero, so it uses the
4779/// universal `reduce.and` test.
4780///
4781/// Before:
4782/// %r = call iT @llvm.vector.reduce.umax.vNiT(<N x iT> %x)
4783/// %cmp = icmp eq iT %r, 0
4784///
4785/// After:
4786/// %lane.cmp = icmp eq <N x iT> %x, zeroinitializer
4787/// %cmp = call i1 @llvm.vector.reduce.and.vNi1(<N x i1> %lane.cmp)
4788bool VectorCombine::foldReductionZeroTest(Instruction &I) {
4789 CmpPredicate Pred;
4790 Value *Op;
4791
4792 if (!match(&I, m_c_ICmp(Pred, m_Value(Op), m_Zero())) ||
4793 !ICmpInst::isEquality(Pred))
4794 return false;
4795
4796 auto *II = dyn_cast<IntrinsicInst>(Op);
4797 if (!II || !II->hasOneUse())
4798 return false;
4799
4800 auto ReduceID = II->getIntrinsicID();
4801 if (ReduceID != Intrinsic::vector_reduce_or &&
4802 ReduceID != Intrinsic::vector_reduce_umax)
4803 return false;
4804
4805 Value *Vec = II->getArgOperand(0);
4806 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
4807 if (!VecTy || !VecTy->getElementType()->isIntegerTy())
4808 return false;
4809
4810 // Map the scalar zero test to an any-lane or all-lane boolean reduction.
4811 Intrinsic::ID NewIID = (Pred == ICmpInst::ICMP_NE)
4812 ? Intrinsic::vector_reduce_or
4813 : Intrinsic::vector_reduce_and;
4814
4815 // This is not an unconditional canonicalization: compare the cost of the
4816 // original scalar reduction and compare with the vector compare and i1
4817 // reduction replacement for both reduce.or and reduce.umax.
4820
4821 auto *CmpTy = cast<VectorType>(CmpInst::makeCmpResultType(VecTy));
4822 InstructionCost NewCost =
4823 TTI.getCmpSelInstrCost(Instruction::ICmp, VecTy, CmpTy, Pred, CostKind);
4825 getArithmeticReductionInstruction(NewIID), CmpTy, std::nullopt, CostKind);
4826
4827 LLVM_DEBUG(dbgs() << "Found a reduction zero test: " << I << "\n OldCost: "
4828 << OldCost << " vs NewCost: " << NewCost << "\n");
4829
4830 if (!OldCost.isValid() || !NewCost.isValid() || NewCost > OldCost)
4831 return false;
4832
4833 Builder.SetInsertPoint(&I);
4834 Value *NewCmp = Builder.CreateICmp(Pred, Vec, Constant::getNullValue(VecTy));
4835 Value *NewReduce = Builder.CreateIntrinsic(NewIID, {CmpTy}, {NewCmp});
4836 replaceValue(I, *NewReduce);
4837 return true;
4838}
4839
4840/// vector.reduce.OP f(X_i) == 0 -> vector.reduce.OP X_i == 0
4841///
4842/// We can prove it for cases when:
4843///
4844/// 1. OP X_i == 0 <=> \forall i \in [1, N] X_i == 0
4845/// 1'. OP X_i == 0 <=> \exists j \in [1, N] X_j == 0
4846/// 2. f(x) == 0 <=> x == 0
4847///
4848/// From 1 and 2 (or 1' and 2), we can infer that
4849///
4850/// OP f(X_i) == 0 <=> OP X_i == 0.
4851///
4852/// (1)
4853/// OP f(X_i) == 0 <=> \forall i \in [1, N] f(X_i) == 0
4854/// (2)
4855/// <=> \forall i \in [1, N] X_i == 0
4856/// (1)
4857/// <=> OP(X_i) == 0
4858///
4859/// For some of the OP's and f's, we need to have domain constraints on X
4860/// to ensure properties 1 (or 1') and 2.
4861bool VectorCombine::foldICmpEqZeroVectorReduce(Instruction &I) {
4862 CmpPredicate Pred;
4863 Value *Op;
4864 if (!match(&I, m_ICmp(Pred, m_Value(Op), m_Zero())) ||
4865 !ICmpInst::isEquality(Pred))
4866 return false;
4867
4868 auto *II = dyn_cast<IntrinsicInst>(Op);
4869 if (!II)
4870 return false;
4871
4872 switch (II->getIntrinsicID()) {
4873 case Intrinsic::vector_reduce_add:
4874 case Intrinsic::vector_reduce_or:
4875 case Intrinsic::vector_reduce_umin:
4876 case Intrinsic::vector_reduce_umax:
4877 case Intrinsic::vector_reduce_smin:
4878 case Intrinsic::vector_reduce_smax:
4879 break;
4880 default:
4881 return false;
4882 }
4883
4884 Value *InnerOp = II->getArgOperand(0);
4885
4886 // TODO: fixed vector type might be too restrictive
4887 if (!II->hasOneUse() || !isa<FixedVectorType>(InnerOp->getType()))
4888 return false;
4889
4890 Value *X = nullptr;
4891
4892 // Check for zero-preserving operations where f(x) = 0 <=> x = 0
4893 //
4894 // 1. f(x) = shl nuw x, y for arbitrary y
4895 // 2. f(x) = mul nuw x, c for defined c != 0
4896 // 3. f(x) = zext x
4897 // 4. f(x) = sext x
4898 // 5. f(x) = neg x
4899 //
4900 if (!(match(InnerOp, m_NUWShl(m_Value(X), m_Value())) || // Case 1
4901 match(InnerOp, m_NUWMul(m_Value(X), m_NonZeroInt())) || // Case 2
4902 match(InnerOp, m_ZExt(m_Value(X))) || // Case 3
4903 match(InnerOp, m_SExt(m_Value(X))) || // Case 4
4904 match(InnerOp, m_Neg(m_Value(X))) // Case 5
4905 ))
4906 return false;
4907
4908 SimplifyQuery S = SQ.getWithInstruction(&I);
4909 auto *XTy = cast<FixedVectorType>(X->getType());
4910
4911 // Check for domain constraints for all supported reductions.
4912 //
4913 // a. OR X_i - has property 1 for every X
4914 // b. UMAX X_i - has property 1 for every X
4915 // c. UMIN X_i - has property 1' for every X
4916 // d. SMAX X_i - has property 1 for X >= 0
4917 // e. SMIN X_i - has property 1' for X >= 0
4918 // f. ADD X_i - has property 1 for X >= 0 && ADD X_i doesn't sign wrap
4919 //
4920 // In order for the proof to work, we need 1 (or 1') to be true for both
4921 // OP f(X_i) and OP X_i and that's why below we check constraints twice.
4922 //
4923 // NOTE: ADD X_i holds property 1 for a mirror case as well, i.e. when
4924 // X <= 0 && ADD X_i doesn't sign wrap. However, due to the nature
4925 // of known bits, we can't reasonably hold knowledge of "either 0
4926 // or negative".
4927 switch (II->getIntrinsicID()) {
4928 case Intrinsic::vector_reduce_add: {
4929 // We need to check that both X_i and f(X_i) have enough leading
4930 // zeros to not overflow.
4931 KnownBits KnownX = computeKnownBits(X, S);
4932 KnownBits KnownFX = computeKnownBits(InnerOp, S);
4933 unsigned NumElems = XTy->getNumElements();
4934 // Adding N elements loses at most ceil(log2(N)) leading bits.
4935 unsigned LostBits = Log2_32_Ceil(NumElems);
4936 unsigned LeadingZerosX = KnownX.countMinLeadingZeros();
4937 unsigned LeadingZerosFX = KnownFX.countMinLeadingZeros();
4938 // Need at least one leading zero left after summation to ensure no overflow
4939 if (LeadingZerosX <= LostBits || LeadingZerosFX <= LostBits)
4940 return false;
4941
4942 // We are not checking whether X or f(X) are positive explicitly because
4943 // we implicitly checked for it when we checked if both cases have enough
4944 // leading zeros to not wrap addition.
4945 break;
4946 }
4947 case Intrinsic::vector_reduce_smin:
4948 case Intrinsic::vector_reduce_smax:
4949 // Check whether X >= 0 and f(X) >= 0
4950 if (!isKnownNonNegative(InnerOp, S) || !isKnownNonNegative(X, S))
4951 return false;
4952
4953 break;
4954 default:
4955 break;
4956 };
4957
4958 LLVM_DEBUG(dbgs() << "Found a reduction to 0 comparison with removable op: "
4959 << *II << "\n");
4960
4961 // For zext/sext, check if the transform is profitable using cost model.
4962 // For other operations (shl, mul, neg), we're removing an instruction
4963 // while keeping the same reduction type, so it's always profitable.
4964 if (isa<ZExtInst>(InnerOp) || isa<SExtInst>(InnerOp)) {
4965 auto *FXTy = cast<FixedVectorType>(InnerOp->getType());
4966 Intrinsic::ID IID = II->getIntrinsicID();
4967
4969 cast<CastInst>(InnerOp)->getOpcode(), FXTy, XTy,
4971
4972 InstructionCost OldReduceCost, NewReduceCost;
4973 switch (IID) {
4974 case Intrinsic::vector_reduce_add:
4975 case Intrinsic::vector_reduce_or:
4976 OldReduceCost = TTI.getArithmeticReductionCost(
4977 getArithmeticReductionInstruction(IID), FXTy, std::nullopt, CostKind);
4978 NewReduceCost = TTI.getArithmeticReductionCost(
4979 getArithmeticReductionInstruction(IID), XTy, std::nullopt, CostKind);
4980 break;
4981 case Intrinsic::vector_reduce_umin:
4982 case Intrinsic::vector_reduce_umax:
4983 case Intrinsic::vector_reduce_smin:
4984 case Intrinsic::vector_reduce_smax:
4985 OldReduceCost = TTI.getMinMaxReductionCost(
4986 getMinMaxReductionIntrinsicOp(IID), FXTy, FastMathFlags(), CostKind);
4987 NewReduceCost = TTI.getMinMaxReductionCost(
4988 getMinMaxReductionIntrinsicOp(IID), XTy, FastMathFlags(), CostKind);
4989 break;
4990 default:
4991 llvm_unreachable("Unexpected reduction");
4992 }
4993
4994 InstructionCost OldCost = OldReduceCost + ExtCost;
4995 InstructionCost NewCost =
4996 NewReduceCost + (InnerOp->hasOneUse() ? 0 : ExtCost);
4997
4998 LLVM_DEBUG(dbgs() << "Found a removable extension before reduction: "
4999 << *InnerOp << "\n OldCost: " << OldCost
5000 << " vs NewCost: " << NewCost << "\n");
5001
5002 // We consider transformation to still be potentially beneficial even
5003 // when the costs are the same because we might remove a use from f(X)
5004 // and unlock other optimizations. Equal costs would just mean that we
5005 // didn't make it worse in the worst case.
5006 if (NewCost > OldCost)
5007 return false;
5008 }
5009
5010 // Since we support zext and sext as f, we might change the scalar type
5011 // of the intrinsic.
5012 Type *Ty = XTy->getScalarType();
5013 Value *NewReduce = Builder.CreateIntrinsic(Ty, II->getIntrinsicID(), {X});
5014 Value *NewCmp =
5015 Builder.CreateICmp(Pred, NewReduce, ConstantInt::getNullValue(Ty));
5016 replaceValue(I, *NewCmp);
5017 return true;
5018}
5019
5020/// Fold comparisons of reduce.or/reduce.and with reduce.umax/reduce.umin
5021/// based on cost, preserving the comparison semantics.
5022///
5023/// We use two fundamental properties for each pair:
5024///
5025/// 1. or(X) == 0 <=> umax(X) == 0
5026/// 2. or(X) == 1 <=> umax(X) == 1
5027/// 3. sign(or(X)) == sign(umax(X))
5028///
5029/// 1. and(X) == -1 <=> umin(X) == -1
5030/// 2. and(X) == -2 <=> umin(X) == -2
5031/// 3. sign(and(X)) == sign(umin(X))
5032///
5033/// From these we can infer the following transformations:
5034/// a. or(X) ==/!= 0 <-> umax(X) ==/!= 0
5035/// b. or(X) s< 0 <-> umax(X) s< 0
5036/// c. or(X) s> -1 <-> umax(X) s> -1
5037/// d. or(X) s< 1 <-> umax(X) s< 1
5038/// e. or(X) ==/!= 1 <-> umax(X) ==/!= 1
5039/// f. or(X) s< 2 <-> umax(X) s< 2
5040/// g. and(X) ==/!= -1 <-> umin(X) ==/!= -1
5041/// h. and(X) s< 0 <-> umin(X) s< 0
5042/// i. and(X) s> -1 <-> umin(X) s> -1
5043/// j. and(X) s> -2 <-> umin(X) s> -2
5044/// k. and(X) ==/!= -2 <-> umin(X) ==/!= -2
5045/// l. and(X) s> -3 <-> umin(X) s> -3
5046///
5047bool VectorCombine::foldEquivalentReductionCmp(Instruction &I) {
5048 CmpPredicate Pred;
5049 Value *ReduceOp;
5050 const APInt *CmpVal;
5051 if (!match(&I, m_ICmp(Pred, m_Value(ReduceOp), m_APInt(CmpVal))))
5052 return false;
5053
5054 auto *II = dyn_cast<IntrinsicInst>(ReduceOp);
5055 if (!II || !II->hasOneUse())
5056 return false;
5057
5058 const auto IsValidOrUmaxCmp = [&]() {
5059 // or === umax for i1
5060 if (CmpVal->getBitWidth() == 1)
5061 return true;
5062
5063 // Cases a and e
5064 bool IsEquality =
5065 (CmpVal->isZero() || CmpVal->isOne()) && ICmpInst::isEquality(Pred);
5066 // Case c
5067 bool IsPositive = CmpVal->isAllOnes() && Pred == ICmpInst::ICMP_SGT;
5068 // Cases b, d, and f
5069 bool IsNegative = (CmpVal->isZero() || CmpVal->isOne() || *CmpVal == 2) &&
5070 Pred == ICmpInst::ICMP_SLT;
5071 return IsEquality || IsPositive || IsNegative;
5072 };
5073
5074 const auto IsValidAndUminCmp = [&]() {
5075 // and === umin for i1
5076 if (CmpVal->getBitWidth() == 1)
5077 return true;
5078
5079 const auto LeadingOnes = CmpVal->countl_one();
5080
5081 // Cases g and k
5082 bool IsEquality =
5083 (CmpVal->isAllOnes() || LeadingOnes + 1 == CmpVal->getBitWidth()) &&
5085 // Case h
5086 bool IsNegative = CmpVal->isZero() && Pred == ICmpInst::ICMP_SLT;
5087 // Cases i, j, and l
5088 bool IsPositive =
5089 // if the number has at least N - 2 leading ones
5090 // and the two LSBs are:
5091 // - 1 x 1 -> -1
5092 // - 1 x 0 -> -2
5093 // - 0 x 1 -> -3
5094 LeadingOnes + 2 >= CmpVal->getBitWidth() &&
5095 ((*CmpVal)[0] || (*CmpVal)[1]) && Pred == ICmpInst::ICMP_SGT;
5096 return IsEquality || IsNegative || IsPositive;
5097 };
5098
5099 Intrinsic::ID OriginalIID = II->getIntrinsicID();
5100 Intrinsic::ID AlternativeIID;
5101
5102 // Check if this is a valid comparison pattern and determine the alternate
5103 // reduction intrinsic.
5104 switch (OriginalIID) {
5105 case Intrinsic::vector_reduce_or:
5106 if (!IsValidOrUmaxCmp())
5107 return false;
5108 AlternativeIID = Intrinsic::vector_reduce_umax;
5109 break;
5110 case Intrinsic::vector_reduce_umax:
5111 if (!IsValidOrUmaxCmp())
5112 return false;
5113 AlternativeIID = Intrinsic::vector_reduce_or;
5114 break;
5115 case Intrinsic::vector_reduce_and:
5116 if (!IsValidAndUminCmp())
5117 return false;
5118 AlternativeIID = Intrinsic::vector_reduce_umin;
5119 break;
5120 case Intrinsic::vector_reduce_umin:
5121 if (!IsValidAndUminCmp())
5122 return false;
5123 AlternativeIID = Intrinsic::vector_reduce_and;
5124 break;
5125 default:
5126 return false;
5127 }
5128
5129 Value *X = II->getArgOperand(0);
5130 auto *VecTy = dyn_cast<FixedVectorType>(X->getType());
5131 if (!VecTy)
5132 return false;
5133
5134 const auto GetReductionCost = [&](Intrinsic::ID IID) -> InstructionCost {
5135 unsigned ReductionOpc = getArithmeticReductionInstruction(IID);
5136 if (ReductionOpc != Instruction::ICmp)
5137 return TTI.getArithmeticReductionCost(ReductionOpc, VecTy, std::nullopt,
5138 CostKind);
5140 FastMathFlags(), CostKind);
5141 };
5142
5143 InstructionCost OrigCost = GetReductionCost(OriginalIID);
5144 InstructionCost AltCost = GetReductionCost(AlternativeIID);
5145
5146 LLVM_DEBUG(dbgs() << "Found equivalent reduction cmp: " << I
5147 << "\n OrigCost: " << OrigCost
5148 << " vs AltCost: " << AltCost << "\n");
5149
5150 if (AltCost >= OrigCost)
5151 return false;
5152
5153 Builder.SetInsertPoint(&I);
5154 Type *ScalarTy = VecTy->getScalarType();
5155 Value *NewReduce = Builder.CreateIntrinsic(ScalarTy, AlternativeIID, {X});
5156 Value *NewCmp =
5157 Builder.CreateICmp(Pred, NewReduce, ConstantInt::get(ScalarTy, *CmpVal));
5158
5159 replaceValue(I, *NewCmp);
5160 return true;
5161}
5162
5163/// Used by foldReduceAddCmpZero to check if we can prove that a value is
5164/// non-positive.
5165/// KnownBits cannot see sext <? x i1> as non-positive: each top bit equals a
5166/// single unknown input bit, which a per-bit lattice cannot track. The fold's
5167/// target shape is popcount-style sums of <N x i1> valid/invalid masks (e.g.
5168/// ray-intersection hits) tested for any-hit.
5169/// Previous attempts to approximate the known bits of such expressions were
5170/// using a fully recursive value tracking approach to infer a constant range
5171/// but ultimately turned to be too expensive in compile time.
5172static bool isKnownNonPositive(const Value *V, const SimplifyQuery &SQ,
5173 unsigned Depth = 0) {
5174 constexpr unsigned MaxLocalDepth = 2;
5175 if (Depth > MaxLocalDepth)
5176 return false;
5177
5178 auto NumSignBits = [&](const Value *X) {
5179 return ComputeNumSignBits(X, SQ.DL, SQ.AC, SQ.CxtI, SQ.DT);
5180 };
5181 if (NumSignBits(V) == V->getType()->getScalarSizeInBits())
5182 return true;
5183
5184 Value *A, *B;
5185 if (match(V, m_Add(m_Value(A), m_Value(B))))
5186 return NumSignBits(A) >= 2 && NumSignBits(B) >= 2 &&
5187 isKnownNonPositive(A, SQ, Depth + 1) &&
5188 isKnownNonPositive(B, SQ, Depth + 1);
5189
5190 return computeKnownBits(V, SQ).isNonPositive();
5191}
5192
5193/// Fold (icmp pred (reduce.add X), 0) to (icmp pred' (reduce.or X), 0) when X
5194/// has lanes known to all be non-negative or all non-positive, so that
5195/// sum == 0 iff every lane is 0. Falls back to reduce.umax if reduce.or is
5196/// more expensive on the target.
5197bool VectorCombine::foldReduceAddCmpZero(Instruction &I) {
5198 CmpPredicate Pred;
5199 Value *Vec;
5200 if (!match(&I, m_ICmp(Pred,
5202 m_Value(Vec))),
5203 m_Zero())))
5204 return false;
5205
5206 auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
5207 if (!VecTy || VecTy->getNumElements() < 2)
5208 return false;
5209
5210 SimplifyQuery Q = SQ.getWithInstruction(&I);
5211 bool IsNonNegative = isKnownNonNegative(Vec, Q);
5212 bool IsNonPositive = !IsNonNegative && isKnownNonPositive(Vec, Q);
5213 if (!IsNonNegative && !IsNonPositive)
5214 return false;
5215
5216 // Summing NumElts lanes can consume up to log2(NumElts) sign bits. Require
5217 // strictly more headroom than that so the sum cannot wrap to zero.
5218 unsigned NumElts = VecTy->getNumElements();
5219 unsigned NumSignBits = ComputeNumSignBits(Vec, *DL, SQ.AC, &I, &DT);
5220 if (Log2_32(NumElts) >= NumSignBits)
5221 return false;
5222
5223 ICmpInst::Predicate NewPred;
5224 switch (Pred) {
5225 case ICmpInst::ICMP_EQ:
5226 case ICmpInst::ICMP_ULE:
5227 case ICmpInst::ICMP_SLE:
5228 case ICmpInst::ICMP_SGE:
5229 NewPred = ICmpInst::ICMP_EQ;
5230 break;
5231 case ICmpInst::ICMP_NE:
5232 case ICmpInst::ICMP_UGT:
5233 case ICmpInst::ICMP_SGT:
5234 case ICmpInst::ICMP_SLT:
5235 NewPred = ICmpInst::ICMP_NE;
5236 break;
5237 default:
5238 return false;
5239 }
5240
5241 // SGT and SLE on a non-positive tree, and SLT and SGE on a non-negative
5242 // tree, are tautologies (always true or always false). Leave those to
5243 // InstCombine rather than mapping them here. Remaining signed inequalities
5244 // also need one extra sign bit so the sum cannot flip sign.
5245 if (!IsNonNegative &&
5246 (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE))
5247 return false;
5248 if (!IsNonPositive &&
5249 (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE))
5250 return false;
5251 if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE ||
5252 Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) &&
5253 Log2_32(NumElts) >= NumSignBits - 1)
5254 return false;
5255
5257 Instruction::Add, VecTy, std::nullopt, CostKind);
5259 Instruction::Or, VecTy, std::nullopt, CostKind);
5261 Intrinsic::umax, VecTy, FastMathFlags(), CostKind);
5262 if (!OrCost.isValid() && !UmaxCost.isValid())
5263 return false;
5264 bool UseOr = OrCost.isValid() && (!UmaxCost.isValid() || OrCost <= UmaxCost);
5265 InstructionCost AltCost = UseOr ? OrCost : UmaxCost;
5266 if (AltCost > OrigCost)
5267 return false;
5268
5269 Builder.SetInsertPoint(&I);
5270 Value *NewReduce = UseOr ? Builder.CreateOrReduce(Vec)
5271 : Builder.CreateIntrinsic(
5272 Intrinsic::vector_reduce_umax, {VecTy}, {Vec});
5273 Worklist.pushValue(NewReduce);
5274 Value *NewCmp = Builder.CreateICmp(
5275 NewPred, NewReduce, ConstantInt::getNullValue(VecTy->getScalarType()));
5276 replaceValue(I, *NewCmp);
5277 return true;
5278}
5279
5280/// Returns true if this ShuffleVectorInst eventually feeds into a
5281/// vector reduction intrinsic (e.g., vector_reduce_add) by only following
5282/// chains of shuffles and binary operators (in any combination/order).
5283/// The search does not go deeper than the given Depth.
5285 constexpr unsigned MaxVisited = 32;
5288 bool FoundReduction = false;
5289
5290 WorkList.push_back(SVI);
5291 while (!WorkList.empty()) {
5292 Instruction *I = WorkList.pop_back_val();
5293 for (User *U : I->users()) {
5294 auto *UI = cast<Instruction>(U);
5295 if (!UI || !Visited.insert(UI).second)
5296 continue;
5297 if (Visited.size() > MaxVisited)
5298 return false;
5299 if (auto *II = dyn_cast<IntrinsicInst>(UI)) {
5300 // More than one reduction reached
5301 if (FoundReduction)
5302 return false;
5303 switch (II->getIntrinsicID()) {
5304 case Intrinsic::vector_reduce_add:
5305 case Intrinsic::vector_reduce_mul:
5306 case Intrinsic::vector_reduce_and:
5307 case Intrinsic::vector_reduce_or:
5308 case Intrinsic::vector_reduce_xor:
5309 case Intrinsic::vector_reduce_smin:
5310 case Intrinsic::vector_reduce_smax:
5311 case Intrinsic::vector_reduce_umin:
5312 case Intrinsic::vector_reduce_umax:
5313 FoundReduction = true;
5314 continue;
5315 default:
5316 return false;
5317 }
5318 }
5319
5321 return false;
5322
5323 WorkList.emplace_back(UI);
5324 }
5325 }
5326 return FoundReduction;
5327}
5328
5329/// This method looks for groups of shuffles acting on binops, of the form:
5330/// %x = shuffle ...
5331/// %y = shuffle ...
5332/// %a = binop %x, %y
5333/// %b = binop %x, %y
5334/// shuffle %a, %b, selectmask
5335/// We may, especially if the shuffle is wider than legal, be able to convert
5336/// the shuffle to a form where only parts of a and b need to be computed. On
5337/// architectures with no obvious "select" shuffle, this can reduce the total
5338/// number of operations if the target reports them as cheaper.
5339bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
5340 auto *SVI = cast<ShuffleVectorInst>(&I);
5341 auto *VT = cast<FixedVectorType>(I.getType());
5342 auto *Op0 = dyn_cast<Instruction>(SVI->getOperand(0));
5343 auto *Op1 = dyn_cast<Instruction>(SVI->getOperand(1));
5344 if (!Op0 || !Op1 || Op0 == Op1 || !Op0->isBinaryOp() || !Op1->isBinaryOp() ||
5345 VT != Op0->getType())
5346 return false;
5347
5348 auto *SVI0A = dyn_cast<Instruction>(Op0->getOperand(0));
5349 auto *SVI0B = dyn_cast<Instruction>(Op0->getOperand(1));
5350 auto *SVI1A = dyn_cast<Instruction>(Op1->getOperand(0));
5351 auto *SVI1B = dyn_cast<Instruction>(Op1->getOperand(1));
5352 SmallPtrSet<Instruction *, 4> InputShuffles({SVI0A, SVI0B, SVI1A, SVI1B});
5353 auto checkSVNonOpUses = [&](Instruction *I) {
5354 if (!I || I->getOperand(0)->getType() != VT)
5355 return true;
5356 return any_of(I->users(), [&](User *U) {
5357 return U != Op0 && U != Op1 &&
5358 !(isa<ShuffleVectorInst>(U) &&
5359 (InputShuffles.contains(cast<Instruction>(U)) ||
5360 isInstructionTriviallyDead(cast<Instruction>(U))));
5361 });
5362 };
5363 if (checkSVNonOpUses(SVI0A) || checkSVNonOpUses(SVI0B) ||
5364 checkSVNonOpUses(SVI1A) || checkSVNonOpUses(SVI1B))
5365 return false;
5366
5367 // Collect all the uses that are shuffles that we can transform together. We
5368 // may not have a single shuffle, but a group that can all be transformed
5369 // together profitably.
5371 auto collectShuffles = [&](Instruction *I) {
5372 for (auto *U : I->users()) {
5373 auto *SV = dyn_cast<ShuffleVectorInst>(U);
5374 if (!SV || SV->getType() != VT)
5375 return false;
5376 if ((SV->getOperand(0) != Op0 && SV->getOperand(0) != Op1) ||
5377 (SV->getOperand(1) != Op0 && SV->getOperand(1) != Op1))
5378 return false;
5379 if (!llvm::is_contained(Shuffles, SV))
5380 Shuffles.push_back(SV);
5381 }
5382 return true;
5383 };
5384 if (!collectShuffles(Op0) || !collectShuffles(Op1))
5385 return false;
5386 // From a reduction, we need to be processing a single shuffle, otherwise the
5387 // other uses will not be lane-invariant.
5388 if (FromReduction && Shuffles.size() > 1)
5389 return false;
5390
5391 // Add any shuffle uses for the shuffles we have found, to include them in our
5392 // cost calculations.
5393 if (!FromReduction) {
5394 for (size_t Idx = 0, E = Shuffles.size(); Idx != E; ++Idx) {
5395 for (auto *U : Shuffles[Idx]->users()) {
5396 ShuffleVectorInst *SSV = dyn_cast<ShuffleVectorInst>(U);
5397 if (SSV && isa<UndefValue>(SSV->getOperand(1)) && SSV->getType() == VT)
5398 Shuffles.push_back(SSV);
5399 }
5400 }
5401 }
5402
5403 // For each of the output shuffles, we try to sort all the first vector
5404 // elements to the beginning, followed by the second array elements at the
5405 // end. If the binops are legalized to smaller vectors, this may reduce total
5406 // number of binops. We compute the ReconstructMask mask needed to convert
5407 // back to the original lane order.
5409 SmallVector<SmallVector<int>> OrigReconstructMasks;
5410 int MaxV1Elt = 0, MaxV2Elt = 0;
5411 unsigned NumElts = VT->getNumElements();
5412 for (ShuffleVectorInst *SVN : Shuffles) {
5413 SmallVector<int> Mask;
5414 SVN->getShuffleMask(Mask);
5415
5416 // Check the operands are the same as the original, or reversed (in which
5417 // case we need to commute the mask).
5418 Value *SVOp0 = SVN->getOperand(0);
5419 Value *SVOp1 = SVN->getOperand(1);
5420 if (isa<UndefValue>(SVOp1)) {
5421 auto *SSV = cast<ShuffleVectorInst>(SVOp0);
5422 SVOp0 = SSV->getOperand(0);
5423 SVOp1 = SSV->getOperand(1);
5424 for (int &Elem : Mask) {
5425 if (Elem >= static_cast<int>(SSV->getShuffleMask().size()))
5426 return false;
5427 Elem = Elem < 0 ? Elem : SSV->getMaskValue(Elem);
5428 }
5429 }
5430 if (SVOp0 == Op1 && SVOp1 == Op0) {
5431 std::swap(SVOp0, SVOp1);
5433 }
5434 if (SVOp0 != Op0 || SVOp1 != Op1)
5435 return false;
5436
5437 // Calculate the reconstruction mask for this shuffle, as the mask needed to
5438 // take the packed values from Op0/Op1 and reconstructing to the original
5439 // order.
5440 SmallVector<int> ReconstructMask;
5441 for (unsigned I = 0; I < Mask.size(); I++) {
5442 if (Mask[I] < 0) {
5443 ReconstructMask.push_back(-1);
5444 } else if (Mask[I] < static_cast<int>(NumElts)) {
5445 MaxV1Elt = std::max(MaxV1Elt, Mask[I]);
5446 auto It = find_if(V1, [&](const std::pair<int, int> &A) {
5447 return Mask[I] == A.first;
5448 });
5449 if (It != V1.end())
5450 ReconstructMask.push_back(It - V1.begin());
5451 else {
5452 ReconstructMask.push_back(V1.size());
5453 V1.emplace_back(Mask[I], V1.size());
5454 }
5455 } else {
5456 MaxV2Elt = std::max<int>(MaxV2Elt, Mask[I] - NumElts);
5457 auto It = find_if(V2, [&](const std::pair<int, int> &A) {
5458 return Mask[I] - static_cast<int>(NumElts) == A.first;
5459 });
5460 if (It != V2.end())
5461 ReconstructMask.push_back(NumElts + It - V2.begin());
5462 else {
5463 ReconstructMask.push_back(NumElts + V2.size());
5464 V2.emplace_back(Mask[I] - NumElts, NumElts + V2.size());
5465 }
5466 }
5467 }
5468
5469 // For reductions, we know that the lane ordering out doesn't alter the
5470 // result. In-order can help simplify the shuffle away.
5471 if (FromReduction)
5472 sort(ReconstructMask);
5473 OrigReconstructMasks.push_back(std::move(ReconstructMask));
5474 }
5475
5476 // If the Maximum element used from V1 and V2 are not larger than the new
5477 // vectors, the vectors are already packes and performing the optimization
5478 // again will likely not help any further. This also prevents us from getting
5479 // stuck in a cycle in case the costs do not also rule it out.
5480 if (V1.empty() || V2.empty() ||
5481 (MaxV1Elt == static_cast<int>(V1.size()) - 1 &&
5482 MaxV2Elt == static_cast<int>(V2.size()) - 1))
5483 return false;
5484
5485 // GetBaseMaskValue takes one of the inputs, which may either be a shuffle, a
5486 // shuffle of another shuffle, or not a shuffle (that is treated like a
5487 // identity shuffle).
5488 auto GetBaseMaskValue = [&](Instruction *I, int M) {
5489 auto *SV = dyn_cast<ShuffleVectorInst>(I);
5490 if (!SV)
5491 return M;
5492 if (isa<UndefValue>(SV->getOperand(1)))
5493 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5494 if (InputShuffles.contains(SSV))
5495 return SSV->getMaskValue(SV->getMaskValue(M));
5496 return SV->getMaskValue(M);
5497 };
5498
5499 // Attempt to sort the inputs my ascending mask values to make simpler input
5500 // shuffles and push complex shuffles down to the uses. We sort on the first
5501 // of the two input shuffle orders, to try and get at least one input into a
5502 // nice order.
5503 auto SortBase = [&](Instruction *A, std::pair<int, int> X,
5504 std::pair<int, int> Y) {
5505 int MXA = GetBaseMaskValue(A, X.first);
5506 int MYA = GetBaseMaskValue(A, Y.first);
5507 return MXA < MYA;
5508 };
5509 stable_sort(V1, [&](std::pair<int, int> A, std::pair<int, int> B) {
5510 return SortBase(SVI0A, A, B);
5511 });
5512 stable_sort(V2, [&](std::pair<int, int> A, std::pair<int, int> B) {
5513 return SortBase(SVI1A, A, B);
5514 });
5515 // Calculate our ReconstructMasks from the OrigReconstructMasks and the
5516 // modified order of the input shuffles.
5517 SmallVector<SmallVector<int>> ReconstructMasks;
5518 for (const auto &Mask : OrigReconstructMasks) {
5519 SmallVector<int> ReconstructMask;
5520 for (int M : Mask) {
5521 auto FindIndex = [](const SmallVector<std::pair<int, int>> &V, int M) {
5522 auto It = find_if(V, [M](auto A) { return A.second == M; });
5523 assert(It != V.end() && "Expected all entries in Mask");
5524 return std::distance(V.begin(), It);
5525 };
5526 if (M < 0)
5527 ReconstructMask.push_back(-1);
5528 else if (M < static_cast<int>(NumElts)) {
5529 ReconstructMask.push_back(FindIndex(V1, M));
5530 } else {
5531 ReconstructMask.push_back(NumElts + FindIndex(V2, M));
5532 }
5533 }
5534 ReconstructMasks.push_back(std::move(ReconstructMask));
5535 }
5536
5537 // Calculate the masks needed for the new input shuffles, which get padded
5538 // with undef
5539 SmallVector<int> V1A, V1B, V2A, V2B;
5540 for (unsigned I = 0; I < V1.size(); I++) {
5541 V1A.push_back(GetBaseMaskValue(SVI0A, V1[I].first));
5542 V1B.push_back(GetBaseMaskValue(SVI0B, V1[I].first));
5543 }
5544 for (unsigned I = 0; I < V2.size(); I++) {
5545 V2A.push_back(GetBaseMaskValue(SVI1A, V2[I].first));
5546 V2B.push_back(GetBaseMaskValue(SVI1B, V2[I].first));
5547 }
5548 while (V1A.size() < NumElts) {
5551 }
5552 while (V2A.size() < NumElts) {
5555 }
5556
5557 auto AddShuffleCost = [&](InstructionCost C, Instruction *I) {
5558 auto *SV = dyn_cast<ShuffleVectorInst>(I);
5559 if (!SV)
5560 return C;
5561 return C + TTI.getShuffleCost(isa<UndefValue>(SV->getOperand(1))
5564 VT, VT, SV->getShuffleMask(), CostKind);
5565 };
5566 auto AddShuffleMaskCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5567 return C +
5569 };
5570
5571 unsigned ElementSize = VT->getElementType()->getPrimitiveSizeInBits();
5572 unsigned MaxVectorSize =
5574 unsigned MaxElementsInVector = MaxVectorSize / ElementSize;
5575 if (MaxElementsInVector == 0)
5576 return false;
5577 // When there are multiple shufflevector operations on the same input,
5578 // especially when the vector length is larger than the register size,
5579 // identical shuffle patterns may occur across different groups of elements.
5580 // To avoid overestimating the cost by counting these repeated shuffles more
5581 // than once, we only account for unique shuffle patterns. This adjustment
5582 // prevents inflated costs in the cost model for wide vectors split into
5583 // several register-sized groups.
5584 std::set<SmallVector<int, 4>> UniqueShuffles;
5585 auto AddShuffleMaskAdjustedCost = [&](InstructionCost C, ArrayRef<int> Mask) {
5586 // Compute the cost for performing the shuffle over the full vector.
5587 auto ShuffleCost =
5589 unsigned NumFullVectors = Mask.size() / MaxElementsInVector;
5590 if (NumFullVectors < 2)
5591 return C + ShuffleCost;
5592 SmallVector<int, 4> SubShuffle(MaxElementsInVector);
5593 unsigned NumUniqueGroups = 0;
5594 unsigned NumGroups = Mask.size() / MaxElementsInVector;
5595 // For each group of MaxElementsInVector contiguous elements,
5596 // collect their shuffle pattern and insert into the set of unique patterns.
5597 for (unsigned I = 0; I < NumFullVectors; ++I) {
5598 for (unsigned J = 0; J < MaxElementsInVector; ++J)
5599 SubShuffle[J] = Mask[MaxElementsInVector * I + J];
5600 if (UniqueShuffles.insert(SubShuffle).second)
5601 NumUniqueGroups += 1;
5602 }
5603 return C + ShuffleCost * NumUniqueGroups / NumGroups;
5604 };
5605 auto AddShuffleAdjustedCost = [&](InstructionCost C, Instruction *I) {
5606 auto *SV = dyn_cast<ShuffleVectorInst>(I);
5607 if (!SV)
5608 return C;
5609 SmallVector<int, 16> Mask;
5610 SV->getShuffleMask(Mask);
5611 return AddShuffleMaskAdjustedCost(C, Mask);
5612 };
5613 // Check that input consists of ShuffleVectors applied to the same input
5614 auto AllShufflesHaveSameOperands =
5615 [](SmallPtrSetImpl<Instruction *> &InputShuffles) {
5616 if (InputShuffles.size() < 2)
5617 return false;
5618 ShuffleVectorInst *FirstSV =
5619 dyn_cast<ShuffleVectorInst>(*InputShuffles.begin());
5620 if (!FirstSV)
5621 return false;
5622
5623 Value *In0 = FirstSV->getOperand(0), *In1 = FirstSV->getOperand(1);
5624 return std::all_of(
5625 std::next(InputShuffles.begin()), InputShuffles.end(),
5626 [&](Instruction *I) {
5627 ShuffleVectorInst *SV = dyn_cast<ShuffleVectorInst>(I);
5628 return SV && SV->getOperand(0) == In0 && SV->getOperand(1) == In1;
5629 });
5630 };
5631
5632 // Get the costs of the shuffles + binops before and after with the new
5633 // shuffle masks.
5634 InstructionCost CostBefore =
5635 TTI.getArithmeticInstrCost(Op0->getOpcode(), VT, CostKind) +
5636 TTI.getArithmeticInstrCost(Op1->getOpcode(), VT, CostKind);
5637 CostBefore += std::accumulate(Shuffles.begin(), Shuffles.end(),
5638 InstructionCost(0), AddShuffleCost);
5639 if (AllShufflesHaveSameOperands(InputShuffles)) {
5640 UniqueShuffles.clear();
5641 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5642 InstructionCost(0), AddShuffleAdjustedCost);
5643 } else {
5644 CostBefore += std::accumulate(InputShuffles.begin(), InputShuffles.end(),
5645 InstructionCost(0), AddShuffleCost);
5646 }
5647
5648 // The new binops will be unused for lanes past the used shuffle lengths.
5649 // These types attempt to get the correct cost for that from the target.
5650 FixedVectorType *Op0SmallVT =
5651 FixedVectorType::get(VT->getScalarType(), V1.size());
5652 FixedVectorType *Op1SmallVT =
5653 FixedVectorType::get(VT->getScalarType(), V2.size());
5654 InstructionCost CostAfter =
5655 TTI.getArithmeticInstrCost(Op0->getOpcode(), Op0SmallVT, CostKind) +
5656 TTI.getArithmeticInstrCost(Op1->getOpcode(), Op1SmallVT, CostKind);
5657 UniqueShuffles.clear();
5658 CostAfter += std::accumulate(ReconstructMasks.begin(), ReconstructMasks.end(),
5659 InstructionCost(0), AddShuffleMaskAdjustedCost);
5660 std::set<SmallVector<int>> OutputShuffleMasks({V1A, V1B, V2A, V2B});
5661 CostAfter +=
5662 std::accumulate(OutputShuffleMasks.begin(), OutputShuffleMasks.end(),
5663 InstructionCost(0), AddShuffleMaskCost);
5664
5665 LLVM_DEBUG(dbgs() << "Found a binop select shuffle pattern: " << I << "\n");
5666 LLVM_DEBUG(dbgs() << " CostBefore: " << CostBefore
5667 << " vs CostAfter: " << CostAfter << "\n");
5668 if (CostBefore < CostAfter ||
5669 (CostBefore == CostAfter && !feedsIntoVectorReduction(SVI)))
5670 return false;
5671
5672 // The cost model has passed, create the new instructions.
5673 auto GetShuffleOperand = [&](Instruction *I, unsigned Op) -> Value * {
5674 auto *SV = dyn_cast<ShuffleVectorInst>(I);
5675 if (!SV)
5676 return I;
5677 if (isa<UndefValue>(SV->getOperand(1)))
5678 if (auto *SSV = dyn_cast<ShuffleVectorInst>(SV->getOperand(0)))
5679 if (InputShuffles.contains(SSV))
5680 return SSV->getOperand(Op);
5681 return SV->getOperand(Op);
5682 };
5683 Builder.SetInsertPoint(*SVI0A->getInsertionPointAfterDef());
5684 Value *NSV0A = Builder.CreateShuffleVector(GetShuffleOperand(SVI0A, 0),
5685 GetShuffleOperand(SVI0A, 1), V1A);
5686 Builder.SetInsertPoint(*SVI0B->getInsertionPointAfterDef());
5687 Value *NSV0B = Builder.CreateShuffleVector(GetShuffleOperand(SVI0B, 0),
5688 GetShuffleOperand(SVI0B, 1), V1B);
5689 Builder.SetInsertPoint(*SVI1A->getInsertionPointAfterDef());
5690 Value *NSV1A = Builder.CreateShuffleVector(GetShuffleOperand(SVI1A, 0),
5691 GetShuffleOperand(SVI1A, 1), V2A);
5692 Builder.SetInsertPoint(*SVI1B->getInsertionPointAfterDef());
5693 Value *NSV1B = Builder.CreateShuffleVector(GetShuffleOperand(SVI1B, 0),
5694 GetShuffleOperand(SVI1B, 1), V2B);
5695 Builder.SetInsertPoint(Op0);
5696 Value *NOp0 = Builder.CreateBinOp((Instruction::BinaryOps)Op0->getOpcode(),
5697 NSV0A, NSV0B);
5698 if (auto *I = dyn_cast<Instruction>(NOp0))
5699 I->copyIRFlags(Op0, true);
5700 Builder.SetInsertPoint(Op1);
5701 Value *NOp1 = Builder.CreateBinOp((Instruction::BinaryOps)Op1->getOpcode(),
5702 NSV1A, NSV1B);
5703 if (auto *I = dyn_cast<Instruction>(NOp1))
5704 I->copyIRFlags(Op1, true);
5705
5706 for (int S = 0, E = ReconstructMasks.size(); S != E; S++) {
5707 Builder.SetInsertPoint(Shuffles[S]);
5708 Value *NSV = Builder.CreateShuffleVector(NOp0, NOp1, ReconstructMasks[S]);
5709 replaceValue(*Shuffles[S], *NSV, false);
5710 }
5711
5712 Worklist.pushValue(NSV0A);
5713 Worklist.pushValue(NSV0B);
5714 Worklist.pushValue(NSV1A);
5715 Worklist.pushValue(NSV1B);
5716 return true;
5717}
5718
5719/// Check if instruction depends on ZExt and this ZExt can be moved after the
5720/// instruction. Move ZExt if it is profitable. For example:
5721/// logic(zext(x),y) -> zext(logic(x,trunc(y)))
5722/// lshr((zext(x),y) -> zext(lshr(x,trunc(y)))
5723/// Cost model calculations takes into account if zext(x) has other users and
5724/// whether it can be propagated through them too.
5725bool VectorCombine::shrinkType(Instruction &I) {
5726 Value *ZExted, *OtherOperand;
5727 if (!match(&I, m_c_BitwiseLogic(m_ZExt(m_Value(ZExted)),
5728 m_Value(OtherOperand))) &&
5729 !match(&I, m_LShr(m_ZExt(m_Value(ZExted)), m_Value(OtherOperand))))
5730 return false;
5731
5732 Value *ZExtOperand = I.getOperand(I.getOperand(0) == OtherOperand ? 1 : 0);
5733
5734 auto *BigTy = cast<FixedVectorType>(I.getType());
5735 auto *SmallTy = cast<FixedVectorType>(ZExted->getType());
5736 unsigned BW = SmallTy->getElementType()->getPrimitiveSizeInBits();
5737
5738 if (I.getOpcode() == Instruction::LShr) {
5739 // Check that the shift amount is less than the number of bits in the
5740 // smaller type. Otherwise, the smaller lshr will return a poison value.
5741 KnownBits ShAmtKB = computeKnownBits(I.getOperand(1), *DL);
5742 if (ShAmtKB.getMaxValue().uge(BW))
5743 return false;
5744 } else {
5745 // Check that the expression overall uses at most the same number of bits as
5746 // ZExted
5747 KnownBits KB = computeKnownBits(&I, *DL);
5748 if (KB.countMaxActiveBits() > BW)
5749 return false;
5750 }
5751
5752 // Calculate costs of leaving current IR as it is and moving ZExt operation
5753 // later, along with adding truncates if needed
5755 Instruction::ZExt, BigTy, SmallTy,
5756 TargetTransformInfo::CastContextHint::None, CostKind);
5757 InstructionCost CurrentCost = ZExtCost;
5758 InstructionCost ShrinkCost = 0;
5759
5760 // Calculate total cost and check that we can propagate through all ZExt users
5761 for (User *U : ZExtOperand->users()) {
5762 auto *UI = cast<Instruction>(U);
5763 if (UI == &I) {
5764 CurrentCost +=
5765 TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5766 ShrinkCost +=
5767 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5768 ShrinkCost += ZExtCost;
5769 continue;
5770 }
5771
5772 if (!Instruction::isBinaryOp(UI->getOpcode()))
5773 return false;
5774
5775 // Check if we can propagate ZExt through its other users
5776 KnownBits KB = computeKnownBits(UI, *DL);
5777 if (KB.countMaxActiveBits() > BW)
5778 return false;
5779
5780 CurrentCost += TTI.getArithmeticInstrCost(UI->getOpcode(), BigTy, CostKind);
5781 ShrinkCost +=
5782 TTI.getArithmeticInstrCost(UI->getOpcode(), SmallTy, CostKind);
5783 ShrinkCost += ZExtCost;
5784 }
5785
5786 // If the other instruction operand is not a constant, we'll need to
5787 // generate a truncate instruction. So we have to adjust cost
5788 if (!isa<Constant>(OtherOperand))
5789 ShrinkCost += TTI.getCastInstrCost(
5790 Instruction::Trunc, SmallTy, BigTy,
5791 TargetTransformInfo::CastContextHint::None, CostKind);
5792
5793 // If the cost of shrinking types and leaving the IR is the same, we'll lean
5794 // towards modifying the IR because shrinking opens opportunities for other
5795 // shrinking optimisations.
5796 if (ShrinkCost > CurrentCost)
5797 return false;
5798
5799 Builder.SetInsertPoint(&I);
5800 Value *Op0 = ZExted;
5801 Value *Op1 = Builder.CreateTrunc(OtherOperand, SmallTy);
5802 // Keep the order of operands the same
5803 if (I.getOperand(0) == OtherOperand)
5804 std::swap(Op0, Op1);
5805 Value *NewBinOp =
5806 Builder.CreateBinOp((Instruction::BinaryOps)I.getOpcode(), Op0, Op1);
5807 cast<Instruction>(NewBinOp)->copyIRFlags(&I);
5808 cast<Instruction>(NewBinOp)->copyMetadata(I);
5809 Value *NewZExtr = Builder.CreateZExt(NewBinOp, BigTy);
5810 replaceValue(I, *NewZExtr);
5811 return true;
5812}
5813
5814/// insert (DstVec, (extract SrcVec, ExtIdx), InsIdx) -->
5815/// shuffle (DstVec, SrcVec, Mask)
5816bool VectorCombine::foldInsExtVectorToShuffle(Instruction &I) {
5817 Value *DstVec, *SrcVec;
5818 uint64_t ExtIdx, InsIdx;
5819 if (!match(&I,
5820 m_InsertElt(m_Value(DstVec),
5821 m_ExtractElt(m_Value(SrcVec), m_ConstantInt(ExtIdx)),
5822 m_ConstantInt(InsIdx))))
5823 return false;
5824
5825 auto *DstVecTy = dyn_cast<FixedVectorType>(I.getType());
5826 auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcVec->getType());
5827 // We can try combining vectors with different element sizes.
5828 if (!DstVecTy || !SrcVecTy ||
5829 SrcVecTy->getElementType() != DstVecTy->getElementType())
5830 return false;
5831
5832 unsigned NumDstElts = DstVecTy->getNumElements();
5833 unsigned NumSrcElts = SrcVecTy->getNumElements();
5834 if (InsIdx >= NumDstElts || ExtIdx >= NumSrcElts || NumDstElts == 1)
5835 return false;
5836
5837 // Insertion into poison is a cheaper single operand shuffle.
5839 SmallVector<int> Mask(NumDstElts, PoisonMaskElem);
5840
5841 bool NeedExpOrNarrow = NumSrcElts != NumDstElts;
5842 bool NeedDstSrcSwap = isa<PoisonValue>(DstVec) && !isa<UndefValue>(SrcVec);
5843 if (NeedDstSrcSwap) {
5845 Mask[InsIdx] = ExtIdx % NumDstElts;
5846 std::swap(DstVec, SrcVec);
5847 } else {
5849 std::iota(Mask.begin(), Mask.end(), 0);
5850 Mask[InsIdx] = (ExtIdx % NumDstElts) + NumDstElts;
5851 }
5852
5853 // Cost
5854 auto *Ins = cast<InsertElementInst>(&I);
5855 auto *Ext = cast<ExtractElementInst>(I.getOperand(1));
5856 InstructionCost InsCost =
5857 TTI.getVectorInstrCost(*Ins, DstVecTy, CostKind, InsIdx);
5858 InstructionCost ExtCost =
5859 TTI.getVectorInstrCost(*Ext, DstVecTy, CostKind, ExtIdx);
5860 InstructionCost OldCost = ExtCost + InsCost;
5861
5862 InstructionCost NewCost = 0;
5863 SmallVector<int> ExtToVecMask;
5864 if (!NeedExpOrNarrow) {
5865 // Ignore 'free' identity insertion shuffle.
5866 // TODO: getShuffleCost should return TCC_Free for Identity shuffles.
5867 if (!ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts))
5868 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, Mask, CostKind, 0,
5869 nullptr, {DstVec, SrcVec});
5870 } else {
5871 // When creating a length-changing-vector, always try to keep the relevant
5872 // element in an equivalent position, so that bulk shuffles are more likely
5873 // to be useful.
5874 ExtToVecMask.assign(NumDstElts, PoisonMaskElem);
5875 ExtToVecMask[ExtIdx % NumDstElts] = ExtIdx;
5876 // Add cost for expanding or narrowing
5878 DstVecTy, SrcVecTy, ExtToVecMask, CostKind);
5879 NewCost += TTI.getShuffleCost(SK, DstVecTy, DstVecTy, Mask, CostKind);
5880 }
5881
5882 if (!Ext->hasOneUse())
5883 NewCost += ExtCost;
5884
5885 LLVM_DEBUG(dbgs() << "Found a insert/extract shuffle-like pair: " << I
5886 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
5887 << "\n");
5888
5889 if (OldCost < NewCost)
5890 return false;
5891
5892 if (NeedExpOrNarrow) {
5893 if (!NeedDstSrcSwap)
5894 SrcVec = Builder.CreateShuffleVector(SrcVec, ExtToVecMask);
5895 else
5896 DstVec = Builder.CreateShuffleVector(DstVec, ExtToVecMask);
5897 }
5898
5899 // Canonicalize undef param to RHS to help further folds.
5900 if (isa<UndefValue>(DstVec) && !isa<UndefValue>(SrcVec)) {
5901 ShuffleVectorInst::commuteShuffleMask(Mask, NumDstElts);
5902 std::swap(DstVec, SrcVec);
5903 }
5904
5905 Value *Shuf = Builder.CreateShuffleVector(DstVec, SrcVec, Mask);
5906 replaceValue(I, *Shuf);
5907
5908 return true;
5909}
5910
5911/// If we're interleaving 2 constant splats, for instance `<vscale x 8 x i32>
5912/// <splat of 666>` and `<vscale x 8 x i32> <splat of 777>`, we can create a
5913/// larger splat `<vscale x 8 x i64> <splat of ((777 << 32) | 666)>` first
5914/// before casting it back into `<vscale x 16 x i32>`.
5915bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
5916 const APInt *SplatVal0, *SplatVal1;
5918 m_APInt(SplatVal0), m_APInt(SplatVal1))))
5919 return false;
5920
5921 LLVM_DEBUG(dbgs() << "VC: Folding interleave2 with two splats: " << I
5922 << "\n");
5923
5924 auto *VTy =
5925 cast<VectorType>(cast<IntrinsicInst>(I).getArgOperand(0)->getType());
5926 auto *ExtVTy = VectorType::getExtendedElementVectorType(VTy);
5927 unsigned Width = VTy->getElementType()->getIntegerBitWidth();
5928
5929 // Just in case the cost of interleave2 intrinsic and bitcast are both
5930 // invalid, in which case we want to bail out, we use <= rather
5931 // than < here. Even they both have valid and equal costs, it's probably
5932 // not a good idea to emit a high-cost constant splat.
5934 TTI.getCastInstrCost(Instruction::BitCast, I.getType(), ExtVTy,
5936 LLVM_DEBUG(dbgs() << "VC: The cost to cast from " << *ExtVTy << " to "
5937 << *I.getType() << " is too high.\n");
5938 return false;
5939 }
5940
5941 APInt NewSplatVal = SplatVal1->zext(Width * 2);
5942 NewSplatVal <<= Width;
5943 NewSplatVal |= SplatVal0->zext(Width * 2);
5944 auto *NewSplat = ConstantVector::getSplat(
5945 ExtVTy->getElementCount(), ConstantInt::get(F.getContext(), NewSplatVal));
5946
5947 IRBuilder<> Builder(&I);
5948 replaceValue(I, *Builder.CreateBitCast(NewSplat, I.getType()));
5949 return true;
5950}
5951
5952/// Given this sequence:
5953/// ```
5954/// %d = llvm.vector.deinterleave2 <vscale x 16 x i32> %v
5955/// %f0 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 0
5956/// %f1 = extractvalue { <vscale x 8 x i32>, <vscale x 8 x i32> } %d, 1
5957///
5958/// %low0 = and <vscale x 8 x i32> %f0, splat (i32 65535)
5959/// %low1 = shl <vscale x 8 x i32> %f1, splat (i32 16)
5960/// %merge0 = or disjoint <vscale x 8 x i32> %low0, %low1
5961///
5962/// %high0 = and <vscale x 8 x i32> %f1, splat (i32 -65536)
5963/// %high1 = lshr <vscale x 8 x i32> %f0, splat (i32 16)
5964/// %merge1 = or disjoint <vscale x 8 x i32> %high0, %high1
5965/// ```
5966/// It is actually just de-interleaving a 16-bit vector with double the
5967/// vector length. More generally speaking, it's de-interleaving on a vector
5968/// with half the element width as the original vector.
5969///
5970/// Therefore, we can turn it into:
5971/// ```
5972/// %narrow.v = bitcast <vscale x 16 x i32> %v to <vscale x 32 x i16>
5973/// %d = llvm.vector.deinterleave2 <vscale x 32 x i16> %narrow.v
5974/// %f0 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 0
5975/// %f1 = extractvalue { <vscale x 16 x i16>, <vscale x 16 x i16> } %d, 1
5976///
5977/// %merge0 = bitcast <vscale x 16 x i16> %f0 to <vscale x 8 x i32>
5978/// %merge1 = bitcast <vscale x 16 x i16> %f1 to <vscale x 8 x i32>
5979/// ```
5980bool VectorCombine::foldDeinterleaveIntrinsics(Instruction &I) {
5981 // This pattern involves bitcast that is not compatible with big endian.
5982 if (DL->isBigEndian())
5983 return false;
5984
5985 using namespace PatternMatch;
5986 Value *DeinterleavedVal;
5987 if (!match(&I, m_Deinterleave2(m_Value(DeinterleavedVal))))
5988 return false;
5989
5990 VectorType *VecTy = cast<VectorType>(DeinterleavedVal->getType());
5991 IntegerType *ElementTy = dyn_cast<IntegerType>(VecTy->getElementType());
5992 if (!ElementTy)
5993 return false;
5994 unsigned ElementWidth = ElementTy->getBitWidth();
5995 if (ElementWidth < 2 || !isPowerOf2_32(ElementWidth))
5996 return false;
5997 unsigned HalfElementWidth = ElementWidth / 2;
5998
5999 if (!I.hasNUses(2))
6000 return false;
6001 std::array<ExtractValueInst *, 2> OrigFields{};
6002 for (User *Usr : I.users()) {
6003 auto *E = dyn_cast<ExtractValueInst>(Usr);
6004 // The deinterleave result can only be used by extractions.
6005 if (!E || E->getNumIndices() != 1)
6006 return false;
6007 unsigned Idx = *E->idx_begin();
6008 // A single field cannot be extracted more than once.
6009 if (Idx >= 2 || OrigFields[Idx] || !E->hasNUses(2))
6010 return false;
6011 OrigFields[Idx] = E;
6012 }
6013
6014 // Find the merge instruction (i.e. OR) first.
6015 SmallVector<Instruction *, 2> MergeInsts;
6016 for (auto *FieldUsr : OrigFields[0]->users()) {
6017 if (!FieldUsr->hasOneUse() || !isa<Instruction>(FieldUsr->user_back()))
6018 return false;
6019 MergeInsts.push_back(cast<Instruction>(FieldUsr->user_back()));
6020 }
6021 assert(MergeInsts.size() == 2);
6022
6023 // Pattern match bottom-up from the merge instructions.
6024 auto MatchMerge = [&](void) -> bool {
6025 APInt LoMask = APInt::getLowBitsSet(ElementWidth, HalfElementWidth);
6026 APInt HiMask = APInt::getHighBitsSet(ElementWidth, HalfElementWidth);
6027 return match(MergeInsts[0],
6028 m_c_Or(m_And(m_Specific(OrigFields[0]), m_SpecificInt(LoMask)),
6029 m_Shl(m_Specific(OrigFields[1]),
6030 m_SpecificInt(HalfElementWidth)))) &&
6031 match(MergeInsts[1],
6032 m_c_Or(m_And(m_Specific(OrigFields[1]), m_SpecificInt(HiMask)),
6033 m_LShr(m_Specific(OrigFields[0]),
6034 m_SpecificInt(HalfElementWidth))));
6035 };
6036 if (!MatchMerge()) {
6037 std::swap(MergeInsts[0], MergeInsts[1]);
6038 if (!MatchMerge())
6039 return false;
6040 }
6041
6042 // Profitability check.
6043 InstructionCost OldCost =
6044 TTI.getInstructionCost(MergeInsts[0], CostKind) +
6045 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(0)),
6046 CostKind) +
6047 TTI.getInstructionCost(cast<Instruction>(MergeInsts[0]->getOperand(1)),
6048 CostKind);
6049 // There are two fields (assuming SHL has the same cost as LSHR).
6050 OldCost *= 2;
6051
6052 auto *NewFieldTy = VecTy->getWithNewBitWidth(HalfElementWidth);
6053 auto *NewVecTy =
6054 VectorType::getDoubleElementsVectorType(cast<VectorType>(NewFieldTy));
6055 InstructionCost NewCost =
6056 TTI.getCastInstrCost(Instruction::BitCast, VecTy, NewVecTy,
6058 TTI.getCastInstrCost(Instruction::BitCast, NewFieldTy,
6059 MergeInsts[0]->getType(), TTI::CastContextHint::None,
6060 CostKind) *
6061 2;
6062 if (OldCost <= NewCost || !NewCost.isValid()) {
6063 LLVM_DEBUG(
6064 dbgs() << "VC: New deinterleave2 sequence cost (" << NewCost << ")"
6065 << " is higher than that of the old one (" << OldCost << ")\n");
6066 return false;
6067 }
6068
6069 // Do the replacement.
6070 IRBuilder<> Builder(&I);
6071 Value *NewVecCast = Builder.CreateBitCast(DeinterleavedVal, NewVecTy);
6072 Value *NewDeinterleave = Builder.CreateIntrinsic(
6073 Intrinsic::vector_deinterleave2, {NewVecTy}, {NewVecCast});
6074 for (auto [Idx, MergeInst] : enumerate(MergeInsts)) {
6075 Value *NewField = Builder.CreateExtractValue(NewDeinterleave, Idx);
6076 NewField = Builder.CreateBitCast(NewField, MergeInst->getType());
6077 replaceValue(*MergeInst, *NewField);
6078 }
6079
6080 return true;
6081}
6082
6083bool VectorCombine::foldBitcastOfVPLoad(Instruction &I) {
6084 const DataLayout &DL = I.getDataLayout();
6085 auto *Cast = dyn_cast<CastInst>(&I);
6086 if (!Cast || !Cast->isNoopCast(DL) || !isa<VectorType>(Cast->getDestTy()))
6087 return false;
6088
6089 // Fold away bit casts of the loaded value by loading the desired type,
6090 // if the mask is all-ones.
6091 Value *EVL;
6092 auto *II = dyn_cast<VPIntrinsic>(I.getOperand(0));
6094 m_Value(), m_AllOnes(), m_Value(EVL)))))
6095 return false;
6096
6097 VectorType *OrigVecTy = cast<VectorType>(II->getType());
6098 Align OrigAlign =
6099 DL.getValueOrABITypeAlignment(II->getPointerAlignment(), OrigVecTy);
6100 ElementCount OrigVecCnt = OrigVecTy->getElementCount();
6101 VectorType *NewVecTy = cast<VectorType>(Cast->getDestTy());
6102 ElementCount NewVecCnt = NewVecTy->getElementCount();
6103
6104 // Right now we only support cases where the NewVec is longer, because for
6105 // cases where it's shorter, we have to be sure that EVL can be exactly
6106 // divided, otherwise it might yield incorrect results or even page faults
6107 // (if we round-up during the division).
6108 if (!(OrigVecCnt.isScalable() == NewVecCnt.isScalable() &&
6109 NewVecCnt.hasKnownScalarFactor(OrigVecCnt)))
6110 return false;
6111
6112 InstructionCost OldCost =
6113 TTI.getMemIntrinsicInstrCost({Intrinsic::vp_load, OrigVecTy,
6114 II->getMemoryPointerParam(), false,
6115 OrigAlign},
6116 CostKind) +
6117 TTI.getCastInstrCost(Instruction::BitCast, Cast->getType(), OrigVecTy,
6120 {Intrinsic::vp_load, NewVecTy, II->getMemoryPointerParam(), false,
6121 OrigAlign},
6122 CostKind);
6123 LLVM_DEBUG(dbgs() << "foldBitcastOfVPLoad: OldCost=" << OldCost
6124 << " NewCost=" << NewCost << "\n");
6125 if (NewCost > OldCost || !NewCost.isValid())
6126 return false;
6127
6128 unsigned Factor = NewVecCnt.getKnownScalarFactor(OrigVecCnt);
6129 Value *NewEVL = Builder.CreateNUWMul(EVL, Builder.getInt32(Factor));
6130 Value *NewMask = Builder.CreateVectorSplat(NewVecCnt, Builder.getTrue());
6131 CallInst *NewVP = Builder.CreateIntrinsicWithoutFolding(
6132 NewVecTy, Intrinsic::vp_load,
6133 {II->getMemoryPointerParam(), NewMask, NewEVL});
6134 // Preserve the original alignment.
6135 NewVP->addParamAttrs(
6136 0, AttrBuilder(II->getContext()).addAlignmentAttr(OrigAlign));
6137 replaceValue(*Cast, *NewVP);
6138 return true;
6139}
6140/// Fold the following cases into a single byte-level bit-reverse operation
6141/// and accepts bswap and bitreverse intrinsics:
6142/// bswap(bitreverse(x)) --> bitcast(bitreverse(bitcast(x)))
6143/// bitreverse(bswap(x)) <--> bitcast(bitreverse(bitcast(x)))
6144/// The direction of the fold is cost-model driven.
6145/// Also supports:
6146/// bitcast(bitreverse(bitcast(x))) --> bitreverse(fshl(x))
6147bool VectorCombine::foldBitOrderReverseAndSwap(Instruction &I) {
6148 Value *X;
6149
6151 Type *Ty = X->getType();
6152 Type *VecTy = I.getOperand(0)->getType();
6153 // Detect the case when bitreversing every octet in X individually. Then we
6154 // can use bswap to reorder the octets before doing a single bitreverse.
6155 bool CanUseBswap =
6156 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6157 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy(8) &&
6158 Ty->getIntegerBitWidth() % 16 == 0;
6159 // Detect the case when bitreversing upper and lower half of X
6160 // individually. Then we can use fshl as a rotate operation, to swap the
6161 // halves before doing a single bitreverse.
6162 bool CanUseFshl =
6163 Ty->isIntegerTy() && Ty == I.getType() && isa<FixedVectorType>(VecTy) &&
6164 cast<FixedVectorType>(VecTy)->getElementType()->isIntegerTy() &&
6165 cast<FixedVectorType>(VecTy)->getNumElements() == 2;
6166 if (CanUseBswap || CanUseFshl) {
6167 auto *InnerCall = dyn_cast<Instruction>(I.getOperand(0));
6168 if (!InnerCall)
6169 return false;
6170 auto *InnerBitCast = dyn_cast<BitCastInst>(InnerCall->getOperand(0));
6171 if (!InnerBitCast)
6172 return false;
6173 Constant *HalfBW = ConstantInt::get(Ty, Ty->getIntegerBitWidth() / 2);
6174 InstructionCost OldCost = TTI.getInstructionCost(InnerBitCast, CostKind) +
6175 TTI.getInstructionCost(InnerCall, CostKind) +
6177 IntrinsicCostAttributes ICABSwap(Intrinsic::bswap, Ty, {Ty});
6178 IntrinsicCostAttributes ICABFshl(Intrinsic::fshl, Ty, {X, X, HalfBW},
6179 {Ty, Ty, Ty});
6180 IntrinsicCostAttributes ICABRev(Intrinsic::bitreverse, Ty, {Ty});
6181 InstructionCost NewCost =
6182 TTI.getIntrinsicInstrCost(CanUseBswap ? ICABSwap : ICABFshl,
6183 CostKind) +
6185 if (!InnerCall->hasOneUse())
6186 NewCost += TTI.getInstructionCost(InnerCall, CostKind) +
6187 TTI.getInstructionCost(InnerBitCast, CostKind);
6188 else if (!InnerBitCast->hasOneUse())
6189 NewCost += TTI.getInstructionCost(InnerBitCast, CostKind);
6190 LLVM_DEBUG(dbgs() << "Found bitreverse vector roundtrip: " << I
6191 << "\n OldCost: " << OldCost
6192 << " vs NewCost: " << NewCost << "\n");
6193 if (NewCost.isValid() && NewCost < OldCost) {
6194 Builder.SetInsertPoint(&I);
6195 Value *Swap =
6196 CanUseBswap
6197 ? Builder.CreateUnaryIntrinsic(Intrinsic::bswap, X)
6198 : Builder.CreateIntrinsic(Ty, Intrinsic::fshl, {X, X, HalfBW});
6199 Worklist.pushValue(Swap);
6200 Value *BRev = Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, Swap);
6201 replaceValue(I, *BRev);
6202 return true;
6203 }
6204 }
6205 }
6206
6207 if (!match(&I, m_BitReverse(m_BSwap(m_Value(X)))) &&
6209 return false;
6210 Type *Ty = I.getType();
6211 Type *I8Ty = Builder.getInt8Ty();
6212 TypeSize ElementSize = DL->getTypeStoreSize(Ty);
6213 ElementCount NewVecCnt = ElementCount::get(ElementSize.getKnownMinValue(),
6214 ElementSize.isScalable());
6215 Type *NewVecTy = VectorType::get(I8Ty, NewVecCnt);
6216 auto *II = cast<IntrinsicInst>(&I);
6217 auto *InnerII = cast<IntrinsicInst>(II->getArgOperand(0));
6218 // OldCost = cost of bitreverse/bswap + cost of bswap/bitreverse
6221 // NewCost = cost of bitcast to byte vector +
6222 // cost of bitreverse/bswap on byte vector +
6223 // cost of bitcast back to original type
6224 InstructionCost CastToVecCost = TTI.getCastInstrCost(
6225 Instruction::BitCast, NewVecTy, Ty, TTI::CastContextHint::None, CostKind);
6226 InstructionCost CastToOrigCost = TTI.getCastInstrCost(
6227 Instruction::BitCast, Ty, NewVecTy, TTI::CastContextHint::None, CostKind);
6228 IntrinsicCostAttributes ICANew(Intrinsic::bitreverse, NewVecTy, {NewVecTy});
6229 InstructionCost NewIntrinsicCost =
6231 InstructionCost NewCost = CastToVecCost + NewIntrinsicCost + CastToOrigCost;
6232 if (!InnerII->hasOneUse())
6233 NewCost += TTI.getInstructionCost(InnerII, CostKind);
6234 LLVM_DEBUG(dbgs() << "Found bitorder reverse and swap: " << I
6235 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6236 << "\n");
6237 if (!NewCost.isValid() || NewCost >= OldCost)
6238 return false;
6239 // Perform transform: bitcast(arg, <N x i8>), bitreverse, bitcast back
6240 Builder.SetInsertPoint(II);
6241 Value *CastToVec = Builder.CreateBitCast(X, NewVecTy);
6242 Value *NewCall =
6243 Builder.CreateUnaryIntrinsic(Intrinsic::bitreverse, CastToVec);
6244 Value *CastToOrig = Builder.CreateBitCast(NewCall, Ty);
6245 replaceValue(I, *CastToOrig);
6246 return true;
6247}
6248
6249/// Given the maximum shuffle index and load vector type, compute the number of
6250/// elements for the shrunk load, rounding up to the next full vector register
6251/// boundary to avoid scalar remainders that legalize poorly.
6252static unsigned getAlignedNumElements(unsigned MaxIdx, FixedVectorType *LoadTy,
6253 const TargetTransformInfo &TTI,
6254 const DataLayout &DL) {
6255 unsigned RawNumElements = MaxIdx + 1u;
6256 Type *ElemTy = LoadTy->getElementType();
6257 // Skip alignment for illegal element types.
6258 if (!TTI.isTypeLegal(ElemTy))
6259 return RawNumElements;
6260
6261 TypeSize ElemSize = DL.getTypeSizeInBits(ElemTy);
6262 if (ElemSize.isScalable() || ElemSize.isZero())
6263 return RawNumElements;
6264
6267 if (RegSize.isScalable() || RegSize.isZero())
6268 return RawNumElements;
6269
6270 unsigned ElemsPerReg = RegSize.getFixedValue() / ElemSize.getFixedValue();
6271 // If the load already fits in a register, keep the exact size.
6272 // Otherwise round up to the next full register boundary.
6273 if (ElemsPerReg == 0 || RawNumElements <= ElemsPerReg)
6274 return RawNumElements;
6275
6276 return alignTo(RawNumElements, ElemsPerReg);
6277}
6278
6279// Attempt to shrink loads that are only used by shufflevector instructions.
6280bool VectorCombine::shrinkLoadForShuffles(Instruction &I) {
6281 auto *OldLoad = dyn_cast<LoadInst>(&I);
6282 if (!OldLoad || !OldLoad->isSimple())
6283 return false;
6284
6285 auto *OldLoadTy = dyn_cast<FixedVectorType>(OldLoad->getType());
6286 if (!OldLoadTy)
6287 return false;
6288
6289 unsigned const OldNumElements = OldLoadTy->getNumElements();
6290
6291 // Search all uses of load. If all uses are shufflevector instructions, and
6292 // the second operands are all poison values, find the minimum and maximum
6293 // indices of the vector elements referenced by all shuffle masks.
6294 // Otherwise return `std::nullopt`.
6295 using IndexRange = std::pair<int, int>;
6296 auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> {
6297 IndexRange OutputRange = IndexRange(OldNumElements, -1);
6298 for (llvm::Use &Use : I.uses()) {
6299 // Ensure all uses match the required pattern.
6300 User *Shuffle = Use.getUser();
6301 ArrayRef<int> Mask;
6302
6303 if (!match(Shuffle,
6304 m_Shuffle(m_Specific(OldLoad), m_Undef(), m_Mask(Mask))))
6305 return std::nullopt;
6306
6307 // Ignore shufflevector instructions that have no uses.
6308 if (Shuffle->use_empty())
6309 continue;
6310
6311 // Find the min and max indices used by the shufflevector instruction.
6312 for (int Index : Mask) {
6313 if (Index >= 0 && Index < static_cast<int>(OldNumElements)) {
6314 OutputRange.first = std::min(Index, OutputRange.first);
6315 OutputRange.second = std::max(Index, OutputRange.second);
6316 }
6317 }
6318 }
6319
6320 if (OutputRange.second < OutputRange.first)
6321 return std::nullopt;
6322
6323 return OutputRange;
6324 };
6325
6326 // Get the range of vector elements used by shufflevector instructions.
6327 if (std::optional<IndexRange> Indices = GetIndexRangeInShuffles()) {
6328 unsigned const NewNumElements =
6329 getAlignedNumElements(Indices->second, OldLoadTy, TTI, *DL);
6330
6331 // If the range of vector elements is smaller than the full load, attempt
6332 // to create a smaller load.
6333 if (NewNumElements < OldNumElements) {
6334 IRBuilder Builder(&I);
6335 Builder.SetCurrentDebugLocation(I.getDebugLoc());
6336
6337 // Calculate costs of old and new ops.
6338 Type *ElemTy = OldLoadTy->getElementType();
6339 FixedVectorType *NewLoadTy = FixedVectorType::get(ElemTy, NewNumElements);
6340 Value *PtrOp = OldLoad->getPointerOperand();
6341
6343 Instruction::Load, OldLoad->getType(), OldLoad->getAlign(),
6344 OldLoad->getPointerAddressSpace(), CostKind);
6345 InstructionCost NewCost =
6346 TTI.getMemoryOpCost(Instruction::Load, NewLoadTy, OldLoad->getAlign(),
6347 OldLoad->getPointerAddressSpace(), CostKind);
6348
6349 using UseEntry = std::pair<ShuffleVectorInst *, std::vector<int>>;
6351 unsigned const MaxIndex = NewNumElements * 2u;
6352
6353 for (llvm::Use &Use : I.uses()) {
6354 auto *Shuffle = cast<ShuffleVectorInst>(Use.getUser());
6355
6356 // Ignore shufflevector instructions that have no uses.
6357 if (Shuffle->use_empty())
6358 continue;
6359
6360 ArrayRef<int> OldMask = Shuffle->getShuffleMask();
6361
6362 // Create entry for new use.
6363 NewUses.push_back({Shuffle, OldMask});
6364
6365 // Validate mask indices.
6366 for (int Index : OldMask) {
6367 if (Index >= static_cast<int>(MaxIndex))
6368 return false;
6369 }
6370
6371 // Update costs.
6372 OldCost +=
6374 OldLoadTy, OldMask, CostKind);
6375 NewCost +=
6377 NewLoadTy, OldMask, CostKind);
6378 }
6379
6380 LLVM_DEBUG(
6381 dbgs() << "Found a load used only by shufflevector instructions: "
6382 << I << "\n OldCost: " << OldCost
6383 << " vs NewCost: " << NewCost << "\n");
6384
6385 if (OldCost < NewCost || !NewCost.isValid())
6386 return false;
6387
6388 // Create new load of smaller vector.
6389 auto *NewLoad = cast<LoadInst>(
6390 Builder.CreateAlignedLoad(NewLoadTy, PtrOp, OldLoad->getAlign()));
6391 NewLoad->copyMetadata(I);
6392
6393 // Replace all uses.
6394 for (UseEntry &Use : NewUses) {
6395 ShuffleVectorInst *Shuffle = Use.first;
6396 std::vector<int> &NewMask = Use.second;
6397
6398 Builder.SetInsertPoint(Shuffle);
6399 Builder.SetCurrentDebugLocation(Shuffle->getDebugLoc());
6400 Value *NewShuffle = Builder.CreateShuffleVector(
6401 NewLoad, PoisonValue::get(NewLoadTy), NewMask);
6402
6403 replaceValue(*Shuffle, *NewShuffle, false);
6404 }
6405
6406 return true;
6407 }
6408 }
6409 return false;
6410}
6411
6412// Attempt to narrow a phi of shufflevector instructions where the two incoming
6413// values have the same operands but different masks. If the two shuffle masks
6414// are offsets of one another we can use one branch to rotate the incoming
6415// vector and perform one larger shuffle after the phi.
6416bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
6417 auto *Phi = dyn_cast<PHINode>(&I);
6418 if (!Phi || Phi->getNumIncomingValues() != 2u)
6419 return false;
6420
6421 Value *Op = nullptr;
6422 ArrayRef<int> Mask0;
6423 ArrayRef<int> Mask1;
6424
6425 if (!match(Phi->getOperand(0u),
6426 m_OneUse(m_Shuffle(m_Value(Op), m_Poison(), m_Mask(Mask0)))) ||
6427 !match(Phi->getOperand(1u),
6428 m_OneUse(m_Shuffle(m_Specific(Op), m_Poison(), m_Mask(Mask1)))))
6429 return false;
6430
6431 auto *Shuf = cast<ShuffleVectorInst>(Phi->getOperand(0u));
6432
6433 // Ensure result vectors are wider than the argument vector.
6434 auto *InputVT = cast<FixedVectorType>(Op->getType());
6435 auto *ResultVT = cast<FixedVectorType>(Shuf->getType());
6436 auto const InputNumElements = InputVT->getNumElements();
6437
6438 if (InputNumElements >= ResultVT->getNumElements())
6439 return false;
6440
6441 // Take the difference of the two shuffle masks at each index. Ignore poison
6442 // values at the same index in both masks.
6443 SmallVector<int, 16> NewMask;
6444 NewMask.reserve(Mask0.size());
6445
6446 for (auto [M0, M1] : zip(Mask0, Mask1)) {
6447 if (M0 >= 0 && M1 >= 0)
6448 NewMask.push_back(M0 - M1);
6449 else if (M0 == -1 && M1 == -1)
6450 continue;
6451 else
6452 return false;
6453 }
6454
6455 // Ensure all elements of the new mask are equal. If the difference between
6456 // the incoming mask elements is the same, the two must be constant offsets
6457 // of one another.
6458 if (NewMask.empty() || !all_equal(NewMask))
6459 return false;
6460
6461 // Create new mask using difference of the two incoming masks.
6462 int MaskOffset = NewMask[0u];
6463 unsigned Index = (InputNumElements + MaskOffset) % InputNumElements;
6464 NewMask.clear();
6465
6466 for (unsigned I = 0u; I < InputNumElements; ++I) {
6467 NewMask.push_back(Index);
6468 Index = (Index + 1u) % InputNumElements;
6469 }
6470
6471 // Calculate costs for worst cases and compare.
6472 auto const Kind = TTI::SK_PermuteSingleSrc;
6473 auto OldCost =
6474 std::max(TTI.getShuffleCost(Kind, ResultVT, InputVT, Mask0, CostKind),
6475 TTI.getShuffleCost(Kind, ResultVT, InputVT, Mask1, CostKind));
6476 auto NewCost = TTI.getShuffleCost(Kind, InputVT, InputVT, NewMask, CostKind) +
6477 TTI.getShuffleCost(Kind, ResultVT, InputVT, Mask1, CostKind);
6478
6479 LLVM_DEBUG(dbgs() << "Found a phi of mergeable shuffles: " << I
6480 << "\n OldCost: " << OldCost << " vs NewCost: " << NewCost
6481 << "\n");
6482
6483 if (NewCost > OldCost)
6484 return false;
6485
6486 // Create new shuffles and narrowed phi.
6487 auto Builder = IRBuilder(Shuf);
6488 Builder.SetCurrentDebugLocation(Shuf->getDebugLoc());
6489 auto *PoisonVal = PoisonValue::get(InputVT);
6490 auto *NewShuf0 = Builder.CreateShuffleVector(Op, PoisonVal, NewMask);
6491 Worklist.push(cast<Instruction>(NewShuf0));
6492
6493 Builder.SetInsertPoint(Phi);
6494 Builder.SetCurrentDebugLocation(Phi->getDebugLoc());
6495 auto *NewPhi = Builder.CreatePHI(NewShuf0->getType(), 2u);
6496 NewPhi->addIncoming(NewShuf0, Phi->getIncomingBlock(0u));
6497 NewPhi->addIncoming(Op, Phi->getIncomingBlock(1u));
6498
6499 Builder.SetInsertPoint(*NewPhi->getInsertionPointAfterDef());
6500 PoisonVal = PoisonValue::get(NewPhi->getType());
6501 auto *NewShuf1 = Builder.CreateShuffleVector(NewPhi, PoisonVal, Mask1);
6502
6503 replaceValue(*Phi, *NewShuf1);
6504 return true;
6505}
6506
6507/// This is the entry point for all transforms. Pass manager differences are
6508/// handled in the callers of this function.
6509bool VectorCombine::run() {
6511 return false;
6512
6513 // Don't attempt vectorization if the target does not support vectors.
6514 if (!TTI.getNumberOfRegisters(TTI.getRegisterClassForType(/*Vector*/ true)))
6515 return false;
6516
6517 LLVM_DEBUG(dbgs() << "\n\nVECTORCOMBINE on " << F.getName() << "\n");
6518
6519 auto FoldInst = [this](Instruction &I) {
6520 Builder.SetInsertPoint(&I);
6521 bool IsVectorType = isa<VectorType>(I.getType());
6522 bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
6523 auto Opcode = I.getOpcode();
6524
6525 LLVM_DEBUG(dbgs() << "VC: Visiting: " << I << '\n');
6526
6527 // These folds should be beneficial regardless of when this pass is run
6528 // in the optimization pipeline.
6529 // The type checking is for run-time efficiency. We can avoid wasting time
6530 // dispatching to folding functions if there's no chance of matching.
6531 if (IsFixedVectorType) {
6532 switch (Opcode) {
6533 case Instruction::InsertElement:
6534 if (vectorizeLoadInsert(I))
6535 return true;
6536 break;
6537 case Instruction::ShuffleVector:
6538 if (widenSubvectorLoad(I))
6539 return true;
6540 break;
6541 default:
6542 break;
6543 }
6544 }
6545
6546 // This transform works with scalable and fixed vectors
6547 // TODO: Identify and allow other scalable transforms
6548 if (IsVectorType) {
6549 if (scalarizeOpOrCmp(I))
6550 return true;
6551 if (scalarizeLoad(I))
6552 return true;
6553 if (scalarizeExtExtract(I))
6554 return true;
6555 if (scalarizeVPIntrinsic(I))
6556 return true;
6557 if (foldInterleaveIntrinsics(I))
6558 return true;
6559 if (foldBitcastOfVPLoad(I))
6560 return true;
6561 }
6562
6563 if (foldDeinterleaveIntrinsics(I))
6564 return true;
6565
6566 if (Opcode == Instruction::Store)
6567 if (foldSingleElementStore(I))
6568 return true;
6569
6570 // If this is an early pipeline invocation of this pass, we are done.
6571 if (TryEarlyFoldsOnly)
6572 return false;
6573
6574 if (Opcode == Instruction::Call)
6575 if (foldBitOrderReverseAndSwap(I))
6576 return true;
6577 if (Opcode == Instruction::BitCast)
6578 if (foldBitOrderReverseAndSwap(I))
6579 return true;
6580
6581 // Otherwise, try folds that improve codegen but may interfere with
6582 // early IR canonicalizations.
6583 // The type checking is for run-time efficiency. We can avoid wasting time
6584 // dispatching to folding functions if there's no chance of matching.
6585 if (IsFixedVectorType) {
6586 switch (Opcode) {
6587 case Instruction::InsertElement:
6588 if (foldInsExtFNeg(I))
6589 return true;
6590 if (foldInsExtBinop(I))
6591 return true;
6592 if (foldInsExtVectorToShuffle(I))
6593 return true;
6594 break;
6595 case Instruction::ShuffleVector:
6596 if (foldPermuteOfBinops(I))
6597 return true;
6598 if (foldShuffleOfBinops(I))
6599 return true;
6600 if (foldShuffleOfSelects(I))
6601 return true;
6602 if (foldShuffleOfCastops(I))
6603 return true;
6604 if (foldShuffleOfShuffles(I))
6605 return true;
6606 if (foldPermuteOfIntrinsic(I))
6607 return true;
6608 if (foldShufflesOfLengthChangingShuffles(I))
6609 return true;
6610 if (foldShuffleOfIntrinsics(I))
6611 return true;
6612 if (foldSelectShuffle(I))
6613 return true;
6614 if (foldShuffleToIdentity(I))
6615 return true;
6616 break;
6617 case Instruction::Load:
6618 if (shrinkLoadForShuffles(I))
6619 return true;
6620 break;
6621 case Instruction::BitCast:
6622 if (foldBitcastShuffle(I))
6623 return true;
6624 if (foldSelectsFromBitcast(I))
6625 return true;
6626 break;
6627 case Instruction::And:
6628 case Instruction::Or:
6629 case Instruction::Xor:
6630 if (foldBitOpOfCastops(I))
6631 return true;
6632 if (foldBitOpOfCastConstant(I))
6633 return true;
6634 break;
6635 case Instruction::PHI:
6636 if (shrinkPhiOfShuffles(I))
6637 return true;
6638 break;
6639 default:
6640 if (shrinkType(I))
6641 return true;
6642 break;
6643 }
6644 } else {
6645 switch (Opcode) {
6646 case Instruction::Call:
6647 if (foldShuffleFromReductions(I))
6648 return true;
6649 if (foldCastFromReductions(I))
6650 return true;
6651 break;
6652 case Instruction::ExtractElement:
6653 if (foldShuffleChainsToReduce(I))
6654 return true;
6655 break;
6656 case Instruction::ICmp:
6657 if (foldSignBitReductionCmp(I))
6658 return true;
6659 if (foldICmpEqZeroVectorReduce(I))
6660 return true;
6661 if (foldReductionZeroTest(I))
6662 return true;
6663 if (foldEquivalentReductionCmp(I))
6664 return true;
6665 if (foldReduceAddCmpZero(I))
6666 return true;
6667 [[fallthrough]];
6668 case Instruction::FCmp:
6669 if (foldExtractExtract(I))
6670 return true;
6671 break;
6672 case Instruction::Or:
6673 if (foldConcatOfBoolMasks(I))
6674 return true;
6675 [[fallthrough]];
6676 default:
6677 if (Instruction::isBinaryOp(Opcode)) {
6678 if (foldExtractExtract(I))
6679 return true;
6680 if (foldExtractedCmps(I))
6681 return true;
6682 if (foldBinopOfReductions(I))
6683 return true;
6684 }
6685 break;
6686 }
6687 }
6688 return false;
6689 };
6690
6691 bool MadeChange = false;
6692 for (BasicBlock &BB : F) {
6693 // Ignore unreachable basic blocks.
6694 if (!DT.isReachableFromEntry(&BB))
6695 continue;
6696 // Use early increment range so that we can erase instructions in loop.
6697 // make_early_inc_range is not applicable here, as the next iterator may
6698 // be invalidated by RecursivelyDeleteTriviallyDeadInstructions.
6699 // We manually maintain the next instruction and update it when it is about
6700 // to be deleted.
6701 Instruction *I = &BB.front();
6702 while (I) {
6703 NextInst = I->getNextNode();
6704 if (!I->isDebugOrPseudoInst())
6705 MadeChange |= FoldInst(*I);
6706 I = NextInst;
6707 }
6708 }
6709
6710 NextInst = nullptr;
6711
6712 while (!Worklist.isEmpty()) {
6713 Instruction *I = Worklist.removeOne();
6714 if (!I)
6715 continue;
6716
6719 continue;
6720 }
6721
6722 MadeChange |= FoldInst(*I);
6723 }
6724
6725 return MadeChange;
6726}
6727
6730 auto &AC = FAM.getResult<AssumptionAnalysis>(F);
6732 DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
6733 AAResults &AA = FAM.getResult<AAManager>(F);
6734 const DataLayout *DL = &F.getDataLayout();
6737 VectorCombine Combiner(F, TTI, DT, AA, AC, DL, CostKind, TryEarlyFoldsOnly);
6738 if (!Combiner.run())
6739 return PreservedAnalyses::all();
6742 return PA;
6743}
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:1050
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1561
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:368
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:377
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1509
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:326
unsigned countl_one() const
Count the number of leading one bits.
Definition APInt.h:1636
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:303
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:293
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:197
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:386
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:236
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1226
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
size_t size() const
Get the array size.
Definition ArrayRef.h:141
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
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 void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isIdempotent() const
Return true if the instruction is idempotent:
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
bool isIntDivRem() const
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:2275
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition APInt.h:2280
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
LLVM_ABI 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