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