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) {
138 SmallDenseMap<BasicBlock *, Value *, 4> ScalarizedValues;
145 if (
Value *Existing = ScalarizedValues.
lookup(inBB)) {
152 if (PHIInVal == PHIUser) {
157 unsigned opId = (B0->
getOperand(0) == PN) ? 1 : 0;
184 ScalarizedValues[inBB] = ScalarVal;
188 for (
auto *
E : Extracts) {
204 ElementCount NumElts =
208 bool IsBigEndian =
DL.isBigEndian();
212 if (
X->getType()->isIntegerTy()) {
214 "Expected fixed vector type for bitcast from scalar integer");
221 unsigned ShiftAmountC = ExtIndexC * DestWidth;
222 if ((!ShiftAmountC ||
223 isDesirableIntType(
X->getType()->getPrimitiveSizeInBits())) &&
226 X =
Builder.CreateLShr(
X, ShiftAmountC,
"extelt.offset");
230 return new BitCastInst(Trunc, DestTy);
232 return new TruncInst(
X, DestTy);
236 if (!
X->getType()->isVectorTy())
243 ElementCount NumSrcElts = SrcTy->getElementCount();
244 if (NumSrcElts == NumElts)
246 return new BitCastInst(Elt, DestTy);
249 "Src and Dst must be the same sort of vector type");
265 unsigned NarrowingRatio =
268 if (ExtIndexC / NarrowingRatio != InsIndexC) {
292 unsigned Chunk = ExtIndexC % NarrowingRatio;
294 Chunk = NarrowingRatio - 1 - Chunk;
299 bool NeedSrcBitcast = SrcTy->getScalarType()->isFloatingPointTy();
301 if (NeedSrcBitcast && NeedDestBitcast)
304 unsigned SrcWidth = SrcTy->getScalarSizeInBits();
305 unsigned ShAmt = Chunk * DestWidth;
311 if (NeedSrcBitcast || NeedDestBitcast)
314 if (NeedSrcBitcast) {
326 if (NeedDestBitcast) {
328 return new BitCastInst(
Builder.CreateTrunc(Scalar, DestIntTy), DestTy);
330 return new TruncInst(Scalar, DestTy);
339 APInt &UnionUsedElts) {
343 case Instruction::ExtractElement: {
347 if (EEIIndexC && EEIIndexC->
getValue().
ult(VWidth)) {
353 case Instruction::ShuffleVector: {
355 unsigned MaskNumElts =
360 if (MaskVal == -1u || MaskVal >= 2 * VWidth)
362 if (Shuffle->
getOperand(0) == V && (MaskVal < VWidth))
363 UnionUsedElts.
setBit(MaskVal);
365 ((MaskVal >= VWidth) && (MaskVal < 2 * VWidth)))
366 UnionUsedElts.
setBit(MaskVal - VWidth);
384 APInt UnionUsedElts(VWidth, 0);
385 for (
const Use &U : V->
uses()) {
398 return UnionUsedElts;
417 SQ.getWithInstruction(&EI)))
429 if (
SI->getCondition()->getType()->isIntegerTy() &&
437 bool HasKnownValidIndex =
false;
444 unsigned NumElts = EC.getKnownMinValue();
445 HasKnownValidIndex = IndexC->getValue().ult(NumElts);
451 if (IID == Intrinsic::stepvector && IndexC->getValue().ult(NumElts)) {
453 unsigned BitWidth = Ty->getIntegerBitWidth();
458 if (IndexC->getValue().getActiveBits() <=
BitWidth)
459 Idx = ConstantInt::get(Ty, IndexC->getValue().zextOrTrunc(
BitWidth));
468 if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
477 if (
Instruction *ScalarPHI = scalarizePHI(EI, Phi))
502 (HasKnownValidIndex ||
533 uint64_t IdxVal = IndexC ? IndexC->getZExtValue() : 0;
534 if (IndexC && IdxVal < EC.getKnownMinValue() &&
GEP->hasOneUse()) {
545 return isa<VectorType>(V->getType());
547 if (VectorOps == 1) {
548 Value *NewPtr =
GEP->getPointerOperand();
550 NewPtr =
Builder.CreateExtractElement(NewPtr, IndexC);
553 for (
unsigned I = 1;
I !=
GEP->getNumOperands(); ++
I) {
562 GEP->getSourceElementType(), NewPtr, NewOps);
576 std::optional<int> SrcIdx;
578 if (SplatIndex != -1)
581 SrcIdx = SVI->getMaskValue(CI->getZExtValue());
591 if (*SrcIdx < (
int)LHSWidth)
592 Src = SVI->getOperand(0);
595 Src = SVI->getOperand(1);
599 Src, ConstantInt::get(Int64Ty, *SrcIdx,
false));
613 if (CI->hasOneUse() && (CI->getOpcode() != Instruction::BitCast) &&
615 Value *EE =
Builder.CreateExtractElement(CI->getOperand(0), Index);
626 unsigned NumElts = EC.getKnownMinValue();
630 if (!EC.isScalable() && NumElts != 1) {
634 APInt PoisonElts(NumElts, 0);
635 APInt DemandedElts(NumElts, 0);
636 DemandedElts.
setBit(IndexC->getZExtValue());
645 APInt PoisonElts(NumElts, 0);
647 SrcVec, DemandedElts, PoisonElts, 0 ,
667 "Invalid CollectSingleShuffleElements");
671 Mask.assign(NumElts, -1);
676 for (
unsigned i = 0; i != NumElts; ++i)
682 for (
unsigned i = 0; i != NumElts; ++i)
683 Mask.push_back(i + NumElts);
689 Value *VecOp = IEI->getOperand(0);
690 Value *ScalarOp = IEI->getOperand(1);
691 Value *IdxOp = IEI->getOperand(2);
702 Mask[InsertedIdx] = -1;
707 unsigned ExtractedIdx =
709 unsigned NumLHSElts =
719 Mask[InsertedIdx % NumElts] = ExtractedIdx;
722 Mask[InsertedIdx % NumElts] = ExtractedIdx + NumLHSElts;
742 unsigned NumInsElts = InsVecType->getNumElements();
743 unsigned NumExtElts = ExtVecType->getNumElements();
746 if (InsVecType->getElementType() != ExtVecType->getElementType() ||
747 NumExtElts >= NumInsElts)
760 for (
unsigned i = 0; i < NumExtElts; ++i)
762 for (
unsigned i = NumExtElts; i < NumInsElts; ++i)
779 if (InsertionBlock != InsElt->
getParent())
797 WideVec->insertAfter(ExtVecOpInst->getIterator());
805 if (!OldExt || OldExt->
getParent() != WideVec->getParent())
831 assert(V->getType()->isVectorTy() &&
"Invalid shuffle!");
835 Mask.assign(NumElts, -1);
836 return std::make_pair(
841 Mask.assign(NumElts, 0);
842 return std::make_pair(V,
nullptr);
847 Value *VecOp = IEI->getOperand(0);
848 Value *ScalarOp = IEI->getOperand(1);
849 Value *IdxOp = IEI->getOperand(2);
853 unsigned ExtractedIdx =
859 if (EI->
getOperand(0) == PermittedRHS || PermittedRHS ==
nullptr) {
862 assert(LR.second ==
nullptr || LR.second ==
RHS);
864 if (LR.first->getType() !=
RHS->getType()) {
872 for (
unsigned i = 0; i < NumElts; ++i)
874 return std::make_pair(V,
nullptr);
877 unsigned NumLHSElts =
879 Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
880 return std::make_pair(LR.first,
RHS);
883 if (VecOp == PermittedRHS) {
886 unsigned NumLHSElts =
889 for (
unsigned i = 0; i != NumElts; ++i)
890 Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
891 return std::make_pair(EI->
getOperand(0), PermittedRHS);
899 return std::make_pair(EI->
getOperand(0), PermittedRHS);
905 for (
unsigned i = 0; i != NumElts; ++i)
907 return std::make_pair(V,
nullptr);
933 assert(NumAggElts > 0 &&
"Aggregate should have elements.");
937 static constexpr auto NotFound = std::nullopt;
938 static constexpr auto FoundMismatch =
nullptr;
945 auto KnowAllElts = [&AggElts]() {
953 static const int DepthLimit = 2 * NumAggElts;
958 Depth < DepthLimit && CurrIVI && !KnowAllElts();
961 auto *InsertedValue =
969 if (Indices.
size() != 1)
975 std::optional<Instruction *> &Elt = AggElts[Indices.
front()];
976 Elt = Elt.value_or(InsertedValue);
989 enum class AggregateDescription {
1005 auto Describe = [](std::optional<Value *> SourceAggregate) {
1006 if (SourceAggregate == NotFound)
1007 return AggregateDescription::NotFound;
1008 if (*SourceAggregate == FoundMismatch)
1009 return AggregateDescription::FoundMismatch;
1010 return AggregateDescription::Found;
1014 bool EltDefinedInUseBB =
false;
1021 auto FindSourceAggregate =
1022 [&](
Instruction *Elt,
unsigned EltIdx, std::optional<BasicBlock *> UseBB,
1023 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1025 if (UseBB && PredBB) {
1028 EltDefinedInUseBB =
true;
1037 Value *SourceAggregate = EVI->getAggregateOperand();
1040 if (SourceAggregate->
getType() != AggTy)
1041 return FoundMismatch;
1043 if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
1044 return FoundMismatch;
1046 return SourceAggregate;
1052 auto FindCommonSourceAggregate =
1053 [&](std::optional<BasicBlock *> UseBB,
1054 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1055 std::optional<Value *> SourceAggregate;
1058 assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
1059 "We don't store nullptr in SourceAggregate!");
1060 assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
1062 "SourceAggregate should be valid after the first element,");
1067 std::optional<Value *> SourceAggregateForElement =
1068 FindSourceAggregate(*
I.value(),
I.index(), UseBB, PredBB);
1075 if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
1076 return SourceAggregateForElement;
1080 switch (Describe(SourceAggregate)) {
1081 case AggregateDescription::NotFound:
1083 SourceAggregate = SourceAggregateForElement;
1085 case AggregateDescription::Found:
1088 if (*SourceAggregateForElement != *SourceAggregate)
1089 return FoundMismatch;
1091 case AggregateDescription::FoundMismatch:
1096 assert(Describe(SourceAggregate) == AggregateDescription::Found &&
1097 "Must be a valid Value");
1098 return *SourceAggregate;
1101 std::optional<Value *> SourceAggregate;
1104 SourceAggregate = FindCommonSourceAggregate(std::nullopt,
1106 if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
1107 if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
1109 ++NumAggregateReconstructionsSimplified;
1122 for (
const std::optional<Instruction *> &
I : AggElts) {
1146 static const int PredCountLimit = 64;
1153 if (Preds.
size() >= PredCountLimit)
1162 bool FoundSrcAgg =
false;
1164 std::pair<
decltype(SourceAggregates)
::iterator,
bool>
IV =
1173 SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
1174 if (Describe(SourceAggregate) == AggregateDescription::Found) {
1176 IV.first->second = *SourceAggregate;
1191 for (
auto &It : SourceAggregates) {
1192 if (Describe(It.second) == AggregateDescription::Found)
1196 if (EltDefinedInUseBB)
1204 if (UseBB != OrigBB)
1209 bool ConstAgg =
true;
1210 for (
auto Val : AggElts) {
1223 for (
auto &It : SourceAggregates) {
1224 if (Describe(It.second) == AggregateDescription::Found)
1228 Builder.SetInsertPoint(Pred->getTerminator());
1230 for (
auto [Idx, Val] :
enumerate(AggElts)) {
1232 V =
Builder.CreateInsertValue(V, Elt, Idx);
1244 Builder.SetInsertPoint(UseBB, UseBB->getFirstNonPHIIt());
1248 PHI->addIncoming(SourceAggregates[Pred], Pred);
1250 ++NumAggregateReconstructionsSimplified;
1263 I.getAggregateOperand(),
I.getInsertedValueOperand(),
I.getIndices(),
1264 SQ.getWithInstruction(&
I)))
1267 bool IsRedundant =
false;
1276 while (V->hasOneUse() &&
Depth < 10) {
1279 if (!UserInsInst || U->getOperand(0) != V)
1281 if (UserInsInst->getIndices() == FirstIndices) {
1309 if (MaskSize != VecSize)
1314 for (
int i = 0; i != MaskSize; ++i) {
1316 if (Elt != -1 && Elt != i && Elt != i + VecSize)
1341 if (NumElements == 1)
1353 if (!Idx || CurrIE->
getOperand(1) != SplatVal)
1360 if (CurrIE != &InsElt &&
1361 (!CurrIE->
hasOneUse() && (NextIE !=
nullptr || !Idx->isZero())))
1364 ElementPresent[Idx->getZExtValue()] =
true;
1370 if (FirstIE == &InsElt)
1378 if (!ElementPresent.
all())
1384 Constant *Zero = ConstantInt::get(Int64Ty, 0);
1391 for (
unsigned i = 0; i != NumElements; ++i)
1392 if (!ElementPresent[i])
1403 if (!Shuf || !Shuf->isZeroEltSplat())
1418 Value *Op0 = Shuf->getOperand(0);
1426 unsigned NumMaskElts =
1429 for (
unsigned i = 0; i != NumMaskElts; ++i)
1430 NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
1441 !(Shuf->isIdentityWithExtract() || Shuf->isIdentityWithPadding()))
1457 Value *
X = Shuf->getOperand(0);
1465 unsigned NumMaskElts =
1469 for (
unsigned i = 0; i != NumMaskElts; ++i) {
1472 NewMask[i] = OldMask[i];
1473 }
else if (OldMask[i] == (
int)IdxC) {
1479 "Unexpected shuffle mask element for identity shuffle");
1499 if (!InsElt1 || !InsElt1->hasOneUse())
1510 Value *NewInsElt1 = Builder.CreateInsertElement(
X, ScalarC, IdxC2);
1523 if (!Inst || !Inst->hasOneUse())
1528 Constant *ShufConstVec, *InsEltScalar;
1552 unsigned NumElts = Mask.size();
1555 for (
unsigned I = 0;
I != NumElts; ++
I) {
1556 if (
I == InsEltIndex) {
1557 NewShufElts[
I] = InsEltScalar;
1558 NewMaskElts[
I] = InsEltIndex + NumElts;
1562 NewMaskElts[
I] = Mask[
I];
1566 if (!NewShufElts[
I])
1593 auto ValI = std::begin(Val);
1600 Mask[
I] = NumElts +
I;
1605 for (
unsigned I = 0;
I < NumElts; ++
I) {
1637 CastOpcode = Instruction::FPExt;
1639 CastOpcode = Instruction::SExt;
1641 CastOpcode = Instruction::ZExt;
1646 if (
X->getType()->getScalarType() !=
Y->getType())
1674 Value *Scalar0, *BaseVec;
1676 if (!VTy || (VTy->getNumElements() & 1) ||
1685 if (Index0 + 1 != Index1 || Index0 & 1)
1702 Type *SrcTy =
X->getType();
1703 unsigned ScalarWidth = SrcTy->getScalarSizeInBits();
1704 unsigned VecEltWidth = VTy->getScalarSizeInBits();
1705 if (ScalarWidth != VecEltWidth * 2 || ShAmt != VecEltWidth)
1710 Value *CastBaseVec = Builder.CreateBitCast(BaseVec, CastTy);
1714 uint64_t NewIndex = IsBigEndian ? Index1 / 2 : Index0 / 2;
1715 Value *NewInsert = Builder.CreateInsertElement(CastBaseVec,
X, NewIndex);
1720 Value *VecOp = IE.getOperand(0);
1721 Value *ScalarOp = IE.getOperand(1);
1722 Value *IdxOp = IE.getOperand(2);
1725 VecOp, ScalarOp, IdxOp,
SQ.getWithInstruction(&IE)))
1733 Value *BaseVec, *OtherScalar;
1738 !
isa<Constant>(OtherScalar) && OtherIndexVal > IndexC->getZExtValue()) {
1739 Value *NewIns =
Builder.CreateInsertElement(BaseVec, ScalarOp, IdxOp);
1741 Builder.getInt64(OtherIndexVal));
1759 Value *NewInsElt =
Builder.CreateInsertElement(NewUndef, ScalarSrc, IdxOp);
1774 Value *NewInsElt =
Builder.CreateInsertElement(VecSrc, ScalarSrc, IdxOp);
1782 uint64_t InsertedIdx, ExtractedIdx;
1806 if (!Insert.hasOneUse())
1815 if (isShuffleRootCandidate(IE)) {
1826 if (LR.first != &IE && LR.second != &IE) {
1828 if (LR.second ==
nullptr)
1837 unsigned VWidth = VecTy->getNumElements();
1838 APInt PoisonElts(VWidth, 0);
1861 return IdentityShuf;
1875 unsigned Depth = 5) {
1882 if (!
I)
return false;
1885 if (!
I->hasOneUse())
1888 if (
Depth == 0)
return false;
1890 switch (
I->getOpcode()) {
1891 case Instruction::UDiv:
1892 case Instruction::SDiv:
1893 case Instruction::URem:
1894 case Instruction::SRem:
1901 case Instruction::Add:
1902 case Instruction::FAdd:
1903 case Instruction::Sub:
1904 case Instruction::FSub:
1905 case Instruction::Mul:
1906 case Instruction::FMul:
1907 case Instruction::FDiv:
1908 case Instruction::FRem:
1909 case Instruction::Shl:
1910 case Instruction::LShr:
1911 case Instruction::AShr:
1912 case Instruction::And:
1913 case Instruction::Or:
1914 case Instruction::Xor:
1915 case Instruction::ICmp:
1916 case Instruction::FCmp:
1917 case Instruction::Trunc:
1918 case Instruction::ZExt:
1919 case Instruction::SExt:
1920 case Instruction::FPToUI:
1921 case Instruction::FPToSI:
1922 case Instruction::UIToFP:
1923 case Instruction::SIToFP:
1924 case Instruction::FPTrunc:
1925 case Instruction::FPExt:
1926 case Instruction::GetElementPtr: {
1929 Type *ITy =
I->getType();
1933 for (
Value *Operand :
I->operands()) {
1939 case Instruction::InsertElement: {
1941 if (!CI)
return false;
1946 bool SeenOnce =
false;
1947 for (
int I : Mask) {
1948 if (
I == ElementNumber) {
1964 Builder.SetInsertPoint(
I);
1965 switch (
I->getOpcode()) {
1966 case Instruction::Add:
1967 case Instruction::FAdd:
1968 case Instruction::Sub:
1969 case Instruction::FSub:
1970 case Instruction::Mul:
1971 case Instruction::FMul:
1972 case Instruction::UDiv:
1973 case Instruction::SDiv:
1974 case Instruction::FDiv:
1975 case Instruction::URem:
1976 case Instruction::SRem:
1977 case Instruction::FRem:
1978 case Instruction::Shl:
1979 case Instruction::LShr:
1980 case Instruction::AShr:
1981 case Instruction::And:
1982 case Instruction::Or:
1983 case Instruction::Xor: {
1985 assert(NewOps.
size() == 2 &&
"binary operator with #ops != 2");
1987 NewOps[0], NewOps[1]);
1994 NewI->setIsExact(BO->
isExact());
1997 NewI->copyFastMathFlags(
I);
2001 case Instruction::ICmp:
2002 assert(NewOps.
size() == 2 &&
"icmp with #ops != 2");
2003 return Builder.CreateICmp(
cast<ICmpInst>(
I)->getPredicate(), NewOps[0],
2005 case Instruction::FCmp:
2006 assert(NewOps.
size() == 2 &&
"fcmp with #ops != 2");
2007 return Builder.CreateFCmp(
cast<FCmpInst>(
I)->getPredicate(), NewOps[0],
2009 case Instruction::Trunc:
2010 case Instruction::ZExt:
2011 case Instruction::SExt:
2012 case Instruction::FPToUI:
2013 case Instruction::FPToSI:
2014 case Instruction::UIToFP:
2015 case Instruction::SIToFP:
2016 case Instruction::FPTrunc:
2017 case Instruction::FPExt: {
2021 I->getType()->getScalarType(),
2023 assert(NewOps.
size() == 1 &&
"cast with #ops != 1");
2027 case Instruction::GetElementPtr: {
2028 Value *Ptr = NewOps[0];
2042 assert(V->getType()->isVectorTy() &&
"can't reorder non-vector elements");
2059 switch (
I->getOpcode()) {
2060 case Instruction::Add:
2061 case Instruction::FAdd:
2062 case Instruction::Sub:
2063 case Instruction::FSub:
2064 case Instruction::Mul:
2065 case Instruction::FMul:
2066 case Instruction::UDiv:
2067 case Instruction::SDiv:
2068 case Instruction::FDiv:
2069 case Instruction::URem:
2070 case Instruction::SRem:
2071 case Instruction::FRem:
2072 case Instruction::Shl:
2073 case Instruction::LShr:
2074 case Instruction::AShr:
2075 case Instruction::And:
2076 case Instruction::Or:
2077 case Instruction::Xor:
2078 case Instruction::ICmp:
2079 case Instruction::FCmp:
2080 case Instruction::Trunc:
2081 case Instruction::ZExt:
2082 case Instruction::SExt:
2083 case Instruction::FPToUI:
2084 case Instruction::FPToSI:
2085 case Instruction::UIToFP:
2086 case Instruction::SIToFP:
2087 case Instruction::FPTrunc:
2088 case Instruction::FPExt:
2089 case Instruction::Select:
2090 case Instruction::GetElementPtr: {
2095 for (
int i = 0, e =
I->getNumOperands(); i != e; ++i) {
2100 if (
I->getOperand(i)->getType()->isVectorTy())
2103 V =
I->getOperand(i);
2105 NeedsRebuild |= (V !=
I->getOperand(i));
2111 case Instruction::InsertElement: {
2119 for (
int e = Mask.size(); Index != e; ++Index) {
2120 if (Mask[Index] == Element) {
2133 Builder.SetInsertPoint(
I);
2134 return Builder.CreateInsertElement(V,
I->getOperand(1), Index);
2150 unsigned MaskElems = Mask.size();
2151 unsigned BegIdx = Mask.front();
2152 unsigned EndIdx = Mask.back();
2153 if (BegIdx > EndIdx || EndIdx >= LHSElems || EndIdx - BegIdx != MaskElems - 1)
2155 for (
unsigned I = 0;
I != MaskElems; ++
I)
2156 if (
static_cast<unsigned>(Mask[
I]) != BegIdx +
I)
2181 case Instruction::Shl: {
2186 Instruction::Shl, ConstantInt::get(Ty, 1),
C,
DL);
2187 assert(ShlOne &&
"Constant folding of immediate constants failed");
2188 return {Instruction::Mul, BO0, ShlOne};
2192 case Instruction::Or: {
2195 return {Instruction::Add, BO0, BO1};
2198 case Instruction::Sub:
2213 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2218 unsigned NumElts = Mask.size();
2222 if (ShufOp && ShufOp->isSelect() &&
2223 (ShufOp->getOperand(0) == Op1 || ShufOp->getOperand(1) == Op1)) {
2229 if (!ShufOp || !ShufOp->isSelect() ||
2230 (ShufOp->getOperand(0) != Op0 && ShufOp->getOperand(1) != Op0))
2233 Value *
X = ShufOp->getOperand(0), *
Y = ShufOp->getOperand(1);
2235 ShufOp->getShuffleMask(Mask1);
2236 assert(Mask1.
size() == NumElts &&
"Vector size changed with select shuffle");
2249 for (
unsigned i = 0; i != NumElts; ++i)
2250 NewMask[i] = Mask[i] < (
signed)NumElts ? Mask[i] : Mask1[i];
2255 "Unexpected shuffle mask");
2261 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2284 Value *
X = Op0IsBinop ? Op1 : Op0;
2305 bool MightCreatePoisonOrUB =
2308 if (MightCreatePoisonOrUB)
2343 Value *NewIns = Builder.CreateInsertElement(PoisonVec,
X, (
uint64_t)0);
2349 unsigned NumMaskElts =
2352 for (
unsigned i = 0; i != NumMaskElts; ++i)
2354 NewMask[i] = Mask[i];
2391 Constant *C0 =
nullptr, *C1 =
nullptr;
2392 bool ConstantsAreOp1;
2395 ConstantsAreOp1 =
false;
2400 ConstantsAreOp1 =
true;
2407 bool DropNSW =
false;
2408 if (ConstantsAreOp1 && Opc0 != Opc1) {
2412 if (Opc0 == Instruction::Shl || Opc1 == Instruction::Shl)
2416 Opc0 = AltB0.Opcode;
2420 Opc1 = AltB1.Opcode;
2425 if (Opc0 != Opc1 || !C0 || !C1)
2438 bool MightCreatePoisonOrUB =
2441 if (MightCreatePoisonOrUB)
2464 if (MightCreatePoisonOrUB && !ConstantsAreOp1)
2474 V =
Builder.CreateShuffleVector(
X,
Y, Mask);
2477 Value *NewBO = ConstantsAreOp1 ?
Builder.CreateBinOp(BOpc, V, NewC) :
2478 Builder.CreateBinOp(BOpc, NewC, V);
2486 NewI->copyIRFlags(B0);
2487 NewI->andIRFlags(B1);
2489 NewI->setHasNoSignedWrap(
false);
2491 NewI->dropPoisonGeneratingFlags();
2510 Type *SrcType =
X->getType();
2511 if (!SrcType->isVectorTy() || !SrcType->isIntOrIntVectorTy() ||
2518 "Expected a shuffle that decreases length");
2525 for (
unsigned i = 0, e = Mask.size(); i != e; ++i) {
2528 uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
2529 assert(LSBIndex <= INT32_MAX &&
"Overflowed 32-bits");
2530 if (Mask[i] != (
int)LSBIndex)
2556 unsigned NarrowNumElts =
2581 bool IsFNeg = S0->getOpcode() == Instruction::FNeg;
2587 S0->getOpcode() !=
S1->getOpcode() ||
2588 (!S0->hasOneUse() && !
S1->hasOneUse()))
2595 NewF = UnaryOperator::CreateFNeg(NewShuf);
2616 switch (CastOpcode) {
2617 case Instruction::SExt:
2618 case Instruction::ZExt:
2619 case Instruction::FPToSI:
2620 case Instruction::FPToUI:
2621 case Instruction::SIToFP:
2622 case Instruction::UIToFP:
2633 if (ShufTy->getElementCount().getKnownMinValue() >
2634 ShufOpTy->getElementCount().getKnownMinValue())
2641 auto *NewIns = Builder.CreateShuffleVector(Cast0->getOperand(0),
2649 if (!Cast1 || Cast0->getOpcode() != Cast1->getOpcode() ||
2650 Cast0->getSrcTy() != Cast1->getSrcTy())
2655 "Expected fixed vector operands for casts and binary shuffle");
2656 if (CastSrcTy->getPrimitiveSizeInBits() > ShufOpTy->getPrimitiveSizeInBits())
2660 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
2664 Value *
X = Cast0->getOperand(0);
2665 Value *
Y = Cast1->getOperand(0);
2680 X->getType()->getPrimitiveSizeInBits() ==
2708 assert(NumElts < Mask.size() &&
2709 "Identity with extract must have less elements than its inputs");
2711 for (
unsigned i = 0; i != NumElts; ++i) {
2713 int MaskElt = Mask[i];
2714 NewMask[i] = ExtractMaskElt ==
PoisonMaskElem ? ExtractMaskElt : MaskElt;
2727 int NumElts = Mask.size();
2753 if (NumElts != InpNumElts)
2757 auto isShufflingScalarIntoOp1 = [&](
Value *&Scalar,
ConstantInt *&IndexC) {
2765 int NewInsIndex = -1;
2766 for (
int i = 0; i != NumElts; ++i) {
2772 if (Mask[i] == NumElts + i)
2776 if (NewInsIndex != -1 || Mask[i] != IndexC->getSExtValue())
2783 assert(NewInsIndex != -1 &&
"Did not fold shuffle with unused operand?");
2786 IndexC = ConstantInt::get(IndexC->getIntegerType(), NewInsIndex);
2795 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2803 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2815 if (!Shuffle0 || !Shuffle0->isIdentityWithPadding() ||
2816 !Shuffle1 || !Shuffle1->isIdentityWithPadding())
2824 Value *
X = Shuffle0->getOperand(0);
2825 Value *
Y = Shuffle1->getOperand(0);
2826 if (
X->getType() !=
Y->getType() ||
2835 "Unexpected operand for identity shuffle");
2843 assert(WideElts > NarrowElts &&
"Unexpected types for identity with padding");
2847 for (
int i = 0, e = Mask.size(); i != e; ++i) {
2853 if (Mask[i] < WideElts) {
2854 if (Shuffle0->getMaskValue(Mask[i]) == -1)
2857 if (Shuffle1->getMaskValue(Mask[i] - WideElts) == -1)
2864 if (Mask[i] < WideElts) {
2865 assert(Mask[i] < NarrowElts &&
"Unexpected shuffle mask");
2866 NewMask[i] = Mask[i];
2868 assert(Mask[i] < (WideElts + NarrowElts) &&
"Unexpected shuffle mask");
2869 NewMask[i] = Mask[i] - (WideElts - NarrowElts);
2891 if (
X->getType() !=
Y->getType())
2900 NewBOI->copyIRFlags(BinOp);
2936 X->getType()->isVectorTy() &&
X->getType() ==
Y->getType() &&
2937 X->getType()->getScalarSizeInBits() ==
2939 (LHS->hasOneUse() || RHS->hasOneUse())) {
2954 X->getType()->isVectorTy() && VWidth == LHSWidth) {
2957 unsigned XNumElts = XType->getNumElements();
2963 ScaledMask, XType, ShufQuery))
2971 "Shuffle with 2 undef ops not simplified?");
2999 APInt PoisonElts(VWidth, 0);
3021 if (
SI->getCondition()->getType()->isIntegerTy() &&
3068 bool MadeChange =
false;
3071 unsigned MaskElems = Mask.size();
3073 unsigned VecBitWidth =
DL.getTypeSizeInBits(SrcTy);
3074 unsigned SrcElemBitWidth =
DL.getTypeSizeInBits(SrcTy->getElementType());
3075 assert(SrcElemBitWidth &&
"vector elements must have a bitwidth");
3076 unsigned SrcNumElems = SrcTy->getNumElements();
3082 if (BC->use_empty())
3085 if (BC->hasOneUse()) {
3087 if (BC2 && isEliminableCastPair(BC, BC2))
3093 unsigned BegIdx = Mask.front();
3094 Type *TgtTy = BC->getDestTy();
3095 unsigned TgtElemBitWidth =
DL.getTypeSizeInBits(TgtTy);
3096 if (!TgtElemBitWidth)
3098 unsigned TgtNumElems = VecBitWidth / TgtElemBitWidth;
3099 bool VecBitWidthsEqual = VecBitWidth == TgtNumElems * TgtElemBitWidth;
3100 bool BegIsAligned = 0 == ((SrcElemBitWidth * BegIdx) % TgtElemBitWidth);
3101 if (!VecBitWidthsEqual)
3106 if (!BegIsAligned) {
3110 for (
unsigned I = 0, E = MaskElems, Idx = BegIdx;
I != E; ++Idx, ++
I)
3111 ShuffleMask[
I] = Idx;
3112 V =
Builder.CreateShuffleVector(V, ShuffleMask,
3116 unsigned SrcElemsPerTgtElem = TgtElemBitWidth / SrcElemBitWidth;
3117 assert(SrcElemsPerTgtElem);
3118 BegIdx /= SrcElemsPerTgtElem;
3119 auto [It, Inserted] = NewBCs.
try_emplace(CastSrcTy);
3121 It->second =
Builder.CreateBitCast(V, CastSrcTy, SVI.
getName() +
".bc");
3122 auto *Ext =
Builder.CreateExtractElement(It->second, BegIdx,
3179 LHSShuffle =
nullptr;
3182 RHSShuffle =
nullptr;
3183 if (!LHSShuffle && !RHSShuffle)
3184 return MadeChange ? &SVI :
nullptr;
3186 Value* LHSOp0 =
nullptr;
3187 Value* LHSOp1 =
nullptr;
3188 Value* RHSOp0 =
nullptr;
3189 unsigned LHSOp0Width = 0;
3190 unsigned RHSOp0Width = 0;
3200 Value* newLHS = LHS;
3201 Value* newRHS = RHS;
3209 else if (LHSOp0Width == LHSWidth) {
3214 if (RHSShuffle && RHSOp0Width == LHSWidth) {
3218 if (LHSOp0 == RHSOp0) {
3223 if (newLHS == LHS && newRHS == RHS)
3224 return MadeChange ? &SVI :
nullptr;
3230 if (RHSShuffle && newRHS != RHS)
3233 unsigned newLHSWidth = (newLHS != LHS) ? LHSOp0Width : LHSWidth;
3239 for (
unsigned i = 0; i < VWidth; ++i) {
3244 }
else if (Mask[i] < (
int)LHSWidth) {
3249 if (newLHS != LHS) {
3250 eltMask = LHSMask[Mask[i]];
3266 else if (newRHS != RHS) {
3267 eltMask = RHSMask[Mask[i]-LHSWidth];
3270 if (eltMask >= (
int)RHSOp0Width) {
3272 "should have been check above");
3276 eltMask = Mask[i]-LHSWidth;
3284 if (eltMask >= 0 && newRHS !=
nullptr && newLHS != newRHS)
3285 eltMask += newLHSWidth;
3290 if (SplatElt >= 0 && SplatElt != eltMask)
3300 if (
isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
3306 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 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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
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.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
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.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
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 * > OverloadTys={})
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)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
auto m_Cmp()
Matches any compare instruction and ignore it.
auto m_Poison()
Match an arbitrary poison constant.
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.
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.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Constant()
Match an arbitrary Constant and ignore it.
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.
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.
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_UnOp()
Match an arbitrary unary operation and ignore it.
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)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
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.