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