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
424 MaskType LaneMask = getBit(CI->getPredicate());
425 if (auto *C = dyn_cast<ConstantInt>(CI->getOperand(1)))
426 LaneMask = getFormsMask(CI->getPredicate(), C->getValue());
427 SeenBefore |= getBit(CI->getPredicate());
428 Mask &= LaneMask;
429 return Mask != 0;
430}
431
434 MaskType Candidate = Mask & SeenBefore;
435 if (!Candidate)
437 if (Candidate & getBit(Preferred->getPredicate()))
438 return Preferred->getPredicate();
439 return static_cast<CmpInst::Predicate>(CmpInst::ICMP_EQ +
440 countr_zero(Candidate));
441}
442
445 const ICmpInst *Preferred) {
447 if (!all_of(VL, [&](Value *V) {
448 auto *CI = dyn_cast<ICmpInst>(V);
449 return isa<PoisonValue>(V) || (CI && Helper.add(CI));
450 }))
452 return Helper.getPredicate(Preferred);
453}
454
456 CmpInst::Predicate Pred) {
457 auto *ICI = dyn_cast<ICmpInst>(CI);
458 if (!ICI || !CmpInst::isIntPredicate(Pred))
459 return false;
460 if (ICI->getPredicate() == Pred)
461 return true;
462 auto *C = dyn_cast<ConstantInt>(ICI->getOperand(1));
463 return C &&
464 (getFormsMask(ICI->getPredicate(), C->getValue()) & getBit(Pred)) != 0;
465}
466
469 CmpInst::Predicate Pred) {
470 if (!canConvertTo(CI, Pred))
471 return nullptr;
472 auto *ICI = cast<ICmpInst>(CI);
473 if (ICI->getPredicate() == Pred)
474 return nullptr;
475 auto *C = cast<ConstantInt>(ICI->getOperand(1));
476 std::optional<std::pair<bool, APInt>> Family =
477 getCmpBoundaryFamily(ICI->getPredicate(), C->getValue());
478 assert(Family && "Expected a boundary family for a convertible compare.");
479 const auto &[IsComplement, K] = *Family;
480 return ConstantInt::get(CI->getContext(),
481 getFamilyConstant(IsComplement, K, Pred));
482}
483
485 const Instruction *Op) {
486 if (I->getOpcode() != Op->getOpcode())
487 return false;
488 const auto *II = dyn_cast<IntrinsicInst>(I);
489 const auto *IOp = dyn_cast<IntrinsicInst>(Op);
490 if (II || IOp)
491 return II && IOp &&
492 isEquivalentIntrinsicID(II->getIntrinsicID(),
493 IOp->getIntrinsicID()) !=
495 return true;
496}
497
499 assert(MainOp && "MainOp cannot be nullptr.");
500 if (isSameOperation(I, MainOp))
501 return MainOp;
502 if (MainOp->getOpcode() == Instruction::Select &&
503 I->getOpcode() == Instruction::ZExt && !isAltShuffle())
504 return MainOp;
505 // Prefer AltOp instead of interchangeable instruction of MainOp.
506 assert(AltOp && "AltOp cannot be nullptr.");
507 if (isSameOperation(I, AltOp))
508 return AltOp;
509 // BinOpSameOpcodeHelper handles only BinaryOperators; a call cannot match.
510 if (!I->isBinaryOp() || !MainOp->isBinaryOp())
511 return nullptr;
513 if (!Converter.add(I) || !Converter.add(MainOp))
514 return nullptr;
515 if (isAltShuffle() && !Converter.hasCandidateOpcode(MainOp->getOpcode())) {
516 BinOpSameOpcodeHelper AltConverter(AltOp);
517 if (AltConverter.add(I) && AltConverter.add(AltOp) &&
518 AltConverter.hasCandidateOpcode(AltOp->getOpcode()))
519 return AltOp;
520 }
521 if (Converter.hasAltOp() && !isAltShuffle())
522 return nullptr;
523 return Converter.hasAltOp() ? AltOp : MainOp;
524}
525
527 constexpr std::array<unsigned, 8> MulDiv = {
528 Instruction::Mul, Instruction::FMul, Instruction::SDiv,
529 Instruction::UDiv, Instruction::FDiv, Instruction::SRem,
530 Instruction::URem, Instruction::FRem};
531 return is_contained(MulDiv, getOpcode()) &&
532 is_contained(MulDiv, getAltOpcode());
533}
534
536 constexpr std::array<unsigned, 4> AddSub = {
537 Instruction::Add, Instruction::Sub, Instruction::FAdd, Instruction::FSub};
538 return is_contained(AddSub, getOpcode()) &&
539 is_contained(AddSub, getAltOpcode());
540}
541
543 return isAddSubLikeOp() || getOpcode() == Instruction::FNeg;
544}
545
547 assert(valid() && "InstructionsState is invalid.");
548 if (!HasCopyables)
549 return false;
550 if (isAltShuffle())
551 return false;
552 auto *I = dyn_cast<Instruction>(V);
553 // Copyable lanes of a cast node are limited to constants representable as
554 // the cast of a source-type constant.
555 if (isa<CastInst>(MainOp)) {
556 if (I || isa<PoisonValue>(V))
557 return false;
558 if (isa<UndefValue>(V))
559 return true;
560 auto *C = dyn_cast<ConstantInt>(V);
561 return C && C->getValue().getActiveBits() <=
562 cast<CastInst>(MainOp)->getSrcTy()->getIntegerBitWidth();
563 }
564 if (!I)
565 return !isa<PoisonValue>(V);
566 // For a GEP main op only single-index GEPs with the same source element
567 // type can be matching lanes; GEPs with a different shape are copyable.
568 if (getOpcode() == Instruction::GetElementPtr)
569 if (auto *GEP = dyn_cast<GetElementPtrInst>(I);
570 GEP && (GEP->getNumOperands() != 2 ||
571 GEP->getSourceElementType() !=
572 cast<GetElementPtrInst>(MainOp)->getSourceElementType()))
573 return true;
574 if (I->getParent() != MainOp->getParent() &&
577 return true;
578 if (isSameOperation(I, MainOp))
579 return false;
580 // BinOpSameOpcodeHelper handles only BinaryOperators; a call is copyable.
581 if (!I->isBinaryOp() || !MainOp->isBinaryOp())
582 return true;
584 return !Converter.add(I) || !Converter.add(MainOp) || Converter.hasAltOp() ||
585 !Converter.hasCandidateOpcode(getOpcode());
586}
587
589 auto *I = dyn_cast<Instruction>(V);
590 return I &&
591 (I->getOpcode() == Instruction::FMul ||
592 I->getOpcode() == Instruction::FAdd) &&
593 I->hasOneUse() && none_of(I->operands(), [&](Value *Op) {
594 return is_contained(VL, Op);
595 });
596}
597
599 auto *I = dyn_cast<Instruction>(V);
600 return I && S.isCopyableElement(I) &&
601 (I->getOpcode() == Instruction::FMul ||
602 I->getOpcode() == Instruction::FAdd) &&
603 I->hasOneUse();
604}
605
607 bool HasFMulOrFAdd = false;
608 for (Value *V :
609 make_filter_range(VL, [](Value *V) { return !isa<PoisonValue>(V); })) {
610 auto *I = dyn_cast<Instruction>(V);
612 continue;
613 if (!isAbsorbableFMulOrFAdd(VL, V))
614 return false;
615 HasFMulOrFAdd = true;
616 }
617 return HasFMulOrFAdd;
618}
619
621 assert(valid() && "InstructionsState is invalid.");
622 if (isCopyableElement(V))
623 return false;
624 auto *ExpandingOp = dyn_cast<Instruction>(V);
625 if (!ExpandingOp)
626 return false;
627 auto CheckForTransformedOpcode = [](const Instruction *RefOp,
628 const Instruction *ExpandingOp) {
629 switch (RefOp->getOpcode()) {
630 case Instruction::Add:
631 switch (ExpandingOp->getOpcode()) {
632 case Instruction::Shl:
633 return match(ExpandingOp, m_Shl(m_Value(), m_One()));
634 default:
635 break;
636 }
637 break;
638 default:
639 break;
640 }
641 return false;
642 };
643 // getMatchingMainOpOrAltOp() may legitimately return nullptr, e.g. for a
644 // split node, whose Scalars combine two unrelated operations (main/alt
645 // ops of the split state), so V is not required to match either of them.
646 Instruction *MainOp = getMatchingMainOpOrAltOp(ExpandingOp);
647 if (!MainOp)
648 return false;
649 return CheckForTransformedOpcode(MainOp, ExpandingOp);
650}
651
653 assert(isExpandedBinOp(I) && "Expected an expanded binop.");
654 switch (I->getOpcode()) {
655 case Instruction::Shl:
656 assert(match(I, m_Shl(m_Value(), m_One())) && "Expected shl x, 1 only.");
657 return Idx == 1;
658 default:
659 llvm_unreachable("Unexpected opcode for an expanded operand.");
660 }
661}
662
664 assert(valid() && "InstructionsState is invalid.");
665 auto *I = dyn_cast<Instruction>(V);
666 if (!HasCopyables)
669 // MainOp for copyables always schedulable to correctly identify
670 // non-schedulable copyables.
671 if (getMainOp() == V)
672 return false;
673 if (isCopyableElement(V)) {
674 auto IsNonSchedulableCopyableElement = [this](Value *V) {
675 auto *I = dyn_cast<Instruction>(V);
676 return !I || isa<PHINode>(I) || I->getParent() != MainOp->getParent() ||
678 // If the copyable instructions comes after MainOp
679 // (non-schedulable, but used in the block) - cannot vectorize
680 // it, will possibly generate use before def.
681 !MainOp->comesBefore(I));
682 };
683
684 return IsNonSchedulableCopyableElement(V);
685 }
688}
689
690/// Find an instruction with a specific opcode in VL.
691/// \param VL Array of values to search through. Must contain only Instructions
692/// and PoisonValues.
693/// \param Opcode The instruction opcode to search for
694/// \returns
695/// - The first instruction found with matching opcode
696/// - nullptr if no matching instruction is found
698 unsigned Opcode) {
699 for (Value *V :
700 make_filter_range(VL, [](Value *V) { return !isa<PoisonValue>(V); })) {
701 assert(isa<Instruction>(V) && "Only accepts PoisonValue and Instruction.");
702 auto *Inst = cast<Instruction>(V);
703 if (Inst->getOpcode() == Opcode)
704 return Inst;
705 }
706 return nullptr;
707}
708
709/// Checks if the provided operands of 2 cmp instructions are compatible, i.e.
710/// compatible instructions or constants, or just some other regular values.
711static bool areCompatibleCmpOps(Value *BaseOp0, Value *BaseOp1, Value *Op0,
712 Value *Op1, const TargetLibraryInfo &TLI) {
713 return (isConstant(BaseOp0) && isConstant(Op0)) ||
714 (isConstant(BaseOp1) && isConstant(Op1)) ||
715 (!isa<Instruction>(BaseOp0) && !isa<Instruction>(Op0) &&
716 !isa<Instruction>(BaseOp1) && !isa<Instruction>(Op1)) ||
717 BaseOp0 == Op0 || BaseOp1 == Op1 ||
718 getSameOpcode({BaseOp0, Op0}, TLI) ||
719 getSameOpcode({BaseOp1, Op1}, TLI);
720}
721
722/// \returns true if a compare instruction \p CI has similar "look" and
723/// same predicate as \p BaseCI, "as is" or with its operands and predicate
724/// swapped, false otherwise.
725static bool isCmpSameOrSwapped(const CmpInst *BaseCI, const CmpInst *CI,
726 const TargetLibraryInfo &TLI) {
727 assert(BaseCI->getOperand(0)->getType() == CI->getOperand(0)->getType() &&
728 "Assessing comparisons of different types?");
729 CmpInst::Predicate BasePred = BaseCI->getPredicate();
730 CmpInst::Predicate Pred = CI->getPredicate();
732
733 Value *BaseOp0 = BaseCI->getOperand(0);
734 Value *BaseOp1 = BaseCI->getOperand(1);
735 Value *Op0 = CI->getOperand(0);
736 Value *Op1 = CI->getOperand(1);
737
738 return (BasePred == Pred &&
739 areCompatibleCmpOps(BaseOp0, BaseOp1, Op0, Op1, TLI)) ||
740 (BasePred == SwappedPred &&
741 areCompatibleCmpOps(BaseOp0, BaseOp1, Op1, Op0, TLI));
742}
743
745 const TargetLibraryInfo &TLI) {
746 // Make sure these are all Instructions.
749
750 auto *It = find_if(VL, IsaPred<Instruction>);
751 if (It == VL.end())
753
754 Instruction *MainOp = cast<Instruction>(*It);
755 unsigned InstCnt = std::count_if(It, VL.end(), IsaPred<Instruction>);
756 if ((VL.size() > 2 && !isa<PHINode>(MainOp) && InstCnt < VL.size() / 2) ||
757 (VL.size() == 2 && InstCnt < 2))
759
760 bool IsCastOp = isa<CastInst>(MainOp);
761 bool IsBinOp = isa<BinaryOperator>(MainOp);
762 bool IsCmpOp = isa<CmpInst>(MainOp);
763 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
765 Instruction *AltOp = MainOp;
766 unsigned Opcode = MainOp->getOpcode();
767 unsigned AltOpcode = Opcode;
768
769 BinOpSameOpcodeHelper BinOpHelper(MainOp);
770 bool SwappedPredsCompatible = IsCmpOp && [&]() {
771 SetVector<unsigned> UniquePreds, UniqueNonSwappedPreds;
772 UniquePreds.insert(BasePred);
773 UniqueNonSwappedPreds.insert(BasePred);
774 for (Value *V : VL) {
775 auto *I = dyn_cast<CmpInst>(V);
776 if (!I)
777 return false;
778 CmpInst::Predicate CurrentPred = I->getPredicate();
779 CmpInst::Predicate SwappedCurrentPred =
780 CmpInst::getSwappedPredicate(CurrentPred);
781 UniqueNonSwappedPreds.insert(CurrentPred);
782 if (!UniquePreds.contains(CurrentPred) &&
783 !UniquePreds.contains(SwappedCurrentPred))
784 UniquePreds.insert(CurrentPred);
785 }
786 // Total number of predicates > 2, but if consider swapped predicates
787 // compatible only 2, consider swappable predicates as compatible opcodes,
788 // not alternate.
789 return UniqueNonSwappedPreds.size() > 2 && UniquePreds.size() == 2;
790 }();
791 // Find the predicate the whole bundle can share, if any, treating
792 // boundary comparisons canonicalized to eq/ne as interchangeable.
794 if (IsCmpOp && isa<ICmpInst>(MainOp))
795 InterchangeablePred =
797 // Check for one alternate opcode from another BinaryOperator.
798 // TODO - generalize to support all operators (types, calls etc.).
799 Intrinsic::ID BaseID = 0;
800 SmallVector<VFInfo, 4> BaseMappings;
801 if (auto *CallBase = dyn_cast<CallInst>(MainOp)) {
803 BaseMappings = VFDatabase(*CallBase).getMappings(*CallBase);
804 if (!isTriviallyVectorizable(BaseID) && BaseMappings.empty())
806 }
807 bool AnyPoison = InstCnt != VL.size();
808 // Check MainOp too to be sure that it matches the requirements for the
809 // instructions.
810 for (Instruction *I :
812 // Cannot combine poison and divisions.
813 // TODO: do some smart analysis of the CallInsts to exclude divide-like
814 // intrinsics/functions only.
815 if (AnyPoison && (I->isIntDivRem() || I->isFPDivRem() || isa<CallInst>(I)))
817 unsigned InstOpcode = I->getOpcode();
818 if (IsBinOp && isa<BinaryOperator>(I)) {
819 if (BinOpHelper.add(I))
820 continue;
821 } else if (IsCastOp && isa<CastInst>(I)) {
822 Value *Op0 = MainOp->getOperand(0);
823 Type *Ty0 = Op0->getType();
824 Value *Op1 = I->getOperand(0);
825 Type *Ty1 = Op1->getType();
826 if (Ty0 == Ty1) {
827 if (InstOpcode == Opcode || InstOpcode == AltOpcode)
828 continue;
829 if (Opcode == AltOpcode) {
831 isValidForAlternation(InstOpcode) &&
832 "Cast isn't safe for alternation, logic needs to be updated!");
833 AltOpcode = InstOpcode;
834 AltOp = I;
835 continue;
836 }
837 }
838 } else if (auto *Inst = dyn_cast<CmpInst>(I); Inst && IsCmpOp) {
839 auto *BaseInst = cast<CmpInst>(MainOp);
840 Type *Ty0 = BaseInst->getOperand(0)->getType();
841 Type *Ty1 = Inst->getOperand(0)->getType();
842 if (Ty0 == Ty1) {
843 assert(InstOpcode == Opcode && "Expected same CmpInst opcode.");
844 assert(InstOpcode == AltOpcode &&
845 "Alternate instructions are only supported by BinaryOperator "
846 "and CastInst.");
847 // Check for compatible operands. If the corresponding operands are not
848 // compatible - need to perform alternate vectorization.
849 CmpInst::Predicate CurrentPred = Inst->getPredicate();
850 CmpInst::Predicate SwappedCurrentPred =
851 CmpInst::getSwappedPredicate(CurrentPred);
852
853 if ((VL.size() == 2 || SwappedPredsCompatible) &&
854 (BasePred == CurrentPred || BasePred == SwappedCurrentPred))
855 continue;
856
857 if (isCmpSameOrSwapped(BaseInst, Inst, TLI))
858 continue;
859 if (CmpSamePredicateHelper::canConvertTo(Inst, InterchangeablePred))
860 continue;
861 auto *AltInst = cast<CmpInst>(AltOp);
862 if (MainOp != AltOp) {
863 if (isCmpSameOrSwapped(AltInst, Inst, TLI))
864 continue;
865 } else if (BasePred != CurrentPred) {
866 assert(
867 isValidForAlternation(InstOpcode) &&
868 "CmpInst isn't safe for alternation, logic needs to be updated!");
869 AltOp = I;
870 continue;
871 }
872 CmpInst::Predicate AltPred = AltInst->getPredicate();
873 if (BasePred == CurrentPred || BasePred == SwappedCurrentPred ||
874 AltPred == CurrentPred || AltPred == SwappedCurrentPred)
875 continue;
876 }
877 } else if (InstOpcode == Opcode) {
878 assert(InstOpcode == AltOpcode &&
879 "Alternate instructions are only supported by BinaryOperator and "
880 "CastInst.");
881 if (auto *Gep = dyn_cast<GetElementPtrInst>(I)) {
882 if (Gep->getNumOperands() != 2 ||
883 Gep->getOperand(0)->getType() != MainOp->getOperand(0)->getType())
885 } else if (auto *EI = dyn_cast<ExtractElementInst>(I)) {
888 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
889 auto *BaseLI = cast<LoadInst>(MainOp);
890 if (!LI->isSimple() || !BaseLI->isSimple())
892 } else if (auto *Call = dyn_cast<CallInst>(I)) {
893 auto *CallBase = cast<CallInst>(MainOp);
895 Intrinsic::ID Equivalent = isEquivalentIntrinsicID(ID, BaseID);
896 if (Call->getCalledFunction() != CallBase->getCalledFunction() &&
897 isEquivalentIntrinsicID(Equivalent, Intrinsic::fmuladd) ==
900 if (Call->hasOperandBundles() &&
902 !std::equal(Call->op_begin() + Call->getBundleOperandsStartIndex(),
903 Call->op_begin() + Call->getBundleOperandsEndIndex(),
904 CallBase->op_begin() +
907 if (ID != BaseID && Equivalent == Intrinsic::not_intrinsic)
909 if (!ID) {
910 SmallVector<VFInfo, 4> Mappings =
911 VFDatabase(*Call).getMappings(*Call);
912 if (Mappings.size() != BaseMappings.size() ||
913 Mappings.front().ISA != BaseMappings.front().ISA ||
914 Mappings.front().ScalarName != BaseMappings.front().ScalarName ||
915 Mappings.front().VectorName != BaseMappings.front().VectorName ||
916 Mappings.front().Shape.VF != BaseMappings.front().Shape.VF ||
917 Mappings.front().Shape.Parameters !=
918 BaseMappings.front().Shape.Parameters)
920 }
921 }
922 continue;
923 }
925 }
926
927 if (IsBinOp) {
928 if (!BinOpHelper.hasDefinedMainOpcode() ||
929 !BinOpHelper.hasDefinedAltOpcode())
931 MainOp = findInstructionWithOpcode(VL, BinOpHelper.getMainOpcode());
932 assert(MainOp && "Cannot find MainOp with Opcode from BinOpHelper.");
933 AltOp = findInstructionWithOpcode(VL, BinOpHelper.getAltOpcode());
934 assert(AltOp && "Cannot find AltOp with Opcode from BinOpHelper.");
935 } else if (auto *CB = dyn_cast<CallInst>(MainOp);
936 CB &&
937 getVectorIntrinsicIDForCall(CB, &TLI) == Intrinsic::fmuladd) {
938 // fma and fmuladd share a single vector fma node; use the fma as the
939 // representative so the fused form is not weakened to fmuladd.
940 auto *It = find_if(VL, [&](Value *V) {
941 auto *CI = dyn_cast<CallInst>(V);
942 return CI && getVectorIntrinsicIDForCall(CI, &TLI) == Intrinsic::fma;
943 });
944 if (It != VL.end())
945 MainOp = AltOp = cast<Instruction>(*It);
946 }
947 if (IsCmpOp && InterchangeablePred != CmpInst::BAD_ICMP_PREDICATE &&
948 InterchangeablePred != BasePred) {
949 // Every lane is convertible to the shared predicate, so the alternate
950 // operation is never set for such bundles.
951 auto *SharedIt = find_if(VL, [&](Value *V) {
952 auto *CI = dyn_cast<ICmpInst>(V);
953 return CI && CI->getPredicate() == InterchangeablePred;
954 });
955 assert(SharedIt != VL.end() &&
956 "Expected an instruction with the shared predicate.");
957 MainOp = AltOp = cast<Instruction>(*SharedIt);
958 }
959 assert((MainOp == AltOp || !allSameOpcode(VL)) &&
960 "Incorrect implementation of allSameOpcode.");
961 InstructionsState S(MainOp, AltOp);
962 assert(all_of(VL,
963 [&](Value *V) {
964 return isa<PoisonValue>(V) ||
966 }) &&
967 "Invalid InstructionsState.");
968 return S;
969}
970
971std::pair<Instruction *, SmallVector<Value *>>
973 Instruction *SelectedOp = S.getMatchingMainOpOrAltOp(I);
974 assert(SelectedOp && "Cannot convert the instruction.");
975 if (I->isBinaryOp()) {
977 return std::make_pair(SelectedOp, Converter.getOperand(SelectedOp));
978 }
979 // Use args() to skip the trailing callee operand in CallInst::operands().
980 if (auto *CI = dyn_cast<CallInst>(I))
981 return std::make_pair(SelectedOp, SmallVector<Value *>(CI->args()));
982 // A comparison lane interchangeable with the main operation (e.g. x == 0
983 // in an x <u C bundle) is emitted with the main predicate and the
984 // adjusted constant.
985 if (auto *MainCI = dyn_cast<ICmpInst>(SelectedOp);
986 MainCI && !S.isAltShuffle())
988 cast<ICmpInst>(I), MainCI->getPredicate()))
989 return std::make_pair(SelectedOp,
990 SmallVector<Value *>{I->getOperand(0), C});
991 return std::make_pair(SelectedOp, SmallVector<Value *>(I->operands()));
992}
993
995 Instruction *AltOp, const TargetLibraryInfo &TLI) {
996 if (auto *MainCI = dyn_cast<CmpInst>(MainOp)) {
997 auto *AltCI = cast<CmpInst>(AltOp);
998 CmpInst::Predicate MainP = MainCI->getPredicate();
999 [[maybe_unused]] CmpInst::Predicate AltP = AltCI->getPredicate();
1000 assert(MainP != AltP && "Expected different main/alternate predicates.");
1001 auto *CI = cast<CmpInst>(I);
1002 if (isCmpSameOrSwapped(MainCI, CI, TLI))
1003 return false;
1004 if (isCmpSameOrSwapped(AltCI, CI, TLI))
1005 return true;
1006 CmpInst::Predicate P = CI->getPredicate();
1008
1009 assert((MainP == P || AltP == P || MainP == SwappedP || AltP == SwappedP) &&
1010 "CmpInst expected to match either main or alternate predicate or "
1011 "their swap.");
1012 return MainP != P && MainP != SwappedP;
1013 }
1014 return InstructionsState(MainOp, AltOp).getMatchingMainOpOrAltOp(I) == AltOp;
1015}
1016
1018 const InstructionsState &S, const TargetLibraryInfo &TLI,
1020 SmallVectorImpl<Value *> &ReassocScalars, SmallBitVector &SubLanes) {
1021 assert(S.isAltShuffle() && "Expected an alternate node.");
1022 const unsigned NumLanes = VL.size();
1023 SmallVector<unsigned> LaneOpcodes =
1024 map_to_vector(seq<unsigned>(NumLanes), [&](unsigned Lane) {
1026 S.getMainOp(), S.getAltOp(), TLI)
1027 ? S.getAltOpcode()
1028 : S.getOpcode();
1029 });
1030 // A lane value peels only as a single-use chain link with the lane's own
1031 // opcode, keeping every combine level on the same main/alt pattern.
1032 auto GetChainLink = [&](unsigned Lane, Value *V) -> Instruction * {
1033 auto *I = dyn_cast<Instruction>(V);
1034 if (!I || !I->hasOneUse() || I->getOpcode() != LaneOpcodes[Lane] ||
1036 return nullptr;
1037 return I;
1038 };
1040 Columns.emplace_back(Op0.begin(), Op0.end());
1041 Columns.emplace_back(Op1.begin(), Op1.end());
1042 // The chain link of a commutative lane may sit in the second column;
1043 // normalize so every lane's link leads.
1044 for (unsigned Lane : seq<unsigned>(NumLanes)) {
1045 if (GetChainLink(Lane, Columns[0][Lane]))
1046 continue;
1047 Instruction *Link = GetChainLink(Lane, Columns[1][Lane]);
1048 if (!Link || !Link->isCommutative())
1049 return {};
1050 std::swap(Columns[0][Lane], Columns[1][Lane]);
1051 }
1052 // Peel the leading column while every lane stays a matching chain link.
1053 while (all_of(seq<unsigned>(NumLanes), [&](unsigned Lane) {
1054 return GetChainLink(Lane, Columns[0][Lane]) != nullptr;
1055 })) {
1056 SmallVector<Value *> NewColumn(NumLanes);
1057 for (unsigned Lane : seq<unsigned>(NumLanes)) {
1058 Instruction *Link = GetChainLink(Lane, Columns[0][Lane]);
1059 ReassocScalars.push_back(Link);
1060 // The chain of a commutative lane may continue in the second operand;
1061 // keep the chain link as the running value.
1062 unsigned RunningOp = Link->isCommutative() &&
1063 !GetChainLink(Lane, Link->getOperand(0)) &&
1064 GetChainLink(Lane, Link->getOperand(1))
1065 ? 1
1066 : 0;
1067 NewColumn[Lane] = Link->getOperand(1 - RunningOp);
1068 Columns[0][Lane] = Link->getOperand(RunningOp);
1069 }
1070 Columns.insert(std::next(Columns.begin()), std::move(NewColumn));
1071 }
1072 assert(!ReassocScalars.empty() &&
1073 "Normalization guarantees at least one peeled level.");
1074 SubLanes.resize(NumLanes);
1075 for (unsigned Lane : seq<unsigned>(NumLanes))
1076 if (LaneOpcodes[Lane] == Instruction::Sub ||
1077 LaneOpcodes[Lane] == Instruction::FSub)
1078 SubLanes.set(Lane);
1079 return Columns;
1080}
1081} // 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
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
static bool isIntPredicate(Predicate P)
Definition InstrTypes.h:839
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
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
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
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
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...
CmpInst::Predicate getPredicate(const ICmpInst *Preferred) const
Returns the shared predicate, preferring the predicate of Preferred when the whole list can use it,...
bool add(const ICmpInst *CI)
Intersects the convertible predicate set of CI with the running set.
static ConstantInt * getAdjustedConstant(const CmpInst *CI, CmpInst::Predicate Pred)
Returns the adjusted constant operand expressing CI with the predicate Pred, or nullptr if not conver...
static bool canConvertTo(const CmpInst *CI, CmpInst::Predicate Pred)
Checks if the comparison CI can be expressed with the predicate Pred by adjusting its constant operan...
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.
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...
bool allSameOpcode(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:258
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:165
bool isReassocChainLink(const Instruction *I)
Definition SLPUtils.cpp:59
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:156
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:67
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
Definition SLPUtils.cpp:481
bool isConstant(Value *V)
Definition SLPUtils.cpp:39
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