21#define DEBUG_TYPE "instcombine"
39 unsigned MaximalPossibleTotalShiftAmount =
42 APInt MaximalRepresentableShiftAmount =
44 return MaximalRepresentableShiftAmount.
uge(MaximalPossibleTotalShiftAmount);
60 bool AnalyzeForSignBitExtraction) {
72 Value *Trunc =
nullptr;
91 if (AnalyzeForSignBitExtraction && !HadTwoRightShifts)
98 if (!IdenticalShOpcodes && !AnalyzeForSignBitExtraction)
104 if (Trunc && !AnalyzeForSignBitExtraction &&
111 SQ.getWithInstruction(Sh0)));
114 unsigned NewShAmtBitWidth = NewShAmt->getType()->getScalarSizeInBits();
115 unsigned XBitWidth =
X->getType()->getScalarSizeInBits();
118 APInt(NewShAmtBitWidth, XBitWidth))))
126 if (HadTwoRightShifts && (Trunc || AnalyzeForSignBitExtraction)) {
130 APInt(NewShAmtBitWidth, XBitWidth - 1))))
133 if (AnalyzeForSignBitExtraction)
137 assert(IdenticalShOpcodes &&
"Should not get here with different shifts.");
139 if (NewShAmt->getType() !=
X->getType()) {
141 X->getType(),
SQ.DL);
153 if (ShiftOpcode == Instruction::BinaryOps::Shl) {
193 "The input must be 'shl'!");
208 bool HadTrunc = WidestTy != NarrowestTy;
244 MaskShAmt, ShiftShAmt,
false,
false, Q));
255 SumOfShAmts, ConstantInt::get(SumOfShAmts->getType()->getScalarType(),
258 Instruction::ZExt, SumOfShAmts, ExtendedTy, Q.
DL);
259 if (!ExtendedSumOfShAmts)
265 Instruction::Shl, ExtendedAllOnes, ExtendedSumOfShAmts, Q.
DL);
266 if (!ExtendedInvertedMask)
283 ShiftShAmt, MaskShAmt,
false,
false, Q));
297 -(
int)WidestTyBitWidth));
305 if (!ExtendedNumHighBitsToClear)
311 ExtendedNumHighBitsToClear, Q.
DL);
335 X = Builder.CreateTrunc(
X, NarrowestTy);
344 Builder.Insert(NewShift);
355 assert(
I.isShift() &&
"Expected a shift as input");
358 (!BinInst->isBitwiseLogicOp() &&
359 BinInst->getOpcode() != Instruction::Add &&
360 BinInst->getOpcode() != Instruction::Sub) ||
361 !BinInst->hasOneUse())
370 if ((BinInst->getOpcode() == Instruction::Add ||
371 BinInst->getOpcode() == Instruction::Sub) &&
372 ShiftOpcode != Instruction::Shl)
375 Type *Ty =
I.getType();
380 auto matchFirstShift = [&](
Value *V,
Value *W) {
381 unsigned Size = Ty->getScalarSizeInBits();
392 bool FirstShiftIsOp1 =
false;
393 if (matchFirstShift(BinInst->getOperand(0), BinInst->getOperand(1)))
394 Y = BinInst->getOperand(1);
395 else if (matchFirstShift(BinInst->getOperand(1), BinInst->getOperand(0))) {
396 Y = BinInst->getOperand(0);
397 FirstShiftIsOp1 = BinInst->getOpcode() == Instruction::Sub;
403 Value *NewShift1 = Builder.CreateBinOp(ShiftOpcode,
X, ShiftSumC);
404 Value *NewShift2 = Builder.CreateBinOp(ShiftOpcode,
Y, C1);
405 Value *Op1 = FirstShiftIsOp1 ? NewShift2 : NewShift1;
406 Value *Op2 = FirstShiftIsOp1 ? NewShift1 : NewShift2;
414 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
416 Type *Ty =
I.getType();
452 if (
I.getOpcode() == Instruction::Shl) {
461 unsigned BitWidth = Ty->getScalarSizeInBits();
471 assert(!
AC->isZero() &&
"Expected simplify of shifted zero");
472 unsigned PosOffset = (-*AddC).getZExtValue();
474 auto isSuitableForPreShift = [PosOffset, &
I,
AC]() {
475 switch (
I.getOpcode()) {
478 case Instruction::Shl:
479 return (
I.hasNoSignedWrap() ||
I.hasNoUnsignedWrap()) &&
480 AC->eq(
AC->lshr(PosOffset).shl(PosOffset));
481 case Instruction::LShr:
482 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).lshr(PosOffset));
483 case Instruction::AShr:
484 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).ashr(PosOffset));
487 if (isSuitableForPreShift()) {
488 Constant *NewC = ConstantInt::get(Ty,
I.getOpcode() == Instruction::Shl
489 ?
AC->lshr(PosOffset)
490 :
AC->shl(PosOffset));
493 if (
I.getOpcode() == Instruction::Shl) {
521 if ((
I.getOpcode() == Instruction::LShr ||
522 I.getOpcode() == Instruction::AShr) &&
546 const APInt *InnerShiftConst;
553 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
554 if (IsInnerShl == IsOuterShl)
560 if (*InnerShiftConst == OuterShAmt)
570 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
573 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
599 if (!
I)
return false;
603 if (!
I->hasOneUse())
return false;
605 switch (
I->getOpcode()) {
606 default:
return false;
607 case Instruction::And:
608 case Instruction::Or:
609 case Instruction::Xor:
614 case Instruction::Shl:
615 case Instruction::LShr:
618 case Instruction::Select: {
620 Value *TrueVal =
SI->getTrueValue();
621 Value *FalseVal =
SI->getFalseValue();
625 case Instruction::PHI: {
635 case Instruction::Mul: {
636 const APInt *MulConst;
638 return !IsLeftShift &&
match(
I->getOperand(1),
m_APInt(MulConst)) &&
649 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
659 auto NewInnerShift = [&](
unsigned ShAmt) {
660 InnerShift->
setOperand(1, ConstantInt::get(ShType, ShAmt));
673 if (IsInnerShl == IsOuterShl) {
675 if (InnerShAmt + OuterShAmt >= TypeWidth)
678 return NewInnerShift(InnerShAmt + OuterShAmt);
684 if (InnerShAmt == OuterShAmt) {
685 APInt Mask = IsInnerShl
689 ConstantInt::get(ShType, Mask));
692 AndI->takeName(InnerShift);
697 assert(InnerShAmt > OuterShAmt &&
698 "Unexpected opposite direction logical shift pair");
704 return NewInnerShift(InnerShAmt - OuterShAmt);
722 switch (
I->getOpcode()) {
724 case Instruction::And:
725 case Instruction::Or:
726 case Instruction::Xor:
734 case Instruction::Shl:
735 case Instruction::LShr:
739 case Instruction::Select:
745 case Instruction::PHI: {
752 isLeftShift, IC,
DL));
755 case Instruction::Mul: {
756 assert(!isLeftShift &&
"Unexpected shift direction!");
759 unsigned TypeWidth =
I->getType()->getScalarSizeInBits();
761 auto *
And = BinaryOperator::CreateAnd(Neg,
762 ConstantInt::get(
I->getType(), Mask));
776 case Instruction::Add:
777 return Shift.
getOpcode() == Instruction::Shl;
778 case Instruction::Or:
779 case Instruction::And:
781 case Instruction::Xor:
794 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
797 I.getOpcode(),
Builder.CreateBinOp(
I.getOpcode(), C2, C1),
X);
800 R->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap() &&
804 R->setIsExact(
I.isExact() && BO0->
isExact());
808 Type *Ty =
I.getType();
809 unsigned TypeBits = Ty->getScalarSizeInBits();
817 Constant *NegDivC = ConstantInt::get(Ty, -(*DivC));
821 auto ExtOpcode = (
I.getOpcode() == Instruction::AShr) ? Instruction::SExt
831 "Shift over the type width should have been removed already");
835 if (
I.getOpcode() != Instruction::AShr &&
838 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
839 " to eliminate shift:\n IN: "
840 << *Op0 <<
"\n SH: " <<
I <<
"\n");
859 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(1), C1);
862 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(0), C1);
890 Value *NewShift =
Builder.CreateBinOp(
I.getOpcode(), FalseVal, C1);
907 Value *NewShift =
Builder.CreateBinOp(
I.getOpcode(), TrueVal, C1);
928 assert(
I.getOpcode() == Instruction::LShr);
931 Value *ShiftAmt =
I.getOperand(1);
932 Type *Ty =
I.getType();
934 if (Ty->getScalarSizeInBits() < 3)
937 const APInt *ShAmtAPInt =
nullptr;
938 Value *
X =
nullptr, *
Y =
nullptr;
949 if (
X->getType()->getScalarSizeInBits() != ShAmt ||
950 Y->getType()->getScalarSizeInBits() != ShAmt)
954 if (!
Add->hasOneUse()) {
968 Builder.SetInsertPoint(AddInst);
972 Builder.CreateICmpULT(NarrowAdd,
X,
"add.narrowed.overflow");
977 if (!
Add->hasOneUse()) {
983 return new ZExtInst(Overflow, Ty);
988 assert(
I.isShift() &&
"Expected a shift as input");
990 if (
I.getOpcode() == Instruction::Shl) {
991 if (
I.hasNoUnsignedWrap() &&
I.hasNoSignedWrap())
1020 if (
I.getOpcode() == Instruction::Shl) {
1023 I.setHasNoUnsignedWrap();
1027 if (!
I.hasNoSignedWrap()) {
1031 I.setHasNoSignedWrap();
1050 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
1062 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1063 Type *Ty =
I.getType();
1064 unsigned BitWidth = Ty->getScalarSizeInBits();
1068 unsigned ShAmtC =
C->getZExtValue();
1074 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1075 if (ShAmtC < SrcWidth &&
1083 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1090 if (ShrAmt < ShAmtC) {
1092 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1093 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1094 NewShl->setHasNoUnsignedWrap(
1095 I.hasNoUnsignedWrap() ||
1098 I.hasNoSignedWrap()));
1099 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1102 if (ShrAmt > ShAmtC) {
1104 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1107 NewShr->setIsExact(
true);
1115 if (ShrAmt < ShAmtC) {
1117 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1118 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1119 NewShl->setHasNoUnsignedWrap(
1120 I.hasNoUnsignedWrap() ||
1123 I.hasNoSignedWrap()));
1124 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1127 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1129 if (ShrAmt > ShAmtC) {
1131 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1135 NewShr->setIsExact(OldShr->isExact());
1138 return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
1148 unsigned ShDiff = ShrAmtC > ShAmtC ? ShrAmtC - ShAmtC : ShAmtC - ShrAmtC;
1149 Constant *ShiftDiffC = ConstantInt::get(
X->getType(), ShDiff);
1150 auto ShiftOpc = ShrAmtC > ShAmtC ? Shr->
getOpcode() : Instruction::Shl;
1156 Value *NewShift =
Builder.CreateBinOp(ShiftOpc,
X, ShiftDiffC,
"sh.diff");
1157 Value *Trunc =
Builder.CreateTrunc(NewShift, Ty,
"tr.sh.diff");
1159 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, Mask));
1165 switch (BinOpcode) {
1168 case Instruction::Add:
1169 case Instruction::And:
1170 case Instruction::Or:
1171 case Instruction::Xor:
1172 case Instruction::Sub:
1180 isSuitableBinOpcode(Op0BO->
getOpcode())) {
1201 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1203 Constant *Mask = ConstantInt::get(Ty, Bits);
1204 return BinaryOperator::CreateAnd(
B, Mask);
1215 X->getName() +
".mask");
1218 Disjoint && Disjoint->isDisjoint())
1228 return BinaryOperator::CreateSub(NewLHS, NewShift);
1241 return BinaryOperator::CreateAnd(Mask,
X);
1247 return BinaryOperator::CreateShl(
AllOnes, Op1);
1256 return BinaryOperator::CreateMul(
X,
Builder.CreateShl(C2, C1));
1260 auto *NewC =
Builder.CreateShl(ConstantInt::get(Ty, 1), C1);
1261 return createSelectInstWithUnknownProfile(
X, NewC,
1269 return BinaryOperator::CreateLShr(
1277 return BinaryOperator::CreateAnd(NegX,
X);
1286 SQ.getWithInstruction(&
I)))
1295 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1296 Type *Ty =
I.getType();
1299 unsigned BitWidth = Ty->getScalarSizeInBits();
1312 auto *NewSub = BinaryOperator::CreateNUWSub(
X, NewLshr);
1313 NewSub->setHasNoSignedWrap(
1322 return BinaryOperator::CreateAnd(
X,
Y);
1329 auto *NewSub = BinaryOperator::CreateNUWSub(NewLshr,
Y);
1330 NewSub->setHasNoSignedWrap(
1336 switch (BinOpcode) {
1339 case Instruction::Add:
1340 case Instruction::And:
1341 case Instruction::Or:
1342 case Instruction::Xor:
1353 if (isSuitableBinOpcode(Op0OB->
getOpcode())) {
1355 !OBO || OBO->hasNoUnsignedWrap()) {
1357 Y, Op1,
"",
I.isExact() && Op0OB->
getOpcode() != Instruction::And);
1360 NewBinOp->setHasNoUnsignedWrap(
true);
1361 NewBinOp->setHasNoSignedWrap(OBO->hasNoSignedWrap());
1364 Disjoint->isDisjoint());
1372 unsigned ShAmtC =
C->getZExtValue();
1375 (
II->getIntrinsicID() == Intrinsic::ctlz ||
1376 II->getIntrinsicID() == Intrinsic::cttz ||
1377 II->getIntrinsicID() == Intrinsic::ctpop)) {
1381 bool IsPop =
II->getIntrinsicID() == Intrinsic::ctpop;
1389 if (C1->
ult(ShAmtC)) {
1391 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShlAmtC);
1394 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1395 NewLShr->setIsExact(
I.isExact());
1400 Value *NewLShr =
Builder.CreateLShr(
X, ShiftDiff,
"",
I.isExact());
1402 return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
1404 }
else if (C1->
ugt(ShAmtC)) {
1406 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmtC - ShAmtC);
1409 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1410 NewShl->setHasNoUnsignedWrap(
true);
1411 NewShl->setHasNoSignedWrap(ShAmtC > 0);
1418 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1424 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1436 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1438 Constant *Mask = ConstantInt::get(Ty, Bits);
1439 return BinaryOperator::CreateAnd(NewAdd, Mask);
1443 (!Ty->isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1445 "Big shift not simplified to zero?");
1452 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1454 if (SrcTyBitWidth == 1) {
1455 auto *NewC = ConstantInt::get(
1460 if ((!Ty->isIntegerTy() || shouldChangeType(Ty,
X->getType())) &&
1470 if (ShAmtC ==
BitWidth - SrcTyBitWidth) {
1472 unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1492 return BinaryOperator::CreateAnd(Signbit,
X);
1504 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1512 if (AmtSum < SrcWidth &&
1514 Value *SumShift =
Builder.CreateLShr(
X, AmtSum,
"sum.shift");
1515 Value *Trunc =
Builder.CreateTrunc(SumShift, Ty,
I.getName());
1520 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, MaskC));
1526 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1536 auto *NewAdd = BinaryOperator::CreateNUWAdd(
1537 X,
Builder.CreateLShr(
X, ConstantInt::get(Ty, ShAmtC),
"",
1539 NewAdd->setHasNoSignedWrap(
1552 if (MulC->
eq(NewMulC.
shl(ShAmtC))) {
1554 BinaryOperator::CreateNUWMul(
X, ConstantInt::get(Ty, NewMulC));
1556 "lshr X, 0 should be handled by simplifyLShrInst.");
1557 NewMul->setHasNoSignedWrap(
true);
1565 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1567 return BinaryOperator::CreateNSWAdd(
1568 X,
Builder.CreateLShr(
X, ConstantInt::get(Ty, ShAmtC),
"",
1578 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1579 unsigned WidthDiff =
BitWidth - SrcWidth;
1580 if (SrcWidth % 16 == 0) {
1581 Value *NarrowSwap =
Builder.CreateUnaryIntrinsic(Intrinsic::bswap,
X);
1582 if (ShAmtC >= WidthDiff) {
1584 Value *NewShift =
Builder.CreateLShr(NarrowSwap, ShAmtC - WidthDiff);
1589 Constant *ShiftDiff = ConstantInt::get(Ty, WidthDiff - ShAmtC);
1590 return BinaryOperator::CreateShl(NewZExt, ShiftDiff);
1597 Value *BoolX, *BoolY;
1602 (
X->hasOneUse() ||
Y->hasOneUse() || Op0->
hasOneUse())) {
1616 return BinaryOperator::CreateAnd(Mask,
X);
1622 return BinaryOperator::CreateLShr(
AllOnes, Op1);
1629 Value *Shl0_Op0, *Shl0_Op1, *Shl1_Op1;
1638 if (HasNUW || HasNSW) {
1640 Shl0_Op1,
"", HasNUW, HasNSW);
1641 return BinaryOperator::CreateLShr(NewShl, Shl1_Op1);
1651 "Must be called with arithmetic right-shift instruction only.");
1657 APInt(
C->getType()->getScalarSizeInBits(),
1658 V->getType()->getScalarSizeInBits())));
1666 if (!
match(&OldAShr,
1672 !BitWidthSplat(C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1678 bool HadTrunc = MaybeTrunc != HighBitExtract;
1681 Value *
X, *NumLowBitsToSkip;
1687 if (!
match(NumLowBitsToSkip,
1690 !BitWidthSplat(C0, HighBitExtract))
1718 SQ.getWithInstruction(&
I)))
1727 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1728 Type *Ty =
I.getType();
1729 unsigned BitWidth = Ty->getScalarSizeInBits();
1730 const APInt *ShAmtAPInt;
1739 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1748 if (ShlAmt < ShAmt) {
1750 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShlAmt);
1751 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1752 NewAShr->setIsExact(
I.isExact());
1755 if (ShlAmt > ShAmt) {
1757 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmt - ShAmt);
1759 NewShl->setHasNoSignedWrap(
true);
1768 AmtSum = std::min(AmtSum,
BitWidth - 1);
1770 return BinaryOperator::CreateAShr(
X, ConstantInt::get(Ty, AmtSum));
1774 (Ty->isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1776 Type *SrcTy =
X->getType();
1777 ShAmt = std::min(ShAmt, SrcTy->getScalarSizeInBits() - 1);
1778 Value *NewSh =
Builder.CreateAShr(
X, ConstantInt::get(SrcTy, ShAmt));
1800 (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1805 auto *NewAdd = BinaryOperator::CreateNSWAdd(
1807 Builder.CreateAShr(
X, ConstantInt::get(Ty, ShAmt),
"",
I.isExact()));
1808 NewAdd->setHasNoUnsignedWrap(
1825 Constant *Mask = ConstantInt::get(Ty, 1);
1839 Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file provides internal interfaces used to implement the InstCombine.
static Value * foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt, bool IsOuterShl, InstCombiner::BuilderTy &Builder)
Fold OuterShift (InnerShift X, C1), C2.
static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q)
static Instruction * dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
static bool canEvaluateShifted(Value *V, unsigned NumBits, bool IsLeftShift, InstCombinerImpl &IC, Instruction *CxtI)
See if we can compute the specified value, but shifted logically to the left or right by some number ...
bool canTryToConstantAddTwoShiftAmounts(Value *Sh0, Value *ShAmt0, Value *Sh1, Value *ShAmt1)
static Instruction * foldShiftOfShiftedBinOp(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a shift-by-constant of a bin op (bitwise logic op or add/sub w/ shl) that itself has a shi...
static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl, Instruction *InnerShift, InstCombinerImpl &IC, Instruction *CxtI)
Return true if we can simplify two logical (either left or right) shifts that have constant shift amo...
static Value * getShiftedValue(Value *V, unsigned NumBits, bool isLeftShift, InstCombinerImpl &IC, const DataLayout &DL)
When canEvaluateShifted() returns true for an expression, this function inserts the new computation t...
static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift, BinaryOperator *BO)
This file provides the interface for the instcombine pass implementation.
static bool hasNoSignedWrap(BinaryOperator &I)
static bool hasNoUnsignedWrap(BinaryOperator &I)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
bool eq(const APInt &RHS) const
Equality comparison.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt shl(unsigned shiftAmt) const
Left-shift function.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
static LLVM_ABI BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
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 LLVM_ABI CastInst * CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a Trunc or BitCast cast instruction.
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 ...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLE
signed less or equal
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
This is an important base class in LLVM.
static LLVM_ABI Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Instruction * visitLShr(BinaryOperator &I)
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Instruction * visitAShr(BinaryOperator &I)
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * visitShl(BinaryOperator &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Instruction * foldVariableSignZeroExtensionOfVariableHighBitExtract(BinaryOperator &OldAShr)
Instruction * commonShiftTransforms(BinaryOperator &I)
bool SimplifyDemandedInstructionBits(Instruction &Inst)
Tries to simplify operands to an integer instruction based on its demanded bits.
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Instruction * FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I)
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
Instruction * InsertNewInstWith(Instruction *New, BasicBlock::iterator Old)
Same as InsertNewInstBefore, but also sets the debug loc.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CxtI=nullptr, unsigned Depth=0) const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
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 void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
bool isLogicalShift() const
Return true if this is a logical shift left or a logical shift right.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
@ MAX_INT_BITS
Maximum number of bits that can be specified.
op_range incoming_values()
void setIncomingValue(unsigned i, Value *V)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM_ABI Type * getExtendedType() const
Given scalar/vector integer type, returns a type with elements twice as wide as in the original type.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
This class represents zero extension of integer types.
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.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
Exact_match< T > m_Exact(const T &SubPattern)
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap >, DisjointOr_match< LHS, RHS > > m_NUWAddLike(const LHS &L, const RHS &R)
Match either "add nuw" or "or disjoint".
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto cast_or_null(const Y &Val)
LLVM_ABI Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Shl, 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 void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a LShr, fold the result or return null.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned countMinSignBits() const
Returns the number of times the sign bit is replicated into the other bits.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned getBitWidth() const
Get the bit width of this value.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.