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_or_null<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() || getOpcode() == Instruction::GetElementPtr)
551 return false;
552 auto *I = dyn_cast<Instruction>(V);
553 if (!I)
554 return !isa<PoisonValue>(V);
555 if (I->getParent() != MainOp->getParent() &&
558 return true;
559 if (isSameOperation(I, MainOp))
560 return false;
561 // BinOpSameOpcodeHelper handles only BinaryOperators; a call is copyable.
562 if (!I->isBinaryOp() || !MainOp->isBinaryOp())
563 return true;
565 return !Converter.add(I) || !Converter.add(MainOp) || Converter.hasAltOp() ||
566 !Converter.hasCandidateOpcode(getOpcode());
567}
568
570 auto *I = dyn_cast<Instruction>(V);
571 return I &&
572 (I->getOpcode() == Instruction::FMul ||
573 I->getOpcode() == Instruction::FAdd) &&
574 I->hasOneUse() && none_of(I->operands(), [&](Value *Op) {
575 return is_contained(VL, Op);
576 });
577}
578
580 auto *I = dyn_cast<Instruction>(V);
581 return I && S.isCopyableElement(I) &&
582 (I->getOpcode() == Instruction::FMul ||
583 I->getOpcode() == Instruction::FAdd) &&
584 I->hasOneUse();
585}
586
588 bool HasFMulOrFAdd = false;
589 for (Value *V : VL) {
590 if (isa<PoisonValue>(V))
591 continue;
592 auto *I = dyn_cast<Instruction>(V);
594 continue;
595 if (!isAbsorbableFMulOrFAdd(VL, V))
596 return false;
597 HasFMulOrFAdd = true;
598 }
599 return HasFMulOrFAdd;
600}
601
603 assert(valid() && "InstructionsState is invalid.");
604 if (isCopyableElement(V))
605 return false;
606 auto *ExpandingOp = dyn_cast<Instruction>(V);
607 if (!ExpandingOp)
608 return false;
609 auto CheckForTransformedOpcode = [](const Instruction *RefOp,
610 const Instruction *ExpandingOp) {
611 switch (RefOp->getOpcode()) {
612 case Instruction::Add:
613 switch (ExpandingOp->getOpcode()) {
614 case Instruction::Shl:
615 return match(ExpandingOp, m_Shl(m_Value(), m_One()));
616 default:
617 break;
618 }
619 break;
620 default:
621 break;
622 }
623 return false;
624 };
625 // getMatchingMainOpOrAltOp() may legitimately return nullptr, e.g. for a
626 // split node, whose Scalars combine two unrelated operations (main/alt
627 // ops of the split state), so V is not required to match either of them.
628 Instruction *MainOp = getMatchingMainOpOrAltOp(ExpandingOp);
629 if (!MainOp)
630 return false;
631 return CheckForTransformedOpcode(MainOp, ExpandingOp);
632}
633
635 assert(isExpandedBinOp(I) && "Expected an expanded binop.");
636 switch (I->getOpcode()) {
637 case Instruction::Shl:
638 assert(match(I, m_Shl(m_Value(), m_One())) && "Expected shl x, 1 only.");
639 return Idx == 1;
640 default:
641 llvm_unreachable("Unexpected opcode for an expanded operand.");
642 }
643}
644
646 assert(valid() && "InstructionsState is invalid.");
647 auto *I = dyn_cast<Instruction>(V);
648 if (!HasCopyables)
651 // MainOp for copyables always schedulable to correctly identify
652 // non-schedulable copyables.
653 if (getMainOp() == V)
654 return false;
655 if (isCopyableElement(V)) {
656 auto IsNonSchedulableCopyableElement = [this](Value *V) {
657 auto *I = dyn_cast<Instruction>(V);
658 return !I || isa<PHINode>(I) || I->getParent() != MainOp->getParent() ||
660 // If the copyable instructions comes after MainOp
661 // (non-schedulable, but used in the block) - cannot vectorize
662 // it, will possibly generate use before def.
663 !MainOp->comesBefore(I));
664 };
665
666 return IsNonSchedulableCopyableElement(V);
667 }
670}
671
672/// Find an instruction with a specific opcode in VL.
673/// \param VL Array of values to search through. Must contain only Instructions
674/// and PoisonValues.
675/// \param Opcode The instruction opcode to search for
676/// \returns
677/// - The first instruction found with matching opcode
678/// - nullptr if no matching instruction is found
680 unsigned Opcode) {
681 for (Value *V : VL) {
682 if (isa<PoisonValue>(V))
683 continue;
684 assert(isa<Instruction>(V) && "Only accepts PoisonValue and Instruction.");
685 auto *Inst = cast<Instruction>(V);
686 if (Inst->getOpcode() == Opcode)
687 return Inst;
688 }
689 return nullptr;
690}
691
692/// Checks if the provided operands of 2 cmp instructions are compatible, i.e.
693/// compatible instructions or constants, or just some other regular values.
694static bool areCompatibleCmpOps(Value *BaseOp0, Value *BaseOp1, Value *Op0,
695 Value *Op1, const TargetLibraryInfo &TLI) {
696 return (isConstant(BaseOp0) && isConstant(Op0)) ||
697 (isConstant(BaseOp1) && isConstant(Op1)) ||
698 (!isa<Instruction>(BaseOp0) && !isa<Instruction>(Op0) &&
699 !isa<Instruction>(BaseOp1) && !isa<Instruction>(Op1)) ||
700 BaseOp0 == Op0 || BaseOp1 == Op1 ||
701 getSameOpcode({BaseOp0, Op0}, TLI) ||
702 getSameOpcode({BaseOp1, Op1}, TLI);
703}
704
705/// \returns true if a compare instruction \p CI has similar "look" and
706/// same predicate as \p BaseCI, "as is" or with its operands and predicate
707/// swapped, false otherwise.
708static bool isCmpSameOrSwapped(const CmpInst *BaseCI, const CmpInst *CI,
709 const TargetLibraryInfo &TLI) {
710 assert(BaseCI->getOperand(0)->getType() == CI->getOperand(0)->getType() &&
711 "Assessing comparisons of different types?");
712 CmpInst::Predicate BasePred = BaseCI->getPredicate();
713 CmpInst::Predicate Pred = CI->getPredicate();
715
716 Value *BaseOp0 = BaseCI->getOperand(0);
717 Value *BaseOp1 = BaseCI->getOperand(1);
718 Value *Op0 = CI->getOperand(0);
719 Value *Op1 = CI->getOperand(1);
720
721 return (BasePred == Pred &&
722 areCompatibleCmpOps(BaseOp0, BaseOp1, Op0, Op1, TLI)) ||
723 (BasePred == SwappedPred &&
724 areCompatibleCmpOps(BaseOp0, BaseOp1, Op1, Op0, TLI));
725}
726
728 const TargetLibraryInfo &TLI) {
729 // Make sure these are all Instructions.
732
733 auto *It = find_if(VL, IsaPred<Instruction>);
734 if (It == VL.end())
736
737 Instruction *MainOp = cast<Instruction>(*It);
738 unsigned InstCnt = std::count_if(It, VL.end(), IsaPred<Instruction>);
739 if ((VL.size() > 2 && !isa<PHINode>(MainOp) && InstCnt < VL.size() / 2) ||
740 (VL.size() == 2 && InstCnt < 2))
742
743 bool IsCastOp = isa<CastInst>(MainOp);
744 bool IsBinOp = isa<BinaryOperator>(MainOp);
745 bool IsCmpOp = isa<CmpInst>(MainOp);
746 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
748 Instruction *AltOp = MainOp;
749 unsigned Opcode = MainOp->getOpcode();
750 unsigned AltOpcode = Opcode;
751
752 BinOpSameOpcodeHelper BinOpHelper(MainOp);
753 bool SwappedPredsCompatible = IsCmpOp && [&]() {
754 SetVector<unsigned> UniquePreds, UniqueNonSwappedPreds;
755 UniquePreds.insert(BasePred);
756 UniqueNonSwappedPreds.insert(BasePred);
757 for (Value *V : VL) {
758 auto *I = dyn_cast<CmpInst>(V);
759 if (!I)
760 return false;
761 CmpInst::Predicate CurrentPred = I->getPredicate();
762 CmpInst::Predicate SwappedCurrentPred =
763 CmpInst::getSwappedPredicate(CurrentPred);
764 UniqueNonSwappedPreds.insert(CurrentPred);
765 if (!UniquePreds.contains(CurrentPred) &&
766 !UniquePreds.contains(SwappedCurrentPred))
767 UniquePreds.insert(CurrentPred);
768 }
769 // Total number of predicates > 2, but if consider swapped predicates
770 // compatible only 2, consider swappable predicates as compatible opcodes,
771 // not alternate.
772 return UniqueNonSwappedPreds.size() > 2 && UniquePreds.size() == 2;
773 }();
774 // Find the predicate the whole bundle can share, if any, treating
775 // boundary comparisons canonicalized to eq/ne as interchangeable.
777 if (IsCmpOp && isa<ICmpInst>(MainOp))
778 InterchangeablePred =
780 // Check for one alternate opcode from another BinaryOperator.
781 // TODO - generalize to support all operators (types, calls etc.).
782 Intrinsic::ID BaseID = 0;
783 SmallVector<VFInfo, 4> BaseMappings;
784 if (auto *CallBase = dyn_cast<CallInst>(MainOp)) {
786 BaseMappings = VFDatabase(*CallBase).getMappings(*CallBase);
787 if (!isTriviallyVectorizable(BaseID) && BaseMappings.empty())
789 }
790 bool AnyPoison = InstCnt != VL.size();
791 // Check MainOp too to be sure that it matches the requirements for the
792 // instructions.
793 for (Value *V : iterator_range(It, VL.end())) {
794 auto *I = dyn_cast<Instruction>(V);
795 if (!I)
796 continue;
797
798 // Cannot combine poison and divisions.
799 // TODO: do some smart analysis of the CallInsts to exclude divide-like
800 // intrinsics/functions only.
801 if (AnyPoison && (I->isIntDivRem() || I->isFPDivRem() || isa<CallInst>(I)))
803 unsigned InstOpcode = I->getOpcode();
804 if (IsBinOp && isa<BinaryOperator>(I)) {
805 if (BinOpHelper.add(I))
806 continue;
807 } else if (IsCastOp && isa<CastInst>(I)) {
808 Value *Op0 = MainOp->getOperand(0);
809 Type *Ty0 = Op0->getType();
810 Value *Op1 = I->getOperand(0);
811 Type *Ty1 = Op1->getType();
812 if (Ty0 == Ty1) {
813 if (InstOpcode == Opcode || InstOpcode == AltOpcode)
814 continue;
815 if (Opcode == AltOpcode) {
817 isValidForAlternation(InstOpcode) &&
818 "Cast isn't safe for alternation, logic needs to be updated!");
819 AltOpcode = InstOpcode;
820 AltOp = I;
821 continue;
822 }
823 }
824 } else if (auto *Inst = dyn_cast<CmpInst>(I); Inst && IsCmpOp) {
825 auto *BaseInst = cast<CmpInst>(MainOp);
826 Type *Ty0 = BaseInst->getOperand(0)->getType();
827 Type *Ty1 = Inst->getOperand(0)->getType();
828 if (Ty0 == Ty1) {
829 assert(InstOpcode == Opcode && "Expected same CmpInst opcode.");
830 assert(InstOpcode == AltOpcode &&
831 "Alternate instructions are only supported by BinaryOperator "
832 "and CastInst.");
833 // Check for compatible operands. If the corresponding operands are not
834 // compatible - need to perform alternate vectorization.
835 CmpInst::Predicate CurrentPred = Inst->getPredicate();
836 CmpInst::Predicate SwappedCurrentPred =
837 CmpInst::getSwappedPredicate(CurrentPred);
838
839 if ((VL.size() == 2 || SwappedPredsCompatible) &&
840 (BasePred == CurrentPred || BasePred == SwappedCurrentPred))
841 continue;
842
843 if (isCmpSameOrSwapped(BaseInst, Inst, TLI))
844 continue;
845 if (CmpSamePredicateHelper::canConvertTo(Inst, InterchangeablePred))
846 continue;
847 auto *AltInst = cast<CmpInst>(AltOp);
848 if (MainOp != AltOp) {
849 if (isCmpSameOrSwapped(AltInst, Inst, TLI))
850 continue;
851 } else if (BasePred != CurrentPred) {
852 assert(
853 isValidForAlternation(InstOpcode) &&
854 "CmpInst isn't safe for alternation, logic needs to be updated!");
855 AltOp = I;
856 continue;
857 }
858 CmpInst::Predicate AltPred = AltInst->getPredicate();
859 if (BasePred == CurrentPred || BasePred == SwappedCurrentPred ||
860 AltPred == CurrentPred || AltPred == SwappedCurrentPred)
861 continue;
862 }
863 } else if (InstOpcode == Opcode) {
864 assert(InstOpcode == AltOpcode &&
865 "Alternate instructions are only supported by BinaryOperator and "
866 "CastInst.");
867 if (auto *Gep = dyn_cast<GetElementPtrInst>(I)) {
868 if (Gep->getNumOperands() != 2 ||
869 Gep->getOperand(0)->getType() != MainOp->getOperand(0)->getType())
871 } else if (auto *EI = dyn_cast<ExtractElementInst>(I)) {
874 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
875 auto *BaseLI = cast<LoadInst>(MainOp);
876 if (!LI->isSimple() || !BaseLI->isSimple())
878 } else if (auto *Call = dyn_cast<CallInst>(I)) {
879 auto *CallBase = cast<CallInst>(MainOp);
881 Intrinsic::ID Equivalent = isEquivalentIntrinsicID(ID, BaseID);
882 if (Call->getCalledFunction() != CallBase->getCalledFunction() &&
883 isEquivalentIntrinsicID(Equivalent, Intrinsic::fmuladd) ==
886 if (Call->hasOperandBundles() &&
888 !std::equal(Call->op_begin() + Call->getBundleOperandsStartIndex(),
889 Call->op_begin() + Call->getBundleOperandsEndIndex(),
890 CallBase->op_begin() +
893 if (ID != BaseID && Equivalent == Intrinsic::not_intrinsic)
895 if (!ID) {
896 SmallVector<VFInfo, 4> Mappings =
897 VFDatabase(*Call).getMappings(*Call);
898 if (Mappings.size() != BaseMappings.size() ||
899 Mappings.front().ISA != BaseMappings.front().ISA ||
900 Mappings.front().ScalarName != BaseMappings.front().ScalarName ||
901 Mappings.front().VectorName != BaseMappings.front().VectorName ||
902 Mappings.front().Shape.VF != BaseMappings.front().Shape.VF ||
903 Mappings.front().Shape.Parameters !=
904 BaseMappings.front().Shape.Parameters)
906 }
907 }
908 continue;
909 }
911 }
912
913 if (IsBinOp) {
914 if (!BinOpHelper.hasDefinedMainOpcode() ||
915 !BinOpHelper.hasDefinedAltOpcode())
917 MainOp = findInstructionWithOpcode(VL, BinOpHelper.getMainOpcode());
918 assert(MainOp && "Cannot find MainOp with Opcode from BinOpHelper.");
919 AltOp = findInstructionWithOpcode(VL, BinOpHelper.getAltOpcode());
920 assert(AltOp && "Cannot find AltOp with Opcode from BinOpHelper.");
921 } else if (auto *CB = dyn_cast<CallInst>(MainOp);
922 CB &&
923 getVectorIntrinsicIDForCall(CB, &TLI) == Intrinsic::fmuladd) {
924 // fma and fmuladd share a single vector fma node; use the fma as the
925 // representative so the fused form is not weakened to fmuladd.
926 auto *It = find_if(VL, [&](Value *V) {
927 auto *CI = dyn_cast<CallInst>(V);
928 return CI && getVectorIntrinsicIDForCall(CI, &TLI) == Intrinsic::fma;
929 });
930 if (It != VL.end())
931 MainOp = AltOp = cast<Instruction>(*It);
932 }
933 if (IsCmpOp && InterchangeablePred != CmpInst::BAD_ICMP_PREDICATE &&
934 InterchangeablePred != BasePred) {
935 // Every lane is convertible to the shared predicate, so the alternate
936 // operation is never set for such bundles.
937 auto *SharedIt = find_if(VL, [&](Value *V) {
938 auto *CI = dyn_cast<ICmpInst>(V);
939 return CI && CI->getPredicate() == InterchangeablePred;
940 });
941 assert(SharedIt != VL.end() &&
942 "Expected an instruction with the shared predicate.");
943 MainOp = AltOp = cast<Instruction>(*SharedIt);
944 }
945 assert((MainOp == AltOp || !allSameOpcode(VL)) &&
946 "Incorrect implementation of allSameOpcode.");
947 InstructionsState S(MainOp, AltOp);
948 assert(all_of(VL,
949 [&](Value *V) {
950 return isa<PoisonValue>(V) ||
952 }) &&
953 "Invalid InstructionsState.");
954 return S;
955}
956
957std::pair<Instruction *, SmallVector<Value *>>
959 Instruction *SelectedOp = S.getMatchingMainOpOrAltOp(I);
960 assert(SelectedOp && "Cannot convert the instruction.");
961 if (I->isBinaryOp()) {
963 return std::make_pair(SelectedOp, Converter.getOperand(SelectedOp));
964 }
965 // Use args() to skip the trailing callee operand in CallInst::operands().
966 if (auto *CI = dyn_cast<CallInst>(I))
967 return std::make_pair(SelectedOp, SmallVector<Value *>(CI->args()));
968 // A comparison lane interchangeable with the main operation (e.g. x == 0
969 // in an x <u C bundle) is emitted with the main predicate and the
970 // adjusted constant.
971 if (auto *MainCI = dyn_cast<ICmpInst>(SelectedOp);
972 MainCI && !S.isAltShuffle())
974 cast<ICmpInst>(I), MainCI->getPredicate()))
975 return std::make_pair(SelectedOp,
976 SmallVector<Value *>{I->getOperand(0), C});
977 return std::make_pair(SelectedOp, SmallVector<Value *>(I->operands()));
978}
979
981 Instruction *AltOp, const TargetLibraryInfo &TLI) {
982 if (auto *MainCI = dyn_cast<CmpInst>(MainOp)) {
983 auto *AltCI = cast<CmpInst>(AltOp);
984 CmpInst::Predicate MainP = MainCI->getPredicate();
985 [[maybe_unused]] CmpInst::Predicate AltP = AltCI->getPredicate();
986 assert(MainP != AltP && "Expected different main/alternate predicates.");
987 auto *CI = cast<CmpInst>(I);
988 if (isCmpSameOrSwapped(MainCI, CI, TLI))
989 return false;
990 if (isCmpSameOrSwapped(AltCI, CI, TLI))
991 return true;
992 CmpInst::Predicate P = CI->getPredicate();
994
995 assert((MainP == P || AltP == P || MainP == SwappedP || AltP == SwappedP) &&
996 "CmpInst expected to match either main or alternate predicate or "
997 "their swap.");
998 return MainP != P && MainP != SwappedP;
999 }
1000 return InstructionsState(MainOp, AltOp).getMatchingMainOpOrAltOp(I) == AltOp;
1001}
1002
1004 const InstructionsState &S, const TargetLibraryInfo &TLI,
1006 SmallVectorImpl<Value *> &ReassocScalars, SmallBitVector &SubLanes) {
1007 assert(S.isAltShuffle() && "Expected an alternate node.");
1008 const unsigned NumLanes = VL.size();
1009 SmallVector<unsigned> LaneOpcodes =
1010 map_to_vector(seq<unsigned>(NumLanes), [&](unsigned Lane) {
1012 S.getMainOp(), S.getAltOp(), TLI)
1013 ? S.getAltOpcode()
1014 : S.getOpcode();
1015 });
1016 // A lane value peels only as a single-use chain link with the lane's own
1017 // opcode, keeping every combine level on the same main/alt pattern.
1018 auto GetChainLink = [&](unsigned Lane, Value *V) -> Instruction * {
1019 auto *I = dyn_cast<Instruction>(V);
1020 if (!I || !I->hasOneUse() || I->getOpcode() != LaneOpcodes[Lane] ||
1022 return nullptr;
1023 return I;
1024 };
1026 Columns.emplace_back(Op0.begin(), Op0.end());
1027 Columns.emplace_back(Op1.begin(), Op1.end());
1028 // The chain link of a commutative lane may sit in the second column;
1029 // normalize so every lane's link leads.
1030 for (unsigned Lane : seq<unsigned>(NumLanes)) {
1031 if (GetChainLink(Lane, Columns[0][Lane]))
1032 continue;
1033 Instruction *Link = GetChainLink(Lane, Columns[1][Lane]);
1034 if (!Link || !Link->isCommutative())
1035 return {};
1036 std::swap(Columns[0][Lane], Columns[1][Lane]);
1037 }
1038 // Peel the leading column while every lane stays a matching chain link.
1039 while (all_of(seq<unsigned>(NumLanes), [&](unsigned Lane) {
1040 return GetChainLink(Lane, Columns[0][Lane]) != nullptr;
1041 })) {
1042 SmallVector<Value *> NewColumn(NumLanes);
1043 for (unsigned Lane : seq<unsigned>(NumLanes)) {
1044 Instruction *Link = GetChainLink(Lane, Columns[0][Lane]);
1045 ReassocScalars.push_back(Link);
1046 // The chain of a commutative lane may continue in the second operand;
1047 // keep the chain link as the running value.
1048 unsigned RunningOp = Link->isCommutative() &&
1049 !GetChainLink(Lane, Link->getOperand(0)) &&
1050 GetChainLink(Lane, Link->getOperand(1))
1051 ? 1
1052 : 0;
1053 NewColumn[Lane] = Link->getOperand(1 - RunningOp);
1054 Columns[0][Lane] = Link->getOperand(RunningOp);
1055 }
1056 Columns.insert(std::next(Columns.begin()), std::move(NewColumn));
1057 }
1058 assert(!ReassocScalars.empty() &&
1059 "Normalization guarantees at least one peeled level.");
1060 SubLanes.resize(NumLanes);
1061 for (unsigned Lane : seq<unsigned>(NumLanes))
1062 if (LaneOpcodes[Lane] == Instruction::Sub ||
1063 LaneOpcodes[Lane] == Instruction::FSub)
1064 SubLanes.set(Lane);
1065 return Columns;
1066}
1067} // 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
#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:1561
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition APInt.h:203
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:368
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:377
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1509
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1116
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:206
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:216
unsigned logBase2() const
Definition APInt.h:1782
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:437
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:386
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:236
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:255
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
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:58
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:66
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
Definition SLPUtils.cpp:483
bool isConstant(Value *V)
Definition SLPUtils.cpp:38
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:1739
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 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:2039
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 dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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:1753
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:1772
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:1947
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