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