44#define DEBUG_TYPE "instcombine"
47using namespace PatternMatch;
50 "Number of aggregate reconstructions turned into reuse of the "
51 "original aggregate");
62 if (
auto *
C = dyn_cast<Constant>(V))
63 return CEI ||
C->getSplatValue();
65 if (CEI &&
match(V, m_Intrinsic<Intrinsic::stepvector>())) {
66 ElementCount EC = cast<VectorType>(V->getType())->getElementCount();
108 for (
auto *U : PN->
users()) {
114 }
else if (!PHIUser) {
115 PHIUser = cast<Instruction>(U);
128 !(isa<BinaryOperator>(PHIUser)) ||
142 if (PHIInVal == PHIUser) {
147 unsigned opId = (B0->
getOperand(0) == PN) ? 1 : 0;
160 Instruction *pos = dyn_cast<Instruction>(PHIInVal);
162 if (pos && !isa<PHINode>(pos)) {
174 for (
auto *E : Extracts) {
191 cast<VectorType>(
Ext.getVectorOperandType())->getElementCount();
198 if (
X->getType()->isIntegerTy()) {
199 assert(isa<FixedVectorType>(
Ext.getVectorOperand()->getType()) &&
200 "Expected fixed vector type for bitcast from scalar integer");
207 unsigned ShiftAmountC = ExtIndexC * DestWidth;
208 if ((!ShiftAmountC ||
209 isDesirableIntType(
X->getType()->getPrimitiveSizeInBits())) &&
210 Ext.getVectorOperand()->hasOneUse()) {
222 if (!
X->getType()->isVectorTy())
228 auto *SrcTy = cast<VectorType>(
X->getType());
230 if (NumSrcElts == NumElts)
235 "Src and Dst must be the same sort of vector type");
251 unsigned NarrowingRatio =
254 if (ExtIndexC / NarrowingRatio != InsIndexC) {
260 if (
X->hasOneUse() &&
Ext.getVectorOperand()->hasOneUse()) {
278 unsigned Chunk = ExtIndexC % NarrowingRatio;
280 Chunk = NarrowingRatio - 1 - Chunk;
285 bool NeedSrcBitcast = SrcTy->getScalarType()->isFloatingPointTy();
287 if (NeedSrcBitcast && NeedDestBitcast)
290 unsigned SrcWidth = SrcTy->getScalarSizeInBits();
291 unsigned ShAmt = Chunk * DestWidth;
296 if (!
X->hasOneUse() || !
Ext.getVectorOperand()->hasOneUse())
297 if (NeedSrcBitcast || NeedDestBitcast)
300 if (NeedSrcBitcast) {
307 if (!
Ext.getVectorOperand()->hasOneUse())
312 if (NeedDestBitcast) {
324 unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
330 case Instruction::ExtractElement: {
334 if (EEIIndexC && EEIIndexC->
getValue().
ult(VWidth)) {
339 case Instruction::ShuffleVector: {
341 unsigned MaskNumElts =
342 cast<FixedVectorType>(UserInstr->
getType())->getNumElements();
344 UsedElts =
APInt(VWidth, 0);
345 for (
unsigned i = 0; i < MaskNumElts; i++) {
347 if (MaskVal == -1u || MaskVal >= 2 * VWidth)
349 if (Shuffle->
getOperand(0) == V && (MaskVal < VWidth))
352 ((MaskVal >= VWidth) && (MaskVal < 2 * VWidth)))
353 UsedElts.
setBit(MaskVal - VWidth);
368 unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
370 APInt UnionUsedElts(VWidth, 0);
371 for (
const Use &U : V->uses()) {
372 if (
Instruction *
I = dyn_cast<Instruction>(U.getUser())) {
383 return UnionUsedElts;
414 if (SI->getCondition()->getType()->isIntegerTy() &&
421 auto *IndexC = dyn_cast<ConstantInt>(Index);
422 bool HasKnownValidIndex =
false;
429 unsigned NumElts = EC.getKnownMinValue();
430 HasKnownValidIndex = IndexC->getValue().ult(NumElts);
436 if (IID == Intrinsic::stepvector && IndexC->getValue().ult(NumElts)) {
442 if (IndexC->getValue().getActiveBits() <=
BitWidth)
443 Idx = ConstantInt::get(Ty, IndexC->getValue().zextOrTrunc(
BitWidth));
452 if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
460 if (
auto *Phi = dyn_cast<PHINode>(SrcVec))
461 if (
Instruction *ScalarPHI = scalarizePHI(EI, Phi))
469 m_Intrinsic<Intrinsic::vector_extract>(
m_Value(V),
m_Zero())))
486 (HasKnownValidIndex ||
502 CmpInst *SrcCmpInst = cast<CmpInst>(SrcVec);
507 if (
auto *
I = dyn_cast<Instruction>(SrcVec)) {
508 if (
auto *IE = dyn_cast<InsertElementInst>(
I)) {
512 if (isa<Constant>(IE->getOperand(2)) && IndexC)
514 }
else if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I)) {
515 auto *VecType = cast<VectorType>(
GEP->getType());
517 uint64_t IdxVal = IndexC ? IndexC->getZExtValue() : 0;
518 if (IndexC && IdxVal < EC.getKnownMinValue() &&
GEP->hasOneUse()) {
529 return isa<VectorType>(V->getType());
531 if (VectorOps == 1) {
532 Value *NewPtr =
GEP->getPointerOperand();
533 if (isa<VectorType>(NewPtr->
getType()))
537 for (
unsigned I = 1;
I !=
GEP->getNumOperands(); ++
I) {
539 if (isa<VectorType>(
Op->getType()))
546 GEP->getSourceElementType(), NewPtr, NewOps);
551 }
else if (
auto *SVI = dyn_cast<ShuffleVectorInst>(
I)) {
559 if (isa<FixedVectorType>(SVI->getType())) {
560 std::optional<int> SrcIdx;
562 if (SplatIndex != -1)
564 else if (
ConstantInt *CI = dyn_cast<ConstantInt>(Index))
565 SrcIdx = SVI->getMaskValue(CI->getZExtValue());
570 cast<FixedVectorType>(SVI->getOperand(0)->getType())
575 if (*SrcIdx < (
int)LHSWidth)
576 Src = SVI->getOperand(0);
579 Src = SVI->getOperand(1);
583 Src, ConstantInt::get(Int64Ty, *SrcIdx,
false));
586 }
else if (
auto *CI = dyn_cast<CastInst>(
I)) {
590 if (CI->hasOneUse() && (CI->getOpcode() != Instruction::BitCast)) {
602 unsigned NumElts = EC.getKnownMinValue();
606 if (!EC.isScalable() && NumElts != 1) {
610 APInt PoisonElts(NumElts, 0);
611 APInt DemandedElts(NumElts, 0);
612 DemandedElts.
setBit(IndexC->getZExtValue());
621 APInt PoisonElts(NumElts, 0);
623 SrcVec, DemandedElts, PoisonElts, 0 ,
643 "Invalid CollectSingleShuffleElements");
644 unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
647 Mask.assign(NumElts, -1);
652 for (
unsigned i = 0; i != NumElts; ++i)
658 for (
unsigned i = 0; i != NumElts; ++i)
659 Mask.push_back(i + NumElts);
665 Value *VecOp = IEI->getOperand(0);
666 Value *ScalarOp = IEI->getOperand(1);
667 Value *IdxOp = IEI->getOperand(2);
669 if (!isa<ConstantInt>(IdxOp))
671 unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue();
673 if (isa<PoisonValue>(ScalarOp)) {
678 Mask[InsertedIdx] = -1;
683 unsigned ExtractedIdx =
684 cast<ConstantInt>(EI->
getOperand(1))->getZExtValue();
685 unsigned NumLHSElts =
686 cast<FixedVectorType>(
LHS->
getType())->getNumElements();
695 Mask[InsertedIdx % NumElts] = ExtractedIdx;
698 Mask[InsertedIdx % NumElts] = ExtractedIdx + NumLHSElts;
716 auto *InsVecType = cast<FixedVectorType>(InsElt->
getType());
718 unsigned NumInsElts = InsVecType->getNumElements();
719 unsigned NumExtElts = ExtVecType->getNumElements();
722 if (InsVecType->getElementType() != ExtVecType->getElementType() ||
723 NumExtElts >= NumInsElts)
731 for (
unsigned i = 0; i < NumExtElts; ++i)
733 for (
unsigned i = NumExtElts; i < NumInsElts; ++i)
737 auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
738 BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
751 if (InsertionBlock != InsElt->
getParent())
768 if (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
769 WideVec->insertAfter(ExtVecOpInst->getIterator());
777 if (!OldExt || OldExt->
getParent() != WideVec->getParent())
803 assert(V->getType()->isVectorTy() &&
"Invalid shuffle!");
804 unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
807 Mask.assign(NumElts, -1);
808 return std::make_pair(
812 if (isa<ConstantAggregateZero>(V)) {
813 Mask.assign(NumElts, 0);
814 return std::make_pair(V,
nullptr);
819 Value *VecOp = IEI->getOperand(0);
820 Value *ScalarOp = IEI->getOperand(1);
821 Value *IdxOp = IEI->getOperand(2);
824 if (isa<ConstantInt>(EI->
getOperand(1)) && isa<ConstantInt>(IdxOp)) {
825 unsigned ExtractedIdx =
826 cast<ConstantInt>(EI->
getOperand(1))->getZExtValue();
827 unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue();
831 if (EI->
getOperand(0) == PermittedRHS || PermittedRHS ==
nullptr) {
834 assert(LR.second ==
nullptr || LR.second ==
RHS);
844 for (
unsigned i = 0; i < NumElts; ++i)
846 return std::make_pair(V,
nullptr);
849 unsigned NumLHSElts =
850 cast<FixedVectorType>(
RHS->
getType())->getNumElements();
851 Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
852 return std::make_pair(LR.first,
RHS);
855 if (VecOp == PermittedRHS) {
858 unsigned NumLHSElts =
861 for (
unsigned i = 0; i != NumElts; ++i)
862 Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
863 return std::make_pair(EI->
getOperand(0), PermittedRHS);
871 return std::make_pair(EI->
getOperand(0), PermittedRHS);
877 for (
unsigned i = 0; i != NumElts; ++i)
879 return std::make_pair(V,
nullptr);
905 assert(NumAggElts > 0 &&
"Aggregate should have elements.");
909 static constexpr auto NotFound = std::nullopt;
910 static constexpr auto FoundMismatch =
nullptr;
917 auto KnowAllElts = [&AggElts]() {
925 static const int DepthLimit = 2 * NumAggElts;
930 Depth < DepthLimit && CurrIVI && !KnowAllElts();
931 CurrIVI = dyn_cast<InsertValueInst>(CurrIVI->getAggregateOperand()),
933 auto *InsertedValue =
934 dyn_cast<Instruction>(CurrIVI->getInsertedValueOperand());
941 if (Indices.
size() != 1)
947 std::optional<Instruction *> &Elt = AggElts[Indices.
front()];
948 Elt = Elt.value_or(InsertedValue);
961 enum class AggregateDescription {
977 auto Describe = [](std::optional<Value *> SourceAggregate) {
978 if (SourceAggregate == NotFound)
979 return AggregateDescription::NotFound;
980 if (*SourceAggregate == FoundMismatch)
981 return AggregateDescription::FoundMismatch;
982 return AggregateDescription::Found;
986 bool EltDefinedInUseBB =
false;
993 auto FindSourceAggregate =
994 [&](
Instruction *Elt,
unsigned EltIdx, std::optional<BasicBlock *> UseBB,
995 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
997 if (UseBB && PredBB) {
1000 EltDefinedInUseBB =
true;
1005 auto *EVI = dyn_cast_or_null<ExtractValueInst>(Elt);
1009 Value *SourceAggregate = EVI->getAggregateOperand();
1012 if (SourceAggregate->
getType() != AggTy)
1013 return FoundMismatch;
1015 if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
1016 return FoundMismatch;
1018 return SourceAggregate;
1024 auto FindCommonSourceAggregate =
1025 [&](std::optional<BasicBlock *> UseBB,
1026 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1027 std::optional<Value *> SourceAggregate;
1030 assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
1031 "We don't store nullptr in SourceAggregate!");
1032 assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
1034 "SourceAggregate should be valid after the first element,");
1039 std::optional<Value *> SourceAggregateForElement =
1040 FindSourceAggregate(*
I.value(),
I.index(), UseBB, PredBB);
1047 if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
1048 return SourceAggregateForElement;
1052 switch (Describe(SourceAggregate)) {
1053 case AggregateDescription::NotFound:
1055 SourceAggregate = SourceAggregateForElement;
1057 case AggregateDescription::Found:
1060 if (*SourceAggregateForElement != *SourceAggregate)
1061 return FoundMismatch;
1063 case AggregateDescription::FoundMismatch:
1068 assert(Describe(SourceAggregate) == AggregateDescription::Found &&
1069 "Must be a valid Value");
1070 return *SourceAggregate;
1073 std::optional<Value *> SourceAggregate;
1076 SourceAggregate = FindCommonSourceAggregate(std::nullopt,
1078 if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
1079 if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
1081 ++NumAggregateReconstructionsSimplified;
1094 for (
const std::optional<Instruction *> &
I : AggElts) {
1118 static const int PredCountLimit = 64;
1125 if (Preds.
size() >= PredCountLimit)
1134 bool FoundSrcAgg =
false;
1136 std::pair<
decltype(SourceAggregates)::iterator,
bool>
IV =
1145 SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
1146 if (Describe(SourceAggregate) == AggregateDescription::Found) {
1148 IV.first->second = *SourceAggregate;
1152 auto *BI = dyn_cast<BranchInst>(Pred->getTerminator());
1153 if (!BI || !BI->isUnconditional())
1163 for (
auto &It : SourceAggregates) {
1164 if (Describe(It.second) == AggregateDescription::Found)
1168 if (EltDefinedInUseBB)
1176 if (UseBB != OrigBB)
1181 bool ConstAgg =
true;
1182 for (
auto Val : AggElts) {
1184 if (!isa<Constant>(Elt)) {
1195 for (
auto &It : SourceAggregates) {
1196 if (Describe(It.second) == AggregateDescription::Found)
1220 PHI->addIncoming(SourceAggregates[Pred], Pred);
1222 ++NumAggregateReconstructionsSimplified;
1235 I.getAggregateOperand(),
I.getInsertedValueOperand(),
I.getIndices(),
1239 bool IsRedundant =
false;
1248 while (V->hasOneUse() &&
Depth < 10) {
1249 User *U = V->user_back();
1250 auto UserInsInst = dyn_cast<InsertValueInst>(U);
1251 if (!UserInsInst || U->getOperand(0) != V)
1253 if (UserInsInst->getIndices() == FirstIndices) {
1281 if (MaskSize != VecSize)
1286 for (
int i = 0; i != MaskSize; ++i) {
1288 if (Elt != -1 && Elt != i && Elt != i + VecSize)
1307 if (isa<ScalableVectorType>(VecTy))
1309 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
1313 if (NumElements == 1)
1328 auto *NextIE = dyn_cast<InsertElementInst>(CurrIE->
getOperand(0));
1332 if (CurrIE != &InsElt &&
1333 (!CurrIE->
hasOneUse() && (NextIE !=
nullptr || !
Idx->isZero())))
1336 ElementPresent[
Idx->getZExtValue()] =
true;
1342 if (FirstIE == &InsElt)
1350 if (!ElementPresent.
all())
1356 Constant *Zero = ConstantInt::get(Int64Ty, 0);
1357 if (!cast<ConstantInt>(FirstIE->
getOperand(2))->isZero())
1363 for (
unsigned i = 0; i != NumElements; ++i)
1364 if (!ElementPresent[i])
1374 auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0));
1375 if (!Shuf || !Shuf->isZeroEltSplat())
1380 if (isa<ScalableVectorType>(Shuf->getType()))
1390 Value *Op0 = Shuf->getOperand(0);
1398 unsigned NumMaskElts =
1399 cast<FixedVectorType>(Shuf->getType())->getNumElements();
1401 for (
unsigned i = 0; i != NumMaskElts; ++i)
1402 NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
1411 auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0));
1413 !(Shuf->isIdentityWithExtract() || Shuf->isIdentityWithPadding()))
1418 if (isa<ScalableVectorType>(Shuf->getType()))
1429 Value *
X = Shuf->getOperand(0);
1437 unsigned NumMaskElts =
1438 cast<FixedVectorType>(Shuf->getType())->getNumElements();
1441 for (
unsigned i = 0; i != NumMaskElts; ++i) {
1444 NewMask[i] = OldMask[i];
1445 }
else if (OldMask[i] == (
int)IdxC) {
1451 "Unexpected shuffle mask element for identity shuffle");
1470 auto *InsElt1 = dyn_cast<InsertElementInst>(InsElt2.
getOperand(0));
1471 if (!InsElt1 || !InsElt1->hasOneUse())
1478 match(InsElt1->getOperand(1),
m_Value(
Y)) && !isa<Constant>(
Y) &&
1492 auto *Inst = dyn_cast<Instruction>(InsElt.
getOperand(0));
1495 if (!Inst || !Inst->hasOneUse())
1497 if (
auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0))) {
1500 Constant *ShufConstVec, *InsEltScalar;
1524 unsigned NumElts = Mask.size();
1527 for (
unsigned I = 0;
I != NumElts; ++
I) {
1528 if (
I == InsEltIndex) {
1529 NewShufElts[
I] = InsEltScalar;
1530 NewMaskElts[
I] = InsEltIndex + NumElts;
1534 NewMaskElts[
I] = Mask[
I];
1538 if (!NewShufElts[
I])
1546 }
else if (
auto *IEI = dyn_cast<InsertElementInst>(Inst)) {
1551 if (isa<ScalableVectorType>(InsElt.
getType()))
1554 cast<FixedVectorType>(InsElt.
getType())->getNumElements();
1565 auto ValI = std::begin(Val);
1572 Mask[
I] = NumElts +
I;
1577 for (
unsigned I = 0;
I < NumElts; ++
I) {
1609 CastOpcode = Instruction::FPExt;
1611 CastOpcode = Instruction::SExt;
1613 CastOpcode = Instruction::ZExt;
1618 if (
X->getType()->getScalarType() !=
Y->getType())
1645 auto *VTy = dyn_cast<FixedVectorType>(InsElt.
getType());
1646 Value *Scalar0, *BaseVec;
1648 if (!VTy || (VTy->getNumElements() & 1) ||
1657 if (Index0 + 1 != Index1 || Index0 & 1)
1674 Type *SrcTy =
X->getType();
1676 unsigned VecEltWidth = VTy->getScalarSizeInBits();
1677 if (ScalarWidth != VecEltWidth * 2 || ShAmt != VecEltWidth)
1686 uint64_t NewIndex = IsBigEndian ? Index1 / 2 : Index0 / 2;
1692 Value *VecOp = IE.getOperand(0);
1693 Value *ScalarOp = IE.getOperand(1);
1694 Value *IdxOp = IE.getOperand(2);
1701 if (
auto *IndexC = dyn_cast<ConstantInt>(IdxOp)) {
1705 Value *BaseVec, *OtherScalar;
1710 !isa<Constant>(OtherScalar) && OtherIndexVal > IndexC->getZExtValue()) {
1742 cast<VectorType>(VecSrc->
getType())->getElementType() ==
1754 uint64_t InsertedIdx, ExtractedIdx;
1756 if (isa<FixedVectorType>(IE.getType()) &&
1760 isa<FixedVectorType>(ExtVecOp->
getType()) &&
1762 cast<FixedVectorType>(ExtVecOp->
getType())->getNumElements()) {
1778 if (!Insert.hasOneUse())
1780 auto *InsertUser = dyn_cast<InsertElementInst>(Insert.user_back());
1787 if (isShuffleRootCandidate(IE)) {
1798 if (LR.first != &IE && LR.second != &IE) {
1800 if (LR.second ==
nullptr)
1808 if (
auto VecTy = dyn_cast<FixedVectorType>(VecOp->
getType())) {
1809 unsigned VWidth = VecTy->getNumElements();
1810 APInt PoisonElts(VWidth, 0);
1833 return IdentityShuf;
1847 unsigned Depth = 5) {
1849 if (isa<Constant>(V))
1854 if (!
I)
return false;
1857 if (!
I->hasOneUse())
1860 if (
Depth == 0)
return false;
1862 switch (
I->getOpcode()) {
1863 case Instruction::UDiv:
1864 case Instruction::SDiv:
1865 case Instruction::URem:
1866 case Instruction::SRem:
1873 case Instruction::Add:
1874 case Instruction::FAdd:
1875 case Instruction::Sub:
1876 case Instruction::FSub:
1877 case Instruction::Mul:
1878 case Instruction::FMul:
1879 case Instruction::FDiv:
1880 case Instruction::FRem:
1881 case Instruction::Shl:
1882 case Instruction::LShr:
1883 case Instruction::AShr:
1884 case Instruction::And:
1885 case Instruction::Or:
1886 case Instruction::Xor:
1887 case Instruction::ICmp:
1888 case Instruction::FCmp:
1889 case Instruction::Trunc:
1890 case Instruction::ZExt:
1891 case Instruction::SExt:
1892 case Instruction::FPToUI:
1893 case Instruction::FPToSI:
1894 case Instruction::UIToFP:
1895 case Instruction::SIToFP:
1896 case Instruction::FPTrunc:
1897 case Instruction::FPExt:
1898 case Instruction::GetElementPtr: {
1901 Type *ITy =
I->getType();
1903 Mask.size() > cast<FixedVectorType>(ITy)->getNumElements())
1905 for (
Value *Operand :
I->operands()) {
1911 case Instruction::InsertElement: {
1912 ConstantInt *CI = dyn_cast<ConstantInt>(
I->getOperand(2));
1913 if (!CI)
return false;
1918 bool SeenOnce =
false;
1919 for (
int I : Mask) {
1920 if (
I == ElementNumber) {
1937 switch (
I->getOpcode()) {
1938 case Instruction::Add:
1939 case Instruction::FAdd:
1940 case Instruction::Sub:
1941 case Instruction::FSub:
1942 case Instruction::Mul:
1943 case Instruction::FMul:
1944 case Instruction::UDiv:
1945 case Instruction::SDiv:
1946 case Instruction::FDiv:
1947 case Instruction::URem:
1948 case Instruction::SRem:
1949 case Instruction::FRem:
1950 case Instruction::Shl:
1951 case Instruction::LShr:
1952 case Instruction::AShr:
1953 case Instruction::And:
1954 case Instruction::Or:
1955 case Instruction::Xor: {
1957 assert(NewOps.
size() == 2 &&
"binary operator with #ops != 2");
1959 NewOps[0], NewOps[1]);
1960 if (
auto *NewI = dyn_cast<Instruction>(New)) {
1961 if (isa<OverflowingBinaryOperator>(BO)) {
1965 if (isa<PossiblyExactOperator>(BO)) {
1966 NewI->setIsExact(BO->
isExact());
1968 if (isa<FPMathOperator>(BO))
1969 NewI->copyFastMathFlags(
I);
1973 case Instruction::ICmp:
1974 assert(NewOps.
size() == 2 &&
"icmp with #ops != 2");
1975 return Builder.
CreateICmp(cast<ICmpInst>(
I)->getPredicate(), NewOps[0],
1977 case Instruction::FCmp:
1978 assert(NewOps.
size() == 2 &&
"fcmp with #ops != 2");
1979 return Builder.
CreateFCmp(cast<FCmpInst>(
I)->getPredicate(), NewOps[0],
1981 case Instruction::Trunc:
1982 case Instruction::ZExt:
1983 case Instruction::SExt:
1984 case Instruction::FPToUI:
1985 case Instruction::FPToSI:
1986 case Instruction::UIToFP:
1987 case Instruction::SIToFP:
1988 case Instruction::FPTrunc:
1989 case Instruction::FPExt: {
1993 I->getType()->getScalarType(),
1994 cast<VectorType>(NewOps[0]->getType())->getElementCount());
1995 assert(NewOps.
size() == 1 &&
"cast with #ops != 1");
1999 case Instruction::GetElementPtr: {
2002 return Builder.
CreateGEP(cast<GEPOperator>(
I)->getSourceElementType(),
2004 cast<GEPOperator>(
I)->getNoWrapFlags());
2014 assert(V->getType()->isVectorTy() &&
"can't reorder non-vector elements");
2015 Type *EltTy = V->getType()->getScalarType();
2017 if (isa<PoisonValue>(V))
2023 if (isa<ConstantAggregateZero>(V))
2026 if (
Constant *
C = dyn_cast<Constant>(V))
2031 switch (
I->getOpcode()) {
2032 case Instruction::Add:
2033 case Instruction::FAdd:
2034 case Instruction::Sub:
2035 case Instruction::FSub:
2036 case Instruction::Mul:
2037 case Instruction::FMul:
2038 case Instruction::UDiv:
2039 case Instruction::SDiv:
2040 case Instruction::FDiv:
2041 case Instruction::URem:
2042 case Instruction::SRem:
2043 case Instruction::FRem:
2044 case Instruction::Shl:
2045 case Instruction::LShr:
2046 case Instruction::AShr:
2047 case Instruction::And:
2048 case Instruction::Or:
2049 case Instruction::Xor:
2050 case Instruction::ICmp:
2051 case Instruction::FCmp:
2052 case Instruction::Trunc:
2053 case Instruction::ZExt:
2054 case Instruction::SExt:
2055 case Instruction::FPToUI:
2056 case Instruction::FPToSI:
2057 case Instruction::UIToFP:
2058 case Instruction::SIToFP:
2059 case Instruction::FPTrunc:
2060 case Instruction::FPExt:
2061 case Instruction::Select:
2062 case Instruction::GetElementPtr: {
2066 cast<FixedVectorType>(
I->getType())->getNumElements());
2067 for (
int i = 0, e =
I->getNumOperands(); i != e; ++i) {
2072 if (
I->getOperand(i)->getType()->isVectorTy())
2075 V =
I->getOperand(i);
2077 NeedsRebuild |= (V !=
I->getOperand(i));
2083 case Instruction::InsertElement: {
2084 int Element = cast<ConstantInt>(
I->getOperand(2))->getLimitedValue();
2091 for (
int e = Mask.size(); Index != e; ++Index) {
2092 if (Mask[Index] == Element) {
2122 unsigned MaskElems = Mask.size();
2123 unsigned BegIdx = Mask.front();
2124 unsigned EndIdx = Mask.back();
2125 if (BegIdx > EndIdx || EndIdx >= LHSElems || EndIdx - BegIdx != MaskElems - 1)
2127 for (
unsigned I = 0;
I != MaskElems; ++
I)
2128 if (
static_cast<unsigned>(Mask[
I]) != BegIdx +
I)
2141 Opcode(
Opc), Op0(V0), Op1(V1) {}
2142 operator bool()
const {
return Opcode != 0; }
2153 case Instruction::Shl: {
2158 Instruction::Shl, ConstantInt::get(Ty, 1),
C,
DL);
2159 assert(ShlOne &&
"Constant folding of immediate constants failed");
2160 return {Instruction::Mul, BO0, ShlOne};
2164 case Instruction::Or: {
2166 if (cast<PossiblyDisjointInst>(BO)->isDisjoint())
2167 return {Instruction::Add, BO0, BO1};
2170 case Instruction::Sub:
2185 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2190 unsigned NumElts = Mask.size();
2193 auto *ShufOp = dyn_cast<ShuffleVectorInst>(Op0);
2194 if (ShufOp && ShufOp->isSelect() &&
2195 (ShufOp->getOperand(0) == Op1 || ShufOp->getOperand(1) == Op1)) {
2200 ShufOp = dyn_cast<ShuffleVectorInst>(Op1);
2201 if (!ShufOp || !ShufOp->isSelect() ||
2202 (ShufOp->getOperand(0) != Op0 && ShufOp->getOperand(1) != Op0))
2205 Value *
X = ShufOp->getOperand(0), *
Y = ShufOp->getOperand(1);
2207 ShufOp->getShuffleMask(Mask1);
2208 assert(Mask1.
size() == NumElts &&
"Vector size changed with select shuffle");
2221 for (
unsigned i = 0; i != NumElts; ++i)
2222 NewMask[i] = Mask[i] < (
signed)NumElts ? Mask[i] : Mask1[i];
2227 "Unexpected shuffle mask");
2233 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2250 auto *BO = cast<BinaryOperator>(Op0IsBinop ? Op0 : Op1);
2256 Value *
X = Op0IsBinop ? Op1 : Op0;
2277 bool MightCreatePoisonOrUB =
2280 if (MightCreatePoisonOrUB)
2321 unsigned NumMaskElts =
2322 cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2324 for (
unsigned i = 0; i != NumMaskElts; ++i)
2326 NewMask[i] = Mask[i];
2338 unsigned NumElts = cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2363 Constant *C0 =
nullptr, *C1 =
nullptr;
2364 bool ConstantsAreOp1;
2367 ConstantsAreOp1 =
false;
2372 ConstantsAreOp1 =
true;
2379 bool DropNSW =
false;
2380 if (ConstantsAreOp1 && Opc0 != Opc1) {
2384 if (Opc0 == Instruction::Shl || Opc1 == Instruction::Shl)
2387 assert(isa<Constant>(AltB0.Op1) &&
"Expecting constant with alt binop");
2388 Opc0 = AltB0.Opcode;
2389 C0 = cast<Constant>(AltB0.Op1);
2391 assert(isa<Constant>(AltB1.Op1) &&
"Expecting constant with alt binop");
2392 Opc1 = AltB1.Opcode;
2393 C1 = cast<Constant>(AltB1.Op1);
2397 if (Opc0 != Opc1 || !C0 || !C1)
2410 bool MightCreatePoisonOrUB =
2413 if (MightCreatePoisonOrUB)
2436 if (MightCreatePoisonOrUB && !ConstantsAreOp1)
2457 if (
auto *NewI = dyn_cast<Instruction>(NewBO)) {
2458 NewI->copyIRFlags(B0);
2459 NewI->andIRFlags(B1);
2461 NewI->setHasNoSignedWrap(
false);
2463 NewI->dropPoisonGeneratingFlags();
2482 Type *SrcType =
X->getType();
2484 cast<FixedVectorType>(SrcType)->getNumElements() !=
2485 cast<FixedVectorType>(DestType)->getNumElements() ||
2490 "Expected a shuffle that decreases length");
2497 for (
unsigned i = 0, e = Mask.size(); i != e; ++i) {
2500 uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
2501 assert(LSBIndex <= INT32_MAX &&
"Overflowed 32-bits");
2502 if (Mask[i] != (
int)LSBIndex)
2528 unsigned NarrowNumElts =
2529 cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2532 cast<FixedVectorType>(NarrowCond->
getType())->getNumElements() !=
2534 !cast<ShuffleVectorInst>(
Cond)->isIdentityWithPadding())
2548 auto *S0 = dyn_cast<Instruction>(Shuf.
getOperand(0));
2553 bool IsFNeg = S0->getOpcode() == Instruction::FNeg;
2559 S0->getOpcode() !=
S1->getOpcode() ||
2560 (!S0->hasOneUse() && !
S1->hasOneUse()))
2567 NewF = UnaryOperator::CreateFNeg(NewShuf);
2581 auto *Cast0 = dyn_cast<CastInst>(Shuf.
getOperand(0));
2588 switch (CastOpcode) {
2589 case Instruction::SExt:
2590 case Instruction::ZExt:
2591 case Instruction::FPToSI:
2592 case Instruction::FPToUI:
2593 case Instruction::SIToFP:
2594 case Instruction::UIToFP:
2600 VectorType *CastSrcTy = cast<VectorType>(Cast0->getSrcTy());
2605 if (ShufTy->getElementCount().getKnownMinValue() >
2606 ShufOpTy->getElementCount().getKnownMinValue())
2611 if (isa<PoisonValue>(Shuf.
getOperand(1)) && Cast0->hasOneUse() &&
2619 auto *Cast1 = dyn_cast<CastInst>(Shuf.
getOperand(1));
2621 if (!Cast1 || Cast0->getOpcode() != Cast1->getOpcode() ||
2622 Cast0->getSrcTy() != Cast1->getSrcTy())
2626 assert(isa<FixedVectorType>(CastSrcTy) && isa<FixedVectorType>(ShufOpTy) &&
2627 "Expected fixed vector operands for casts and binary shuffle");
2628 if (CastSrcTy->getPrimitiveSizeInBits() > ShufOpTy->getPrimitiveSizeInBits())
2632 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
2636 Value *
X = Cast0->getOperand(0);
2637 Value *
Y = Cast1->getOperand(0);
2652 X->getType()->getPrimitiveSizeInBits() ==
2678 unsigned NumElts = cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2680 assert(NumElts < Mask.size() &&
2681 "Identity with extract must have less elements than its inputs");
2683 for (
unsigned i = 0; i != NumElts; ++i) {
2685 int MaskElt = Mask[i];
2686 NewMask[i] = ExtractMaskElt ==
PoisonMaskElem ? ExtractMaskElt : MaskElt;
2699 int NumElts = Mask.size();
2700 int InpNumElts = cast<FixedVectorType>(V0->
getType())->getNumElements();
2725 if (NumElts != InpNumElts)
2729 auto isShufflingScalarIntoOp1 = [&](
Value *&Scalar,
ConstantInt *&IndexC) {
2737 int NewInsIndex = -1;
2738 for (
int i = 0; i != NumElts; ++i) {
2744 if (Mask[i] == NumElts + i)
2748 if (NewInsIndex != -1 || Mask[i] != IndexC->getSExtValue())
2755 assert(NewInsIndex != -1 &&
"Did not fold shuffle with unused operand?");
2758 IndexC = ConstantInt::get(IndexC->getIntegerType(), NewInsIndex);
2767 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2775 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2785 auto *Shuffle0 = dyn_cast<ShuffleVectorInst>(Shuf.
getOperand(0));
2786 auto *Shuffle1 = dyn_cast<ShuffleVectorInst>(Shuf.
getOperand(1));
2787 if (!Shuffle0 || !Shuffle0->isIdentityWithPadding() ||
2788 !Shuffle1 || !Shuffle1->isIdentityWithPadding())
2796 Value *
X = Shuffle0->getOperand(0);
2797 Value *
Y = Shuffle1->getOperand(0);
2798 if (
X->getType() !=
Y->getType() ||
2801 cast<FixedVectorType>(Shuffle0->getType())->getNumElements()) ||
2802 !
isPowerOf2_32(cast<FixedVectorType>(
X->getType())->getNumElements()) ||
2807 "Unexpected operand for identity shuffle");
2813 int NarrowElts = cast<FixedVectorType>(
X->getType())->getNumElements();
2814 int WideElts = cast<FixedVectorType>(Shuffle0->getType())->getNumElements();
2815 assert(WideElts > NarrowElts &&
"Unexpected types for identity with padding");
2819 for (
int i = 0, e = Mask.size(); i != e; ++i) {
2825 if (Mask[i] < WideElts) {
2826 if (Shuffle0->getMaskValue(Mask[i]) == -1)
2829 if (Shuffle1->getMaskValue(Mask[i] - WideElts) == -1)
2836 if (Mask[i] < WideElts) {
2837 assert(Mask[i] < NarrowElts &&
"Unexpected shuffle mask");
2838 NewMask[i] = Mask[i];
2840 assert(Mask[i] < (WideElts + NarrowElts) &&
"Unexpected shuffle mask");
2841 NewMask[i] = Mask[i] - (WideElts - NarrowElts);
2863 if (
X->getType() !=
Y->getType())
2866 auto *BinOp = cast<BinaryOperator>(Op0);
2871 if (
auto NewBOI = dyn_cast<Instruction>(NewBO))
2872 NewBOI->copyIRFlags(BinOp);
2896 unsigned VWidth = cast<FixedVectorType>(SVI.
getType())->getNumElements();
2897 unsigned LHSWidth = cast<FixedVectorType>(
LHS->
getType())->getNumElements();
2908 X->getType()->isVectorTy() &&
X->getType() ==
Y->getType() &&
2909 X->getType()->getScalarSizeInBits() ==
2926 X->getType()->isVectorTy() && VWidth == LHSWidth) {
2928 auto *XType = cast<FixedVectorType>(
X->getType());
2929 unsigned XNumElts = XType->getNumElements();
2935 ScaledMask, XType, ShufQuery))
2943 "Shuffle with 2 undef ops not simplified?");
2971 APInt PoisonElts(VWidth, 0);
2990 if (
auto *SI = dyn_cast<SelectInst>(
LHS)) {
2993 if (SI->getCondition()->getType()->isIntegerTy() &&
2994 (isa<PoisonValue>(
RHS) ||
3000 if (
auto *PN = dyn_cast<PHINode>(
LHS)) {
3040 bool MadeChange =
false;
3043 unsigned MaskElems = Mask.size();
3044 auto *SrcTy = cast<FixedVectorType>(V->getType());
3047 assert(SrcElemBitWidth &&
"vector elements must have a bitwidth");
3048 unsigned SrcNumElems = SrcTy->getNumElements();
3054 if (BC->use_empty())
3057 if (BC->hasOneUse()) {
3058 auto *BC2 = dyn_cast<BitCastInst>(BC->user_back());
3059 if (BC2 && isEliminableCastPair(BC, BC2))
3065 unsigned BegIdx = Mask.front();
3066 Type *TgtTy = BC->getDestTy();
3068 if (!TgtElemBitWidth)
3070 unsigned TgtNumElems = VecBitWidth / TgtElemBitWidth;
3071 bool VecBitWidthsEqual = VecBitWidth == TgtNumElems * TgtElemBitWidth;
3072 bool BegIsAligned = 0 == ((SrcElemBitWidth * BegIdx) % TgtElemBitWidth);
3073 if (!VecBitWidthsEqual)
3078 if (!BegIsAligned) {
3082 for (
unsigned I = 0, E = MaskElems,
Idx = BegIdx;
I != E; ++
Idx, ++
I)
3083 ShuffleMask[
I] =
Idx;
3088 unsigned SrcElemsPerTgtElem = TgtElemBitWidth / SrcElemBitWidth;
3089 assert(SrcElemsPerTgtElem);
3090 BegIdx /= SrcElemsPerTgtElem;
3091 auto [It, Inserted] = NewBCs.
try_emplace(CastSrcTy);
3151 LHSShuffle =
nullptr;
3154 RHSShuffle =
nullptr;
3155 if (!LHSShuffle && !RHSShuffle)
3156 return MadeChange ? &SVI :
nullptr;
3158 Value* LHSOp0 =
nullptr;
3159 Value* LHSOp1 =
nullptr;
3160 Value* RHSOp0 =
nullptr;
3161 unsigned LHSOp0Width = 0;
3162 unsigned RHSOp0Width = 0;
3166 LHSOp0Width = cast<FixedVectorType>(LHSOp0->
getType())->getNumElements();
3170 RHSOp0Width = cast<FixedVectorType>(RHSOp0->
getType())->getNumElements();
3181 else if (LHSOp0Width == LHSWidth) {
3186 if (RHSShuffle && RHSOp0Width == LHSWidth) {
3190 if (LHSOp0 == RHSOp0) {
3195 if (newLHS ==
LHS && newRHS ==
RHS)
3196 return MadeChange ? &SVI :
nullptr;
3202 if (RHSShuffle && newRHS !=
RHS)
3205 unsigned newLHSWidth = (newLHS !=
LHS) ? LHSOp0Width : LHSWidth;
3211 for (
unsigned i = 0; i < VWidth; ++i) {
3216 }
else if (Mask[i] < (
int)LHSWidth) {
3221 if (newLHS !=
LHS) {
3222 eltMask = LHSMask[Mask[i]];
3225 if (eltMask >= (
int)LHSOp0Width && isa<PoisonValue>(LHSOp1))
3238 else if (newRHS !=
RHS) {
3239 eltMask = RHSMask[Mask[i]-LHSWidth];
3242 if (eltMask >= (
int)RHSOp0Width) {
3244 "should have been check above");
3248 eltMask = Mask[i]-LHSWidth;
3256 if (eltMask >= 0 && newRHS !=
nullptr && newLHS != newRHS)
3257 eltMask += newLHSWidth;
3262 if (SplatElt >= 0 && SplatElt != eltMask)
3272 if (
isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
3278 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
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file provides internal interfaces used to implement the InstCombine.
static Instruction * foldConstantInsEltIntoShuffle(InsertElementInst &InsElt)
insertelt (shufflevector X, CVec, Mask|insertelt X, C1, CIndex1), C, CIndex --> shufflevector X,...
static 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 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 APInt findDemandedEltsBySingleUser(Value *V, Instruction *UserInstr)
Find elements of V demanded by UserInstr.
static Instruction * foldShuffleOfUnaryOps(ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
Canonicalize FP negate/abs after shuffle.
static Instruction * foldCastShuffle(ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder)
Canonicalize casts after shuffle.
static Instruction * narrowInsElt(InsertElementInst &InsElt, InstCombiner::BuilderTy &Builder)
If both the base vector and the inserted element are extended from the same type, do the insert eleme...
static bool isShuffleEquivalentToSelect(ShuffleVectorInst &Shuf)
static Instruction * foldInsSequenceIntoSplat(InsertElementInst &InsElt)
Turn a chain of inserts that splats a value into an insert + shuffle: insertelt(insertelt(insertelt(i...
static Instruction * foldInsEltIntoIdentityShuffle(InsertElementInst &InsElt)
Try to fold an extract+insert element into an existing identity shuffle by changing the shuffle's mas...
static 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
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
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 std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static SDValue narrowVectorSelect(SDNode *N, SelectionDAG &DAG, const SDLoc &DL, const X86Subtarget &Subtarget)
If both arms of a vector select are concatenated vectors, split the select, and concatenate the resul...
static const uint32_t IV[8]
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
LLVM Basic Block Representation.
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...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
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...
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
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.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
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 * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false)
Given an instruction with a select as one operand and a constant as the other operand,...
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 * 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.
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
void addValue(Value *V)
Add value to the worklist if it is an instruction.
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, 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.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
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.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
LLVM_ABI unsigned getStructNumElements() const
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM_ABI uint64_t getArrayNumElements() const
static UnaryOperator * CreateWithCopiedFlags(UnaryOps Opc, Value *V, Instruction *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
UnaryOps getOpcode() const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
class_match< UnaryOperator > m_UnOp()
Match an arbitrary unary operation and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
auto m_Undef()
Match an arbitrary undef constant.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
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.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
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,...
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...
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)
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
SimplifyQuery getWithInstruction(const Instruction *I) const
A MapVector that performs no allocations if smaller than a certain size.