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;
160 B0->getOperand(opId)->getName() +
".Elt"),
164 Value *FirstOp = (
B0->getOperand(0) == PN) ? scalarPHI :
Op;
165 Value *SecondOp = (
B0->getOperand(0) == PN) ?
Op : scalarPHI;
167 B0->getOpcode(), FirstOp, SecondOp, B0),
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;
420 if (!VecTy || !VecTy->getElementType()->isPointerTy())
423 unsigned NumElts = VecTy->getNumElements();
431 unsigned IdxWidth =
DL.getIndexTypeSizeInBits(VecTy->getElementType());
434 for (
unsigned I = 0;
I != NumElts; ++
I) {
443 Offset =
C->sextOrTrunc(IdxWidth);
448 else if (
Base != EltBase)
450 Offsets.push_back(
Offset);
454 APInt Stride = Offsets[1] - Offsets[0];
455 for (
unsigned I = 1;
I != NumElts; ++
I)
456 if (Offsets[
I] - Offsets[0] != Stride *
I)
462 Type *IdxTy =
DL.getIndexType(VecTy->getElementType());
464 Value *Ptr = Builder.CreatePtrAdd(
465 Base, Builder.CreateMul(Idx, ConstantInt::get(IdxTy, Stride)));
466 return Builder.CreatePtrAdd(Ptr, ConstantInt::get(IdxTy, Offsets[0]));
473 SQ.getWithInstruction(&EI)))
485 if (
SI->getCondition()->getType()->isIntegerTy() &&
499 bool HasKnownValidIndex =
false;
506 unsigned NumElts = EC.getKnownMinValue();
507 HasKnownValidIndex = IndexC->getValue().ult(NumElts);
513 if (IID == Intrinsic::stepvector && IndexC->getValue().ult(NumElts)) {
515 unsigned BitWidth = Ty->getIntegerBitWidth();
520 if (IndexC->getValue().getActiveBits() <=
BitWidth)
521 Idx = ConstantInt::get(Ty, IndexC->getValue().zextOrTrunc(
BitWidth));
530 if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
539 if (
Instruction *ScalarPHI = scalarizePHI(EI, Phi))
564 (HasKnownValidIndex ||
595 uint64_t IdxVal = IndexC ? IndexC->getZExtValue() : 0;
596 if (IndexC && IdxVal < EC.getKnownMinValue() &&
GEP->hasOneUse()) {
607 return isa<VectorType>(V->getType());
609 if (VectorOps == 1) {
610 Value *NewPtr =
GEP->getPointerOperand();
612 NewPtr =
Builder.CreateExtractElement(NewPtr, IndexC);
615 for (
unsigned I = 1;
I !=
GEP->getNumOperands(); ++
I) {
624 GEP->getSourceElementType(), NewPtr, NewOps);
638 std::optional<int> SrcIdx;
640 if (SplatIndex != -1)
643 SrcIdx = SVI->getMaskValue(CI->getZExtValue());
653 if (*SrcIdx < (
int)LHSWidth)
654 Src = SVI->getOperand(0);
657 Src = SVI->getOperand(1);
661 Src, ConstantInt::get(Int64Ty, *SrcIdx,
false));
675 if (CI->hasOneUse() && (CI->getOpcode() != Instruction::BitCast) &&
677 Value *EE =
Builder.CreateExtractElement(CI->getOperand(0), Index);
688 unsigned NumElts = EC.getKnownMinValue();
692 if (!EC.isScalable() && NumElts != 1) {
696 APInt PoisonElts(NumElts, 0);
697 APInt DemandedElts(NumElts, 0);
698 DemandedElts.
setBit(IndexC->getZExtValue());
707 APInt PoisonElts(NumElts, 0);
709 SrcVec, DemandedElts, PoisonElts, 0 ,
729 "Invalid CollectSingleShuffleElements");
733 Mask.assign(NumElts, -1);
738 for (
unsigned i = 0; i != NumElts; ++i)
744 for (
unsigned i = 0; i != NumElts; ++i)
745 Mask.push_back(i + NumElts);
751 Value *VecOp = IEI->getOperand(0);
752 Value *ScalarOp = IEI->getOperand(1);
753 Value *IdxOp = IEI->getOperand(2);
764 Mask[InsertedIdx] = -1;
769 unsigned ExtractedIdx =
771 unsigned NumLHSElts =
781 Mask[InsertedIdx % NumElts] = ExtractedIdx;
784 Mask[InsertedIdx % NumElts] = ExtractedIdx + NumLHSElts;
804 unsigned NumInsElts = InsVecType->getNumElements();
805 unsigned NumExtElts = ExtVecType->getNumElements();
808 if (InsVecType->getElementType() != ExtVecType->getElementType() ||
809 NumExtElts >= NumInsElts)
822 for (
unsigned i = 0; i < NumExtElts; ++i)
824 for (
unsigned i = NumExtElts; i < NumInsElts; ++i)
841 if (InsertionBlock != InsElt->
getParent())
859 WideVec->insertAfter(ExtVecOpInst->getIterator());
876 if (!OldExt || OldExt->
getParent() != WideVec->getParent())
902 assert(V->getType()->isVectorTy() &&
"Invalid shuffle!");
906 Mask.assign(NumElts, -1);
907 return std::make_pair(
912 Mask.assign(NumElts, 0);
913 return std::make_pair(V,
nullptr);
918 Value *VecOp = IEI->getOperand(0);
919 Value *ScalarOp = IEI->getOperand(1);
920 Value *IdxOp = IEI->getOperand(2);
924 unsigned ExtractedIdx =
930 if (EI->
getOperand(0) == PermittedRHS || PermittedRHS ==
nullptr) {
933 assert(LR.second ==
nullptr || LR.second ==
RHS);
935 if (LR.first->getType() !=
RHS->getType()) {
943 for (
unsigned i = 0; i < NumElts; ++i)
945 return std::make_pair(V,
nullptr);
948 unsigned NumLHSElts =
950 Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
951 return std::make_pair(LR.first,
RHS);
954 if (VecOp == PermittedRHS) {
957 unsigned NumLHSElts =
960 for (
unsigned i = 0; i != NumElts; ++i)
961 Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
962 return std::make_pair(EI->
getOperand(0), PermittedRHS);
970 return std::make_pair(EI->
getOperand(0), PermittedRHS);
976 for (
unsigned i = 0; i != NumElts; ++i)
978 return std::make_pair(V,
nullptr);
1004 assert(NumAggElts > 0 &&
"Aggregate should have elements.");
1008 static constexpr auto NotFound = std::nullopt;
1009 static constexpr auto FoundMismatch =
nullptr;
1016 auto KnowAllElts = [&AggElts]() {
1024 static const int DepthLimit = 2 * NumAggElts;
1029 Depth < DepthLimit && CurrIVI && !KnowAllElts();
1032 auto *InsertedValue =
1040 if (Indices.
size() != 1)
1046 std::optional<Instruction *> &Elt = AggElts[Indices.
front()];
1047 Elt = Elt.value_or(InsertedValue);
1060 enum class AggregateDescription {
1076 auto Describe = [](std::optional<Value *> SourceAggregate) {
1077 if (SourceAggregate == NotFound)
1078 return AggregateDescription::NotFound;
1079 if (*SourceAggregate == FoundMismatch)
1080 return AggregateDescription::FoundMismatch;
1081 return AggregateDescription::Found;
1085 bool EltDefinedInUseBB =
false;
1092 auto FindSourceAggregate =
1093 [&](
Instruction *Elt,
unsigned EltIdx, std::optional<BasicBlock *> UseBB,
1094 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1096 if (UseBB && PredBB) {
1099 EltDefinedInUseBB =
true;
1108 Value *SourceAggregate = EVI->getAggregateOperand();
1111 if (SourceAggregate->
getType() != AggTy)
1112 return FoundMismatch;
1114 if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
1115 return FoundMismatch;
1117 return SourceAggregate;
1123 auto FindCommonSourceAggregate =
1124 [&](std::optional<BasicBlock *> UseBB,
1125 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1126 std::optional<Value *> SourceAggregate;
1129 assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
1130 "We don't store nullptr in SourceAggregate!");
1131 assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
1133 "SourceAggregate should be valid after the first element,");
1138 std::optional<Value *> SourceAggregateForElement =
1139 FindSourceAggregate(*
I.value(),
I.index(), UseBB, PredBB);
1146 if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
1147 return SourceAggregateForElement;
1151 switch (Describe(SourceAggregate)) {
1152 case AggregateDescription::NotFound:
1154 SourceAggregate = SourceAggregateForElement;
1156 case AggregateDescription::Found:
1159 if (*SourceAggregateForElement != *SourceAggregate)
1160 return FoundMismatch;
1162 case AggregateDescription::FoundMismatch:
1167 assert(Describe(SourceAggregate) == AggregateDescription::Found &&
1168 "Must be a valid Value");
1169 return *SourceAggregate;
1172 std::optional<Value *> SourceAggregate;
1175 SourceAggregate = FindCommonSourceAggregate(std::nullopt,
1177 if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
1178 if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
1180 ++NumAggregateReconstructionsSimplified;
1193 for (
const std::optional<Instruction *> &
I : AggElts) {
1217 static const int PredCountLimit = 64;
1224 if (Preds.
size() >= PredCountLimit)
1233 bool FoundSrcAgg =
false;
1235 std::pair<
decltype(SourceAggregates)
::iterator,
bool>
IV =
1244 SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
1245 if (Describe(SourceAggregate) == AggregateDescription::Found) {
1247 IV.first->second = *SourceAggregate;
1262 for (
auto &It : SourceAggregates) {
1263 if (Describe(It.second) == AggregateDescription::Found)
1267 if (EltDefinedInUseBB)
1275 if (UseBB != OrigBB)
1280 bool ConstAgg =
true;
1281 for (
auto Val : AggElts) {
1294 for (
auto &It : SourceAggregates) {
1295 if (Describe(It.second) == AggregateDescription::Found)
1299 Builder.SetInsertPoint(Pred->getTerminator());
1301 for (
auto [Idx, Val] :
enumerate(AggElts)) {
1303 V =
Builder.CreateInsertValue(V, Elt, Idx);
1315 Builder.SetInsertPoint(UseBB, UseBB->getFirstNonPHIIt());
1319 PHI->addIncoming(SourceAggregates[Pred], Pred);
1321 ++NumAggregateReconstructionsSimplified;
1334 I.getAggregateOperand(),
I.getInsertedValueOperand(),
I.getIndices(),
1335 SQ.getWithInstruction(&
I)))
1338 bool IsRedundant =
false;
1347 while (V->hasOneUse() &&
Depth < 10) {
1350 if (!UserInsInst || U->getOperand(0) != V)
1352 if (UserInsInst->getIndices() == FirstIndices) {
1380 if (MaskSize != VecSize)
1385 for (
int i = 0; i != MaskSize; ++i) {
1387 if (Elt != -1 && Elt != i && Elt != i + VecSize)
1412 if (NumElements == 1)
1424 if (!Idx || CurrIE->
getOperand(1) != SplatVal)
1431 if (CurrIE != &InsElt &&
1432 (!CurrIE->
hasOneUse() && (NextIE !=
nullptr || !Idx->isZero())))
1435 ElementPresent[Idx->getZExtValue()] =
true;
1441 if (FirstIE == &InsElt)
1449 if (!ElementPresent.
all())
1455 Constant *Zero = ConstantInt::get(Int64Ty, 0);
1462 for (
unsigned i = 0; i != NumElements; ++i)
1463 if (!ElementPresent[i])
1474 if (!Shuf || !Shuf->isZeroEltSplat())
1489 Value *Op0 = Shuf->getOperand(0);
1497 unsigned NumMaskElts =
1500 for (
unsigned i = 0; i != NumMaskElts; ++i)
1501 NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
1512 !(Shuf->isIdentityWithExtract() || Shuf->isIdentityWithPadding()))
1528 Value *
X = Shuf->getOperand(0);
1536 unsigned NumMaskElts =
1540 for (
unsigned i = 0; i != NumMaskElts; ++i) {
1543 NewMask[i] = OldMask[i];
1544 }
else if (OldMask[i] == (
int)IdxC) {
1550 "Unexpected shuffle mask element for identity shuffle");
1570 if (!InsElt1 || !InsElt1->hasOneUse())
1581 Value *NewInsElt1 = Builder.CreateInsertElement(
X, ScalarC, IdxC2);
1594 if (!Inst || !Inst->hasOneUse())
1599 Constant *ShufConstVec, *InsEltScalar;
1623 unsigned NumElts = Mask.size();
1626 for (
unsigned I = 0;
I != NumElts; ++
I) {
1627 if (
I == InsEltIndex) {
1628 NewShufElts[
I] = InsEltScalar;
1629 NewMaskElts[
I] = InsEltIndex + NumElts;
1633 NewMaskElts[
I] = Mask[
I];
1637 if (!NewShufElts[
I])
1664 auto ValI = std::begin(Val);
1671 Mask[
I] = NumElts +
I;
1676 for (
unsigned I = 0;
I < NumElts; ++
I) {
1708 CastOpcode = Instruction::FPExt;
1710 CastOpcode = Instruction::SExt;
1712 CastOpcode = Instruction::ZExt;
1717 if (
X->getType()->getScalarType() !=
Y->getType())
1745 Value *Scalar0, *BaseVec;
1747 if (!VTy || (VTy->getNumElements() & 1) ||
1756 if (Index0 + 1 != Index1 || Index0 & 1)
1773 Type *SrcTy =
X->getType();
1774 unsigned ScalarWidth = SrcTy->getScalarSizeInBits();
1775 unsigned VecEltWidth = VTy->getScalarSizeInBits();
1776 if (ScalarWidth != VecEltWidth * 2 || ShAmt != VecEltWidth)
1781 Value *CastBaseVec = Builder.CreateBitCast(BaseVec, CastTy);
1785 uint64_t NewIndex = IsBigEndian ? Index1 / 2 : Index0 / 2;
1786 Value *NewInsert = Builder.CreateInsertElement(CastBaseVec,
X, NewIndex);
1791 Value *VecOp = IE.getOperand(0);
1792 Value *ScalarOp = IE.getOperand(1);
1793 Value *IdxOp = IE.getOperand(2);
1796 VecOp, ScalarOp, IdxOp,
SQ.getWithInstruction(&IE)))
1804 Value *BaseVec, *OtherScalar;
1805 uint64_t OtherIndexVal;
1809 !
isa<Constant>(OtherScalar) && OtherIndexVal > IndexC->getZExtValue()) {
1810 Value *NewIns =
Builder.CreateInsertElement(BaseVec, ScalarOp, IdxOp);
1812 Builder.getInt64(OtherIndexVal));
1830 Value *NewInsElt =
Builder.CreateInsertElement(NewUndef, ScalarSrc, IdxOp);
1845 Value *NewInsElt =
Builder.CreateInsertElement(VecSrc, ScalarSrc, IdxOp);
1853 uint64_t InsertedIdx, ExtractedIdx;
1877 if (!Insert.hasOneUse())
1886 if (isShuffleRootCandidate(IE)) {
1897 if (LR.first != &IE && LR.second != &IE) {
1899 if (LR.second ==
nullptr)
1908 unsigned VWidth = VecTy->getNumElements();
1909 APInt PoisonElts(VWidth, 0);
1932 return IdentityShuf;
1946 unsigned Depth = 5) {
1953 if (!
I)
return false;
1956 if (!
I->hasOneUse())
1959 if (
Depth == 0)
return false;
1961 switch (
I->getOpcode()) {
1962 case Instruction::UDiv:
1963 case Instruction::SDiv:
1964 case Instruction::URem:
1965 case Instruction::SRem:
1972 case Instruction::Add:
1973 case Instruction::FAdd:
1974 case Instruction::Sub:
1975 case Instruction::FSub:
1976 case Instruction::Mul:
1977 case Instruction::FMul:
1978 case Instruction::FDiv:
1979 case Instruction::FRem:
1980 case Instruction::Shl:
1981 case Instruction::LShr:
1982 case Instruction::AShr:
1983 case Instruction::And:
1984 case Instruction::Or:
1985 case Instruction::Xor:
1986 case Instruction::ICmp:
1987 case Instruction::FCmp:
1988 case Instruction::Trunc:
1989 case Instruction::ZExt:
1990 case Instruction::SExt:
1991 case Instruction::FPToUI:
1992 case Instruction::FPToSI:
1993 case Instruction::UIToFP:
1994 case Instruction::SIToFP:
1995 case Instruction::FPTrunc:
1996 case Instruction::FPExt:
1997 case Instruction::GetElementPtr: {
2000 Type *ITy =
I->getType();
2004 for (
Value *Operand :
I->operands()) {
2010 case Instruction::InsertElement: {
2012 if (!CI)
return false;
2017 bool SeenOnce =
false;
2018 for (
int I : Mask) {
2019 if (
I == ElementNumber) {
2035 Builder.SetInsertPoint(
I);
2036 switch (
I->getOpcode()) {
2037 case Instruction::Add:
2038 case Instruction::FAdd:
2039 case Instruction::Sub:
2040 case Instruction::FSub:
2041 case Instruction::Mul:
2042 case Instruction::FMul:
2043 case Instruction::UDiv:
2044 case Instruction::SDiv:
2045 case Instruction::FDiv:
2046 case Instruction::URem:
2047 case Instruction::SRem:
2048 case Instruction::FRem:
2049 case Instruction::Shl:
2050 case Instruction::LShr:
2051 case Instruction::AShr:
2052 case Instruction::And:
2053 case Instruction::Or:
2054 case Instruction::Xor: {
2056 assert(NewOps.
size() == 2 &&
"binary operator with #ops != 2");
2058 NewOps[0], NewOps[1]);
2065 NewI->setIsExact(BO->
isExact());
2068 NewI->copyFastMathFlags(
I);
2072 case Instruction::ICmp: {
2073 assert(NewOps.
size() == 2 &&
"icmp with #ops != 2");
2075 NewOps[0], NewOps[1]);
2077 NewI->copyIRFlags(
I);
2080 case Instruction::FCmp:
2081 assert(NewOps.
size() == 2 &&
"fcmp with #ops != 2");
2082 return Builder.CreateFCmpFMF(
cast<FCmpInst>(
I)->getPredicate(), NewOps[0],
2084 case Instruction::Trunc:
2085 case Instruction::ZExt:
2086 case Instruction::SExt:
2087 case Instruction::FPToUI:
2088 case Instruction::FPToSI:
2089 case Instruction::UIToFP:
2090 case Instruction::SIToFP:
2091 case Instruction::FPTrunc:
2092 case Instruction::FPExt: {
2096 I->getType()->getScalarType(),
2098 assert(NewOps.
size() == 1 &&
"cast with #ops != 1");
2100 Builder.CreateCast(
cast<CastInst>(
I)->getOpcode(), NewOps[0], DestTy);
2102 NewI->copyIRFlags(
I);
2105 case Instruction::GetElementPtr: {
2106 Value *Ptr = NewOps[0];
2120 assert(V->getType()->isVectorTy() &&
"can't reorder non-vector elements");
2137 switch (
I->getOpcode()) {
2138 case Instruction::Add:
2139 case Instruction::FAdd:
2140 case Instruction::Sub:
2141 case Instruction::FSub:
2142 case Instruction::Mul:
2143 case Instruction::FMul:
2144 case Instruction::UDiv:
2145 case Instruction::SDiv:
2146 case Instruction::FDiv:
2147 case Instruction::URem:
2148 case Instruction::SRem:
2149 case Instruction::FRem:
2150 case Instruction::Shl:
2151 case Instruction::LShr:
2152 case Instruction::AShr:
2153 case Instruction::And:
2154 case Instruction::Or:
2155 case Instruction::Xor:
2156 case Instruction::ICmp:
2157 case Instruction::FCmp:
2158 case Instruction::Trunc:
2159 case Instruction::ZExt:
2160 case Instruction::SExt:
2161 case Instruction::FPToUI:
2162 case Instruction::FPToSI:
2163 case Instruction::UIToFP:
2164 case Instruction::SIToFP:
2165 case Instruction::FPTrunc:
2166 case Instruction::FPExt:
2167 case Instruction::Select:
2168 case Instruction::GetElementPtr: {
2173 for (
int i = 0, e =
I->getNumOperands(); i != e; ++i) {
2178 if (
I->getOperand(i)->getType()->isVectorTy())
2181 V =
I->getOperand(i);
2183 NeedsRebuild |= (V !=
I->getOperand(i));
2189 case Instruction::InsertElement: {
2197 for (
int e = Mask.size(); Index != e; ++Index) {
2198 if (Mask[Index] == Element) {
2211 Builder.SetInsertPoint(
I);
2212 return Builder.CreateInsertElement(V,
I->getOperand(1), Index);
2228 unsigned MaskElems = Mask.size();
2229 unsigned BegIdx = Mask.front();
2230 unsigned EndIdx = Mask.back();
2231 if (BegIdx > EndIdx || EndIdx >= LHSElems || EndIdx - BegIdx != MaskElems - 1)
2233 for (
unsigned I = 0;
I != MaskElems; ++
I)
2234 if (
static_cast<unsigned>(Mask[
I]) != BegIdx +
I)
2259 case Instruction::Shl: {
2264 Instruction::Shl, ConstantInt::get(Ty, 1),
C,
DL);
2265 assert(ShlOne &&
"Constant folding of immediate constants failed");
2266 return {Instruction::Mul, BO0, ShlOne};
2270 case Instruction::Or: {
2273 return {Instruction::Add, BO0, BO1};
2276 case Instruction::Sub:
2291 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2296 unsigned NumElts = Mask.size();
2300 if (ShufOp && ShufOp->isSelect() &&
2301 (ShufOp->getOperand(0) == Op1 || ShufOp->getOperand(1) == Op1)) {
2307 if (!ShufOp || !ShufOp->isSelect() ||
2308 (ShufOp->getOperand(0) != Op0 && ShufOp->getOperand(1) != Op0))
2311 Value *
X = ShufOp->getOperand(0), *
Y = ShufOp->getOperand(1);
2313 ShufOp->getShuffleMask(Mask1);
2314 assert(Mask1.
size() == NumElts &&
"Vector size changed with select shuffle");
2327 for (
unsigned i = 0; i != NumElts; ++i)
2328 NewMask[i] = Mask[i] < (
signed)NumElts ? Mask[i] : Mask1[i];
2333 "Unexpected shuffle mask");
2339 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2362 Value *
X = Op0IsBinop ? Op1 : Op0;
2371 bool IsFloatingPointTy =
2384 bool MightCreatePoisonOrUB =
2387 if (MightCreatePoisonOrUB)
2428 Value *NewIns = Builder.CreateInsertElement(PoisonVec,
X, (
uint64_t)0);
2434 unsigned NumMaskElts =
2437 for (
unsigned i = 0; i != NumMaskElts; ++i)
2439 NewMask[i] = Mask[i];
2476 Constant *C0 =
nullptr, *C1 =
nullptr;
2477 bool ConstantsAreOp1;
2480 ConstantsAreOp1 =
false;
2485 ConstantsAreOp1 =
true;
2492 bool DropNSW =
false;
2493 if (ConstantsAreOp1 && Opc0 != Opc1) {
2497 if (Opc0 == Instruction::Shl || Opc1 == Instruction::Shl)
2501 Opc0 = AltB0.Opcode;
2505 Opc1 = AltB1.Opcode;
2510 if (Opc0 != Opc1 || !C0 || !C1)
2523 bool MightCreatePoisonOrUB =
2526 if (MightCreatePoisonOrUB)
2540 if (!B0->hasOneUse() && !B1->hasOneUse())
2549 if (MightCreatePoisonOrUB && !ConstantsAreOp1)
2559 V =
Builder.CreateShuffleVector(
X,
Y, Mask);
2562 Value *NewBO = ConstantsAreOp1 ?
Builder.CreateBinOp(BOpc, V, NewC) :
2563 Builder.CreateBinOp(BOpc, NewC, V);
2571 NewI->copyIRFlags(B0);
2572 NewI->andIRFlags(B1);
2574 NewI->setHasNoSignedWrap(
false);
2576 NewI->dropPoisonGeneratingFlags();
2595 Type *SrcType =
X->getType();
2596 if (!SrcType->isVectorTy() || !SrcType->isIntOrIntVectorTy() ||
2603 "Expected a shuffle that decreases length");
2610 for (
unsigned i = 0, e = Mask.size(); i != e; ++i) {
2613 uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
2614 assert(LSBIndex <= INT32_MAX &&
"Overflowed 32-bits");
2615 if (Mask[i] != (
int)LSBIndex)
2641 unsigned NarrowNumElts =
2666 bool IsFNeg = S0->getOpcode() == Instruction::FNeg;
2672 S0->getOpcode() !=
S1->getOpcode() ||
2673 (!S0->hasOneUse() && !
S1->hasOneUse()))
2680 NewF = UnaryOperator::CreateFNeg(NewShuf);
2701 switch (CastOpcode) {
2702 case Instruction::SExt:
2703 case Instruction::ZExt:
2704 case Instruction::FPToSI:
2705 case Instruction::FPToUI:
2706 case Instruction::SIToFP:
2707 case Instruction::UIToFP:
2718 if (ShufTy->getElementCount().getKnownMinValue() >
2719 ShufOpTy->getElementCount().getKnownMinValue())
2726 auto *NewIns = Builder.CreateShuffleVector(Cast0->getOperand(0),
2734 if (!Cast1 || Cast0->getOpcode() != Cast1->getOpcode() ||
2735 Cast0->getSrcTy() != Cast1->getSrcTy())
2740 "Expected fixed vector operands for casts and binary shuffle");
2741 if (CastSrcTy->getPrimitiveSizeInBits() > ShufOpTy->getPrimitiveSizeInBits())
2745 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
2749 Value *
X = Cast0->getOperand(0);
2750 Value *
Y = Cast1->getOperand(0);
2765 X->getType()->getPrimitiveSizeInBits() ==
2793 assert(NumElts < Mask.size() &&
2794 "Identity with extract must have less elements than its inputs");
2796 for (
unsigned i = 0; i != NumElts; ++i) {
2798 int MaskElt = Mask[i];
2799 NewMask[i] = ExtractMaskElt ==
PoisonMaskElem ? ExtractMaskElt : MaskElt;
2812 int NumElts = Mask.size();
2838 if (NumElts != InpNumElts)
2842 auto isShufflingScalarIntoOp1 = [&](
Value *&Scalar,
ConstantInt *&IndexC) {
2850 int NewInsIndex = -1;
2851 for (
int i = 0; i != NumElts; ++i) {
2857 if (Mask[i] == NumElts + i)
2861 if (NewInsIndex != -1 || Mask[i] != IndexC->getSExtValue())
2868 assert(NewInsIndex != -1 &&
"Did not fold shuffle with unused operand?");
2871 IndexC = ConstantInt::get(IndexC->getIntegerType(), NewInsIndex);
2880 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2888 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2900 if (!Shuffle0 || !Shuffle0->isIdentityWithPadding() ||
2901 !Shuffle1 || !Shuffle1->isIdentityWithPadding())
2909 Value *
X = Shuffle0->getOperand(0);
2910 Value *
Y = Shuffle1->getOperand(0);
2911 if (
X->getType() !=
Y->getType() ||
2920 "Unexpected operand for identity shuffle");
2928 assert(WideElts > NarrowElts &&
"Unexpected types for identity with padding");
2932 for (
int i = 0, e = Mask.size(); i != e; ++i) {
2938 if (Mask[i] < WideElts) {
2939 if (Shuffle0->getMaskValue(Mask[i]) == -1)
2942 if (Shuffle1->getMaskValue(Mask[i] - WideElts) == -1)
2949 if (Mask[i] < WideElts) {
2950 assert(Mask[i] < NarrowElts &&
"Unexpected shuffle mask");
2951 NewMask[i] = Mask[i];
2953 assert(Mask[i] < (WideElts + NarrowElts) &&
"Unexpected shuffle mask");
2954 NewMask[i] = Mask[i] - (WideElts - NarrowElts);
2976 if (
X->getType() !=
Y->getType())
2985 NewBOI->copyIRFlags(BinOp);
3021 X->getType()->isVectorTy() &&
X->getType() ==
Y->getType() &&
3022 X->getType()->getScalarSizeInBits() ==
3024 (LHS->hasOneUse() || RHS->hasOneUse())) {
3039 X->getType()->isVectorTy() && VWidth == LHSWidth) {
3042 unsigned XNumElts = XType->getNumElements();
3048 ScaledMask, XType, ShufQuery))
3056 "Shuffle with 2 undef ops not simplified?");
3084 APInt PoisonElts(VWidth, 0);
3106 if (
SI->getCondition()->getType()->isIntegerTy() &&
3153 bool MadeChange =
false;
3156 unsigned MaskElems = Mask.size();
3158 unsigned VecBitWidth =
DL.getTypeSizeInBits(SrcTy);
3159 unsigned SrcElemBitWidth =
DL.getTypeSizeInBits(SrcTy->getElementType());
3160 assert(SrcElemBitWidth &&
"vector elements must have a bitwidth");
3161 unsigned SrcNumElems = SrcTy->getNumElements();
3167 if (BC->use_empty())
3170 if (BC->hasOneUse()) {
3172 if (BC2 && isEliminableCastPair(BC, BC2))
3178 unsigned BegIdx = Mask.front();
3179 Type *TgtTy = BC->getDestTy();
3180 unsigned TgtElemBitWidth =
DL.getTypeSizeInBits(TgtTy);
3181 if (!TgtElemBitWidth)
3183 unsigned TgtNumElems = VecBitWidth / TgtElemBitWidth;
3184 bool VecBitWidthsEqual = VecBitWidth == TgtNumElems * TgtElemBitWidth;
3185 bool BegIsAligned = 0 == ((SrcElemBitWidth * BegIdx) % TgtElemBitWidth);
3186 if (!VecBitWidthsEqual)
3191 if (!BegIsAligned) {
3195 for (
unsigned I = 0, E = MaskElems, Idx = BegIdx;
I != E; ++Idx, ++
I)
3196 ShuffleMask[
I] = Idx;
3197 V =
Builder.CreateShuffleVector(V, ShuffleMask,
3201 unsigned SrcElemsPerTgtElem = TgtElemBitWidth / SrcElemBitWidth;
3202 assert(SrcElemsPerTgtElem);
3203 BegIdx /= SrcElemsPerTgtElem;
3204 auto [It, Inserted] = NewBCs.
try_emplace(CastSrcTy);
3206 It->second =
Builder.CreateBitCast(V, CastSrcTy, SVI.
getName() +
".bc");
3207 auto *Ext =
Builder.CreateExtractElement(It->second, BegIdx,
3264 LHSShuffle =
nullptr;
3267 RHSShuffle =
nullptr;
3268 if (!LHSShuffle && !RHSShuffle)
3269 return MadeChange ? &SVI :
nullptr;
3271 Value* LHSOp0 =
nullptr;
3272 Value* LHSOp1 =
nullptr;
3273 Value* RHSOp0 =
nullptr;
3274 unsigned LHSOp0Width = 0;
3275 unsigned RHSOp0Width = 0;
3285 Value* newLHS = LHS;
3286 Value* newRHS = RHS;
3294 else if (LHSOp0Width == LHSWidth) {
3299 if (RHSShuffle && RHSOp0Width == LHSWidth) {
3303 if (LHSOp0 == RHSOp0) {
3308 if (newLHS == LHS && newRHS == RHS)
3309 return MadeChange ? &SVI :
nullptr;
3315 if (RHSShuffle && newRHS != RHS)
3318 unsigned newLHSWidth = (newLHS != LHS) ? LHSOp0Width : LHSWidth;
3324 for (
unsigned i = 0; i < VWidth; ++i) {
3329 }
else if (Mask[i] < (
int)LHSWidth) {
3334 if (newLHS != LHS) {
3335 eltMask = LHSMask[Mask[i]];
3351 else if (newRHS != RHS) {
3352 eltMask = RHSMask[Mask[i]-LHSWidth];
3355 if (eltMask >= (
int)RHSOp0Width) {
3357 "should have been check above");
3361 eltMask = Mask[i]-LHSWidth;
3369 if (eltMask >= 0 && newRHS !=
nullptr && newLHS != newRHS)
3370 eltMask += newLHSWidth;
3375 if (SplatElt >= 0 && SplatElt != eltMask)
3385 if (
isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
3391 return MadeChange ? &SVI :
nullptr;
3413 if (
DL.isBigEndian())
3428 auto isDeinterleaveShuffle =
3435 unsigned NumInputElements =
3441 NumInputElements) &&
3442 ShuffleMask.size() * 2 == NumInputElements)
3445 return {
nullptr, UINT_MAX};
3452 DIV = isDeinterleaveShuffle(SVI).first;
3458 if (!
all_of(DI->users(), [](User *Usr) ->
bool {
3459 auto *EV = dyn_cast<ExtractValueInst>(Usr);
3460 return EV && EV->getNumIndices() == 1;
3471 if (!InputVecTy->getElementCount().isKnownEven())
3477 for (
auto *Usr : DIV->
users()) {
3481 auto [
V,
Index] = isDeinterleaveShuffle(FieldI);
3486 if (FieldI->getParent() != SVI->
getParent())
3488 if (FieldI != SVI && FieldI->comesBefore(SVI))
3494 for (User *
Field : DI->users()) {
3496 unsigned FieldIdx = *FieldI->idx_begin();
3507 for (
auto [
Field, FieldIdx] : Fields) {
3508 for (User *FieldUsr :
Field->users()) {
3513 if (ZExt->getDestTy() != ZExt->getSrcTy()->getExtendedType())
3515 FieldReplacements.
push_back({ZExt, FieldIdx});
3520 Builder.SetInsertPoint(DI ? DI : SVI);
3529 unsigned InElementBitWidth = InElementTy->getBitWidth();
3532 Value *NewField1 =
Builder.CreateLShr(Bitcast, InElementBitWidth);
3534 for (
auto [
I, Idx] : FieldReplacements) {
3535 assert(Idx < 2 &&
"unsupported field index");
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 Value * foldExtractOfStridedPointerVector(ExtractElementInst &EI, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
Fold a variable extract from a vector of pointers that all point into the same object at a constant s...
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
OptimizedStructLayoutField Field
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.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
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.
static DebugLoc getCompilerGenerated()
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 * foldExtractionOfVectorDeinterleave(ZExtInst &RootZExt)
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)
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.
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
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 hasNoInfs() const LLVM_READONLY
Determine whether the no-infs 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()
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
iterator_range< user_iterator > users()
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
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.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
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 bool isSingleSourceMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from 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 isDeInterleaveMaskOfFactor(ArrayRef< int > Mask, unsigned Factor, unsigned &Index)
Check if the mask is a DE-interleave mask of the given factor Factor like: <Index,...
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.
static VectorType * getHalfElementsVectorType(VectorType *VTy)
This static method returns a VectorType with half as many elements as the input type and the same ele...
static VectorType * getExtendedElementVectorType(VectorType *VTy)
This static method is like getInteger except that the element types are twice as wide as the elements...
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
This class represents zero extension of integer types.
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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ 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.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
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.
PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
Matches GEP with i8 source element type.
auto m_Cmp()
Matches any compare instruction and ignore it.
auto m_Poison()
Match an arbitrary poison constant.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
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.
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.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
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.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_Deinterleave2(const Opnd &Op)
auto m_FAbs(const Opnd0 &Op0)
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.
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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
RelativeUniformCounterPtr Values
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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...
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
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)
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.