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