LLVM 24.0.0git
SLPCompatibilityAnalysis.cpp
Go to the documentation of this file.
1//===- SLPCompatibilityAnalysis.cpp - SLP same-opcode helpers -------------===//
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
10#include "SLPUtils.h"
11
12#include "llvm/ADT/APInt.h"
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/SetVector.h"
18#include "llvm/ADT/bit.h"
20#include "llvm/IR/Constants.h"
21#include "llvm/IR/InstrTypes.h"
22#include "llvm/IR/Instruction.h"
25#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/Value.h"
30
31#include <algorithm>
32#include <array>
33#include <cassert>
34#include <optional>
35#include <utility>
36
37using namespace llvm;
38using namespace llvm::PatternMatch;
39
40namespace llvm::slpvectorizer {
41
42bool isValidForAlternation(unsigned Opcode) {
43 return !Instruction::isIntDivRem(Opcode);
44}
45
46std::pair<Constant *, unsigned>
47BinOpSameOpcodeHelper::isBinOpWithConstant(const Instruction *I) {
48 [[maybe_unused]] unsigned Opcode = I->getOpcode();
49 assert(binary_search(SupportedOp, Opcode) && "Unsupported opcode.");
50 (void)SupportedOp;
51 auto *BinOp = cast<BinaryOperator>(I);
52 auto GetConstant = [](Value *V) -> Constant * {
53 if (auto *CI = dyn_cast<ConstantInt>(V))
54 return CI;
55 return dyn_cast<ConstantFP>(V);
56 };
57 if (Constant *C = GetConstant(BinOp->getOperand(1)))
58 return {C, 1};
59 if (!isCommutative(I))
60 return {nullptr, 0};
61 if (Constant *C = GetConstant(BinOp->getOperand(0)))
62 return {C, 0};
63 return {nullptr, 0};
64}
65
66bool BinOpSameOpcodeHelper::InterchangeableInfo::trySet(
67 MaskType OpcodeInMaskForm, MaskType InterchangeableMask) {
68 if (Mask & InterchangeableMask) {
69 SeenBefore |= OpcodeInMaskForm;
70 Mask &= InterchangeableMask;
71 return true;
72 }
73 return false;
74}
75
76unsigned BinOpSameOpcodeHelper::InterchangeableInfo::getOpcode() const {
77 MaskType Candidate = Mask & SeenBefore;
78 if (Candidate & MainOpBIT)
79 return I->getOpcode();
80 if (Candidate & ShlBIT)
81 return Instruction::Shl;
82 if (Candidate & AShrBIT)
83 return Instruction::AShr;
84 if (Candidate & MulBIT)
85 return Instruction::Mul;
86 if (Candidate & AddBIT)
87 return Instruction::Add;
88 if (Candidate & SubBIT)
89 return Instruction::Sub;
90 if (Candidate & FAddBIT)
91 return Instruction::FAdd;
92 if (Candidate & FSubBIT)
93 return Instruction::FSub;
94 if (Candidate & AndBIT)
95 return Instruction::And;
96 if (Candidate & OrBIT)
97 return Instruction::Or;
98 if (Candidate & XorBIT)
99 return Instruction::Xor;
100 llvm_unreachable("Cannot find interchangeable instruction.");
101}
102
103bool BinOpSameOpcodeHelper::InterchangeableInfo::hasCandidateOpcode(
104 unsigned Opcode) const {
105 MaskType Candidate = Mask & SeenBefore;
106 switch (Opcode) {
107 case Instruction::Shl:
108 return Candidate & ShlBIT;
109 case Instruction::AShr:
110 return Candidate & AShrBIT;
111 case Instruction::Mul:
112 return Candidate & MulBIT;
113 case Instruction::Add:
114 return Candidate & AddBIT;
115 case Instruction::Sub:
116 return Candidate & SubBIT;
117 case Instruction::And:
118 return Candidate & AndBIT;
119 case Instruction::Or:
120 return Candidate & OrBIT;
121 case Instruction::Xor:
122 return Candidate & XorBIT;
123 case Instruction::FAdd:
124 return Candidate & FAddBIT;
125 case Instruction::FSub:
126 return Candidate & FSubBIT;
127 case Instruction::LShr:
128 case Instruction::FMul:
129 case Instruction::SDiv:
130 case Instruction::UDiv:
131 case Instruction::FDiv:
132 case Instruction::SRem:
133 case Instruction::URem:
134 case Instruction::FRem:
135 return false;
136 default:
137 break;
138 }
139 llvm_unreachable("Cannot find interchangeable instruction.");
140}
141
142SmallVector<Value *> BinOpSameOpcodeHelper::InterchangeableInfo::getOperand(
143 const Instruction *To) const {
144 unsigned ToOpcode = To->getOpcode();
145 unsigned FromOpcode = I->getOpcode();
146 if (FromOpcode == ToOpcode)
147 return SmallVector<Value *>(I->operands());
148 assert(binary_search(SupportedOp, ToOpcode) && "Unsupported opcode.");
149 auto [C, Pos] = isBinOpWithConstant(I);
150 Type *RHSType = I->getOperand(Pos)->getType();
151 Constant *RHS;
152 if (auto *CFP = dyn_cast<ConstantFP>(C)) {
153 // fsub(x, c) == fadd(x, -c) for every FP constant c, since IEEE 754
154 // defines subtraction as addition of the negated operand.
155 assert(is_contained({Instruction::FAdd, Instruction::FSub}, ToOpcode) &&
156 "Cannot convert the instruction.");
157 RHS = ConstantFP::get(RHSType, -CFP->getValueAPF());
158 } else {
159 auto *CI = cast<ConstantInt>(C);
160 const APInt &FromCIValue = CI->getValue();
161 unsigned FromCIValueBitWidth = FromCIValue.getBitWidth();
162 switch (FromOpcode) {
163 case Instruction::Shl:
164 if (ToOpcode == Instruction::Add && FromCIValue.isOne())
165 return {I->getOperand(0), I->getOperand(0)};
166 if (ToOpcode == Instruction::Mul) {
167 RHS = ConstantInt::get(RHSType,
168 APInt::getOneBitSet(FromCIValueBitWidth,
169 FromCIValue.getZExtValue()));
170 } else {
171 assert(FromCIValue.isZero() && "Cannot convert the instruction.");
172 RHS = ConstantExpr::getBinOpIdentity(ToOpcode, RHSType,
173 /*AllowRHSConstant=*/true);
174 }
175 break;
176 case Instruction::Mul:
177 assert(FromCIValue.isPowerOf2() && "Cannot convert the instruction.");
178 if (ToOpcode == Instruction::Shl) {
179 RHS = ConstantInt::get(
180 RHSType, APInt(FromCIValueBitWidth, FromCIValue.logBase2()));
181 } else {
182 assert(FromCIValue.isOne() && "Cannot convert the instruction.");
183 RHS = ConstantExpr::getBinOpIdentity(ToOpcode, RHSType,
184 /*AllowRHSConstant=*/true);
185 }
186 break;
187 case Instruction::Add:
188 case Instruction::Sub:
189 if (FromCIValue.isZero()) {
190 RHS = ConstantExpr::getBinOpIdentity(ToOpcode, RHSType,
191 /*AllowRHSConstant=*/true);
192 } else {
193 assert(is_contained({Instruction::Add, Instruction::Sub}, ToOpcode) &&
194 "Cannot convert the instruction.");
195 APInt NegatedVal = APInt(FromCIValue);
196 NegatedVal.negate();
197 RHS = ConstantInt::get(RHSType, NegatedVal);
198 }
199 break;
200 case Instruction::And:
201 assert(FromCIValue.isAllOnes() && "Cannot convert the instruction.");
202 RHS = ConstantExpr::getBinOpIdentity(ToOpcode, RHSType,
203 /*AllowRHSConstant=*/true);
204 break;
205 default:
206 assert(FromCIValue.isZero() && "Cannot convert the instruction.");
207 RHS = ConstantExpr::getBinOpIdentity(ToOpcode, RHSType,
208 /*AllowRHSConstant=*/true);
209 break;
210 }
211 }
212 Value *LHS = I->getOperand(1 - Pos);
213 // If the target opcode is non-commutative (e.g., shl, sub),
214 // force the variable to the left and the constant to the right.
215 if (Pos == 1 || !Instruction::isCommutative(ToOpcode))
216 return SmallVector<Value *>({LHS, RHS});
217
218 return SmallVector<Value *>({RHS, LHS});
219}
220
221bool BinOpSameOpcodeHelper::isValidForAlternation(const Instruction *I) const {
222 return slpvectorizer::isValidForAlternation(MainOp.I->getOpcode()) &&
224}
225
226bool BinOpSameOpcodeHelper::initializeAltOp(const Instruction *I) {
227 if (AltOp.I)
228 return true;
229 if (!isValidForAlternation(I))
230 return false;
231 AltOp.I = I;
232 return true;
233}
234
237 "BinOpSameOpcodeHelper only accepts BinaryOperator.");
238 unsigned Opcode = I->getOpcode();
239 MaskType OpcodeInMaskForm;
240 // Prefer Shl, AShr, Mul, Add, Sub, And, Or, Xor, FAdd and FSub over
241 // MainOp.
242 switch (Opcode) {
243 case Instruction::Shl:
244 OpcodeInMaskForm = ShlBIT;
245 break;
246 case Instruction::AShr:
247 OpcodeInMaskForm = AShrBIT;
248 break;
249 case Instruction::Mul:
250 OpcodeInMaskForm = MulBIT;
251 break;
252 case Instruction::Add:
253 OpcodeInMaskForm = AddBIT;
254 break;
255 case Instruction::Sub:
256 OpcodeInMaskForm = SubBIT;
257 break;
258 case Instruction::And:
259 OpcodeInMaskForm = AndBIT;
260 break;
261 case Instruction::Or:
262 OpcodeInMaskForm = OrBIT;
263 break;
264 case Instruction::Xor:
265 OpcodeInMaskForm = XorBIT;
266 break;
267 case Instruction::FAdd:
268 OpcodeInMaskForm = FAddBIT;
269 break;
270 case Instruction::FSub:
271 OpcodeInMaskForm = FSubBIT;
272 break;
273 default:
274 return MainOp.equal(Opcode) || (initializeAltOp(I) && AltOp.equal(Opcode));
275 }
276 MaskType InterchangeableMask = OpcodeInMaskForm;
277 auto [C, Pos] = isBinOpWithConstant(I);
278 if (auto *CI = dyn_cast_if_present<ConstantInt>(C)) {
279 constexpr MaskType CanBeAll =
280 XorBIT | OrBIT | AndBIT | SubBIT | AddBIT | MulBIT | AShrBIT | ShlBIT;
281 const APInt &CIValue = CI->getValue();
282 switch (Opcode) {
283 case Instruction::Shl:
284 if (CIValue.ult(CIValue.getBitWidth()))
285 InterchangeableMask = CIValue.isZero() ? CanBeAll : MulBIT | ShlBIT;
286 if (CIValue.isOne())
287 InterchangeableMask |= AddBIT;
288 break;
289 case Instruction::Mul:
290 if (CIValue.isOne()) {
291 InterchangeableMask = CanBeAll;
292 break;
293 }
294 if (CIValue.isPowerOf2())
295 InterchangeableMask = MulBIT | ShlBIT;
296 break;
297 case Instruction::Add:
298 case Instruction::Sub:
299 InterchangeableMask = CIValue.isZero() ? CanBeAll : SubBIT | AddBIT;
300 break;
301 case Instruction::And:
302 if (CIValue.isAllOnes())
303 InterchangeableMask = CanBeAll;
304 break;
305 case Instruction::Xor:
306 if (CIValue.isZero())
307 InterchangeableMask = XorBIT | OrBIT | SubBIT | AddBIT;
308 break;
309 default:
310 if (CIValue.isZero())
311 InterchangeableMask = CanBeAll;
312 break;
313 }
314 } else if (C && Pos == 1) {
315 // FAdd/FSub with a constant RHS: negating the constant always
316 // converts one into the other, so no value check is needed. A
317 // constant LHS (Pos == 0, e.g. "0.0 - x") is excluded: unlike a
318 // constant RHS, it cannot be moved to the other opcode without also
319 // swapping the variable operand, which would misalign it against
320 // lanes that keep their native opcode (their variable operand stays
321 // on the other side).
322 InterchangeableMask = FSubBIT | FAddBIT;
323 }
324 return MainOp.trySet(OpcodeInMaskForm, InterchangeableMask) ||
325 (initializeAltOp(I) &&
326 AltOp.trySet(OpcodeInMaskForm, InterchangeableMask));
327}
328
329/// If the comparison (Pred, X, C) is a single-element or single-complement
330/// range check, returns its boundary family: false + K for the singleton
331/// {K} (eq forms), true + K for the complement of {K} (ne forms).
332static std::optional<std::pair<bool, APInt>>
334 const unsigned BW = C.getBitWidth();
335 const bool IsSigned = CmpInst::isSigned(Pred);
336 const APInt Min = IsSigned ? APInt::getSignedMinValue(BW) : APInt(BW, 0);
337 const APInt Max =
338 IsSigned ? APInt::getSignedMaxValue(BW) : APInt::getMaxValue(BW);
339 switch (Pred) {
340 case CmpInst::ICMP_EQ:
341 return std::make_pair(false, C);
342 case CmpInst::ICMP_NE:
343 return std::make_pair(true, C);
346 if (C == Min + 1)
347 return std::make_pair(false, Min);
348 if (C == Max)
349 return std::make_pair(true, C);
350 break;
353 if (C == Min)
354 return std::make_pair(false, C);
355 if (C == Max - 1)
356 return std::make_pair(true, Max);
357 break;
360 if (C == Min)
361 return std::make_pair(true, C);
362 if (C == Max - 1)
363 return std::make_pair(false, Max);
364 break;
367 if (C == Min + 1)
368 return std::make_pair(true, Min);
369 if (C == Max)
370 return std::make_pair(false, C);
371 break;
372 default:
373 break;
374 }
375 return std::nullopt;
376}
377
378CmpSamePredicateHelper::MaskType
379CmpSamePredicateHelper::getFormsMask(CmpInst::Predicate Pred, const APInt &C) {
380 MaskType M = getBit(Pred);
381 std::optional<std::pair<bool, APInt>> Family = getCmpBoundaryFamily(Pred, C);
382 if (!Family)
383 return M;
384 const auto &[IsComplement, K] = *Family;
385 // At each type boundary the two range checks covering exactly {K}; the
386 // complement family uses their inverses, covering everything but {K}.
387 const MaskType LoU = getBit(CmpInst::ICMP_ULT) | getBit(CmpInst::ICMP_ULE);
388 const MaskType HiU = getBit(CmpInst::ICMP_UGT) | getBit(CmpInst::ICMP_UGE);
389 const MaskType LoS = getBit(CmpInst::ICMP_SLT) | getBit(CmpInst::ICMP_SLE);
390 const MaskType HiS = getBit(CmpInst::ICMP_SGT) | getBit(CmpInst::ICMP_SGE);
391 if (K.isZero())
392 M |= IsComplement ? HiU : LoU;
393 if (K.isMaxValue())
394 M |= IsComplement ? LoU : HiU;
395 if (K.isMinSignedValue())
396 M |= IsComplement ? HiS : LoS;
397 if (K.isMaxSignedValue())
398 M |= IsComplement ? LoS : HiS;
399 return M | getBit(IsComplement ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ);
400}
401
402APInt CmpSamePredicateHelper::getFamilyConstant(bool IsComplement,
403 const APInt &K,
404 CmpInst::Predicate Pred) {
405 if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE)
406 return K;
407 // The complement form uses the singleton constant of the inverse
408 // predicate.
409 if (IsComplement)
410 Pred = CmpInst::getInversePredicate(Pred);
411 switch (Pred) {
414 return K + 1;
417 return K - 1;
418 default:
419 return K;
420 }
421}
422
423/// Returns the predicate and the compared constant of the comparison lane
424/// \p I, treating trunc X to i1 as and X, 1 ne 0.
425static std::optional<std::pair<CmpInst::Predicate, APInt>>
427 if (auto *TI = dyn_cast<TruncInst>(I);
428 TI && TI->getType()->isIntOrIntVectorTy(1))
429 return std::make_pair(
431 APInt::getZero(TI->getSrcTy()->getScalarSizeInBits()));
432 const APInt *C;
433 if (auto *CI = dyn_cast<ICmpInst>(I);
434 CI && match(CI->getOperand(1), m_APInt(C)))
435 return std::make_pair(CI->getPredicate(), *C);
436 return std::nullopt;
437}
438
439CmpSamePredicateHelper::MaskType
440CmpSamePredicateHelper::getLaneMask(const Instruction *I) {
441 if (std::optional<std::pair<CmpInst::Predicate, APInt>> Cmp =
443 MaskType M = getFormsMask(Cmp->first, Cmp->second);
444 // trunc X to i1 is also and X, 1 eq 1.
445 return isa<TruncInst>(I) ? M | getBit(CmpInst::ICMP_EQ) : M;
446 }
447 if (auto *CI = dyn_cast<ICmpInst>(I))
448 return getBit(CI->getPredicate());
449 return 0;
450}
451
453 if (auto *CI = dyn_cast<ICmpInst>(I);
454 CI && !match(CI->getOperand(0), m_OneUse(m_And(m_Value(), m_Value()))))
455 return false;
456 std::optional<std::pair<CmpInst::Predicate, APInt>> Cmp =
458 if (!Cmp)
459 return false;
460 std::optional<std::pair<bool, APInt>> Family =
461 getCmpBoundaryFamily(Cmp->first, Cmp->second);
462 return Family && Family->second.isZero();
463}
464
466 if (auto *CI = dyn_cast<ICmpInst>(I))
467 SeenBefore |= getBit(CI->getPredicate());
468 Mask &= getLaneMask(I);
469 return Mask != 0;
470}
471
474 MaskType Candidate = Mask & SeenBefore;
475 if (!Candidate)
477 if (Candidate & getBit(Preferred->getPredicate()))
478 return Preferred->getPredicate();
479 return static_cast<CmpInst::Predicate>(CmpInst::ICMP_EQ +
480 countr_zero(Candidate));
481}
482
485 const ICmpInst *Preferred) {
487 if (!all_of(VL, [&](Value *V) {
488 auto *I = dyn_cast<Instruction>(V);
489 return isa<PoisonValue>(V) || (I && Helper.add(I));
490 }))
492 return Helper.getPredicate(Preferred);
493}
494
496 CmpInst::Predicate Pred) {
497 return CmpInst::isIntPredicate(Pred) && (getLaneMask(I) & getBit(Pred)) != 0;
498}
499
501 CmpInst::Predicate Pred) {
502 if (!canConvertTo(I, Pred))
503 return nullptr;
504 if (auto *CI = dyn_cast<ICmpInst>(I); CI && CI->getPredicate() == Pred)
505 return nullptr;
506 if (isa<TruncInst>(I) && Pred == CmpInst::ICMP_EQ)
507 return ConstantInt::get(I->getOperand(0)->getType(), 1);
508 auto [LanePred, C] = *getLaneConstantCmp(I);
509 std::optional<std::pair<bool, APInt>> Family =
510 getCmpBoundaryFamily(LanePred, C);
511 assert(Family && "Expected a boundary family for a convertible compare.");
512 const auto &[IsComplement, K] = *Family;
513 return ConstantInt::get(I->getOperand(0)->getType(),
514 getFamilyConstant(IsComplement, K, Pred));
515}
516
518 const Instruction *Op) {
519 if (I->getOpcode() != Op->getOpcode())
520 return false;
521 const auto *II = dyn_cast<IntrinsicInst>(I);
522 const auto *IOp = dyn_cast<IntrinsicInst>(Op);
523 if (II || IOp)
524 return II && IOp &&
525 isEquivalentIntrinsicID(II->getIntrinsicID(),
526 IOp->getIntrinsicID()) !=
528 return true;
529}
530
532 assert(MainOp && "MainOp cannot be nullptr.");
533 if (isSameOperation(I, MainOp))
534 return MainOp;
535 if (MainOp->getOpcode() == Instruction::Select &&
536 I->getOpcode() == Instruction::ZExt && !isAltShuffle())
537 return MainOp;
538 if (MainOp->getOpcode() == Instruction::ICmp &&
539 I->getOpcode() == Instruction::Trunc && !isAltShuffle())
540 return MainOp;
541 // Prefer AltOp instead of interchangeable instruction of MainOp.
542 assert(AltOp && "AltOp cannot be nullptr.");
543 if (isSameOperation(I, AltOp))
544 return AltOp;
545 // BinOpSameOpcodeHelper handles only BinaryOperators; a call cannot match.
546 if (!I->isBinaryOp() || !MainOp->isBinaryOp())
547 return nullptr;
549 if (!Converter.add(I) || !Converter.add(MainOp))
550 return nullptr;
551 if (isAltShuffle() && !Converter.hasCandidateOpcode(MainOp->getOpcode())) {
552 BinOpSameOpcodeHelper AltConverter(AltOp);
553 if (AltConverter.add(I) && AltConverter.add(AltOp) &&
554 AltConverter.hasCandidateOpcode(AltOp->getOpcode()))
555 return AltOp;
556 }
557 if (Converter.hasAltOp() && !isAltShuffle())
558 return nullptr;
559 return Converter.hasAltOp() ? AltOp : MainOp;
560}
561
563 constexpr std::array<unsigned, 8> MulDiv = {
564 Instruction::Mul, Instruction::FMul, Instruction::SDiv,
565 Instruction::UDiv, Instruction::FDiv, Instruction::SRem,
566 Instruction::URem, Instruction::FRem};
567 return is_contained(MulDiv, getOpcode()) &&
568 is_contained(MulDiv, getAltOpcode());
569}
570
572 constexpr std::array<unsigned, 4> AddSub = {
573 Instruction::Add, Instruction::Sub, Instruction::FAdd, Instruction::FSub};
574 return is_contained(AddSub, getOpcode()) &&
575 is_contained(AddSub, getAltOpcode());
576}
577
579 return isAddSubLikeOp() || getOpcode() == Instruction::FNeg;
580}
581
583 assert(valid() && "InstructionsState is invalid.");
584 if (!HasCopyables)
585 return false;
586 if (isAltShuffle())
587 return false;
588 auto *I = dyn_cast<Instruction>(V);
589 // Copyable lanes of a cast node are limited to constants representable as
590 // the cast of a source-type constant.
591 if (isa<CastInst>(MainOp)) {
592 if (I || isa<PoisonValue>(V))
593 return false;
594 if (isa<UndefValue>(V))
595 return true;
596 auto *C = dyn_cast<ConstantInt>(V);
597 return C && C->getValue().getActiveBits() <=
598 cast<CastInst>(MainOp)->getSrcTy()->getIntegerBitWidth();
599 }
600 if (!I)
601 return !isa<PoisonValue>(V);
602 // For a GEP main op only single-index GEPs with the same source element
603 // type can be matching lanes; GEPs with a different shape are copyable.
604 if (getOpcode() == Instruction::GetElementPtr)
605 if (auto *GEP = dyn_cast<GetElementPtrInst>(I);
606 GEP && (GEP->getNumOperands() != 2 ||
607 GEP->getSourceElementType() !=
608 cast<GetElementPtrInst>(MainOp)->getSourceElementType()))
609 return true;
610 if (I->getParent() != MainOp->getParent() &&
613 return true;
614 if (isSameOperation(I, MainOp))
615 return false;
616 // BinOpSameOpcodeHelper handles only BinaryOperators; a call is copyable.
617 if (!I->isBinaryOp() || !MainOp->isBinaryOp())
618 return true;
620 return !Converter.add(I) || !Converter.add(MainOp) || Converter.hasAltOp() ||
621 !Converter.hasCandidateOpcode(getOpcode());
622}
623
625 auto *I = dyn_cast<Instruction>(V);
626 return I &&
627 (I->getOpcode() == Instruction::FMul ||
628 I->getOpcode() == Instruction::FAdd) &&
629 I->hasOneUse() && none_of(I->operands(), [&](Value *Op) {
630 return is_contained(VL, Op);
631 });
632}
633
635 auto *I = dyn_cast<Instruction>(V);
636 return I && S.isCopyableElement(I) &&
637 (I->getOpcode() == Instruction::FMul ||
638 I->getOpcode() == Instruction::FAdd) &&
639 I->hasOneUse();
640}
641
643 bool HasFMulOrFAdd = false;
644 for (Value *V :
645 make_filter_range(VL, [](Value *V) { return !isa<PoisonValue>(V); })) {
646 auto *I = dyn_cast<Instruction>(V);
648 continue;
649 if (!isAbsorbableFMulOrFAdd(VL, V))
650 return false;
651 HasFMulOrFAdd = true;
652 }
653 return HasFMulOrFAdd;
654}
655
657 assert(valid() && "InstructionsState is invalid.");
658 if (isCopyableElement(V))
659 return false;
660 auto *ExpandingOp = dyn_cast<Instruction>(V);
661 if (!ExpandingOp)
662 return false;
663 auto CheckForTransformedOpcode = [](const Instruction *RefOp,
664 const Instruction *ExpandingOp) {
665 switch (RefOp->getOpcode()) {
666 case Instruction::Add:
667 switch (ExpandingOp->getOpcode()) {
668 case Instruction::Shl:
669 return match(ExpandingOp, m_Shl(m_Value(), m_One()));
670 default:
671 break;
672 }
673 break;
674 default:
675 break;
676 }
677 return false;
678 };
679 // getMatchingMainOpOrAltOp() may legitimately return nullptr, e.g. for a
680 // split node, whose Scalars combine two unrelated operations (main/alt
681 // ops of the split state), so V is not required to match either of them.
682 Instruction *MainOp = getMatchingMainOpOrAltOp(ExpandingOp);
683 if (!MainOp)
684 return false;
685 return CheckForTransformedOpcode(MainOp, ExpandingOp);
686}
687
689 assert(isExpandedBinOp(I) && "Expected an expanded binop.");
690 switch (I->getOpcode()) {
691 case Instruction::Shl:
692 assert(match(I, m_Shl(m_Value(), m_One())) && "Expected shl x, 1 only.");
693 return Idx == 1;
694 default:
695 llvm_unreachable("Unexpected opcode for an expanded operand.");
696 }
697}
698
700 assert(valid() && "InstructionsState is invalid.");
701 auto *I = dyn_cast<Instruction>(V);
702 if (!HasCopyables)
705 // MainOp for copyables always schedulable to correctly identify
706 // non-schedulable copyables.
707 if (getMainOp() == V)
708 return false;
709 if (isCopyableElement(V)) {
710 auto IsNonSchedulableCopyableElement = [this](Value *V) {
711 auto *I = dyn_cast<Instruction>(V);
712 return !I || isa<PHINode>(I) || I->getParent() != MainOp->getParent() ||
714 // If the copyable instructions comes after MainOp
715 // (non-schedulable, but used in the block) - cannot vectorize
716 // it, will possibly generate use before def.
717 !MainOp->comesBefore(I));
718 };
719
720 return IsNonSchedulableCopyableElement(V);
721 }
724}
725
726/// Find an instruction with a specific opcode in VL.
727/// \param VL Array of values to search through. Must contain only Instructions
728/// and PoisonValues.
729/// \param Opcode The instruction opcode to search for
730/// \returns
731/// - The first instruction found with matching opcode
732/// - nullptr if no matching instruction is found
734 unsigned Opcode) {
735 for (Value *V :
736 make_filter_range(VL, [](Value *V) { return !isa<PoisonValue>(V); })) {
737 assert(isa<Instruction>(V) && "Only accepts PoisonValue and Instruction.");
738 auto *Inst = cast<Instruction>(V);
739 if (Inst->getOpcode() == Opcode)
740 return Inst;
741 }
742 return nullptr;
743}
744
745/// Checks if the provided operands of 2 cmp instructions are compatible, i.e.
746/// compatible instructions or constants, or just some other regular values.
747static bool areCompatibleCmpOps(Value *BaseOp0, Value *BaseOp1, Value *Op0,
748 Value *Op1, const TargetLibraryInfo &TLI) {
749 return (isConstant(BaseOp0) && isConstant(Op0)) ||
750 (isConstant(BaseOp1) && isConstant(Op1)) ||
751 (!isa<Instruction>(BaseOp0) && !isa<Instruction>(Op0) &&
752 !isa<Instruction>(BaseOp1) && !isa<Instruction>(Op1)) ||
753 BaseOp0 == Op0 || BaseOp1 == Op1 ||
754 getSameOpcode({BaseOp0, Op0}, TLI) ||
755 getSameOpcode({BaseOp1, Op1}, TLI);
756}
757
758/// \returns true if a compare instruction \p CI has similar "look" and
759/// same predicate as \p BaseCI, "as is" or with its operands and predicate
760/// swapped, false otherwise.
761static bool isCmpSameOrSwapped(const CmpInst *BaseCI, const CmpInst *CI,
762 const TargetLibraryInfo &TLI) {
763 assert(BaseCI->getOperand(0)->getType() == CI->getOperand(0)->getType() &&
764 "Assessing comparisons of different types?");
765 CmpInst::Predicate BasePred = BaseCI->getPredicate();
766 CmpInst::Predicate Pred = CI->getPredicate();
768
769 Value *BaseOp0 = BaseCI->getOperand(0);
770 Value *BaseOp1 = BaseCI->getOperand(1);
771 Value *Op0 = CI->getOperand(0);
772 Value *Op1 = CI->getOperand(1);
773
774 return (BasePred == Pred &&
775 areCompatibleCmpOps(BaseOp0, BaseOp1, Op0, Op1, TLI)) ||
776 (BasePred == SwappedPred &&
777 areCompatibleCmpOps(BaseOp0, BaseOp1, Op1, Op0, TLI));
778}
779
781 const TargetLibraryInfo &TLI) {
782 // Make sure these are all Instructions.
785
786 auto *It = find_if(VL, IsaPred<Instruction>);
787 if (It == VL.end())
789
790 Instruction *MainOp = cast<Instruction>(*It);
791 unsigned InstCnt = std::count_if(It, VL.end(), IsaPred<Instruction>);
792 if ((VL.size() > 2 && !isa<PHINode>(MainOp) && InstCnt < VL.size() / 2) ||
793 (VL.size() == 2 && InstCnt < 2))
795
796 // Match trunc X to i1 lanes against the compares.
797 if (isa<TruncInst>(MainOp) && MainOp->getType()->isIntOrIntVectorTy(1))
798 if (auto *CmpIt = find_if(VL, IsaPred<ICmpInst>); CmpIt != VL.end())
799 MainOp = cast<Instruction>(*CmpIt);
800
801 bool IsCastOp = isa<CastInst>(MainOp);
802 bool IsBinOp = isa<BinaryOperator>(MainOp);
803 bool IsCmpOp = isa<CmpInst>(MainOp);
804 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
806 Instruction *AltOp = MainOp;
807 unsigned Opcode = MainOp->getOpcode();
808 unsigned AltOpcode = Opcode;
809
810 BinOpSameOpcodeHelper BinOpHelper(MainOp);
811 bool SwappedPredsCompatible = IsCmpOp && [&]() {
812 SetVector<unsigned> UniquePreds, UniqueNonSwappedPreds;
813 UniquePreds.insert(BasePred);
814 UniqueNonSwappedPreds.insert(BasePred);
815 for (Value *V : VL) {
816 auto *I = dyn_cast<CmpInst>(V);
817 if (!I)
818 return false;
819 CmpInst::Predicate CurrentPred = I->getPredicate();
820 CmpInst::Predicate SwappedCurrentPred =
821 CmpInst::getSwappedPredicate(CurrentPred);
822 UniqueNonSwappedPreds.insert(CurrentPred);
823 if (!UniquePreds.contains(CurrentPred) &&
824 !UniquePreds.contains(SwappedCurrentPred))
825 UniquePreds.insert(CurrentPred);
826 }
827 // Total number of predicates > 2, but if consider swapped predicates
828 // compatible only 2, consider swappable predicates as compatible opcodes,
829 // not alternate.
830 return UniqueNonSwappedPreds.size() > 2 && UniquePreds.size() == 2;
831 }();
832 // Find the predicate the whole bundle can share, if any, treating
833 // boundary comparisons canonicalized to eq/ne as interchangeable.
835 if (IsCmpOp && isa<ICmpInst>(MainOp))
836 InterchangeablePred =
838 // Check for one alternate opcode from another BinaryOperator.
839 // TODO - generalize to support all operators (types, calls etc.).
840 Intrinsic::ID BaseID = 0;
841 SmallVector<VFInfo, 4> BaseMappings;
842 if (auto *CallBase = dyn_cast<CallInst>(MainOp)) {
844 BaseMappings = VFDatabase(*CallBase).getMappings(*CallBase);
845 if (!isTriviallyVectorizable(BaseID) && BaseMappings.empty())
847 }
848 bool AnyPoison = InstCnt != VL.size();
849 // Check MainOp too to be sure that it matches the requirements for the
850 // instructions.
851 for (Instruction *I :
853 // Cannot combine poison and divisions.
854 // TODO: do some smart analysis of the CallInsts to exclude divide-like
855 // intrinsics/functions only.
856 if (AnyPoison && (I->isIntDivRem() || I->isFPDivRem() || isa<CallInst>(I)))
858 unsigned InstOpcode = I->getOpcode();
859 if (IsBinOp && isa<BinaryOperator>(I)) {
860 if (BinOpHelper.add(I))
861 continue;
862 } else if (IsCastOp && isa<CastInst>(I)) {
863 Value *Op0 = MainOp->getOperand(0);
864 Type *Ty0 = Op0->getType();
865 Value *Op1 = I->getOperand(0);
866 Type *Ty1 = Op1->getType();
867 if (Ty0 == Ty1) {
868 if (InstOpcode == Opcode || InstOpcode == AltOpcode)
869 continue;
870 if (Opcode == AltOpcode) {
872 isValidForAlternation(InstOpcode) &&
873 "Cast isn't safe for alternation, logic needs to be updated!");
874 AltOpcode = InstOpcode;
875 AltOp = I;
876 continue;
877 }
878 }
879 } else if (auto *Inst = dyn_cast<CmpInst>(I); Inst && IsCmpOp) {
880 auto *BaseInst = cast<CmpInst>(MainOp);
881 Type *Ty0 = BaseInst->getOperand(0)->getType();
882 Type *Ty1 = Inst->getOperand(0)->getType();
883 if (Ty0 == Ty1) {
884 assert(InstOpcode == Opcode && "Expected same CmpInst opcode.");
885 assert(InstOpcode == AltOpcode &&
886 "Alternate instructions are only supported by BinaryOperator "
887 "and CastInst.");
888 // Check for compatible operands. If the corresponding operands are not
889 // compatible - need to perform alternate vectorization.
890 CmpInst::Predicate CurrentPred = Inst->getPredicate();
891 CmpInst::Predicate SwappedCurrentPred =
892 CmpInst::getSwappedPredicate(CurrentPred);
893
894 if ((VL.size() == 2 || SwappedPredsCompatible) &&
895 (BasePred == CurrentPred || BasePred == SwappedCurrentPred))
896 continue;
897
898 if (isCmpSameOrSwapped(BaseInst, Inst, TLI))
899 continue;
900 if (CmpSamePredicateHelper::canConvertTo(Inst, InterchangeablePred))
901 continue;
902 auto *AltInst = cast<CmpInst>(AltOp);
903 if (MainOp != AltOp) {
904 if (isCmpSameOrSwapped(AltInst, Inst, TLI))
905 continue;
906 } else if (BasePred != CurrentPred) {
907 assert(
908 isValidForAlternation(InstOpcode) &&
909 "CmpInst isn't safe for alternation, logic needs to be updated!");
910 AltOp = I;
911 continue;
912 }
913 CmpInst::Predicate AltPred = AltInst->getPredicate();
914 if (BasePred == CurrentPred || BasePred == SwappedCurrentPred ||
915 AltPred == CurrentPred || AltPred == SwappedCurrentPred)
916 continue;
917 }
918 } else if (auto *TI = dyn_cast<TruncInst>(I); TI && IsCmpOp) {
919 // trunc X to i1 is the bit test and X, 1 != 0 or and X, 1 == 1, so the
920 // whole list must be the bit tests of the same type sharing the
921 // predicate.
922 if (InterchangeablePred != CmpInst::BAD_ICMP_PREDICATE &&
923 TI->getSrcTy() == MainOp->getOperand(0)->getType() &&
924 all_of(VL, [](Value *V) {
925 auto *I = dyn_cast<Instruction>(V);
926 return isa<PoisonValue>(V) ||
928 }))
929 continue;
930 } else if (InstOpcode == Opcode) {
931 assert(InstOpcode == AltOpcode &&
932 "Alternate instructions are only supported by BinaryOperator and "
933 "CastInst.");
934 if (auto *Gep = dyn_cast<GetElementPtrInst>(I)) {
935 if (Gep->getNumOperands() != 2 ||
936 Gep->getOperand(0)->getType() != MainOp->getOperand(0)->getType())
938 } else if (auto *EI = dyn_cast<ExtractElementInst>(I)) {
941 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
942 auto *BaseLI = cast<LoadInst>(MainOp);
943 if (!LI->isSimple() || !BaseLI->isSimple())
945 } else if (auto *Call = dyn_cast<CallInst>(I)) {
946 auto *CallBase = cast<CallInst>(MainOp);
948 Intrinsic::ID Equivalent = isEquivalentIntrinsicID(ID, BaseID);
949 if (Call->getCalledFunction() != CallBase->getCalledFunction() &&
950 isEquivalentIntrinsicID(Equivalent, Intrinsic::fmuladd) ==
953 if (Call->hasOperandBundles() &&
955 !std::equal(Call->op_begin() + Call->getBundleOperandsStartIndex(),
956 Call->op_begin() + Call->getBundleOperandsEndIndex(),
957 CallBase->op_begin() +
960 if (ID != BaseID && Equivalent == Intrinsic::not_intrinsic)
962 if (!ID) {
963 SmallVector<VFInfo, 4> Mappings =
964 VFDatabase(*Call).getMappings(*Call);
965 if (Mappings.size() != BaseMappings.size() ||
966 Mappings.front().ISA != BaseMappings.front().ISA ||
967 Mappings.front().ScalarName != BaseMappings.front().ScalarName ||
968 Mappings.front().VectorName != BaseMappings.front().VectorName ||
969 Mappings.front().Shape.VF != BaseMappings.front().Shape.VF ||
970 Mappings.front().Shape.Parameters !=
971 BaseMappings.front().Shape.Parameters)
973 }
974 }
975 continue;
976 }
978 }
979
980 if (IsBinOp) {
981 if (!BinOpHelper.hasDefinedMainOpcode() ||
982 !BinOpHelper.hasDefinedAltOpcode())
984 MainOp = findInstructionWithOpcode(VL, BinOpHelper.getMainOpcode());
985 assert(MainOp && "Cannot find MainOp with Opcode from BinOpHelper.");
986 AltOp = findInstructionWithOpcode(VL, BinOpHelper.getAltOpcode());
987 assert(AltOp && "Cannot find AltOp with Opcode from BinOpHelper.");
988 } else if (auto *CB = dyn_cast<CallInst>(MainOp);
989 CB &&
990 getVectorIntrinsicIDForCall(CB, &TLI) == Intrinsic::fmuladd) {
991 // fma and fmuladd share a single vector fma node; use the fma as the
992 // representative so the fused form is not weakened to fmuladd.
993 auto *It = find_if(VL, [&](Value *V) {
994 auto *CI = dyn_cast<CallInst>(V);
995 return CI && getVectorIntrinsicIDForCall(CI, &TLI) == Intrinsic::fma;
996 });
997 if (It != VL.end())
998 MainOp = AltOp = cast<Instruction>(*It);
999 }
1000 if (IsCmpOp && InterchangeablePred != CmpInst::BAD_ICMP_PREDICATE &&
1001 InterchangeablePred != BasePred) {
1002 // Every lane is convertible to the shared predicate, so the alternate
1003 // operation is never set for such bundles.
1004 auto *SharedIt = find_if(VL, [&](Value *V) {
1005 auto *CI = dyn_cast<ICmpInst>(V);
1006 return CI && CI->getPredicate() == InterchangeablePred;
1007 });
1008 assert(SharedIt != VL.end() &&
1009 "Expected an instruction with the shared predicate.");
1010 MainOp = AltOp = cast<Instruction>(*SharedIt);
1011 }
1012 assert((MainOp == AltOp || !allSameOpcode(VL)) &&
1013 "Incorrect implementation of allSameOpcode.");
1014 InstructionsState S(MainOp, AltOp);
1015 assert(all_of(VL,
1016 [&](Value *V) {
1017 return isa<PoisonValue>(V) ||
1019 }) &&
1020 "Invalid InstructionsState.");
1021 return S;
1022}
1023
1024std::pair<Instruction *, SmallVector<Value *>>
1026 Instruction *SelectedOp = S.getMatchingMainOpOrAltOp(I);
1027 assert(SelectedOp && "Cannot convert the instruction.");
1028 if (I->isBinaryOp()) {
1030 return std::make_pair(SelectedOp, Converter.getOperand(SelectedOp));
1031 }
1032 // Use args() to skip the trailing callee operand in CallInst::operands().
1033 if (auto *CI = dyn_cast<CallInst>(I))
1034 return std::make_pair(SelectedOp, SmallVector<Value *>(CI->args()));
1035 // A comparison lane interchangeable with the main operation (e.g. x == 0
1036 // in an x <u C bundle) is emitted with the main predicate and the
1037 // adjusted constant.
1038 if (auto *MainCI = dyn_cast<ICmpInst>(SelectedOp);
1039 MainCI && !S.isAltShuffle())
1041 I, MainCI->getPredicate()))
1042 return std::make_pair(SelectedOp,
1043 SmallVector<Value *>{I->getOperand(0), C});
1044 return std::make_pair(SelectedOp, SmallVector<Value *>(I->operands()));
1045}
1046
1048 Instruction *AltOp, const TargetLibraryInfo &TLI) {
1049 if (auto *MainCI = dyn_cast<CmpInst>(MainOp)) {
1050 auto *AltCI = cast<CmpInst>(AltOp);
1051 CmpInst::Predicate MainP = MainCI->getPredicate();
1052 [[maybe_unused]] CmpInst::Predicate AltP = AltCI->getPredicate();
1053 assert(MainP != AltP && "Expected different main/alternate predicates.");
1054 auto *CI = cast<CmpInst>(I);
1055 if (isCmpSameOrSwapped(MainCI, CI, TLI))
1056 return false;
1057 if (isCmpSameOrSwapped(AltCI, CI, TLI))
1058 return true;
1059 CmpInst::Predicate P = CI->getPredicate();
1061
1062 assert((MainP == P || AltP == P || MainP == SwappedP || AltP == SwappedP) &&
1063 "CmpInst expected to match either main or alternate predicate or "
1064 "their swap.");
1065 return MainP != P && MainP != SwappedP;
1066 }
1067 return InstructionsState(MainOp, AltOp).getMatchingMainOpOrAltOp(I) == AltOp;
1068}
1069
1071 const InstructionsState &S, const TargetLibraryInfo &TLI,
1073 SmallVectorImpl<Value *> &ReassocScalars, SmallBitVector &SubLanes) {
1074 assert(S.isAltShuffle() && "Expected an alternate node.");
1075 const unsigned NumLanes = VL.size();
1076 SmallVector<unsigned> LaneOpcodes =
1077 map_to_vector(seq<unsigned>(NumLanes), [&](unsigned Lane) {
1079 S.getMainOp(), S.getAltOp(), TLI)
1080 ? S.getAltOpcode()
1081 : S.getOpcode();
1082 });
1083 // A lane value peels only as a single-use chain link with the lane's own
1084 // opcode, keeping every combine level on the same main/alt pattern.
1085 auto GetChainLink = [&](unsigned Lane, Value *V) -> Instruction * {
1086 auto *I = dyn_cast<Instruction>(V);
1087 if (!I || !I->hasOneUse() || I->getOpcode() != LaneOpcodes[Lane] ||
1089 return nullptr;
1090 return I;
1091 };
1093 Columns.emplace_back(Op0.begin(), Op0.end());
1094 Columns.emplace_back(Op1.begin(), Op1.end());
1095 // The chain link of a commutative lane may sit in the second column;
1096 // normalize so every lane's link leads.
1097 for (unsigned Lane : seq<unsigned>(NumLanes)) {
1098 if (GetChainLink(Lane, Columns[0][Lane]))
1099 continue;
1100 Instruction *Link = GetChainLink(Lane, Columns[1][Lane]);
1101 if (!Link || !Link->isCommutative())
1102 return {};
1103 std::swap(Columns[0][Lane], Columns[1][Lane]);
1104 }
1105 // Peel the leading column while every lane stays a matching chain link.
1106 while (all_of(seq<unsigned>(NumLanes), [&](unsigned Lane) {
1107 return GetChainLink(Lane, Columns[0][Lane]) != nullptr;
1108 })) {
1109 SmallVector<Value *> NewColumn(NumLanes);
1110 for (unsigned Lane : seq<unsigned>(NumLanes)) {
1111 Instruction *Link = GetChainLink(Lane, Columns[0][Lane]);
1112 ReassocScalars.push_back(Link);
1113 // The chain of a commutative lane may continue in the second operand;
1114 // keep the chain link as the running value.
1115 unsigned RunningOp = Link->isCommutative() &&
1116 !GetChainLink(Lane, Link->getOperand(0)) &&
1117 GetChainLink(Lane, Link->getOperand(1))
1118 ? 1
1119 : 0;
1120 NewColumn[Lane] = Link->getOperand(1 - RunningOp);
1121 Columns[0][Lane] = Link->getOperand(RunningOp);
1122 }
1123 Columns.insert(std::next(Columns.begin()), std::move(NewColumn));
1124 }
1125 assert(!ReassocScalars.empty() &&
1126 "Normalization guarantees at least one peeled level.");
1127 SubLanes.resize(NumLanes);
1128 for (unsigned Lane : seq<unsigned>(NumLanes))
1129 if (LaneOpcodes[Lane] == Instruction::Sub ||
1130 LaneOpcodes[Lane] == Instruction::FSub)
1131 SubLanes.set(Lane);
1132 return Columns;
1133}
1134} // namespace llvm::slpvectorizer
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Early If Converter
Hexagon Common GEP
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
#define P(N)
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
This file defines less commonly used SmallVector utilities.
This file defines the SmallVector class.
Value * RHS
Value * LHS
This file implements the C++20 <bit> header.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition APInt.h:202
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
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
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1115
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:215
unsigned logBase2() const
Definition APInt.h:1781
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:436
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
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
unsigned getBundleOperandsStartIndex() const
Return the index of the first bundle operand in the Use array.
bool hasOperandBundles() const
Return true if this User has any operand bundles.
This class is the base class for the comparison instructions.
Definition InstrTypes.h:728
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
bool isSigned() const
Definition InstrTypes.h:993
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
bool isIntPredicate() const
Definition InstrTypes.h:846
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 an important base class in LLVM.
Definition Constant.h:43
This instruction compares its operands according to the predicate given to the constructor.
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isIntDivRem() const
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
SmallBitVector & set()
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
op_iterator op_begin()
Definition User.h:259
Value * getOperand(unsigned i) const
Definition User.h:207
The Vector Function Database.
Definition VectorUtils.h:35
static SmallVector< VFInfo, 8 > getMappings(const CallInst &CI)
Retrieve all the VFInfo instances associated to the CallInst CI.
Definition VectorUtils.h:76
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
Helper class that determines VL can use the same opcode.
bool hasCandidateOpcode(unsigned Opcode) const
Checks if the list of potential opcodes includes Opcode.
Helper class that determines whether a list of integer comparisons can share a single predicate.
static CmpInst::Predicate getSharedPredicate(ArrayRef< Value * > VL, const ICmpInst *Preferred)
Returns the predicate the whole list can share, or BAD_ICMP_PREDICATE when it cannot share a natively...
static Constant * getAdjustedConstant(const Instruction *I, CmpInst::Predicate Pred)
Returns the adjusted constant operand expressing the comparison lane I with the predicate Pred,...
CmpInst::Predicate getPredicate(const ICmpInst *Preferred) const
Returns the shared predicate, preferring the predicate of Preferred when the whole list can use it,...
static bool isBitTest(const Instruction *I)
Checks if the comparison lane I is the bit test of the single use and A, B != 0 or and A,...
bool add(const Instruction *I)
Intersects the convertible predicate set of the comparison lane I (an icmp or a trunc to i1) with the...
static bool canConvertTo(const Instruction *I, CmpInst::Predicate Pred)
Checks if the comparison lane I can be expressed with the predicate Pred by adjusting its constant op...
Main data required for vectorization of instructions.
Instruction * getMatchingMainOpOrAltOp(Instruction *I) const
Checks if the instruction matches either the main or alternate opcode.
static bool isSameOperation(const Instruction *I, const Instruction *Op)
Checks if I is the same operation as Op, distinguishing calls by intrinsic ID (all calls share the Ca...
bool valid() const
Checks if the current state is valid, i.e. has non-null MainOp.
bool isExpandedBinOp(Value *V) const
Checks if the value V is a transformed instruction, compatible either with main or alternate ops.
bool isAddSubLikeOp() const
Checks if main/alt instructions are add/sub/fadd/fsub operations.
bool isExpandedOperand(Instruction *I, unsigned Idx) const
Checks if the operand at index Idx of instruction I is an expanded operand.
bool isCopyableElement(Value *V) const
Checks if the value is a copyable element.
bool isAltShuffle() const
Some of the instructions in the list have alternate opcodes.
bool isNonSchedulable(Value *V) const
Checks if the value is non-schedulable.
bool isAddSubOrFNegLikeOp() const
Checks for an add/sub-like operation or an fneg, which models a flattened fadd reduction chain link: ...
bool isMulDivLikeOp() const
Checks if main/alt instructions are mul/div/rem/fmul/fdiv/frem operations.
unsigned getOpcode() const
The main/alternate opcodes for the list of instructions.
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
A private "module" namespace for types and utilities used by this pass.
static std::optional< std::pair< bool, APInt > > getCmpBoundaryFamily(CmpInst::Predicate Pred, const APInt &C)
If the comparison (Pred, X, C) is a single-element or single-complement range check,...
SmallVector< SmallVector< Value * > > scanAltAssociativeOperands(const InstructionsState &S, const TargetLibraryInfo &TLI, ArrayRef< Value * > VL, ArrayRef< Value * > Op0, ArrayRef< Value * > Op1, SmallVectorImpl< Value * > &ReassocScalars, SmallBitVector &SubLanes)
Peel the per-lane associative chains of an alternate node into operand columns.
std::pair< Instruction *, SmallVector< Value * > > convertTo(Instruction *I, const InstructionsState &S)
bool isAlternateInstruction(Instruction *I, Instruction *MainOp, Instruction *AltOp, const TargetLibraryInfo &TLI)
Checks if the specified instruction I is an alternate operation for the given MainOp and AltOp instru...
static std::optional< std::pair< CmpInst::Predicate, APInt > > getLaneConstantCmp(const Instruction *I)
Returns the predicate and the compared constant of the comparison lane I, treating trunc X to i1 as a...
bool allSameOpcode(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:282
bool isValidForAlternation(unsigned Opcode)
static bool areCompatibleCmpOps(Value *BaseOp0, Value *BaseOp1, Value *Op0, Value *Op1, const TargetLibraryInfo &TLI)
Checks if the provided operands of 2 cmp instructions are compatible, i.e.
static Instruction * findInstructionWithOpcode(ArrayRef< Value * > VL, unsigned Opcode)
Find an instruction with a specific opcode in VL.
bool hasOnlyAbsorbableCopyableFMulOrFAdds(ArrayRef< Value * > VL)
Checks if every copyable in VL is an absorbable fmul/fadd: the binops die instead of being computed a...
bool isCommutative(const Instruction *I, const Value *ValWithUses, bool IsCopyable)
Definition SLPUtils.cpp:188
bool isReassocChainLink(const Instruction *I)
Definition SLPUtils.cpp:82
Intrinsic::ID isEquivalentIntrinsicID(Intrinsic::ID LHS, Intrinsic::ID RHS)
Checks if LHS and RHS are the same intrinsic, or one is llvm.fma and the other is llvm....
Definition SLPUtils.cpp:179
InstructionsState getSameOpcode(ArrayRef< Value * > VL, const TargetLibraryInfo &TLI)
bool isAbsorbableCopyableFMulOrFAdd(const InstructionsState &S, Value *V)
Checks if V is a copyable single-use fmul/fadd, absorbable as fmuladd(a, b, -0.0) or fmuladd(1....
bool isVectorLikeInstWithConstOps(Value *V)
Checks if V is one of vector-like instructions, i.e.
Definition SLPUtils.cpp:90
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
Definition SLPUtils.cpp:505
bool isConstant(Value *V)
Definition SLPUtils.cpp:47
bool isAbsorbableFMulOrFAdd(ArrayRef< Value * > VL, Value *V)
Checks if V is a single-use fmul/fadd with operands outside VL.
static bool isCmpSameOrSwapped(const CmpInst *BaseCI, const CmpInst *CI, const TargetLibraryInfo &TLI)
This is an optimization pass for GlobalISel generic memory operations.
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 getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
auto binary_search(R &&Range, T &&Value)
Provide wrappers to std::binary_search which take ranges instead of having to pass begin/end explicit...
Definition STLExtras.h:2055
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
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
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
DWARFExpression::Operation Op
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 auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880