44#define DEBUG_TYPE "instcombine"
50 "Number of aggregate reconstructions turned into reuse of the "
51 "original aggregate");
63 return CEI ||
C->getSplatValue();
102 SmallVector<Instruction *, 2> Extracts;
108 for (
auto *U : PN->
users()) {
114 }
else if (!PHIUser) {
142 if (PHIInVal == PHIUser) {
147 unsigned opId = (B0->
getOperand(0) == PN) ? 1 : 0;
179 for (
auto *
E : Extracts) {
195 ElementCount NumElts =
199 bool IsBigEndian =
DL.isBigEndian();
203 if (
X->getType()->isIntegerTy()) {
205 "Expected fixed vector type for bitcast from scalar integer");
212 unsigned ShiftAmountC = ExtIndexC * DestWidth;
213 if ((!ShiftAmountC ||
214 isDesirableIntType(
X->getType()->getPrimitiveSizeInBits())) &&
217 X =
Builder.CreateLShr(
X, ShiftAmountC,
"extelt.offset");
221 return new BitCastInst(Trunc, DestTy);
223 return new TruncInst(
X, DestTy);
227 if (!
X->getType()->isVectorTy())
234 ElementCount NumSrcElts = SrcTy->getElementCount();
235 if (NumSrcElts == NumElts)
237 return new BitCastInst(Elt, DestTy);
240 "Src and Dst must be the same sort of vector type");
256 unsigned NarrowingRatio =
259 if (ExtIndexC / NarrowingRatio != InsIndexC) {
283 unsigned Chunk = ExtIndexC % NarrowingRatio;
285 Chunk = NarrowingRatio - 1 - Chunk;
290 bool NeedSrcBitcast = SrcTy->getScalarType()->isFloatingPointTy();
292 if (NeedSrcBitcast && NeedDestBitcast)
295 unsigned SrcWidth = SrcTy->getScalarSizeInBits();
296 unsigned ShAmt = Chunk * DestWidth;
302 if (NeedSrcBitcast || NeedDestBitcast)
305 if (NeedSrcBitcast) {
317 if (NeedDestBitcast) {
319 return new BitCastInst(
Builder.CreateTrunc(Scalar, DestIntTy), DestTy);
321 return new TruncInst(Scalar, DestTy);
330 APInt &UnionUsedElts) {
334 case Instruction::ExtractElement: {
338 if (EEIIndexC && EEIIndexC->
getValue().
ult(VWidth)) {
344 case Instruction::ShuffleVector: {
346 unsigned MaskNumElts =
351 if (MaskVal == -1u || MaskVal >= 2 * VWidth)
353 if (Shuffle->
getOperand(0) == V && (MaskVal < VWidth))
354 UnionUsedElts.
setBit(MaskVal);
356 ((MaskVal >= VWidth) && (MaskVal < 2 * VWidth)))
357 UnionUsedElts.
setBit(MaskVal - VWidth);
375 APInt UnionUsedElts(VWidth, 0);
376 for (
const Use &U : V->
uses()) {
389 return UnionUsedElts;
408 SQ.getWithInstruction(&EI)))
420 if (
SI->getCondition()->getType()->isIntegerTy() &&
428 bool HasKnownValidIndex =
false;
435 unsigned NumElts = EC.getKnownMinValue();
436 HasKnownValidIndex = IndexC->getValue().ult(NumElts);
442 if (IID == Intrinsic::stepvector && IndexC->getValue().ult(NumElts)) {
444 unsigned BitWidth = Ty->getIntegerBitWidth();
449 if (IndexC->getValue().getActiveBits() <=
BitWidth)
450 Idx = ConstantInt::get(Ty, IndexC->getValue().zextOrTrunc(
BitWidth));
459 if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
468 if (
Instruction *ScalarPHI = scalarizePHI(EI, Phi))
493 (HasKnownValidIndex ||
524 uint64_t IdxVal = IndexC ? IndexC->getZExtValue() : 0;
525 if (IndexC && IdxVal < EC.getKnownMinValue() &&
GEP->hasOneUse()) {
536 return isa<VectorType>(V->getType());
538 if (VectorOps == 1) {
539 Value *NewPtr =
GEP->getPointerOperand();
541 NewPtr =
Builder.CreateExtractElement(NewPtr, IndexC);
544 for (
unsigned I = 1;
I !=
GEP->getNumOperands(); ++
I) {
553 GEP->getSourceElementType(), NewPtr, NewOps);
567 std::optional<int> SrcIdx;
569 if (SplatIndex != -1)
572 SrcIdx = SVI->getMaskValue(CI->getZExtValue());
582 if (*SrcIdx < (
int)LHSWidth)
583 Src = SVI->getOperand(0);
586 Src = SVI->getOperand(1);
590 Src, ConstantInt::get(Int64Ty, *SrcIdx,
false));
604 if (CI->hasOneUse() && (CI->getOpcode() != Instruction::BitCast) &&
606 Value *EE =
Builder.CreateExtractElement(CI->getOperand(0), Index);
617 unsigned NumElts = EC.getKnownMinValue();
621 if (!EC.isScalable() && NumElts != 1) {
625 APInt PoisonElts(NumElts, 0);
626 APInt DemandedElts(NumElts, 0);
627 DemandedElts.
setBit(IndexC->getZExtValue());
636 APInt PoisonElts(NumElts, 0);
638 SrcVec, DemandedElts, PoisonElts, 0 ,
658 "Invalid CollectSingleShuffleElements");
662 Mask.assign(NumElts, -1);
667 for (
unsigned i = 0; i != NumElts; ++i)
673 for (
unsigned i = 0; i != NumElts; ++i)
674 Mask.push_back(i + NumElts);
680 Value *VecOp = IEI->getOperand(0);
681 Value *ScalarOp = IEI->getOperand(1);
682 Value *IdxOp = IEI->getOperand(2);
693 Mask[InsertedIdx] = -1;
698 unsigned ExtractedIdx =
700 unsigned NumLHSElts =
710 Mask[InsertedIdx % NumElts] = ExtractedIdx;
713 Mask[InsertedIdx % NumElts] = ExtractedIdx + NumLHSElts;
733 unsigned NumInsElts = InsVecType->getNumElements();
734 unsigned NumExtElts = ExtVecType->getNumElements();
737 if (InsVecType->getElementType() != ExtVecType->getElementType() ||
738 NumExtElts >= NumInsElts)
751 for (
unsigned i = 0; i < NumExtElts; ++i)
753 for (
unsigned i = NumExtElts; i < NumInsElts; ++i)
770 if (InsertionBlock != InsElt->
getParent())
788 WideVec->insertAfter(ExtVecOpInst->getIterator());
796 if (!OldExt || OldExt->
getParent() != WideVec->getParent())
822 assert(V->getType()->isVectorTy() &&
"Invalid shuffle!");
826 Mask.assign(NumElts, -1);
827 return std::make_pair(
832 Mask.assign(NumElts, 0);
833 return std::make_pair(V,
nullptr);
838 Value *VecOp = IEI->getOperand(0);
839 Value *ScalarOp = IEI->getOperand(1);
840 Value *IdxOp = IEI->getOperand(2);
844 unsigned ExtractedIdx =
850 if (EI->
getOperand(0) == PermittedRHS || PermittedRHS ==
nullptr) {
853 assert(LR.second ==
nullptr || LR.second ==
RHS);
855 if (LR.first->getType() !=
RHS->getType()) {
863 for (
unsigned i = 0; i < NumElts; ++i)
865 return std::make_pair(V,
nullptr);
868 unsigned NumLHSElts =
870 Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
871 return std::make_pair(LR.first,
RHS);
874 if (VecOp == PermittedRHS) {
877 unsigned NumLHSElts =
880 for (
unsigned i = 0; i != NumElts; ++i)
881 Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
882 return std::make_pair(EI->
getOperand(0), PermittedRHS);
890 return std::make_pair(EI->
getOperand(0), PermittedRHS);
896 for (
unsigned i = 0; i != NumElts; ++i)
898 return std::make_pair(V,
nullptr);
924 assert(NumAggElts > 0 &&
"Aggregate should have elements.");
928 static constexpr auto NotFound = std::nullopt;
929 static constexpr auto FoundMismatch =
nullptr;
936 auto KnowAllElts = [&AggElts]() {
944 static const int DepthLimit = 2 * NumAggElts;
949 Depth < DepthLimit && CurrIVI && !KnowAllElts();
952 auto *InsertedValue =
960 if (Indices.
size() != 1)
966 std::optional<Instruction *> &Elt = AggElts[Indices.
front()];
967 Elt = Elt.value_or(InsertedValue);
980 enum class AggregateDescription {
996 auto Describe = [](std::optional<Value *> SourceAggregate) {
997 if (SourceAggregate == NotFound)
998 return AggregateDescription::NotFound;
999 if (*SourceAggregate == FoundMismatch)
1000 return AggregateDescription::FoundMismatch;
1001 return AggregateDescription::Found;
1005 bool EltDefinedInUseBB =
false;
1012 auto FindSourceAggregate =
1013 [&](
Instruction *Elt,
unsigned EltIdx, std::optional<BasicBlock *> UseBB,
1014 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1016 if (UseBB && PredBB) {
1019 EltDefinedInUseBB =
true;
1028 Value *SourceAggregate = EVI->getAggregateOperand();
1031 if (SourceAggregate->
getType() != AggTy)
1032 return FoundMismatch;
1034 if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
1035 return FoundMismatch;
1037 return SourceAggregate;
1043 auto FindCommonSourceAggregate =
1044 [&](std::optional<BasicBlock *> UseBB,
1045 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1046 std::optional<Value *> SourceAggregate;
1049 assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
1050 "We don't store nullptr in SourceAggregate!");
1051 assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
1053 "SourceAggregate should be valid after the first element,");
1058 std::optional<Value *> SourceAggregateForElement =
1059 FindSourceAggregate(*
I.value(),
I.index(), UseBB, PredBB);
1066 if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
1067 return SourceAggregateForElement;
1071 switch (Describe(SourceAggregate)) {
1072 case AggregateDescription::NotFound:
1074 SourceAggregate = SourceAggregateForElement;
1076 case AggregateDescription::Found:
1079 if (*SourceAggregateForElement != *SourceAggregate)
1080 return FoundMismatch;
1082 case AggregateDescription::FoundMismatch:
1087 assert(Describe(SourceAggregate) == AggregateDescription::Found &&
1088 "Must be a valid Value");
1089 return *SourceAggregate;
1092 std::optional<Value *> SourceAggregate;
1095 SourceAggregate = FindCommonSourceAggregate(std::nullopt,
1097 if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
1098 if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
1100 ++NumAggregateReconstructionsSimplified;
1113 for (
const std::optional<Instruction *> &
I : AggElts) {
1137 static const int PredCountLimit = 64;
1144 if (Preds.
size() >= PredCountLimit)
1153 bool FoundSrcAgg =
false;
1155 std::pair<
decltype(SourceAggregates)
::iterator,
bool>
IV =
1164 SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
1165 if (Describe(SourceAggregate) == AggregateDescription::Found) {
1167 IV.first->second = *SourceAggregate;
1172 if (!BI || !BI->isUnconditional())
1182 for (
auto &It : SourceAggregates) {
1183 if (Describe(It.second) == AggregateDescription::Found)
1187 if (EltDefinedInUseBB)
1195 if (UseBB != OrigBB)
1200 bool ConstAgg =
true;
1201 for (
auto Val : AggElts) {
1214 for (
auto &It : SourceAggregates) {
1215 if (Describe(It.second) == AggregateDescription::Found)
1219 Builder.SetInsertPoint(Pred->getTerminator());
1221 for (
auto [Idx, Val] :
enumerate(AggElts)) {
1223 V =
Builder.CreateInsertValue(V, Elt, Idx);
1235 Builder.SetInsertPoint(UseBB, UseBB->getFirstNonPHIIt());
1239 PHI->addIncoming(SourceAggregates[Pred], Pred);
1241 ++NumAggregateReconstructionsSimplified;
1254 I.getAggregateOperand(),
I.getInsertedValueOperand(),
I.getIndices(),
1255 SQ.getWithInstruction(&
I)))
1258 bool IsRedundant =
false;
1267 while (V->hasOneUse() &&
Depth < 10) {
1270 if (!UserInsInst || U->getOperand(0) != V)
1272 if (UserInsInst->getIndices() == FirstIndices) {
1300 if (MaskSize != VecSize)
1305 for (
int i = 0; i != MaskSize; ++i) {
1307 if (Elt != -1 && Elt != i && Elt != i + VecSize)
1332 if (NumElements == 1)
1344 if (!Idx || CurrIE->
getOperand(1) != SplatVal)
1351 if (CurrIE != &InsElt &&
1352 (!CurrIE->
hasOneUse() && (NextIE !=
nullptr || !Idx->isZero())))
1355 ElementPresent[Idx->getZExtValue()] =
true;
1361 if (FirstIE == &InsElt)
1369 if (!ElementPresent.
all())
1375 Constant *Zero = ConstantInt::get(Int64Ty, 0);
1382 for (
unsigned i = 0; i != NumElements; ++i)
1383 if (!ElementPresent[i])
1394 if (!Shuf || !Shuf->isZeroEltSplat())
1409 Value *Op0 = Shuf->getOperand(0);
1417 unsigned NumMaskElts =
1420 for (
unsigned i = 0; i != NumMaskElts; ++i)
1421 NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
1432 !(Shuf->isIdentityWithExtract() || Shuf->isIdentityWithPadding()))
1448 Value *
X = Shuf->getOperand(0);
1456 unsigned NumMaskElts =
1460 for (
unsigned i = 0; i != NumMaskElts; ++i) {
1463 NewMask[i] = OldMask[i];
1464 }
else if (OldMask[i] == (
int)IdxC) {
1470 "Unexpected shuffle mask element for identity shuffle");
1490 if (!InsElt1 || !InsElt1->hasOneUse())
1501 Value *NewInsElt1 = Builder.CreateInsertElement(
X, ScalarC, IdxC2);
1514 if (!Inst || !Inst->hasOneUse())
1519 Constant *ShufConstVec, *InsEltScalar;
1543 unsigned NumElts = Mask.size();
1546 for (
unsigned I = 0;
I != NumElts; ++
I) {
1547 if (
I == InsEltIndex) {
1548 NewShufElts[
I] = InsEltScalar;
1549 NewMaskElts[
I] = InsEltIndex + NumElts;
1553 NewMaskElts[
I] = Mask[
I];
1557 if (!NewShufElts[
I])
1584 auto ValI = std::begin(Val);
1591 Mask[
I] = NumElts +
I;
1596 for (
unsigned I = 0;
I < NumElts; ++
I) {
1628 CastOpcode = Instruction::FPExt;
1630 CastOpcode = Instruction::SExt;
1632 CastOpcode = Instruction::ZExt;
1637 if (
X->getType()->getScalarType() !=
Y->getType())
1665 Value *Scalar0, *BaseVec;
1667 if (!VTy || (VTy->getNumElements() & 1) ||
1676 if (Index0 + 1 != Index1 || Index0 & 1)
1693 Type *SrcTy =
X->getType();
1694 unsigned ScalarWidth = SrcTy->getScalarSizeInBits();
1695 unsigned VecEltWidth = VTy->getScalarSizeInBits();
1696 if (ScalarWidth != VecEltWidth * 2 || ShAmt != VecEltWidth)
1701 Value *CastBaseVec = Builder.CreateBitCast(BaseVec, CastTy);
1705 uint64_t NewIndex = IsBigEndian ? Index1 / 2 : Index0 / 2;
1706 Value *NewInsert = Builder.CreateInsertElement(CastBaseVec,
X, NewIndex);
1711 Value *VecOp = IE.getOperand(0);
1712 Value *ScalarOp = IE.getOperand(1);
1713 Value *IdxOp = IE.getOperand(2);
1716 VecOp, ScalarOp, IdxOp,
SQ.getWithInstruction(&IE)))
1724 Value *BaseVec, *OtherScalar;
1729 !
isa<Constant>(OtherScalar) && OtherIndexVal > IndexC->getZExtValue()) {
1730 Value *NewIns =
Builder.CreateInsertElement(BaseVec, ScalarOp, IdxOp);
1732 Builder.getInt64(OtherIndexVal));
1750 Value *NewInsElt =
Builder.CreateInsertElement(NewUndef, ScalarSrc, IdxOp);
1765 Value *NewInsElt =
Builder.CreateInsertElement(VecSrc, ScalarSrc, IdxOp);
1773 uint64_t InsertedIdx, ExtractedIdx;
1797 if (!Insert.hasOneUse())
1806 if (isShuffleRootCandidate(IE)) {
1817 if (LR.first != &IE && LR.second != &IE) {
1819 if (LR.second ==
nullptr)
1828 unsigned VWidth = VecTy->getNumElements();
1829 APInt PoisonElts(VWidth, 0);
1852 return IdentityShuf;
1866 unsigned Depth = 5) {
1873 if (!
I)
return false;
1876 if (!
I->hasOneUse())
1879 if (
Depth == 0)
return false;
1881 switch (
I->getOpcode()) {
1882 case Instruction::UDiv:
1883 case Instruction::SDiv:
1884 case Instruction::URem:
1885 case Instruction::SRem:
1892 case Instruction::Add:
1893 case Instruction::FAdd:
1894 case Instruction::Sub:
1895 case Instruction::FSub:
1896 case Instruction::Mul:
1897 case Instruction::FMul:
1898 case Instruction::FDiv:
1899 case Instruction::FRem:
1900 case Instruction::Shl:
1901 case Instruction::LShr:
1902 case Instruction::AShr:
1903 case Instruction::And:
1904 case Instruction::Or:
1905 case Instruction::Xor:
1906 case Instruction::ICmp:
1907 case Instruction::FCmp:
1908 case Instruction::Trunc:
1909 case Instruction::ZExt:
1910 case Instruction::SExt:
1911 case Instruction::FPToUI:
1912 case Instruction::FPToSI:
1913 case Instruction::UIToFP:
1914 case Instruction::SIToFP:
1915 case Instruction::FPTrunc:
1916 case Instruction::FPExt:
1917 case Instruction::GetElementPtr: {
1920 Type *ITy =
I->getType();
1924 for (
Value *Operand :
I->operands()) {
1930 case Instruction::InsertElement: {
1932 if (!CI)
return false;
1937 bool SeenOnce =
false;
1938 for (
int I : Mask) {
1939 if (
I == ElementNumber) {
1955 Builder.SetInsertPoint(
I);
1956 switch (
I->getOpcode()) {
1957 case Instruction::Add:
1958 case Instruction::FAdd:
1959 case Instruction::Sub:
1960 case Instruction::FSub:
1961 case Instruction::Mul:
1962 case Instruction::FMul:
1963 case Instruction::UDiv:
1964 case Instruction::SDiv:
1965 case Instruction::FDiv:
1966 case Instruction::URem:
1967 case Instruction::SRem:
1968 case Instruction::FRem:
1969 case Instruction::Shl:
1970 case Instruction::LShr:
1971 case Instruction::AShr:
1972 case Instruction::And:
1973 case Instruction::Or:
1974 case Instruction::Xor: {
1976 assert(NewOps.
size() == 2 &&
"binary operator with #ops != 2");
1978 NewOps[0], NewOps[1]);
1985 NewI->setIsExact(BO->
isExact());
1988 NewI->copyFastMathFlags(
I);
1992 case Instruction::ICmp:
1993 assert(NewOps.
size() == 2 &&
"icmp with #ops != 2");
1994 return Builder.CreateICmp(
cast<ICmpInst>(
I)->getPredicate(), NewOps[0],
1996 case Instruction::FCmp:
1997 assert(NewOps.
size() == 2 &&
"fcmp with #ops != 2");
1998 return Builder.CreateFCmp(
cast<FCmpInst>(
I)->getPredicate(), NewOps[0],
2000 case Instruction::Trunc:
2001 case Instruction::ZExt:
2002 case Instruction::SExt:
2003 case Instruction::FPToUI:
2004 case Instruction::FPToSI:
2005 case Instruction::UIToFP:
2006 case Instruction::SIToFP:
2007 case Instruction::FPTrunc:
2008 case Instruction::FPExt: {
2012 I->getType()->getScalarType(),
2014 assert(NewOps.
size() == 1 &&
"cast with #ops != 1");
2018 case Instruction::GetElementPtr: {
2019 Value *Ptr = NewOps[0];
2033 assert(V->getType()->isVectorTy() &&
"can't reorder non-vector elements");
2050 switch (
I->getOpcode()) {
2051 case Instruction::Add:
2052 case Instruction::FAdd:
2053 case Instruction::Sub:
2054 case Instruction::FSub:
2055 case Instruction::Mul:
2056 case Instruction::FMul:
2057 case Instruction::UDiv:
2058 case Instruction::SDiv:
2059 case Instruction::FDiv:
2060 case Instruction::URem:
2061 case Instruction::SRem:
2062 case Instruction::FRem:
2063 case Instruction::Shl:
2064 case Instruction::LShr:
2065 case Instruction::AShr:
2066 case Instruction::And:
2067 case Instruction::Or:
2068 case Instruction::Xor:
2069 case Instruction::ICmp:
2070 case Instruction::FCmp:
2071 case Instruction::Trunc:
2072 case Instruction::ZExt:
2073 case Instruction::SExt:
2074 case Instruction::FPToUI:
2075 case Instruction::FPToSI:
2076 case Instruction::UIToFP:
2077 case Instruction::SIToFP:
2078 case Instruction::FPTrunc:
2079 case Instruction::FPExt:
2080 case Instruction::Select:
2081 case Instruction::GetElementPtr: {
2086 for (
int i = 0, e =
I->getNumOperands(); i != e; ++i) {
2091 if (
I->getOperand(i)->getType()->isVectorTy())
2094 V =
I->getOperand(i);
2096 NeedsRebuild |= (V !=
I->getOperand(i));
2102 case Instruction::InsertElement: {
2110 for (
int e = Mask.size(); Index != e; ++Index) {
2111 if (Mask[Index] == Element) {
2124 Builder.SetInsertPoint(
I);
2125 return Builder.CreateInsertElement(V,
I->getOperand(1), Index);
2141 unsigned MaskElems = Mask.size();
2142 unsigned BegIdx = Mask.front();
2143 unsigned EndIdx = Mask.back();
2144 if (BegIdx > EndIdx || EndIdx >= LHSElems || EndIdx - BegIdx != MaskElems - 1)
2146 for (
unsigned I = 0;
I != MaskElems; ++
I)
2147 if (
static_cast<unsigned>(Mask[
I]) != BegIdx +
I)
2172 case Instruction::Shl: {
2177 Instruction::Shl, ConstantInt::get(Ty, 1),
C,
DL);
2178 assert(ShlOne &&
"Constant folding of immediate constants failed");
2179 return {Instruction::Mul, BO0, ShlOne};
2183 case Instruction::Or: {
2186 return {Instruction::Add, BO0, BO1};
2189 case Instruction::Sub:
2204 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2209 unsigned NumElts = Mask.size();
2213 if (ShufOp && ShufOp->isSelect() &&
2214 (ShufOp->getOperand(0) == Op1 || ShufOp->getOperand(1) == Op1)) {
2220 if (!ShufOp || !ShufOp->isSelect() ||
2221 (ShufOp->getOperand(0) != Op0 && ShufOp->getOperand(1) != Op0))
2224 Value *
X = ShufOp->getOperand(0), *
Y = ShufOp->getOperand(1);
2226 ShufOp->getShuffleMask(Mask1);
2227 assert(Mask1.
size() == NumElts &&
"Vector size changed with select shuffle");
2240 for (
unsigned i = 0; i != NumElts; ++i)
2241 NewMask[i] = Mask[i] < (
signed)NumElts ? Mask[i] : Mask1[i];
2246 "Unexpected shuffle mask");
2252 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2275 Value *
X = Op0IsBinop ? Op1 : Op0;
2296 bool MightCreatePoisonOrUB =
2299 if (MightCreatePoisonOrUB)
2334 Value *NewIns = Builder.CreateInsertElement(PoisonVec,
X, (
uint64_t)0);
2340 unsigned NumMaskElts =
2343 for (
unsigned i = 0; i != NumMaskElts; ++i)
2345 NewMask[i] = Mask[i];
2382 Constant *C0 =
nullptr, *C1 =
nullptr;
2383 bool ConstantsAreOp1;
2386 ConstantsAreOp1 =
false;
2391 ConstantsAreOp1 =
true;
2398 bool DropNSW =
false;
2399 if (ConstantsAreOp1 && Opc0 != Opc1) {
2403 if (Opc0 == Instruction::Shl || Opc1 == Instruction::Shl)
2407 Opc0 = AltB0.Opcode;
2411 Opc1 = AltB1.Opcode;
2416 if (Opc0 != Opc1 || !C0 || !C1)
2429 bool MightCreatePoisonOrUB =
2432 if (MightCreatePoisonOrUB)
2455 if (MightCreatePoisonOrUB && !ConstantsAreOp1)
2465 V =
Builder.CreateShuffleVector(
X,
Y, Mask);
2468 Value *NewBO = ConstantsAreOp1 ?
Builder.CreateBinOp(BOpc, V, NewC) :
2469 Builder.CreateBinOp(BOpc, NewC, V);
2477 NewI->copyIRFlags(B0);
2478 NewI->andIRFlags(B1);
2480 NewI->setHasNoSignedWrap(
false);
2482 NewI->dropPoisonGeneratingFlags();
2501 Type *SrcType =
X->getType();
2502 if (!SrcType->isVectorTy() || !SrcType->isIntOrIntVectorTy() ||
2509 "Expected a shuffle that decreases length");
2516 for (
unsigned i = 0, e = Mask.size(); i != e; ++i) {
2519 uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
2520 assert(LSBIndex <= INT32_MAX &&
"Overflowed 32-bits");
2521 if (Mask[i] != (
int)LSBIndex)
2547 unsigned NarrowNumElts =
2572 bool IsFNeg = S0->getOpcode() == Instruction::FNeg;
2578 S0->getOpcode() !=
S1->getOpcode() ||
2579 (!S0->hasOneUse() && !
S1->hasOneUse()))
2586 NewF = UnaryOperator::CreateFNeg(NewShuf);
2607 switch (CastOpcode) {
2608 case Instruction::SExt:
2609 case Instruction::ZExt:
2610 case Instruction::FPToSI:
2611 case Instruction::FPToUI:
2612 case Instruction::SIToFP:
2613 case Instruction::UIToFP:
2624 if (ShufTy->getElementCount().getKnownMinValue() >
2625 ShufOpTy->getElementCount().getKnownMinValue())
2632 auto *NewIns = Builder.CreateShuffleVector(Cast0->getOperand(0),
2640 if (!Cast1 || Cast0->getOpcode() != Cast1->getOpcode() ||
2641 Cast0->getSrcTy() != Cast1->getSrcTy())
2646 "Expected fixed vector operands for casts and binary shuffle");
2647 if (CastSrcTy->getPrimitiveSizeInBits() > ShufOpTy->getPrimitiveSizeInBits())
2651 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
2655 Value *
X = Cast0->getOperand(0);
2656 Value *
Y = Cast1->getOperand(0);
2671 X->getType()->getPrimitiveSizeInBits() ==
2699 assert(NumElts < Mask.size() &&
2700 "Identity with extract must have less elements than its inputs");
2702 for (
unsigned i = 0; i != NumElts; ++i) {
2704 int MaskElt = Mask[i];
2705 NewMask[i] = ExtractMaskElt ==
PoisonMaskElem ? ExtractMaskElt : MaskElt;
2718 int NumElts = Mask.size();
2744 if (NumElts != InpNumElts)
2748 auto isShufflingScalarIntoOp1 = [&](
Value *&Scalar,
ConstantInt *&IndexC) {
2756 int NewInsIndex = -1;
2757 for (
int i = 0; i != NumElts; ++i) {
2763 if (Mask[i] == NumElts + i)
2767 if (NewInsIndex != -1 || Mask[i] != IndexC->getSExtValue())
2774 assert(NewInsIndex != -1 &&
"Did not fold shuffle with unused operand?");
2777 IndexC = ConstantInt::get(IndexC->getIntegerType(), NewInsIndex);
2786 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2794 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2806 if (!Shuffle0 || !Shuffle0->isIdentityWithPadding() ||
2807 !Shuffle1 || !Shuffle1->isIdentityWithPadding())
2815 Value *
X = Shuffle0->getOperand(0);
2816 Value *
Y = Shuffle1->getOperand(0);
2817 if (
X->getType() !=
Y->getType() ||
2826 "Unexpected operand for identity shuffle");
2834 assert(WideElts > NarrowElts &&
"Unexpected types for identity with padding");
2838 for (
int i = 0, e = Mask.size(); i != e; ++i) {
2844 if (Mask[i] < WideElts) {
2845 if (Shuffle0->getMaskValue(Mask[i]) == -1)
2848 if (Shuffle1->getMaskValue(Mask[i] - WideElts) == -1)
2855 if (Mask[i] < WideElts) {
2856 assert(Mask[i] < NarrowElts &&
"Unexpected shuffle mask");
2857 NewMask[i] = Mask[i];
2859 assert(Mask[i] < (WideElts + NarrowElts) &&
"Unexpected shuffle mask");
2860 NewMask[i] = Mask[i] - (WideElts - NarrowElts);
2882 if (
X->getType() !=
Y->getType())
2891 NewBOI->copyIRFlags(BinOp);
2927 X->getType()->isVectorTy() &&
X->getType() ==
Y->getType() &&
2928 X->getType()->getScalarSizeInBits() ==
2930 (LHS->hasOneUse() || RHS->hasOneUse())) {
2945 X->getType()->isVectorTy() && VWidth == LHSWidth) {
2948 unsigned XNumElts = XType->getNumElements();
2954 ScaledMask, XType, ShufQuery))
2962 "Shuffle with 2 undef ops not simplified?");
2990 APInt PoisonElts(VWidth, 0);
3012 if (
SI->getCondition()->getType()->isIntegerTy() &&
3059 bool MadeChange =
false;
3062 unsigned MaskElems = Mask.size();
3064 unsigned VecBitWidth =
DL.getTypeSizeInBits(SrcTy);
3065 unsigned SrcElemBitWidth =
DL.getTypeSizeInBits(SrcTy->getElementType());
3066 assert(SrcElemBitWidth &&
"vector elements must have a bitwidth");
3067 unsigned SrcNumElems = SrcTy->getNumElements();
3073 if (BC->use_empty())
3076 if (BC->hasOneUse()) {
3078 if (BC2 && isEliminableCastPair(BC, BC2))
3084 unsigned BegIdx = Mask.front();
3085 Type *TgtTy = BC->getDestTy();
3086 unsigned TgtElemBitWidth =
DL.getTypeSizeInBits(TgtTy);
3087 if (!TgtElemBitWidth)
3089 unsigned TgtNumElems = VecBitWidth / TgtElemBitWidth;
3090 bool VecBitWidthsEqual = VecBitWidth == TgtNumElems * TgtElemBitWidth;
3091 bool BegIsAligned = 0 == ((SrcElemBitWidth * BegIdx) % TgtElemBitWidth);
3092 if (!VecBitWidthsEqual)
3097 if (!BegIsAligned) {
3101 for (
unsigned I = 0, E = MaskElems, Idx = BegIdx;
I != E; ++Idx, ++
I)
3102 ShuffleMask[
I] = Idx;
3103 V =
Builder.CreateShuffleVector(V, ShuffleMask,
3107 unsigned SrcElemsPerTgtElem = TgtElemBitWidth / SrcElemBitWidth;
3108 assert(SrcElemsPerTgtElem);
3109 BegIdx /= SrcElemsPerTgtElem;
3110 auto [It, Inserted] = NewBCs.
try_emplace(CastSrcTy);
3112 It->second =
Builder.CreateBitCast(V, CastSrcTy, SVI.
getName() +
".bc");
3113 auto *Ext =
Builder.CreateExtractElement(It->second, BegIdx,
3170 LHSShuffle =
nullptr;
3173 RHSShuffle =
nullptr;
3174 if (!LHSShuffle && !RHSShuffle)
3175 return MadeChange ? &SVI :
nullptr;
3177 Value* LHSOp0 =
nullptr;
3178 Value* LHSOp1 =
nullptr;
3179 Value* RHSOp0 =
nullptr;
3180 unsigned LHSOp0Width = 0;
3181 unsigned RHSOp0Width = 0;
3191 Value* newLHS = LHS;
3192 Value* newRHS = RHS;
3200 else if (LHSOp0Width == LHSWidth) {
3205 if (RHSShuffle && RHSOp0Width == LHSWidth) {
3209 if (LHSOp0 == RHSOp0) {
3214 if (newLHS == LHS && newRHS == RHS)
3215 return MadeChange ? &SVI :
nullptr;
3221 if (RHSShuffle && newRHS != RHS)
3224 unsigned newLHSWidth = (newLHS != LHS) ? LHSOp0Width : LHSWidth;
3230 for (
unsigned i = 0; i < VWidth; ++i) {
3235 }
else if (Mask[i] < (
int)LHSWidth) {
3240 if (newLHS != LHS) {
3241 eltMask = LHSMask[Mask[i]];
3257 else if (newRHS != RHS) {
3258 eltMask = RHSMask[Mask[i]-LHSWidth];
3261 if (eltMask >= (
int)RHSOp0Width) {
3263 "should have been check above");
3267 eltMask = Mask[i]-LHSWidth;
3275 if (eltMask >= 0 && newRHS !=
nullptr && newLHS != newRHS)
3276 eltMask += newLHSWidth;
3281 if (SplatElt >= 0 && SplatElt != eltMask)
3291 if (
isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
3297 return MadeChange ? &SVI :
nullptr;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
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 Value * evaluateInDifferentElementOrder(Value *V, ArrayRef< int > Mask, IRBuilderBase &Builder)
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 ShuffleOps collectShuffleElements(Value *V, SmallVectorImpl< int > &Mask, Value *PermittedRHS, InstCombinerImpl &IC, bool &Rerun)
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, const SimplifyQuery &SQ)
static Instruction * foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf)
static Instruction * foldIdentityExtractShuffle(ShuffleVectorInst &Shuf)
Try to fold an extract subvector operation.
static bool findDemandedEltsBySingleUser(Value *V, Instruction *UserInstr, APInt &UnionUsedElts)
Find elements of V demanded by UserInstr.
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.
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 Instruction * foldTruncShuffle(ShuffleVectorInst &Shuf, bool IsBigEndian)
Convert a narrowing shuffle of a bitcasted vector into a vector truncate.
static bool 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 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 * buildNew(Instruction *I, ArrayRef< Value * > NewOps, IRBuilderBase &Builder)
Rebuild a new instruction just like 'I' but with the new operands given.
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 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 ConstantInt * getPreferredVectorIndex(ConstantInt *IndexC)
Given a constant index for a extractelement or insertelement instruction, return it with the canonica...
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).
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
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 TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 SDLoc &DL, 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.
LLVM_ABI 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.
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.
LLVM_ABI 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...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
This class represents a no-op cast from one type to another.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
static LLVM_ABI CmpInst * CreateWithCopiedFlags(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Instruction *FlagsSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate, the two operands and the instructio...
OtherOps getOpcode() const
Get the opcode casted to the right type.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
static LLVM_ABI Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
This is the shared class of boolean and integer constants.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
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 LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI 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.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI void setNoWrapFlags(GEPNoWrapFlags NW)
Set nowrap flags for GEP instruction.
Common base class shared among various IRBuilders.
This instruction inserts a single (scalar) element into a VectorType value.
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
VectorType * getType() const
Overload to return most specific vector type.
This instruction inserts a struct field of array element value into an aggregate value.
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, 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 * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
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)
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
Instruction * InsertNewInstWith(Instruction *New, BasicBlock::iterator Old)
Same as InsertNewInstBefore, but also sets the debug loc.
void addToWorklist(Instruction *I)
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.
const SimplifyQuery & getSimplifyQuery() const
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI 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.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
A wrapper class for inspecting calls to intrinsic functions.
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
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.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
static LLVM_ABI 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="", InsertPosition InsertBefore=nullptr, const 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...
int getMaskValue(unsigned Elt) const
Return the shuffle mask value of this instruction for the given element index.
static LLVM_ABI bool isSelectMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from its source vectors without lane crossings.
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...
LLVM_ABI bool isIdentityWithExtract() const
Return true if this shuffle extracts the first N elements of exactly one source vector.
static LLVM_ABI 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 LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
static void commuteShuffleMask(MutableArrayRef< int > Mask, unsigned InVecNumElts)
Change values in a shuffle permute mask assuming the two vector operands of length InVecNumElts have ...
LLVM_ABI 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.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
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.
LLVM_ABI unsigned getStructNumElements() const
LLVM_ABI uint64_t getArrayNumElements() const
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI 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.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static UnaryOperator * CreateWithCopiedFlags(UnaryOps Opc, Value *V, Instruction *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
UnaryOps getOpcode() const
static LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static LLVM_ABI bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
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.
const ParentTy * getParent() const
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.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
BinaryOpc_match< LHS, RHS, false > m_BinOp(unsigned Opcode, const LHS &L, const RHS &R)
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
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.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
class_match< UnaryOperator > m_UnOp()
Match an arbitrary unary operation and ignore it.
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.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
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.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI 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 ...
LLVM_ABI 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.
auto dyn_cast_or_null(const Y &Val)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
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...
LLVM_ABI Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an InsertValueInst, fold the result or return null.
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
constexpr int PoisonMaskElem
LLVM_ABI Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
LLVM_ABI Value * simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, const SimplifyQuery &Q)
Given operands for an InsertElement, fold the result or return null.
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...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
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)
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q)
Given operands for an ExtractElementInst, fold the result or return null.
LLVM_ABI bool scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Attempt to narrow/widen the Mask shuffle mask to the NumDstElts target width.
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
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
A MapVector that performs no allocations if smaller than a certain size.