44#define DEBUG_TYPE "instcombine"
47using namespace PatternMatch;
50 "Number of aggregate reconstructions turned into reuse of the "
51 "original aggregate");
62 if (
auto *
C = dyn_cast<Constant>(V))
63 return CEI ||
C->getSplatValue();
65 if (CEI &&
match(V, m_Intrinsic<Intrinsic::experimental_stepvector>())) {
66 ElementCount EC = cast<VectorType>(V->getType())->getElementCount();
108 for (
auto *U : PN->
users()) {
114 }
else if (!PHIUser) {
115 PHIUser = cast<Instruction>(U);
128 !(isa<BinaryOperator>(PHIUser)) ||
142 if (PHIInVal == PHIUser) {
147 unsigned opId = (B0->
getOperand(0) == PN) ? 1 : 0;
154 scalarPHI, Op, B0), *B0);
160 Instruction *pos = dyn_cast<Instruction>(PHIInVal);
162 if (pos && !isa<PHINode>(pos)) {
174 for (
auto *
E : Extracts)
188 cast<VectorType>(
Ext.getVectorOperandType())->getElementCount();
195 if (
X->getType()->isIntegerTy()) {
196 assert(isa<FixedVectorType>(
Ext.getVectorOperand()->getType()) &&
197 "Expected fixed vector type for bitcast from scalar integer");
204 unsigned ShiftAmountC = ExtIndexC * DestWidth;
206 (isDesirableIntType(
X->getType()->getPrimitiveSizeInBits()) &&
207 Ext.getVectorOperand()->hasOneUse())) {
219 if (!
X->getType()->isVectorTy())
225 auto *SrcTy = cast<VectorType>(
X->getType());
227 if (NumSrcElts == NumElts)
232 "Src and Dst must be the same sort of vector type");
248 unsigned NarrowingRatio =
251 if (ExtIndexC / NarrowingRatio != InsIndexC) {
257 if (
X->hasOneUse() &&
Ext.getVectorOperand()->hasOneUse()) {
275 unsigned Chunk = ExtIndexC % NarrowingRatio;
277 Chunk = NarrowingRatio - 1 - Chunk;
282 bool NeedSrcBitcast = SrcTy->getScalarType()->isFloatingPointTy();
284 if (NeedSrcBitcast && NeedDestBitcast)
287 unsigned SrcWidth = SrcTy->getScalarSizeInBits();
288 unsigned ShAmt = Chunk * DestWidth;
293 if (!
X->hasOneUse() || !
Ext.getVectorOperand()->hasOneUse())
294 if (NeedSrcBitcast || NeedDestBitcast)
297 if (NeedSrcBitcast) {
304 if (!
Ext.getVectorOperand()->hasOneUse())
309 if (NeedDestBitcast) {
321 unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
327 case Instruction::ExtractElement: {
331 if (EEIIndexC && EEIIndexC->
getValue().
ult(VWidth)) {
336 case Instruction::ShuffleVector: {
338 unsigned MaskNumElts =
339 cast<FixedVectorType>(UserInstr->
getType())->getNumElements();
341 UsedElts =
APInt(VWidth, 0);
342 for (
unsigned i = 0; i < MaskNumElts; i++) {
343 unsigned MaskVal =
Shuffle->getMaskValue(i);
344 if (MaskVal == -1u || MaskVal >= 2 * VWidth)
346 if (
Shuffle->getOperand(0) == V && (MaskVal < VWidth))
348 if (
Shuffle->getOperand(1) == V &&
349 ((MaskVal >= VWidth) && (MaskVal < 2 * VWidth)))
350 UsedElts.
setBit(MaskVal - VWidth);
365 unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
367 APInt UnionUsedElts(VWidth, 0);
368 for (
const Use &U : V->uses()) {
369 if (
Instruction *
I = dyn_cast<Instruction>(U.getUser())) {
380 return UnionUsedElts;
411 if (
SI->getCondition()->getType()->isIntegerTy() &&
418 auto *IndexC = dyn_cast<ConstantInt>(
Index);
425 unsigned NumElts = EC.getKnownMinValue();
431 if (IID == Intrinsic::experimental_stepvector &&
432 IndexC->getValue().ult(NumElts)) {
438 if (IndexC->getValue().getActiveBits() <=
BitWidth)
448 if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
456 if (
auto *Phi = dyn_cast<PHINode>(SrcVec))
457 if (
Instruction *ScalarPHI = scalarizePHI(EI, Phi))
490 if (
auto *
I = dyn_cast<Instruction>(SrcVec)) {
491 if (
auto *IE = dyn_cast<InsertElementInst>(
I)) {
495 if (isa<Constant>(IE->getOperand(2)) && IndexC)
497 }
else if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I)) {
498 auto *VecType = cast<VectorType>(
GEP->getType());
500 uint64_t IdxVal = IndexC ? IndexC->getZExtValue() : 0;
501 if (IndexC && IdxVal < EC.getKnownMinValue() &&
GEP->hasOneUse()) {
512 return isa<VectorType>(V->getType());
514 if (VectorOps == 1) {
515 Value *NewPtr =
GEP->getPointerOperand();
516 if (isa<VectorType>(NewPtr->
getType()))
520 for (
unsigned I = 1;
I !=
GEP->getNumOperands(); ++
I) {
522 if (isa<VectorType>(Op->getType()))
529 GEP->getSourceElementType(), NewPtr, NewOps);
534 }
else if (
auto *SVI = dyn_cast<ShuffleVectorInst>(
I)) {
538 if (isa<FixedVectorType>(SVI->getType()) && isa<ConstantInt>(
Index)) {
540 SVI->getMaskValue(cast<ConstantInt>(
Index)->getZExtValue());
542 unsigned LHSWidth = cast<FixedVectorType>(SVI->getOperand(0)->getType())
547 if (SrcIdx < (
int)LHSWidth)
548 Src = SVI->getOperand(0);
551 Src = SVI->getOperand(1);
557 }
else if (
auto *CI = dyn_cast<CastInst>(
I)) {
561 if (CI->hasOneUse() && (CI->getOpcode() != Instruction::BitCast)) {
573 unsigned NumElts = EC.getKnownMinValue();
577 if (!EC.isScalable() && NumElts != 1) {
581 APInt UndefElts(NumElts, 0);
582 APInt DemandedElts(NumElts, 0);
583 DemandedElts.
setBit(IndexC->getZExtValue());
592 APInt UndefElts(NumElts, 0);
594 SrcVec, DemandedElts, UndefElts, 0 ,
613 "Invalid CollectSingleShuffleElements");
614 unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
617 Mask.assign(NumElts, -1);
622 for (
unsigned i = 0; i != NumElts; ++i)
628 for (
unsigned i = 0; i != NumElts; ++i)
629 Mask.push_back(i + NumElts);
635 Value *VecOp = IEI->getOperand(0);
636 Value *ScalarOp = IEI->getOperand(1);
637 Value *IdxOp = IEI->getOperand(2);
639 if (!isa<ConstantInt>(IdxOp))
641 unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue();
643 if (isa<UndefValue>(ScalarOp)) {
648 Mask[InsertedIdx] = -1;
653 unsigned ExtractedIdx =
654 cast<ConstantInt>(EI->
getOperand(1))->getZExtValue();
655 unsigned NumLHSElts =
656 cast<FixedVectorType>(
LHS->
getType())->getNumElements();
665 Mask[InsertedIdx % NumElts] = ExtractedIdx;
668 Mask[InsertedIdx % NumElts] = ExtractedIdx + NumLHSElts;
686 auto *InsVecType = cast<FixedVectorType>(InsElt->
getType());
688 unsigned NumInsElts = InsVecType->getNumElements();
689 unsigned NumExtElts = ExtVecType->getNumElements();
692 if (InsVecType->getElementType() != ExtVecType->getElementType() ||
693 NumExtElts >= NumInsElts)
701 for (
unsigned i = 0; i < NumExtElts; ++i)
703 for (
unsigned i = NumExtElts; i < NumInsElts; ++i)
707 auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
708 BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
721 if (InsertionBlock != InsElt->
getParent())
738 if (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
739 WideVec->insertAfter(ExtVecOpInst);
750 NewExt->insertAfter(OldExt);
768 assert(V->getType()->isVectorTy() &&
"Invalid shuffle!");
769 unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
772 Mask.assign(NumElts, -1);
773 return std::make_pair(
777 if (isa<ConstantAggregateZero>(V)) {
778 Mask.assign(NumElts, 0);
779 return std::make_pair(V,
nullptr);
784 Value *VecOp = IEI->getOperand(0);
785 Value *ScalarOp = IEI->getOperand(1);
786 Value *IdxOp = IEI->getOperand(2);
789 if (isa<ConstantInt>(EI->
getOperand(1)) && isa<ConstantInt>(IdxOp)) {
790 unsigned ExtractedIdx =
791 cast<ConstantInt>(EI->
getOperand(1))->getZExtValue();
792 unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue();
796 if (EI->
getOperand(0) == PermittedRHS || PermittedRHS ==
nullptr) {
799 assert(LR.second ==
nullptr || LR.second ==
RHS);
808 for (
unsigned i = 0; i < NumElts; ++i)
810 return std::make_pair(V,
nullptr);
813 unsigned NumLHSElts =
814 cast<FixedVectorType>(
RHS->
getType())->getNumElements();
815 Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
816 return std::make_pair(LR.first,
RHS);
819 if (VecOp == PermittedRHS) {
822 unsigned NumLHSElts =
825 for (
unsigned i = 0; i != NumElts; ++i)
826 Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
827 return std::make_pair(EI->
getOperand(0), PermittedRHS);
835 return std::make_pair(EI->
getOperand(0), PermittedRHS);
841 for (
unsigned i = 0; i != NumElts; ++i)
843 return std::make_pair(V,
nullptr);
869 assert(NumAggElts > 0 &&
"Aggregate should have elements.");
873 static constexpr auto NotFound = std::nullopt;
874 static constexpr auto FoundMismatch =
nullptr;
881 auto KnowAllElts = [&AggElts]() {
889 static const int DepthLimit = 2 * NumAggElts;
894 Depth < DepthLimit && CurrIVI && !KnowAllElts();
895 CurrIVI = dyn_cast<InsertValueInst>(CurrIVI->getAggregateOperand()),
897 auto *InsertedValue =
898 dyn_cast<Instruction>(CurrIVI->getInsertedValueOperand());
905 if (Indices.
size() != 1)
911 std::optional<Instruction *> &Elt = AggElts[Indices.
front()];
912 Elt = Elt.value_or(InsertedValue);
925 enum class AggregateDescription {
941 auto Describe = [](std::optional<Value *> SourceAggregate) {
942 if (SourceAggregate == NotFound)
943 return AggregateDescription::NotFound;
944 if (*SourceAggregate == FoundMismatch)
945 return AggregateDescription::FoundMismatch;
946 return AggregateDescription::Found;
954 auto FindSourceAggregate =
955 [&](
Instruction *Elt,
unsigned EltIdx, std::optional<BasicBlock *> UseBB,
956 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
963 auto *EVI = dyn_cast_or_null<ExtractValueInst>(Elt);
967 Value *SourceAggregate = EVI->getAggregateOperand();
970 if (SourceAggregate->
getType() != AggTy)
971 return FoundMismatch;
973 if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
974 return FoundMismatch;
976 return SourceAggregate;
982 auto FindCommonSourceAggregate =
983 [&](std::optional<BasicBlock *> UseBB,
984 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
985 std::optional<Value *> SourceAggregate;
988 assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
989 "We don't store nullptr in SourceAggregate!");
990 assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
992 "SourceAggregate should be valid after the first element,");
997 std::optional<Value *> SourceAggregateForElement =
998 FindSourceAggregate(*
I.value(),
I.index(), UseBB, PredBB);
1005 if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
1006 return SourceAggregateForElement;
1010 switch (Describe(SourceAggregate)) {
1011 case AggregateDescription::NotFound:
1013 SourceAggregate = SourceAggregateForElement;
1015 case AggregateDescription::Found:
1018 if (*SourceAggregateForElement != *SourceAggregate)
1019 return FoundMismatch;
1021 case AggregateDescription::FoundMismatch:
1026 assert(Describe(SourceAggregate) == AggregateDescription::Found &&
1027 "Must be a valid Value");
1028 return *SourceAggregate;
1031 std::optional<Value *> SourceAggregate;
1034 SourceAggregate = FindCommonSourceAggregate(std::nullopt,
1036 if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
1037 if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
1039 ++NumAggregateReconstructionsSimplified;
1052 for (
const std::optional<Instruction *> &
I : AggElts) {
1076 static const int PredCountLimit = 64;
1083 if (Preds.
size() >= PredCountLimit)
1093 std::pair<
decltype(SourceAggregates)::iterator,
bool>
IV =
1094 SourceAggregates.
insert({Pred,
nullptr});
1102 SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
1103 if (Describe(SourceAggregate) != AggregateDescription::Found)
1105 IV.first->second = *SourceAggregate;
1114 Builder.SetInsertPoint(UseBB->getFirstNonPHI());
1116 Builder.CreatePHI(AggTy, Preds.size(), OrigIVI.getName() +
".merged");
1118 PHI->addIncoming(SourceAggregates[Pred], Pred);
1120 ++NumAggregateReconstructionsSimplified;
1121 return replaceInstUsesWith(OrigIVI,
PHI);
1133 I.getAggregateOperand(),
I.getInsertedValueOperand(),
I.getIndices(),
1137 bool IsRedundant =
false;
1146 while (V->hasOneUse() &&
Depth < 10) {
1147 User *U = V->user_back();
1148 auto UserInsInst = dyn_cast<InsertValueInst>(U);
1149 if (!UserInsInst || U->getOperand(0) != V)
1151 if (UserInsInst->getIndices() == FirstIndices) {
1179 if (MaskSize != VecSize)
1184 for (
int i = 0; i != MaskSize; ++i) {
1186 if (Elt != -1 && Elt != i && Elt != i + VecSize)
1205 if (isa<ScalableVectorType>(VecTy))
1207 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
1211 if (NumElements == 1)
1226 auto *NextIE = dyn_cast<InsertElementInst>(CurrIE->
getOperand(0));
1230 if (CurrIE != &InsElt &&
1231 (!CurrIE->
hasOneUse() && (NextIE !=
nullptr || !
Idx->isZero())))
1234 ElementPresent[
Idx->getZExtValue()] =
true;
1240 if (FirstIE == &InsElt)
1248 if (!ElementPresent.
all())
1255 if (!cast<ConstantInt>(FirstIE->
getOperand(2))->isZero())
1260 for (
unsigned i = 0; i != NumElements; ++i)
1261 if (!ElementPresent[i])
1271 auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0));
1272 if (!Shuf || !Shuf->isZeroEltSplat())
1277 if (isa<ScalableVectorType>(Shuf->getType()))
1287 Value *Op0 = Shuf->getOperand(0);
1295 unsigned NumMaskElts =
1296 cast<FixedVectorType>(Shuf->getType())->getNumElements();
1298 for (
unsigned i = 0; i != NumMaskElts; ++i)
1299 NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
1308 auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0));
1310 !(Shuf->isIdentityWithExtract() || Shuf->isIdentityWithPadding()))
1315 if (isa<ScalableVectorType>(Shuf->getType()))
1326 Value *
X = Shuf->getOperand(0);
1334 unsigned NumMaskElts =
1335 cast<FixedVectorType>(Shuf->getType())->getNumElements();
1338 for (
unsigned i = 0; i != NumMaskElts; ++i) {
1341 NewMask[i] = OldMask[i];
1342 }
else if (OldMask[i] == (
int)IdxC) {
1348 "Unexpected shuffle mask element for identity shuffle");
1367 auto *InsElt1 = dyn_cast<InsertElementInst>(InsElt2.
getOperand(0));
1368 if (!InsElt1 || !InsElt1->hasOneUse())
1375 match(InsElt1->getOperand(1),
m_Value(
Y)) && !isa<Constant>(
Y) &&
1379 Value *NewInsElt1 =
Builder.CreateInsertElement(
X, ScalarC, IdxC2);
1389 auto *Inst = dyn_cast<Instruction>(InsElt.
getOperand(0));
1392 if (!Inst || !Inst->hasOneUse())
1394 if (
auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0))) {
1397 Constant *ShufConstVec, *InsEltScalar;
1421 unsigned NumElts = Mask.size();
1424 for (
unsigned I = 0;
I != NumElts; ++
I) {
1425 if (
I == InsEltIndex) {
1426 NewShufElts[
I] = InsEltScalar;
1427 NewMaskElts[
I] = InsEltIndex + NumElts;
1431 NewMaskElts[
I] = Mask[
I];
1435 if (!NewShufElts[
I])
1443 }
else if (
auto *IEI = dyn_cast<InsertElementInst>(Inst)) {
1448 if (isa<ScalableVectorType>(InsElt.
getType()))
1451 cast<FixedVectorType>(InsElt.
getType())->getNumElements();
1462 auto ValI = std::begin(Val);
1469 Mask[
I] = NumElts +
I;
1474 for (
unsigned I = 0;
I < NumElts; ++
I) {
1506 CastOpcode = Instruction::FPExt;
1508 CastOpcode = Instruction::SExt;
1510 CastOpcode = Instruction::ZExt;
1515 if (
X->getType()->getScalarType() !=
Y->getType())
1542 auto *VTy = dyn_cast<FixedVectorType>(InsElt.
getType());
1543 Value *Scalar0, *BaseVec;
1545 if (!VTy || (VTy->getNumElements() & 1) ||
1554 if (Index0 + 1 != Index1 || Index0 & 1)
1571 Type *SrcTy =
X->getType();
1573 unsigned VecEltWidth = VTy->getScalarSizeInBits();
1574 if (ScalarWidth != VecEltWidth * 2 || ShAmt != VecEltWidth)
1579 Value *CastBaseVec =
Builder.CreateBitCast(BaseVec, CastTy);
1583 uint64_t NewIndex = IsBigEndian ? Index1 / 2 : Index0 / 2;
1584 Value *NewInsert =
Builder.CreateInsertElement(CastBaseVec,
X, NewIndex);
1589 Value *VecOp = IE.getOperand(0);
1590 Value *ScalarOp = IE.getOperand(1);
1591 Value *IdxOp = IE.getOperand(2);
1598 if (
auto *IndexC = dyn_cast<ConstantInt>(IdxOp)) {
1602 Value *BaseVec, *OtherScalar;
1607 !isa<Constant>(OtherScalar) && OtherIndexVal > IndexC->getZExtValue()) {
1638 cast<VectorType>(VecSrc->
getType())->getElementType() ==
1650 uint64_t InsertedIdx, ExtractedIdx;
1652 if (isa<FixedVectorType>(IE.getType()) &&
1656 isa<FixedVectorType>(ExtVecOp->
getType()) &&
1658 cast<FixedVectorType>(ExtVecOp->
getType())->getNumElements()) {
1674 if (!Insert.hasOneUse())
1676 auto *InsertUser = dyn_cast<InsertElementInst>(Insert.user_back());
1683 if (isShuffleRootCandidate(IE)) {
1689 if (LR.first != &IE && LR.second != &IE) {
1691 if (LR.second ==
nullptr)
1698 if (
auto VecTy = dyn_cast<FixedVectorType>(VecOp->
getType())) {
1699 unsigned VWidth = VecTy->getNumElements();
1700 APInt UndefElts(VWidth, 0);
1722 return IdentityShuf;
1736 unsigned Depth = 5) {
1738 if (isa<Constant>(V))
1743 if (!
I)
return false;
1746 if (!
I->hasOneUse())
1749 if (
Depth == 0)
return false;
1751 switch (
I->getOpcode()) {
1752 case Instruction::UDiv:
1753 case Instruction::SDiv:
1754 case Instruction::URem:
1755 case Instruction::SRem:
1762 case Instruction::Add:
1763 case Instruction::FAdd:
1764 case Instruction::Sub:
1765 case Instruction::FSub:
1766 case Instruction::Mul:
1767 case Instruction::FMul:
1768 case Instruction::FDiv:
1769 case Instruction::FRem:
1770 case Instruction::Shl:
1771 case Instruction::LShr:
1772 case Instruction::AShr:
1773 case Instruction::And:
1774 case Instruction::Or:
1775 case Instruction::Xor:
1776 case Instruction::ICmp:
1777 case Instruction::FCmp:
1778 case Instruction::Trunc:
1779 case Instruction::ZExt:
1780 case Instruction::SExt:
1781 case Instruction::FPToUI:
1782 case Instruction::FPToSI:
1783 case Instruction::UIToFP:
1784 case Instruction::SIToFP:
1785 case Instruction::FPTrunc:
1786 case Instruction::FPExt:
1787 case Instruction::GetElementPtr: {
1790 Type *ITy =
I->getType();
1792 Mask.size() > cast<FixedVectorType>(ITy)->getNumElements())
1794 for (
Value *Operand :
I->operands()) {
1800 case Instruction::InsertElement: {
1801 ConstantInt *CI = dyn_cast<ConstantInt>(
I->getOperand(2));
1802 if (!CI)
return false;
1807 bool SeenOnce =
false;
1808 for (
int I : Mask) {
1809 if (
I == ElementNumber) {
1826 switch (
I->getOpcode()) {
1827 case Instruction::Add:
1828 case Instruction::FAdd:
1829 case Instruction::Sub:
1830 case Instruction::FSub:
1831 case Instruction::Mul:
1832 case Instruction::FMul:
1833 case Instruction::UDiv:
1834 case Instruction::SDiv:
1835 case Instruction::FDiv:
1836 case Instruction::URem:
1837 case Instruction::SRem:
1838 case Instruction::FRem:
1839 case Instruction::Shl:
1840 case Instruction::LShr:
1841 case Instruction::AShr:
1842 case Instruction::And:
1843 case Instruction::Or:
1844 case Instruction::Xor: {
1846 assert(NewOps.
size() == 2 &&
"binary operator with #ops != 2");
1849 NewOps[0], NewOps[1],
"", BO);
1850 if (isa<OverflowingBinaryOperator>(BO)) {
1854 if (isa<PossiblyExactOperator>(BO)) {
1855 New->setIsExact(BO->
isExact());
1857 if (isa<FPMathOperator>(BO))
1858 New->copyFastMathFlags(
I);
1861 case Instruction::ICmp:
1862 assert(NewOps.
size() == 2 &&
"icmp with #ops != 2");
1863 return new ICmpInst(
I, cast<ICmpInst>(
I)->getPredicate(),
1864 NewOps[0], NewOps[1]);
1865 case Instruction::FCmp:
1866 assert(NewOps.
size() == 2 &&
"fcmp with #ops != 2");
1867 return new FCmpInst(
I, cast<FCmpInst>(
I)->getPredicate(),
1868 NewOps[0], NewOps[1]);
1869 case Instruction::Trunc:
1870 case Instruction::ZExt:
1871 case Instruction::SExt:
1872 case Instruction::FPToUI:
1873 case Instruction::FPToSI:
1874 case Instruction::UIToFP:
1875 case Instruction::SIToFP:
1876 case Instruction::FPTrunc:
1877 case Instruction::FPExt: {
1881 I->getType()->getScalarType(),
1882 cast<VectorType>(NewOps[0]->getType())->getElementCount());
1883 assert(NewOps.
size() == 1 &&
"cast with #ops != 1");
1887 case Instruction::GetElementPtr: {
1891 cast<GetElementPtrInst>(
I)->getSourceElementType(),
Ptr,
Idx,
"",
I);
1892 GEP->setIsInBounds(cast<GetElementPtrInst>(
I)->isInBounds());
1902 assert(V->getType()->isVectorTy() &&
"can't reorder non-vector elements");
1903 Type *EltTy = V->getType()->getScalarType();
1908 if (isa<ConstantAggregateZero>(V))
1911 if (
Constant *
C = dyn_cast<Constant>(V))
1916 switch (
I->getOpcode()) {
1917 case Instruction::Add:
1918 case Instruction::FAdd:
1919 case Instruction::Sub:
1920 case Instruction::FSub:
1921 case Instruction::Mul:
1922 case Instruction::FMul:
1923 case Instruction::UDiv:
1924 case Instruction::SDiv:
1925 case Instruction::FDiv:
1926 case Instruction::URem:
1927 case Instruction::SRem:
1928 case Instruction::FRem:
1929 case Instruction::Shl:
1930 case Instruction::LShr:
1931 case Instruction::AShr:
1932 case Instruction::And:
1933 case Instruction::Or:
1934 case Instruction::Xor:
1935 case Instruction::ICmp:
1936 case Instruction::FCmp:
1937 case Instruction::Trunc:
1938 case Instruction::ZExt:
1939 case Instruction::SExt:
1940 case Instruction::FPToUI:
1941 case Instruction::FPToSI:
1942 case Instruction::UIToFP:
1943 case Instruction::SIToFP:
1944 case Instruction::FPTrunc:
1945 case Instruction::FPExt:
1946 case Instruction::Select:
1947 case Instruction::GetElementPtr: {
1951 cast<FixedVectorType>(
I->getType())->getNumElements());
1952 for (
int i = 0, e =
I->getNumOperands(); i != e; ++i) {
1957 if (
I->getOperand(i)->getType()->isVectorTy())
1960 V =
I->getOperand(i);
1962 NeedsRebuild |= (V !=
I->getOperand(i));
1969 case Instruction::InsertElement: {
1970 int Element = cast<ConstantInt>(
I->getOperand(2))->getLimitedValue();
1977 for (
int e = Mask.size();
Index != e; ++
Index) {
1978 if (Mask[
Index] == Element) {
2007 unsigned MaskElems = Mask.size();
2008 unsigned BegIdx = Mask.front();
2009 unsigned EndIdx = Mask.back();
2010 if (BegIdx > EndIdx || EndIdx >= LHSElems || EndIdx - BegIdx != MaskElems - 1)
2012 for (
unsigned I = 0;
I != MaskElems; ++
I)
2013 if (
static_cast<unsigned>(Mask[
I]) != BegIdx +
I)
2026 Opcode(Opc), Op0(V0), Op1(V1) {}
2027 operator bool()
const {
return Opcode != 0; }
2038 case Instruction::Shl: {
2043 return {Instruction::Mul, BO0, ShlOne};
2047 case Instruction::Or: {
2051 return {Instruction::Add, BO0, BO1};
2054 case Instruction::Sub:
2069 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2074 unsigned NumElts = Mask.size();
2077 auto *ShufOp = dyn_cast<ShuffleVectorInst>(Op0);
2078 if (ShufOp && ShufOp->isSelect() &&
2079 (ShufOp->getOperand(0) == Op1 || ShufOp->getOperand(1) == Op1)) {
2084 ShufOp = dyn_cast<ShuffleVectorInst>(Op1);
2085 if (!ShufOp || !ShufOp->isSelect() ||
2086 (ShufOp->getOperand(0) != Op0 && ShufOp->getOperand(1) != Op0))
2089 Value *
X = ShufOp->getOperand(0), *
Y = ShufOp->getOperand(1);
2091 ShufOp->getShuffleMask(Mask1);
2092 assert(Mask1.
size() == NumElts &&
"Vector size changed with select shuffle");
2105 for (
unsigned i = 0; i != NumElts; ++i)
2106 NewMask[i] = Mask[i] < (
signed)NumElts ? Mask[i] : Mask1[i];
2111 "Unexpected shuffle mask");
2116 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2133 auto *BO = cast<BinaryOperator>(Op0IsBinop ? Op0 : Op1);
2147 bool MightCreatePoisonOrUB =
2150 if (MightCreatePoisonOrUB)
2155 Value *
X = Op0IsBinop ? Op1 : Op0;
2187 Value *NewIns =
Builder.CreateInsertElement(UndefVec,
X, Zero);
2193 unsigned NumMaskElts =
2194 cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2196 for (
unsigned i = 0; i != NumMaskElts; ++i)
2198 NewMask[i] = Mask[i];
2210 unsigned NumElts = cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2234 Constant *C0 =
nullptr, *C1 =
nullptr;
2235 bool ConstantsAreOp1;
2238 ConstantsAreOp1 =
false;
2243 ConstantsAreOp1 =
true;
2250 bool DropNSW =
false;
2251 if (ConstantsAreOp1 && Opc0 != Opc1) {
2255 if (Opc0 == Instruction::Shl || Opc1 == Instruction::Shl)
2258 assert(isa<Constant>(AltB0.Op1) &&
"Expecting constant with alt binop");
2259 Opc0 = AltB0.Opcode;
2260 C0 = cast<Constant>(AltB0.Op1);
2262 assert(isa<Constant>(AltB1.Op1) &&
"Expecting constant with alt binop");
2263 Opc1 = AltB1.Opcode;
2264 C1 = cast<Constant>(AltB1.Op1);
2268 if (Opc0 != Opc1 || !C0 || !C1)
2281 bool MightCreatePoisonOrUB =
2284 if (MightCreatePoisonOrUB)
2307 if (MightCreatePoisonOrUB && !ConstantsAreOp1)
2328 if (
auto *NewI = dyn_cast<Instruction>(NewBO)) {
2329 NewI->copyIRFlags(B0);
2330 NewI->andIRFlags(B1);
2332 NewI->setHasNoSignedWrap(
false);
2334 NewI->dropPoisonGeneratingFlags();
2353 Type *SrcType =
X->getType();
2355 cast<FixedVectorType>(SrcType)->getNumElements() !=
2356 cast<FixedVectorType>(DestType)->getNumElements() ||
2361 "Expected a shuffle that decreases length");
2368 for (
unsigned i = 0, e = Mask.size(); i != e; ++i) {
2371 uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
2372 assert(LSBIndex <= INT32_MAX &&
"Overflowed 32-bits");
2373 if (Mask[i] != (
int)LSBIndex)
2399 unsigned NarrowNumElts =
2400 cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2403 cast<FixedVectorType>(NarrowCond->
getType())->getNumElements() !=
2405 !cast<ShuffleVectorInst>(
Cond)->isIdentityWithPadding())
2418 auto *S0 = dyn_cast<Instruction>(Shuf.
getOperand(0));
2423 bool IsFNeg = S0->getOpcode() == Instruction::FNeg;
2433 Intrinsic::fabs, Shuf.
getType());
2440 auto *S1 = dyn_cast<Instruction>(Shuf.
getOperand(1));
2443 S0->getOpcode() != S1->getOpcode() ||
2444 (!S0->hasOneUse() && !S1->hasOneUse()))
2451 NewF = UnaryOperator::CreateFNeg(NewShuf);
2454 Intrinsic::fabs, Shuf.
getType());
2466 auto *Cast0 = dyn_cast<CastInst>(Shuf.
getOperand(0));
2467 auto *Cast1 = dyn_cast<CastInst>(Shuf.
getOperand(1));
2468 if (!Cast0 || !Cast1 || Cast0->getOpcode() != Cast1->getOpcode() ||
2469 Cast0->getSrcTy() != Cast1->getSrcTy())
2475 switch (CastOpcode) {
2476 case Instruction::FPToSI:
2477 case Instruction::FPToUI:
2478 case Instruction::SIToFP:
2479 case Instruction::UIToFP:
2487 VectorType *CastSrcTy = cast<VectorType>(Cast0->getSrcTy());
2490 if (ShufTy->getElementCount().getKnownMinValue() >
2491 ShufOpTy->getElementCount().getKnownMinValue())
2495 assert(isa<FixedVectorType>(CastSrcTy) && isa<FixedVectorType>(ShufOpTy) &&
2496 "Expected fixed vector operands for casts and binary shuffle");
2497 if (CastSrcTy->getPrimitiveSizeInBits() > ShufOpTy->getPrimitiveSizeInBits())
2501 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
2505 Value *
X = Cast0->getOperand(0);
2506 Value *
Y = Cast1->getOperand(0);
2521 X->getType()->getPrimitiveSizeInBits() ==
2547 unsigned NumElts = cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2549 assert(NumElts < Mask.size() &&
2550 "Identity with extract must have less elements than its inputs");
2552 for (
unsigned i = 0; i != NumElts; ++i) {
2554 int MaskElt = Mask[i];
2555 NewMask[i] = ExtractMaskElt ==
UndefMaskElem ? ExtractMaskElt : MaskElt;
2568 int NumElts = Mask.size();
2569 int InpNumElts = cast<FixedVectorType>(V0->
getType())->getNumElements();
2594 if (NumElts != InpNumElts)
2598 auto isShufflingScalarIntoOp1 = [&](
Value *&Scalar,
ConstantInt *&IndexC) {
2606 int NewInsIndex = -1;
2607 for (
int i = 0; i != NumElts; ++i) {
2613 if (Mask[i] == NumElts + i)
2617 if (NewInsIndex != -1 || Mask[i] != IndexC->getSExtValue())
2624 assert(NewInsIndex != -1 &&
"Did not fold shuffle with unused operand?");
2636 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2644 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2654 auto *Shuffle0 = dyn_cast<ShuffleVectorInst>(Shuf.
getOperand(0));
2655 auto *Shuffle1 = dyn_cast<ShuffleVectorInst>(Shuf.
getOperand(1));
2656 if (!Shuffle0 || !Shuffle0->isIdentityWithPadding() ||
2657 !Shuffle1 || !Shuffle1->isIdentityWithPadding())
2665 Value *
X = Shuffle0->getOperand(0);
2666 Value *
Y = Shuffle1->getOperand(0);
2667 if (
X->getType() !=
Y->getType() ||
2670 cast<FixedVectorType>(Shuffle0->getType())->getNumElements()) ||
2671 !
isPowerOf2_32(cast<FixedVectorType>(
X->getType())->getNumElements()) ||
2676 "Unexpected operand for identity shuffle");
2682 int NarrowElts = cast<FixedVectorType>(
X->getType())->getNumElements();
2683 int WideElts = cast<FixedVectorType>(Shuffle0->getType())->getNumElements();
2684 assert(WideElts > NarrowElts &&
"Unexpected types for identity with padding");
2688 for (
int i = 0, e = Mask.size(); i != e; ++i) {
2694 if (Mask[i] < WideElts) {
2695 if (Shuffle0->getMaskValue(Mask[i]) == -1)
2698 if (Shuffle1->getMaskValue(Mask[i] - WideElts) == -1)
2705 if (Mask[i] < WideElts) {
2706 assert(Mask[i] < NarrowElts &&
"Unexpected shuffle mask");
2707 NewMask[i] = Mask[i];
2709 assert(Mask[i] < (WideElts + NarrowElts) &&
"Unexpected shuffle mask");
2710 NewMask[i] = Mask[i] - (WideElts - NarrowElts);
2732 if (
X->getType() !=
Y->getType())
2735 auto *BinOp = cast<BinaryOperator>(Op0);
2740 if (
auto NewBOI = dyn_cast<Instruction>(NewBO))
2741 NewBOI->copyIRFlags(BinOp);
2760 unsigned VWidth = cast<FixedVectorType>(SVI.
getType())->getNumElements();
2761 unsigned LHSWidth = cast<FixedVectorType>(
LHS->
getType())->getNumElements();
2772 X->getType()->isVectorTy() &&
X->getType() ==
Y->getType() &&
2773 X->getType()->getScalarSizeInBits() ==
2791 X->getType()->isVectorTy() && VWidth == LHSWidth) {
2793 auto *XType = cast<FixedVectorType>(
X->getType());
2794 unsigned XNumElts = XType->getNumElements();
2796 if (XNumElts >= VWidth) {
2797 assert(XNumElts % VWidth == 0 &&
"Unexpected vector bitcast");
2800 assert(VWidth % XNumElts == 0 &&
"Unexpected vector bitcast");
2804 if (!ScaledMask.
empty()) {
2808 ScaledMask, XType, ShufQuery))
2816 "Shuffle with 2 undef ops not simplified?");
2844 APInt UndefElts(VWidth, 0);
2896 bool MadeChange =
false;
2899 unsigned MaskElems = Mask.size();
2900 auto *SrcTy = cast<FixedVectorType>(V->getType());
2901 unsigned VecBitWidth = SrcTy->getPrimitiveSizeInBits().getFixedValue();
2903 assert(SrcElemBitWidth &&
"vector elements must have a bitwidth");
2904 unsigned SrcNumElems = SrcTy->getNumElements();
2909 if (!BC->use_empty())
2913 unsigned BegIdx = Mask.front();
2914 Type *TgtTy = BC->getDestTy();
2916 if (!TgtElemBitWidth)
2918 unsigned TgtNumElems = VecBitWidth / TgtElemBitWidth;
2919 bool VecBitWidthsEqual = VecBitWidth == TgtNumElems * TgtElemBitWidth;
2920 bool BegIsAligned = 0 == ((SrcElemBitWidth * BegIdx) % TgtElemBitWidth);
2921 if (!VecBitWidthsEqual)
2926 if (!BegIsAligned) {
2930 for (
unsigned I = 0,
E = MaskElems,
Idx = BegIdx;
I !=
E; ++
Idx, ++
I)
2931 ShuffleMask[
I] =
Idx;
2936 unsigned SrcElemsPerTgtElem = TgtElemBitWidth / SrcElemBitWidth;
2937 assert(SrcElemsPerTgtElem);
2938 BegIdx /= SrcElemsPerTgtElem;
2939 bool BCAlreadyExists = NewBCs.
contains(CastSrcTy);
2944 if (!BCAlreadyExists)
2945 NewBCs[CastSrcTy] = NewBC;
3002 LHSShuffle =
nullptr;
3005 RHSShuffle =
nullptr;
3006 if (!LHSShuffle && !RHSShuffle)
3007 return MadeChange ? &SVI :
nullptr;
3009 Value* LHSOp0 =
nullptr;
3010 Value* LHSOp1 =
nullptr;
3011 Value* RHSOp0 =
nullptr;
3012 unsigned LHSOp0Width = 0;
3013 unsigned RHSOp0Width = 0;
3017 LHSOp0Width = cast<FixedVectorType>(LHSOp0->
getType())->getNumElements();
3021 RHSOp0Width = cast<FixedVectorType>(RHSOp0->
getType())->getNumElements();
3032 else if (LHSOp0Width == LHSWidth) {
3037 if (RHSShuffle && RHSOp0Width == LHSWidth) {
3041 if (LHSOp0 == RHSOp0) {
3046 if (newLHS ==
LHS && newRHS ==
RHS)
3047 return MadeChange ? &SVI :
nullptr;
3053 if (RHSShuffle && newRHS !=
RHS)
3056 unsigned newLHSWidth = (newLHS !=
LHS) ? LHSOp0Width : LHSWidth;
3062 for (
unsigned i = 0; i < VWidth; ++i) {
3067 }
else if (Mask[i] < (
int)LHSWidth) {
3072 if (newLHS !=
LHS) {
3073 eltMask = LHSMask[Mask[i]];
3076 if (eltMask >= (
int)LHSOp0Width && isa<UndefValue>(LHSOp1))
3089 else if (newRHS !=
RHS) {
3090 eltMask = RHSMask[Mask[i]-LHSWidth];
3093 if (eltMask >= (
int)RHSOp0Width) {
3095 "should have been check above");
3099 eltMask = Mask[i]-LHSWidth;
3107 if (eltMask >= 0 && newRHS !=
nullptr && newLHS != newRHS)
3108 eltMask += newLHSWidth;
3113 if (SplatElt >= 0 && SplatElt != eltMask)
3123 if (
isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
3129 return MadeChange ? &SVI :
nullptr;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements a class to represent arbitrary precision integral constant values and operations...
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file provides internal interfaces used to implement the InstCombine.
static Instruction * foldConstantInsEltIntoShuffle(InsertElementInst &InsElt)
insertelt (shufflevector X, CVec, Mask|insertelt X, C1, CIndex1), C, CIndex --> shufflevector X,...
static bool collectSingleShuffleElements(Value *V, Value *LHS, Value *RHS, SmallVectorImpl< int > &Mask)
If V is a shuffle of values that ONLY returns elements from either LHS or RHS, return the shuffle mas...
static APInt findDemandedEltsByAllUsers(Value *V)
Find union of elements of V demanded by all its users.
static Instruction * foldTruncInsEltPair(InsertElementInst &InsElt, bool IsBigEndian, InstCombiner::BuilderTy &Builder)
If we are inserting 2 halves of a value into adjacent elements of a vector, try to convert to a singl...
static Instruction * foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf)
static Instruction * foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf)
static Value * buildNew(Instruction *I, ArrayRef< Value * > NewOps)
Rebuild a new instruction just like 'I' but with the new operands given.
static Instruction * foldIdentityExtractShuffle(ShuffleVectorInst &Shuf)
Try to fold an extract subvector operation.
static Instruction * foldInsEltIntoSplat(InsertElementInst &InsElt)
Try to fold an insert element into an existing splat shuffle by changing the shuffle's mask to includ...
std::pair< Value *, Value * > ShuffleOps
We are building a shuffle to create V, which is a sequence of insertelement, extractelement pairs.
ConstantInt * getPreferredVectorIndex(ConstantInt *IndexC)
Given a constant index for a extractelement or insertelement instruction, return it with the canonica...
static Instruction * foldShuffleWithInsert(ShuffleVectorInst &Shuf, InstCombinerImpl &IC)
Try to replace a shuffle with an insertelement or try to replace a shuffle operand with the operand o...
static Instruction * canonicalizeInsertSplat(ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
If we have an insert of a scalar to a non-zero element of an undefined vector and then shuffle that v...
static ShuffleOps collectShuffleElements(Value *V, SmallVectorImpl< int > &Mask, Value *PermittedRHS, InstCombinerImpl &IC)
static Instruction * foldTruncShuffle(ShuffleVectorInst &Shuf, bool IsBigEndian)
Convert a narrowing shuffle of a bitcasted vector into a vector truncate.
static bool cheapToScalarize(Value *V, Value *EI)
Return true if the value is cheaper to scalarize than it is to leave as a vector operation.
static Value * evaluateInDifferentElementOrder(Value *V, ArrayRef< int > Mask)
static void replaceExtractElements(InsertElementInst *InsElt, ExtractElementInst *ExtElt, InstCombinerImpl &IC)
If we have insertion into a vector that is wider than the vector that we are extracting from,...
static bool canEvaluateShuffled(Value *V, ArrayRef< int > Mask, unsigned Depth=5)
Return true if we can evaluate the specified expression tree if the vector elements were shuffled in ...
static Instruction * foldSelectShuffleOfSelectShuffle(ShuffleVectorInst &Shuf)
A select shuffle of a select shuffle with a shared operand can be reduced to a single select shuffle.
static Instruction * hoistInsEltConst(InsertElementInst &InsElt2, InstCombiner::BuilderTy &Builder)
If we have an insertelement instruction feeding into another insertelement and the 2nd is inserting a...
static APInt findDemandedEltsBySingleUser(Value *V, Instruction *UserInstr)
Find elements of V demanded by UserInstr.
static Instruction * foldShuffleOfUnaryOps(ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
Canonicalize FP negate/abs after shuffle.
static Instruction * foldCastShuffle(ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
Canonicalize casts after shuffle.
static Instruction * narrowInsElt(InsertElementInst &InsElt, InstCombiner::BuilderTy &Builder)
If both the base vector and the inserted element are extended from the same type, do the insert eleme...
static bool isShuffleEquivalentToSelect(ShuffleVectorInst &Shuf)
static Instruction * foldInsSequenceIntoSplat(InsertElementInst &InsElt)
Turn a chain of inserts that splats a value into an insert + shuffle: insertelt(insertelt(insertelt(i...
static Instruction * foldInsEltIntoIdentityShuffle(InsertElementInst &InsElt)
Try to fold an extract+insert element into an existing identity shuffle by changing the shuffle's mas...
static bool isShuffleExtractingFromLHS(ShuffleVectorInst &SVI, ArrayRef< int > Mask)
static BinopElts getAlternateBinop(BinaryOperator *BO, const DataLayout &DL)
Binops may be transformed into binops with different opcodes and operands.
This file provides the interface for the instcombine pass implementation.
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the SmallBitVector class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static SDValue narrowVectorSelect(SDNode *N, SelectionDAG &DAG, const X86Subtarget &Subtarget)
If both arms of a vector select are concatenated vectors, split the select, and concatenate the resul...
static const uint32_t IV[8]
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
BinaryOps getOpcode() const
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Instruction *CopyO, const Twine &Name="", Instruction *InsertBefore=nullptr)
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
static CmpInst * Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name="", Instruction *InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
static ConstantAggregateZero * get(Type *Ty)
static Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)
static Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static 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.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
IntegerType * getType() const
getType - Specialize the getType() method to always return an IntegerType, which reduces the amount o...
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This instruction compares its operands according to the predicate given to the constructor.
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
This instruction inserts a single (scalar) element into a VectorType value.
VectorType * getType() const
Overload to return most specific vector type.
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
This instruction inserts a struct field of array element value into an aggregate value.
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts, unsigned Depth=0, bool AllowMultipleUsers=false) override
The specified value produces a vector with any number of elements.
Instruction * foldSelectShuffle(ShuffleVectorInst &Shuf)
Try to fold shuffles that are the equivalent of a vector select.
Instruction * visitInsertValueInst(InsertValueInst &IV)
Try to find redundant insertvalue instructions, like the following ones: %0 = insertvalue { i8,...
Instruction * visitInsertElementInst(InsertElementInst &IE)
Instruction * visitExtractElementInst(ExtractElementInst &EI)
Instruction * simplifyBinOpSplats(ShuffleVectorInst &SVI)
Instruction * foldAggregateConstructionIntoAggregateReuse(InsertValueInst &OrigIVI)
Look for chain of insertvalue's that fully define an aggregate, and trace back the values inserted,...
Instruction * visitShuffleVectorInst(ShuffleVectorInst &SVI)
Instruction * InsertNewInstWith(Instruction *New, Instruction &Old)
Same as InsertNewInstBefore, but also sets the debug loc.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
static Constant * getSafeVectorConstantForBinop(BinaryOperator::BinaryOps Opcode, Constant *In, bool IsRHSConstant)
Some binary operators require special handling to avoid poison and undefined behavior.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
const BasicBlock * getParent() const
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
This instruction constructs a fixed permutation of two input vectors.
bool changesLength() const
Return true if this shuffle returns a vector with a different number of elements than its source vect...
static bool isSelectMask(ArrayRef< int > Mask)
Return true if this shuffle mask chooses elements from its source vectors without lane crossings.
int getMaskValue(unsigned Elt) const
Return the shuffle mask value of this instruction for the given element index.
static bool isIdentityMask(ArrayRef< int > Mask)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
VectorType * getType() const
Overload to return most specific vector type.
bool increasesLength() const
Return true if this shuffle returns a vector with a greater number of elements than its source vector...
bool isIdentityWithExtract() const
Return true if this shuffle extracts the first N elements of exactly one source vector.
static void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
bool isSelect() const
Return true if this shuffle chooses elements from its source vectors without lane crossings and all o...
static void commuteShuffleMask(MutableArrayRef< int > Mask, unsigned InVecNumElts)
Change values in a shuffle permute mask assuming the two vector operands of length InVecNumElts have ...
void commute()
Swap the operands and adjust the mask to preserve the semantics of the instruction.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool all() const
Returns true if all bits are set.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
unsigned getStructNumElements() const
uint64_t getArrayNumElements() const
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
static IntegerType * getInt32Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", Instruction *InsertBefore=nullptr)
UnaryOps getOpcode() const
static UnaryOperator * CreateWithCopiedFlags(UnaryOps Opc, Value *V, Instruction *CopyO, const Twine &Name="", Instruction *InsertBefore=nullptr)
'undef' values are things that do not have specified contents.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
specific_intval< false > m_SpecificInt(APInt V)
Match a specific integer value or vector with all elements equal to the value.
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
CastClass_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastClass_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
CastClass_match< OpTy, Instruction::FPExt > m_FPExt(const OpTy &Op)
class_match< UnaryOperator > m_UnOp()
Match an arbitrary unary operation and ignore it.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
auto m_Undef()
Match an arbitrary undef constant.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
llvm::SmallVector< int, 16 > createUnaryMask(ArrayRef< int > Mask, unsigned NumElts)
Given a shuffle mask for a binary shuffle, create the equivalent shuffle mask assuming both operands ...
bool widenShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Try to transform a shuffle mask by replacing elements with the scaled index for an equivalent mask of...
Value * simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef< int > Mask, Type *RetTy, const SimplifyQuery &Q)
Given operands for a ShuffleVectorInst, fold the result or return null.
constexpr int UndefMaskElem
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an InsertValueInst, fold the result or return null.
void narrowShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Replace each shuffle mask index with the scaled sequential indices for an equivalent mask of narrowed...
Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
Value * simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, const SimplifyQuery &Q)
Given operands for an InsertElement, fold the result or return null.
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
constexpr unsigned BitWidth
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool pred_empty(const BasicBlock *BB)
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if 'V & Mask' is known to be zero.
Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q)
Given operands for an ExtractElementInst, fold the result or return null.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
These are the ingredients in an alternate form binary operator as described below.
BinopElts(BinaryOperator::BinaryOps Opc=(BinaryOperator::BinaryOps) 0, Value *V0=nullptr, Value *V1=nullptr)
BinaryOperator::BinaryOps Opcode
SimplifyQuery getWithInstruction(Instruction *I) const