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))
479 (HasKnownValidIndex ||
495 CmpInst *SrcCmpInst = cast<CmpInst>(SrcVec);
500 if (
auto *
I = dyn_cast<Instruction>(SrcVec)) {
501 if (
auto *IE = dyn_cast<InsertElementInst>(
I)) {
505 if (isa<Constant>(IE->getOperand(2)) && IndexC)
507 }
else if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I)) {
508 auto *VecType = cast<VectorType>(
GEP->getType());
510 uint64_t IdxVal = IndexC ? IndexC->getZExtValue() : 0;
511 if (IndexC && IdxVal < EC.getKnownMinValue() &&
GEP->hasOneUse()) {
522 return isa<VectorType>(V->getType());
524 if (VectorOps == 1) {
525 Value *NewPtr =
GEP->getPointerOperand();
526 if (isa<VectorType>(NewPtr->
getType()))
530 for (
unsigned I = 1;
I !=
GEP->getNumOperands(); ++
I) {
532 if (isa<VectorType>(
Op->getType()))
539 GEP->getSourceElementType(), NewPtr, NewOps);
544 }
else if (
auto *SVI = dyn_cast<ShuffleVectorInst>(
I)) {
548 if (isa<FixedVectorType>(SVI->getType()) && isa<ConstantInt>(Index)) {
550 SVI->getMaskValue(cast<ConstantInt>(Index)->getZExtValue());
552 unsigned LHSWidth = cast<FixedVectorType>(SVI->getOperand(0)->getType())
557 if (SrcIdx < (
int)LHSWidth)
558 Src = SVI->getOperand(0);
561 Src = SVI->getOperand(1);
565 Src, ConstantInt::get(Int64Ty, SrcIdx,
false));
567 }
else if (
auto *CI = dyn_cast<CastInst>(
I)) {
571 if (CI->hasOneUse() && (CI->getOpcode() != Instruction::BitCast)) {
583 unsigned NumElts = EC.getKnownMinValue();
587 if (!EC.isScalable() && NumElts != 1) {
591 APInt PoisonElts(NumElts, 0);
592 APInt DemandedElts(NumElts, 0);
593 DemandedElts.
setBit(IndexC->getZExtValue());
602 APInt PoisonElts(NumElts, 0);
604 SrcVec, DemandedElts, PoisonElts, 0 ,
624 "Invalid CollectSingleShuffleElements");
625 unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
628 Mask.assign(NumElts, -1);
633 for (
unsigned i = 0; i != NumElts; ++i)
639 for (
unsigned i = 0; i != NumElts; ++i)
640 Mask.push_back(i + NumElts);
646 Value *VecOp = IEI->getOperand(0);
647 Value *ScalarOp = IEI->getOperand(1);
648 Value *IdxOp = IEI->getOperand(2);
650 if (!isa<ConstantInt>(IdxOp))
652 unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue();
654 if (isa<PoisonValue>(ScalarOp)) {
659 Mask[InsertedIdx] = -1;
664 unsigned ExtractedIdx =
665 cast<ConstantInt>(EI->
getOperand(1))->getZExtValue();
666 unsigned NumLHSElts =
667 cast<FixedVectorType>(
LHS->
getType())->getNumElements();
676 Mask[InsertedIdx % NumElts] = ExtractedIdx;
679 Mask[InsertedIdx % NumElts] = ExtractedIdx + NumLHSElts;
697 auto *InsVecType = cast<FixedVectorType>(InsElt->
getType());
699 unsigned NumInsElts = InsVecType->getNumElements();
700 unsigned NumExtElts = ExtVecType->getNumElements();
703 if (InsVecType->getElementType() != ExtVecType->getElementType() ||
704 NumExtElts >= NumInsElts)
712 for (
unsigned i = 0; i < NumExtElts; ++i)
714 for (
unsigned i = NumExtElts; i < NumInsElts; ++i)
718 auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
719 BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
732 if (InsertionBlock != InsElt->
getParent())
749 if (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
750 WideVec->insertAfter(ExtVecOpInst);
758 if (!OldExt || OldExt->
getParent() != WideVec->getParent())
784 assert(V->getType()->isVectorTy() &&
"Invalid shuffle!");
785 unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
788 Mask.assign(NumElts, -1);
789 return std::make_pair(
793 if (isa<ConstantAggregateZero>(V)) {
794 Mask.assign(NumElts, 0);
795 return std::make_pair(V,
nullptr);
800 Value *VecOp = IEI->getOperand(0);
801 Value *ScalarOp = IEI->getOperand(1);
802 Value *IdxOp = IEI->getOperand(2);
805 if (isa<ConstantInt>(EI->
getOperand(1)) && isa<ConstantInt>(IdxOp)) {
806 unsigned ExtractedIdx =
807 cast<ConstantInt>(EI->
getOperand(1))->getZExtValue();
808 unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getZExtValue();
812 if (EI->
getOperand(0) == PermittedRHS || PermittedRHS ==
nullptr) {
815 assert(LR.second ==
nullptr || LR.second ==
RHS);
825 for (
unsigned i = 0; i < NumElts; ++i)
827 return std::make_pair(V,
nullptr);
830 unsigned NumLHSElts =
831 cast<FixedVectorType>(
RHS->
getType())->getNumElements();
832 Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
833 return std::make_pair(LR.first,
RHS);
836 if (VecOp == PermittedRHS) {
839 unsigned NumLHSElts =
842 for (
unsigned i = 0; i != NumElts; ++i)
843 Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
844 return std::make_pair(EI->
getOperand(0), PermittedRHS);
852 return std::make_pair(EI->
getOperand(0), PermittedRHS);
858 for (
unsigned i = 0; i != NumElts; ++i)
860 return std::make_pair(V,
nullptr);
886 assert(NumAggElts > 0 &&
"Aggregate should have elements.");
890 static constexpr auto NotFound = std::nullopt;
891 static constexpr auto FoundMismatch =
nullptr;
898 auto KnowAllElts = [&AggElts]() {
906 static const int DepthLimit = 2 * NumAggElts;
911 Depth < DepthLimit && CurrIVI && !KnowAllElts();
912 CurrIVI = dyn_cast<InsertValueInst>(CurrIVI->getAggregateOperand()),
914 auto *InsertedValue =
915 dyn_cast<Instruction>(CurrIVI->getInsertedValueOperand());
922 if (Indices.
size() != 1)
928 std::optional<Instruction *> &Elt = AggElts[Indices.
front()];
929 Elt = Elt.value_or(InsertedValue);
942 enum class AggregateDescription {
958 auto Describe = [](std::optional<Value *> SourceAggregate) {
959 if (SourceAggregate == NotFound)
960 return AggregateDescription::NotFound;
961 if (*SourceAggregate == FoundMismatch)
962 return AggregateDescription::FoundMismatch;
963 return AggregateDescription::Found;
967 bool EltDefinedInUseBB =
false;
974 auto FindSourceAggregate =
975 [&](
Instruction *Elt,
unsigned EltIdx, std::optional<BasicBlock *> UseBB,
976 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
978 if (UseBB && PredBB) {
981 EltDefinedInUseBB =
true;
986 auto *EVI = dyn_cast_or_null<ExtractValueInst>(Elt);
990 Value *SourceAggregate = EVI->getAggregateOperand();
993 if (SourceAggregate->
getType() != AggTy)
994 return FoundMismatch;
996 if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
997 return FoundMismatch;
999 return SourceAggregate;
1005 auto FindCommonSourceAggregate =
1006 [&](std::optional<BasicBlock *> UseBB,
1007 std::optional<BasicBlock *> PredBB) -> std::optional<Value *> {
1008 std::optional<Value *> SourceAggregate;
1011 assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
1012 "We don't store nullptr in SourceAggregate!");
1013 assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
1015 "SourceAggregate should be valid after the first element,");
1020 std::optional<Value *> SourceAggregateForElement =
1021 FindSourceAggregate(*
I.value(),
I.index(), UseBB, PredBB);
1028 if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
1029 return SourceAggregateForElement;
1033 switch (Describe(SourceAggregate)) {
1034 case AggregateDescription::NotFound:
1036 SourceAggregate = SourceAggregateForElement;
1038 case AggregateDescription::Found:
1041 if (*SourceAggregateForElement != *SourceAggregate)
1042 return FoundMismatch;
1044 case AggregateDescription::FoundMismatch:
1049 assert(Describe(SourceAggregate) == AggregateDescription::Found &&
1050 "Must be a valid Value");
1051 return *SourceAggregate;
1054 std::optional<Value *> SourceAggregate;
1057 SourceAggregate = FindCommonSourceAggregate(std::nullopt,
1059 if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
1060 if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
1062 ++NumAggregateReconstructionsSimplified;
1075 for (
const std::optional<Instruction *> &
I : AggElts) {
1099 static const int PredCountLimit = 64;
1106 if (Preds.
size() >= PredCountLimit)
1115 bool FoundSrcAgg =
false;
1117 std::pair<
decltype(SourceAggregates)::iterator,
bool>
IV =
1118 SourceAggregates.
insert({Pred,
nullptr});
1126 SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
1127 if (Describe(SourceAggregate) == AggregateDescription::Found) {
1129 IV.first->second = *SourceAggregate;
1133 auto *BI = dyn_cast<BranchInst>(Pred->getTerminator());
1134 if (!BI || !BI->isUnconditional())
1143 auto OrigBB = OrigIVI.getParent();
1144 for (
auto &It : SourceAggregates) {
1145 if (Describe(It.second) == AggregateDescription::Found)
1149 if (EltDefinedInUseBB)
1157 if (UseBB != OrigBB)
1162 bool ConstAgg =
true;
1163 for (
auto Val : AggElts) {
1165 if (!isa<Constant>(Elt)) {
1176 for (
auto &It : SourceAggregates) {
1177 if (Describe(It.second) == AggregateDescription::Found)
1185 V = Builder.CreateInsertValue(V, Elt,
Idx);
1197 Builder.SetInsertPoint(UseBB, UseBB->getFirstNonPHIIt());
1199 Builder.CreatePHI(AggTy, Preds.size(), OrigIVI.getName() +
".merged");
1201 PHI->addIncoming(SourceAggregates[Pred], Pred);
1203 ++NumAggregateReconstructionsSimplified;
1204 return replaceInstUsesWith(OrigIVI,
PHI);
1216 I.getAggregateOperand(),
I.getInsertedValueOperand(),
I.getIndices(),
1220 bool IsRedundant =
false;
1229 while (V->hasOneUse() &&
Depth < 10) {
1230 User *U = V->user_back();
1231 auto UserInsInst = dyn_cast<InsertValueInst>(U);
1232 if (!UserInsInst || U->getOperand(0) != V)
1234 if (UserInsInst->getIndices() == FirstIndices) {
1262 if (MaskSize != VecSize)
1267 for (
int i = 0; i != MaskSize; ++i) {
1269 if (Elt != -1 && Elt != i && Elt != i + VecSize)
1288 if (isa<ScalableVectorType>(VecTy))
1290 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
1294 if (NumElements == 1)
1309 auto *NextIE = dyn_cast<InsertElementInst>(CurrIE->
getOperand(0));
1313 if (CurrIE != &InsElt &&
1314 (!CurrIE->
hasOneUse() && (NextIE !=
nullptr || !
Idx->isZero())))
1317 ElementPresent[
Idx->getZExtValue()] =
true;
1323 if (FirstIE == &InsElt)
1331 if (!ElementPresent.
all())
1337 Constant *Zero = ConstantInt::get(Int64Ty, 0);
1338 if (!cast<ConstantInt>(FirstIE->
getOperand(2))->isZero())
1344 for (
unsigned i = 0; i != NumElements; ++i)
1345 if (!ElementPresent[i])
1355 auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0));
1356 if (!Shuf || !Shuf->isZeroEltSplat())
1361 if (isa<ScalableVectorType>(Shuf->getType()))
1371 Value *Op0 = Shuf->getOperand(0);
1379 unsigned NumMaskElts =
1380 cast<FixedVectorType>(Shuf->getType())->getNumElements();
1382 for (
unsigned i = 0; i != NumMaskElts; ++i)
1383 NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
1392 auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0));
1394 !(Shuf->isIdentityWithExtract() || Shuf->isIdentityWithPadding()))
1399 if (isa<ScalableVectorType>(Shuf->getType()))
1410 Value *
X = Shuf->getOperand(0);
1418 unsigned NumMaskElts =
1419 cast<FixedVectorType>(Shuf->getType())->getNumElements();
1422 for (
unsigned i = 0; i != NumMaskElts; ++i) {
1425 NewMask[i] = OldMask[i];
1426 }
else if (OldMask[i] == (
int)IdxC) {
1432 "Unexpected shuffle mask element for identity shuffle");
1451 auto *InsElt1 = dyn_cast<InsertElementInst>(InsElt2.
getOperand(0));
1452 if (!InsElt1 || !InsElt1->hasOneUse())
1459 match(InsElt1->getOperand(1),
m_Value(
Y)) && !isa<Constant>(
Y) &&
1473 auto *Inst = dyn_cast<Instruction>(InsElt.
getOperand(0));
1476 if (!Inst || !Inst->hasOneUse())
1478 if (
auto *Shuf = dyn_cast<ShuffleVectorInst>(InsElt.
getOperand(0))) {
1481 Constant *ShufConstVec, *InsEltScalar;
1505 unsigned NumElts = Mask.size();
1508 for (
unsigned I = 0;
I != NumElts; ++
I) {
1509 if (
I == InsEltIndex) {
1510 NewShufElts[
I] = InsEltScalar;
1511 NewMaskElts[
I] = InsEltIndex + NumElts;
1515 NewMaskElts[
I] = Mask[
I];
1519 if (!NewShufElts[
I])
1527 }
else if (
auto *IEI = dyn_cast<InsertElementInst>(Inst)) {
1532 if (isa<ScalableVectorType>(InsElt.
getType()))
1535 cast<FixedVectorType>(InsElt.
getType())->getNumElements();
1546 auto ValI = std::begin(Val);
1553 Mask[
I] = NumElts +
I;
1558 for (
unsigned I = 0;
I < NumElts; ++
I) {
1590 CastOpcode = Instruction::FPExt;
1592 CastOpcode = Instruction::SExt;
1594 CastOpcode = Instruction::ZExt;
1599 if (
X->getType()->getScalarType() !=
Y->getType())
1626 auto *VTy = dyn_cast<FixedVectorType>(InsElt.
getType());
1627 Value *Scalar0, *BaseVec;
1629 if (!VTy || (VTy->getNumElements() & 1) ||
1638 if (Index0 + 1 != Index1 || Index0 & 1)
1655 Type *SrcTy =
X->getType();
1657 unsigned VecEltWidth = VTy->getScalarSizeInBits();
1658 if (ScalarWidth != VecEltWidth * 2 || ShAmt != VecEltWidth)
1667 uint64_t NewIndex = IsBigEndian ? Index1 / 2 : Index0 / 2;
1673 Value *VecOp = IE.getOperand(0);
1674 Value *ScalarOp = IE.getOperand(1);
1675 Value *IdxOp = IE.getOperand(2);
1682 if (
auto *IndexC = dyn_cast<ConstantInt>(IdxOp)) {
1686 Value *BaseVec, *OtherScalar;
1691 !isa<Constant>(OtherScalar) && OtherIndexVal > IndexC->getZExtValue()) {
1723 cast<VectorType>(VecSrc->
getType())->getElementType() ==
1735 uint64_t InsertedIdx, ExtractedIdx;
1737 if (isa<FixedVectorType>(IE.getType()) &&
1741 isa<FixedVectorType>(ExtVecOp->
getType()) &&
1743 cast<FixedVectorType>(ExtVecOp->
getType())->getNumElements()) {
1759 if (!Insert.hasOneUse())
1761 auto *InsertUser = dyn_cast<InsertElementInst>(Insert.user_back());
1768 if (isShuffleRootCandidate(IE)) {
1779 if (LR.first != &IE && LR.second != &IE) {
1781 if (LR.second ==
nullptr)
1789 if (
auto VecTy = dyn_cast<FixedVectorType>(VecOp->
getType())) {
1790 unsigned VWidth = VecTy->getNumElements();
1791 APInt PoisonElts(VWidth, 0);
1814 return IdentityShuf;
1828 unsigned Depth = 5) {
1830 if (isa<Constant>(V))
1835 if (!
I)
return false;
1838 if (!
I->hasOneUse())
1841 if (
Depth == 0)
return false;
1843 switch (
I->getOpcode()) {
1844 case Instruction::UDiv:
1845 case Instruction::SDiv:
1846 case Instruction::URem:
1847 case Instruction::SRem:
1854 case Instruction::Add:
1855 case Instruction::FAdd:
1856 case Instruction::Sub:
1857 case Instruction::FSub:
1858 case Instruction::Mul:
1859 case Instruction::FMul:
1860 case Instruction::FDiv:
1861 case Instruction::FRem:
1862 case Instruction::Shl:
1863 case Instruction::LShr:
1864 case Instruction::AShr:
1865 case Instruction::And:
1866 case Instruction::Or:
1867 case Instruction::Xor:
1868 case Instruction::ICmp:
1869 case Instruction::FCmp:
1870 case Instruction::Trunc:
1871 case Instruction::ZExt:
1872 case Instruction::SExt:
1873 case Instruction::FPToUI:
1874 case Instruction::FPToSI:
1875 case Instruction::UIToFP:
1876 case Instruction::SIToFP:
1877 case Instruction::FPTrunc:
1878 case Instruction::FPExt:
1879 case Instruction::GetElementPtr: {
1882 Type *ITy =
I->getType();
1884 Mask.size() > cast<FixedVectorType>(ITy)->getNumElements())
1886 for (
Value *Operand :
I->operands()) {
1892 case Instruction::InsertElement: {
1893 ConstantInt *CI = dyn_cast<ConstantInt>(
I->getOperand(2));
1894 if (!CI)
return false;
1899 bool SeenOnce =
false;
1900 for (
int I : Mask) {
1901 if (
I == ElementNumber) {
1918 switch (
I->getOpcode()) {
1919 case Instruction::Add:
1920 case Instruction::FAdd:
1921 case Instruction::Sub:
1922 case Instruction::FSub:
1923 case Instruction::Mul:
1924 case Instruction::FMul:
1925 case Instruction::UDiv:
1926 case Instruction::SDiv:
1927 case Instruction::FDiv:
1928 case Instruction::URem:
1929 case Instruction::SRem:
1930 case Instruction::FRem:
1931 case Instruction::Shl:
1932 case Instruction::LShr:
1933 case Instruction::AShr:
1934 case Instruction::And:
1935 case Instruction::Or:
1936 case Instruction::Xor: {
1938 assert(NewOps.
size() == 2 &&
"binary operator with #ops != 2");
1940 NewOps[0], NewOps[1]);
1941 if (
auto *NewI = dyn_cast<Instruction>(New)) {
1942 if (isa<OverflowingBinaryOperator>(BO)) {
1946 if (isa<PossiblyExactOperator>(BO)) {
1947 NewI->setIsExact(BO->
isExact());
1949 if (isa<FPMathOperator>(BO))
1950 NewI->copyFastMathFlags(
I);
1954 case Instruction::ICmp:
1955 assert(NewOps.
size() == 2 &&
"icmp with #ops != 2");
1956 return Builder.
CreateICmp(cast<ICmpInst>(
I)->getPredicate(), NewOps[0],
1958 case Instruction::FCmp:
1959 assert(NewOps.
size() == 2 &&
"fcmp with #ops != 2");
1960 return Builder.
CreateFCmp(cast<FCmpInst>(
I)->getPredicate(), NewOps[0],
1962 case Instruction::Trunc:
1963 case Instruction::ZExt:
1964 case Instruction::SExt:
1965 case Instruction::FPToUI:
1966 case Instruction::FPToSI:
1967 case Instruction::UIToFP:
1968 case Instruction::SIToFP:
1969 case Instruction::FPTrunc:
1970 case Instruction::FPExt: {
1974 I->getType()->getScalarType(),
1975 cast<VectorType>(NewOps[0]->getType())->getElementCount());
1976 assert(NewOps.
size() == 1 &&
"cast with #ops != 1");
1980 case Instruction::GetElementPtr: {
1983 return Builder.
CreateGEP(cast<GEPOperator>(
I)->getSourceElementType(),
1985 cast<GEPOperator>(
I)->isInBounds());
1995 assert(V->getType()->isVectorTy() &&
"can't reorder non-vector elements");
1996 Type *EltTy = V->getType()->getScalarType();
1998 if (isa<PoisonValue>(V))
2004 if (isa<ConstantAggregateZero>(V))
2007 if (
Constant *
C = dyn_cast<Constant>(V))
2012 switch (
I->getOpcode()) {
2013 case Instruction::Add:
2014 case Instruction::FAdd:
2015 case Instruction::Sub:
2016 case Instruction::FSub:
2017 case Instruction::Mul:
2018 case Instruction::FMul:
2019 case Instruction::UDiv:
2020 case Instruction::SDiv:
2021 case Instruction::FDiv:
2022 case Instruction::URem:
2023 case Instruction::SRem:
2024 case Instruction::FRem:
2025 case Instruction::Shl:
2026 case Instruction::LShr:
2027 case Instruction::AShr:
2028 case Instruction::And:
2029 case Instruction::Or:
2030 case Instruction::Xor:
2031 case Instruction::ICmp:
2032 case Instruction::FCmp:
2033 case Instruction::Trunc:
2034 case Instruction::ZExt:
2035 case Instruction::SExt:
2036 case Instruction::FPToUI:
2037 case Instruction::FPToSI:
2038 case Instruction::UIToFP:
2039 case Instruction::SIToFP:
2040 case Instruction::FPTrunc:
2041 case Instruction::FPExt:
2042 case Instruction::Select:
2043 case Instruction::GetElementPtr: {
2047 cast<FixedVectorType>(
I->getType())->getNumElements());
2048 for (
int i = 0, e =
I->getNumOperands(); i != e; ++i) {
2053 if (
I->getOperand(i)->getType()->isVectorTy())
2056 V =
I->getOperand(i);
2058 NeedsRebuild |= (V !=
I->getOperand(i));
2064 case Instruction::InsertElement: {
2065 int Element = cast<ConstantInt>(
I->getOperand(2))->getLimitedValue();
2072 for (
int e = Mask.size(); Index != e; ++Index) {
2073 if (Mask[Index] == Element) {
2103 unsigned MaskElems = Mask.size();
2104 unsigned BegIdx = Mask.front();
2105 unsigned EndIdx = Mask.back();
2106 if (BegIdx > EndIdx || EndIdx >= LHSElems || EndIdx - BegIdx != MaskElems - 1)
2108 for (
unsigned I = 0;
I != MaskElems; ++
I)
2109 if (
static_cast<unsigned>(Mask[
I]) != BegIdx +
I)
2122 Opcode(Opc), Op0(V0), Op1(V1) {}
2123 operator bool()
const {
return Opcode != 0; }
2134 case Instruction::Shl: {
2139 Instruction::Shl, ConstantInt::get(Ty, 1),
C,
DL);
2140 assert(ShlOne &&
"Constant folding of immediate constants failed");
2141 return {Instruction::Mul, BO0, ShlOne};
2145 case Instruction::Or: {
2147 if (cast<PossiblyDisjointInst>(BO)->isDisjoint())
2148 return {Instruction::Add, BO0, BO1};
2151 case Instruction::Sub:
2166 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2171 unsigned NumElts = Mask.size();
2174 auto *ShufOp = dyn_cast<ShuffleVectorInst>(Op0);
2175 if (ShufOp && ShufOp->isSelect() &&
2176 (ShufOp->getOperand(0) == Op1 || ShufOp->getOperand(1) == Op1)) {
2181 ShufOp = dyn_cast<ShuffleVectorInst>(Op1);
2182 if (!ShufOp || !ShufOp->isSelect() ||
2183 (ShufOp->getOperand(0) != Op0 && ShufOp->getOperand(1) != Op0))
2186 Value *
X = ShufOp->getOperand(0), *
Y = ShufOp->getOperand(1);
2188 ShufOp->getShuffleMask(Mask1);
2189 assert(Mask1.
size() == NumElts &&
"Vector size changed with select shuffle");
2202 for (
unsigned i = 0; i != NumElts; ++i)
2203 NewMask[i] = Mask[i] < (
signed)NumElts ? Mask[i] : Mask1[i];
2208 "Unexpected shuffle mask");
2214 assert(Shuf.
isSelect() &&
"Must have select-equivalent shuffle");
2231 auto *BO = cast<BinaryOperator>(Op0IsBinop ? Op0 : Op1);
2237 Value *
X = Op0IsBinop ? Op1 : Op0;
2258 bool MightCreatePoisonOrUB =
2261 if (MightCreatePoisonOrUB)
2302 unsigned NumMaskElts =
2303 cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2305 for (
unsigned i = 0; i != NumMaskElts; ++i)
2307 NewMask[i] = Mask[i];
2319 unsigned NumElts = cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2344 Constant *C0 =
nullptr, *C1 =
nullptr;
2345 bool ConstantsAreOp1;
2348 ConstantsAreOp1 =
false;
2353 ConstantsAreOp1 =
true;
2360 bool DropNSW =
false;
2361 if (ConstantsAreOp1 && Opc0 != Opc1) {
2365 if (Opc0 == Instruction::Shl || Opc1 == Instruction::Shl)
2368 assert(isa<Constant>(AltB0.Op1) &&
"Expecting constant with alt binop");
2369 Opc0 = AltB0.Opcode;
2370 C0 = cast<Constant>(AltB0.Op1);
2372 assert(isa<Constant>(AltB1.Op1) &&
"Expecting constant with alt binop");
2373 Opc1 = AltB1.Opcode;
2374 C1 = cast<Constant>(AltB1.Op1);
2378 if (Opc0 != Opc1 || !C0 || !C1)
2391 bool MightCreatePoisonOrUB =
2394 if (MightCreatePoisonOrUB)
2417 if (MightCreatePoisonOrUB && !ConstantsAreOp1)
2438 if (
auto *NewI = dyn_cast<Instruction>(NewBO)) {
2439 NewI->copyIRFlags(B0);
2440 NewI->andIRFlags(B1);
2442 NewI->setHasNoSignedWrap(
false);
2444 NewI->dropPoisonGeneratingFlags();
2463 Type *SrcType =
X->getType();
2465 cast<FixedVectorType>(SrcType)->getNumElements() !=
2466 cast<FixedVectorType>(DestType)->getNumElements() ||
2471 "Expected a shuffle that decreases length");
2478 for (
unsigned i = 0, e = Mask.size(); i != e; ++i) {
2481 uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
2482 assert(LSBIndex <= INT32_MAX &&
"Overflowed 32-bits");
2483 if (Mask[i] != (
int)LSBIndex)
2509 unsigned NarrowNumElts =
2510 cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2513 cast<FixedVectorType>(NarrowCond->
getType())->getNumElements() !=
2515 !cast<ShuffleVectorInst>(
Cond)->isIdentityWithPadding())
2529 auto *S0 = dyn_cast<Instruction>(Shuf.
getOperand(0));
2534 bool IsFNeg = S0->getOpcode() == Instruction::FNeg;
2554 S0->getOpcode() !=
S1->getOpcode() ||
2555 (!S0->hasOneUse() && !
S1->hasOneUse()))
2562 NewF = UnaryOperator::CreateFNeg(NewShuf);
2577 auto *Cast0 = dyn_cast<CastInst>(Shuf.
getOperand(0));
2578 auto *Cast1 = dyn_cast<CastInst>(Shuf.
getOperand(1));
2579 if (!Cast0 || !Cast1 || Cast0->getOpcode() != Cast1->getOpcode() ||
2580 Cast0->getSrcTy() != Cast1->getSrcTy())
2586 switch (CastOpcode) {
2587 case Instruction::FPToSI:
2588 case Instruction::FPToUI:
2589 case Instruction::SIToFP:
2590 case Instruction::UIToFP:
2598 VectorType *CastSrcTy = cast<VectorType>(Cast0->getSrcTy());
2601 if (ShufTy->getElementCount().getKnownMinValue() >
2602 ShufOpTy->getElementCount().getKnownMinValue())
2606 assert(isa<FixedVectorType>(CastSrcTy) && isa<FixedVectorType>(ShufOpTy) &&
2607 "Expected fixed vector operands for casts and binary shuffle");
2608 if (CastSrcTy->getPrimitiveSizeInBits() > ShufOpTy->getPrimitiveSizeInBits())
2612 if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
2616 Value *
X = Cast0->getOperand(0);
2617 Value *
Y = Cast1->getOperand(0);
2632 X->getType()->getPrimitiveSizeInBits() ==
2658 unsigned NumElts = cast<FixedVectorType>(Shuf.
getType())->getNumElements();
2660 assert(NumElts < Mask.size() &&
2661 "Identity with extract must have less elements than its inputs");
2663 for (
unsigned i = 0; i != NumElts; ++i) {
2665 int MaskElt = Mask[i];
2666 NewMask[i] = ExtractMaskElt ==
PoisonMaskElem ? ExtractMaskElt : MaskElt;
2679 int NumElts = Mask.size();
2680 int InpNumElts = cast<FixedVectorType>(V0->
getType())->getNumElements();
2705 if (NumElts != InpNumElts)
2709 auto isShufflingScalarIntoOp1 = [&](
Value *&Scalar,
ConstantInt *&IndexC) {
2717 int NewInsIndex = -1;
2718 for (
int i = 0; i != NumElts; ++i) {
2724 if (Mask[i] == NumElts + i)
2728 if (NewInsIndex != -1 || Mask[i] != IndexC->getSExtValue())
2735 assert(NewInsIndex != -1 &&
"Did not fold shuffle with unused operand?");
2738 IndexC = ConstantInt::get(IndexC->getIntegerType(), NewInsIndex);
2747 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2755 if (isShufflingScalarIntoOp1(Scalar, IndexC))
2765 auto *Shuffle0 = dyn_cast<ShuffleVectorInst>(Shuf.
getOperand(0));
2766 auto *Shuffle1 = dyn_cast<ShuffleVectorInst>(Shuf.
getOperand(1));
2767 if (!Shuffle0 || !Shuffle0->isIdentityWithPadding() ||
2768 !Shuffle1 || !Shuffle1->isIdentityWithPadding())
2776 Value *
X = Shuffle0->getOperand(0);
2777 Value *
Y = Shuffle1->getOperand(0);
2778 if (
X->getType() !=
Y->getType() ||
2781 cast<FixedVectorType>(Shuffle0->getType())->getNumElements()) ||
2782 !
isPowerOf2_32(cast<FixedVectorType>(
X->getType())->getNumElements()) ||
2787 "Unexpected operand for identity shuffle");
2793 int NarrowElts = cast<FixedVectorType>(
X->getType())->getNumElements();
2794 int WideElts = cast<FixedVectorType>(Shuffle0->getType())->getNumElements();
2795 assert(WideElts > NarrowElts &&
"Unexpected types for identity with padding");
2799 for (
int i = 0, e = Mask.size(); i != e; ++i) {
2805 if (Mask[i] < WideElts) {
2806 if (Shuffle0->getMaskValue(Mask[i]) == -1)
2809 if (Shuffle1->getMaskValue(Mask[i] - WideElts) == -1)
2816 if (Mask[i] < WideElts) {
2817 assert(Mask[i] < NarrowElts &&
"Unexpected shuffle mask");
2818 NewMask[i] = Mask[i];
2820 assert(Mask[i] < (WideElts + NarrowElts) &&
"Unexpected shuffle mask");
2821 NewMask[i] = Mask[i] - (WideElts - NarrowElts);
2843 if (
X->getType() !=
Y->getType())
2846 auto *BinOp = cast<BinaryOperator>(Op0);
2851 if (
auto NewBOI = dyn_cast<Instruction>(NewBO))
2852 NewBOI->copyIRFlags(BinOp);
2876 unsigned VWidth = cast<FixedVectorType>(SVI.
getType())->getNumElements();
2877 unsigned LHSWidth = cast<FixedVectorType>(
LHS->
getType())->getNumElements();
2888 X->getType()->isVectorTy() &&
X->getType() ==
Y->getType() &&
2889 X->getType()->getScalarSizeInBits() ==
2906 X->getType()->isVectorTy() && VWidth == LHSWidth) {
2908 auto *XType = cast<FixedVectorType>(
X->getType());
2909 unsigned XNumElts = XType->getNumElements();
2915 ScaledMask, XType, ShufQuery))
2923 "Shuffle with 2 undef ops not simplified?");
2951 APInt PoisonElts(VWidth, 0);
2970 if (
auto *SI = dyn_cast<SelectInst>(
LHS)) {
2973 if (SI->getCondition()->getType()->isIntegerTy() &&
2974 (isa<PoisonValue>(
RHS) ||
2980 if (
auto *PN = dyn_cast<PHINode>(
LHS)) {
3020 bool MadeChange =
false;
3023 unsigned MaskElems = Mask.size();
3024 auto *SrcTy = cast<FixedVectorType>(V->getType());
3025 unsigned VecBitWidth = SrcTy->getPrimitiveSizeInBits().getFixedValue();
3027 assert(SrcElemBitWidth &&
"vector elements must have a bitwidth");
3028 unsigned SrcNumElems = SrcTy->getNumElements();
3033 if (!BC->use_empty())
3037 unsigned BegIdx = Mask.front();
3038 Type *TgtTy = BC->getDestTy();
3040 if (!TgtElemBitWidth)
3042 unsigned TgtNumElems = VecBitWidth / TgtElemBitWidth;
3043 bool VecBitWidthsEqual = VecBitWidth == TgtNumElems * TgtElemBitWidth;
3044 bool BegIsAligned = 0 == ((SrcElemBitWidth * BegIdx) % TgtElemBitWidth);
3045 if (!VecBitWidthsEqual)
3050 if (!BegIsAligned) {
3054 for (
unsigned I = 0, E = MaskElems,
Idx = BegIdx;
I != E; ++
Idx, ++
I)
3055 ShuffleMask[
I] =
Idx;
3060 unsigned SrcElemsPerTgtElem = TgtElemBitWidth / SrcElemBitWidth;
3061 assert(SrcElemsPerTgtElem);
3062 BegIdx /= SrcElemsPerTgtElem;
3063 bool BCAlreadyExists = NewBCs.
contains(CastSrcTy);
3068 if (!BCAlreadyExists)
3069 NewBCs[CastSrcTy] = NewBC;
3127 LHSShuffle =
nullptr;
3130 RHSShuffle =
nullptr;
3131 if (!LHSShuffle && !RHSShuffle)
3132 return MadeChange ? &SVI :
nullptr;
3134 Value* LHSOp0 =
nullptr;
3135 Value* LHSOp1 =
nullptr;
3136 Value* RHSOp0 =
nullptr;
3137 unsigned LHSOp0Width = 0;
3138 unsigned RHSOp0Width = 0;
3142 LHSOp0Width = cast<FixedVectorType>(LHSOp0->
getType())->getNumElements();
3146 RHSOp0Width = cast<FixedVectorType>(RHSOp0->
getType())->getNumElements();
3157 else if (LHSOp0Width == LHSWidth) {
3162 if (RHSShuffle && RHSOp0Width == LHSWidth) {
3166 if (LHSOp0 == RHSOp0) {
3171 if (newLHS ==
LHS && newRHS ==
RHS)
3172 return MadeChange ? &SVI :
nullptr;
3178 if (RHSShuffle && newRHS !=
RHS)
3181 unsigned newLHSWidth = (newLHS !=
LHS) ? LHSOp0Width : LHSWidth;
3187 for (
unsigned i = 0; i < VWidth; ++i) {
3192 }
else if (Mask[i] < (
int)LHSWidth) {
3197 if (newLHS !=
LHS) {
3198 eltMask = LHSMask[Mask[i]];
3201 if (eltMask >= (
int)LHSOp0Width && isa<PoisonValue>(LHSOp1))
3214 else if (newRHS !=
RHS) {
3215 eltMask = RHSMask[Mask[i]-LHSWidth];
3218 if (eltMask >= (
int)RHSOp0Width) {
3220 "should have been check above");
3224 eltMask = Mask[i]-LHSWidth;
3232 if (eltMask >= 0 && newRHS !=
nullptr && newLHS != newRHS)
3233 eltMask += newLHSWidth;
3238 if (SplatElt >= 0 && SplatElt != eltMask)
3248 if (
isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
3254 return MadeChange ? &SVI :
nullptr;
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the SmallBitVector class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static SDValue narrowVectorSelect(SDNode *N, SelectionDAG &DAG, const 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.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
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 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.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static 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 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 ConstantAggregateZero * get(Type *Ty)
static Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
This is the shared class of boolean and integer constants.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
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 Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
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:
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static 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)
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this 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 * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
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.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
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.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
A wrapper class for inspecting calls to intrinsic functions.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
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 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 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...
bool isIdentityWithExtract() const
Return true if this shuffle extracts the first N elements of exactly one source vector.
static void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
bool isSelect() const
Return true if this shuffle chooses elements from its source vectors without lane crossings and all o...
static 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 ...
void commute()
Swap the operands and adjust the mask to preserve the semantics of the instruction.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool all() const
Returns true if all bits are set.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
unsigned getStructNumElements() const
uint64_t getArrayNumElements() const
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
static UnaryOperator * CreateWithCopiedFlags(UnaryOps Opc, Value *V, Instruction *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
UnaryOps getOpcode() const
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static 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.
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
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.
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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.
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.
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I)
Don't use information from its non-constant operands.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
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 ...
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.
Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an InsertValueInst, fold the result or return null.
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
Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
Value * simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, const SimplifyQuery &Q)
Given operands for an InsertElement, fold the result or return null.
constexpr unsigned BitWidth
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool pred_empty(const BasicBlock *BB)
bool isKnownNeverNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
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.
Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q)
Given operands for an ExtractElementInst, fold the result or return null.
bool scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Attempt to narrow/widen the Mask shuffle mask to the NumDstElts target width.
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