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();
465 assert(!
AC->isZero() &&
"Expected simplify of shifted zero");
475 unsigned PosOffset = (-*AddC).getZExtValue();
477 auto isSuitableForPreShift = [PosOffset, &
I,
AC]() {
478 switch (
I.getOpcode()) {
481 case Instruction::Shl:
482 return (
I.hasNoSignedWrap() ||
I.hasNoUnsignedWrap()) &&
483 AC->eq(
AC->lshr(PosOffset).shl(PosOffset));
484 case Instruction::LShr:
485 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).lshr(PosOffset));
486 case Instruction::AShr:
487 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).ashr(PosOffset));
490 if (isSuitableForPreShift()) {
491 Constant *NewC = ConstantInt::get(Ty,
I.getOpcode() == Instruction::Shl
492 ?
AC->lshr(PosOffset)
493 :
AC->shl(PosOffset));
496 if (
I.getOpcode() == Instruction::Shl) {
514 if (
I.getOpcode() == Instruction::Shl) {
515 if (
AC->countl_zero() >= C2)
516 return BinaryOperator::CreateExactLShr(
517 ConstantInt::get(Ty,
AC->shl(C2)),
X);
518 if (
AC->countl_one() > C2)
519 return BinaryOperator::CreateExactAShr(
520 ConstantInt::get(Ty,
AC->shl(C2)),
X);
521 }
else if (
AC->countr_zero() >= C2) {
522 if (
AC->isSignBitClear()) {
523 auto *Shl = BinaryOperator::CreateNUWShl(
524 ConstantInt::get(Ty,
AC->lshr(C2)),
X);
525 Shl->setHasNoSignedWrap();
528 if (
I.getOpcode() == Instruction::LShr)
529 return BinaryOperator::CreateNUWShl(
530 ConstantInt::get(Ty,
AC->lshr(C2)),
X);
531 return BinaryOperator::CreateNSWShl(ConstantInt::get(Ty,
AC->ashr(C2)),
556 if ((
I.getOpcode() == Instruction::LShr ||
557 I.getOpcode() == Instruction::AShr) &&
582 const APInt *InnerShiftConst;
589 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
593 *InnerShiftConst == OuterShAmt;
594 if (IsInnerShl == IsOuterShl)
600 if (*InnerShiftConst == OuterShAmt)
610 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
613 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
633bool InstCombinerImpl::canEvaluateShifted(
Value *V,
unsigned NumBits,
644 return C->countr_zero() >= NumBits;
649 if (!
I)
return false;
653 if (!
I->hasOneUse())
return false;
655 switch (
I->getOpcode()) {
656 default:
return false;
657 case Instruction::And:
658 case Instruction::Or:
659 case Instruction::Xor:
661 return canEvaluateShifted(
I->getOperand(0), NumBits, IsLeftShift, Semantics,
663 canEvaluateShifted(
I->getOperand(1), NumBits, IsLeftShift, Semantics,
666 case Instruction::Shl:
667 case Instruction::LShr:
671 case Instruction::Select: {
675 return canEvaluateShifted(TrueVal, NumBits, IsLeftShift, Semantics, SI) &&
676 canEvaluateShifted(FalseVal, NumBits, IsLeftShift, Semantics, SI);
678 case Instruction::PHI: {
684 if (!canEvaluateShifted(IncValue, NumBits, IsLeftShift, Semantics, PN))
688 case Instruction::Mul: {
689 const APInt *MulConst;
695 case Instruction::Add: {
700 return canEvaluateShifted(
I->getOperand(0), NumBits, IsLeftShift,
702 canEvaluateShifted(
I->getOperand(1), NumBits, IsLeftShift,
713 return WrapRequired &&
714 canEvaluateShifted(
I->getOperand(0), NumBits, IsLeftShift, Semantics,
716 canEvaluateShifted(
I->getOperand(1), NumBits, IsLeftShift, Semantics,
727 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
737 auto NewInnerShift = [&](
unsigned ShAmt) {
738 InnerShift->
setOperand(1, ConstantInt::get(ShType, ShAmt));
751 if (IsInnerShl == IsOuterShl) {
753 if (InnerShAmt + OuterShAmt >= TypeWidth)
756 return NewInnerShift(InnerShAmt + OuterShAmt);
762 if (InnerShAmt == OuterShAmt) {
765 "Signed Semantics should have nsw and inner shl per "
766 "canEvaluateShiftedShift");
773 APInt Mask = IsInnerShl
777 ConstantInt::get(ShType, Mask));
780 AndI->takeName(InnerShift);
785 assert(InnerShAmt > OuterShAmt &&
786 "Unexpected opposite direction logical shift pair");
792 return NewInnerShift(InnerShAmt - OuterShAmt);
797Value *InstCombinerImpl::getShiftedValue(
Value *V,
unsigned NumBits,
803 IsLeftShift ? Instruction::Shl
805 : Instruction::LShr);
806 return Builder.CreateBinOp(ShiftOp,
C,
807 ConstantInt::get(
C->getType(), NumBits));
813 switch (
I->getOpcode()) {
815 case Instruction::And:
816 case Instruction::Or:
817 case Instruction::Xor:
820 0, getShiftedValue(
I->getOperand(0), NumBits, IsLeftShift, Semantics));
822 1, getShiftedValue(
I->getOperand(1), NumBits, IsLeftShift, Semantics));
825 case Instruction::Shl:
826 case Instruction::LShr:
830 case Instruction::Select:
832 1, getShiftedValue(
I->getOperand(1), NumBits, IsLeftShift, Semantics));
834 2, getShiftedValue(
I->getOperand(2), NumBits, IsLeftShift, Semantics));
836 case Instruction::PHI: {
843 IsLeftShift, Semantics));
846 case Instruction::Mul: {
847 assert(!IsLeftShift &&
"Unexpected shift direction!");
850 unsigned TypeWidth =
I->getType()->getScalarSizeInBits();
852 auto *
And = BinaryOperator::CreateAnd(Neg,
853 ConstantInt::get(
I->getType(), Mask));
857 case Instruction::Add: {
859 I->dropPoisonGeneratingFlags();
861 0, getShiftedValue(
I->getOperand(0), NumBits, IsLeftShift, Semantics));
863 1, getShiftedValue(
I->getOperand(1), NumBits, IsLeftShift, Semantics));
876 case Instruction::Add:
877 return Shift.
getOpcode() == Instruction::Shl;
878 case Instruction::Or:
879 case Instruction::And:
881 case Instruction::Xor:
894 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
897 I.getOpcode(),
Builder.CreateBinOp(
I.getOpcode(), C2, C1),
X);
900 R->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap() &&
904 R->setIsExact(
I.isExact() && BO0->
isExact());
908 Type *Ty =
I.getType();
909 unsigned TypeBits = Ty->getScalarSizeInBits();
917 Constant *NegDivC = ConstantInt::get(Ty, -(*DivC));
921 auto ExtOpcode = (
I.getOpcode() == Instruction::AShr) ? Instruction::SExt
931 "Shift over the type width should have been removed already");
935 if (
I.getOpcode() != Instruction::AShr) {
936 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
939 if (canEvaluateShifted(Op0, Op1C->
getZExtValue(), IsLeftShift, Semantics,
942 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
943 " to eliminate shift:\n IN: "
944 << *Op0 <<
"\n SH: " <<
I <<
"\n");
947 IsLeftShift, Semantics));
964 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(1), C1);
967 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(0), C1);
995 Value *NewShift =
Builder.CreateBinOp(
I.getOpcode(), FalseVal, C1);
1012 Value *NewShift =
Builder.CreateBinOp(
I.getOpcode(), TrueVal, C1);
1033 assert(
I.getOpcode() == Instruction::LShr);
1036 Value *ShiftAmt =
I.getOperand(1);
1037 Type *Ty =
I.getType();
1039 if (Ty->getScalarSizeInBits() < 3)
1042 const APInt *ShAmtAPInt =
nullptr;
1043 Value *
X =
nullptr, *
Y =
nullptr;
1054 if (
X->getType()->getScalarSizeInBits() != ShAmt ||
1055 Y->getType()->getScalarSizeInBits() != ShAmt)
1059 if (!
Add->hasOneUse()) {
1060 for (
User *U :
Add->users()) {
1073 Builder.SetInsertPoint(AddInst);
1077 Builder.CreateICmpULT(NarrowAdd,
X,
"add.narrowed.overflow");
1082 if (!
Add->hasOneUse()) {
1088 return new ZExtInst(Overflow, Ty);
1093 assert(
I.isShift() &&
"Expected a shift as input");
1095 if (
I.getOpcode() == Instruction::Shl) {
1096 if (
I.hasNoUnsignedWrap() &&
I.hasNoSignedWrap())
1108 if (
match(
I.getOperand(1),
1125 if (
I.getOpcode() == Instruction::Shl) {
1128 I.setHasNoUnsignedWrap();
1132 if (!
I.hasNoSignedWrap()) {
1136 I.setHasNoSignedWrap();
1155 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
1167 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1168 Type *Ty =
I.getType();
1169 unsigned BitWidth = Ty->getScalarSizeInBits();
1173 unsigned ShAmtC =
C->getZExtValue();
1179 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1180 if (ShAmtC < SrcWidth &&
1188 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1195 if (ShrAmt < ShAmtC) {
1197 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1198 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1199 NewShl->setHasNoUnsignedWrap(
1200 I.hasNoUnsignedWrap() ||
1203 I.hasNoSignedWrap()));
1204 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1207 if (ShrAmt > ShAmtC) {
1209 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1212 NewShr->setIsExact(
true);
1220 if (ShrAmt < ShAmtC) {
1222 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1223 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1224 NewShl->setHasNoUnsignedWrap(
1225 I.hasNoUnsignedWrap() ||
1228 I.hasNoSignedWrap()));
1229 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1232 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1234 if (ShrAmt > ShAmtC) {
1236 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1240 NewShr->setIsExact(OldShr->isExact());
1243 return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
1253 unsigned ShDiff = ShrAmtC > ShAmtC ? ShrAmtC - ShAmtC : ShAmtC - ShrAmtC;
1254 Constant *ShiftDiffC = ConstantInt::get(
X->getType(), ShDiff);
1255 auto ShiftOpc = ShrAmtC > ShAmtC ? Shr->
getOpcode() : Instruction::Shl;
1261 Value *NewShift =
Builder.CreateBinOp(ShiftOpc,
X, ShiftDiffC,
"sh.diff");
1262 Value *Trunc =
Builder.CreateTrunc(NewShift, Ty,
"tr.sh.diff");
1264 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, Mask));
1270 switch (BinOpcode) {
1273 case Instruction::Add:
1274 case Instruction::And:
1275 case Instruction::Or:
1276 case Instruction::Xor:
1277 case Instruction::Sub:
1285 isSuitableBinOpcode(Op0BO->
getOpcode())) {
1306 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1308 Constant *Mask = ConstantInt::get(Ty, Bits);
1309 return BinaryOperator::CreateAnd(
B, Mask);
1320 X->getName() +
".mask");
1323 Disjoint && Disjoint->isDisjoint())
1333 return BinaryOperator::CreateSub(NewLHS, NewShift);
1346 return BinaryOperator::CreateAnd(Mask,
X);
1352 return BinaryOperator::CreateShl(
AllOnes, Op1);
1361 return BinaryOperator::CreateMul(
X,
Builder.CreateShl(C2, C1));
1365 auto *NewC =
Builder.CreateShl(ConstantInt::get(Ty, 1), C1);
1366 return createSelectInstWithUnknownProfile(
X, NewC,
1374 return BinaryOperator::CreateLShr(
1381 return BinaryOperator::CreateAnd(NegX,
X);
1389 auto *
Mul = BinaryOperator::CreateMul(LowBit, Op0);
1391 if (
I.hasNoUnsignedWrap())
1392 Mul->setHasNoUnsignedWrap();
1401 SQ.getWithInstruction(&
I)))
1410 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1411 Type *Ty =
I.getType();
1414 unsigned BitWidth = Ty->getScalarSizeInBits();
1431 auto *NewSub = BinaryOperator::CreateNUWSub(
X, NewLshr);
1432 NewSub->setHasNoSignedWrap(
1441 return BinaryOperator::CreateAnd(
X,
Y);
1448 auto *NewSub = BinaryOperator::CreateNUWSub(NewLshr,
Y);
1449 NewSub->setHasNoSignedWrap(
1455 switch (BinOpcode) {
1458 case Instruction::Add:
1459 case Instruction::And:
1460 case Instruction::Or:
1461 case Instruction::Xor:
1472 if (isSuitableBinOpcode(Op0OB->
getOpcode())) {
1474 !OBO || OBO->hasNoUnsignedWrap()) {
1476 Y, Op1,
"",
I.isExact() && Op0OB->
getOpcode() != Instruction::And);
1479 NewBinOp->setHasNoUnsignedWrap(
true);
1480 NewBinOp->setHasNoSignedWrap(OBO->hasNoSignedWrap());
1483 Disjoint->isDisjoint());
1491 unsigned ShAmtC =
C->getZExtValue();
1494 (
II->getIntrinsicID() == Intrinsic::ctlz ||
1495 II->getIntrinsicID() == Intrinsic::cttz ||
1496 II->getIntrinsicID() == Intrinsic::ctpop)) {
1500 bool IsPop =
II->getIntrinsicID() == Intrinsic::ctpop;
1508 if (C1->
ult(ShAmtC)) {
1510 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShlAmtC);
1513 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1514 NewLShr->setIsExact(
I.isExact());
1519 Value *NewLShr =
Builder.CreateLShr(
X, ShiftDiff,
"",
I.isExact());
1521 return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
1523 }
else if (C1->
ugt(ShAmtC)) {
1525 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmtC - ShAmtC);
1528 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1529 NewShl->setHasNoUnsignedWrap(
true);
1530 NewShl->setHasNoSignedWrap(ShAmtC > 0);
1537 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1543 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1555 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1557 Constant *Mask = ConstantInt::get(Ty, Bits);
1558 return BinaryOperator::CreateAnd(NewAdd, Mask);
1562 (!Ty->isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1564 "Big shift not simplified to zero?");
1571 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1573 if (SrcTyBitWidth == 1) {
1574 auto *NewC = ConstantInt::get(
1579 if ((!Ty->isIntegerTy() || shouldChangeType(Ty,
X->getType())) &&
1589 if (ShAmtC ==
BitWidth - SrcTyBitWidth) {
1591 unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1611 return BinaryOperator::CreateAnd(Signbit,
X);
1623 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1631 if (AmtSum < SrcWidth &&
1633 Value *SumShift =
Builder.CreateLShr(
X, AmtSum,
"sum.shift");
1634 Value *Trunc =
Builder.CreateTrunc(SumShift, Ty,
I.getName());
1639 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, MaskC));
1645 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1655 auto *NewAdd = BinaryOperator::CreateNUWAdd(
1656 X,
Builder.CreateLShr(
X, ConstantInt::get(Ty, ShAmtC),
"",
1658 NewAdd->setHasNoSignedWrap(
1671 if (MulC->
eq(NewMulC.
shl(ShAmtC))) {
1673 BinaryOperator::CreateNUWMul(
X, ConstantInt::get(Ty, NewMulC));
1675 "lshr X, 0 should be handled by simplifyLShrInst.");
1676 NewMul->setHasNoSignedWrap(
true);
1684 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1686 return BinaryOperator::CreateNSWAdd(
1687 X,
Builder.CreateLShr(
X, ConstantInt::get(Ty, ShAmtC),
"",
1697 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1698 unsigned WidthDiff =
BitWidth - SrcWidth;
1699 if (SrcWidth % 16 == 0) {
1700 Value *NarrowSwap =
Builder.CreateUnaryIntrinsic(Intrinsic::bswap,
X);
1701 if (ShAmtC >= WidthDiff) {
1703 Value *NewShift =
Builder.CreateLShr(NarrowSwap, ShAmtC - WidthDiff);
1708 Constant *ShiftDiff = ConstantInt::get(Ty, WidthDiff - ShAmtC);
1709 return BinaryOperator::CreateShl(NewZExt, ShiftDiff);
1716 Value *BoolX, *BoolY;
1721 (
X->hasOneUse() ||
Y->hasOneUse() || Op0->
hasOneUse())) {
1735 return BinaryOperator::CreateAnd(Mask,
X);
1741 return BinaryOperator::CreateLShr(
AllOnes, Op1);
1748 Value *Shl0_Op0, *Shl0_Op1, *Shl1_Op1;
1757 if (HasNUW || HasNSW) {
1759 Shl0_Op1,
"", HasNUW, HasNSW);
1760 return BinaryOperator::CreateLShr(NewShl, Shl1_Op1);
1770 "Must be called with arithmetic right-shift instruction only.");
1783 if (!
match(&OldAShr,
1789 !BitWidthSplat(C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1795 bool HadTrunc = MaybeTrunc != HighBitExtract;
1798 Value *
X, *NumLowBitsToSkip;
1804 if (!
match(NumLowBitsToSkip,
1807 !BitWidthSplat(C0, HighBitExtract))
1835 SQ.getWithInstruction(&
I)))
1844 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1845 Type *Ty =
I.getType();
1846 unsigned BitWidth = Ty->getScalarSizeInBits();
1847 const APInt *ShAmtAPInt;
1856 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1865 if (ShlAmt < ShAmt) {
1867 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShlAmt);
1868 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1869 NewAShr->setIsExact(
I.isExact());
1872 if (ShlAmt > ShAmt) {
1874 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmt - ShAmt);
1876 NewShl->setHasNoSignedWrap(
true);
1885 AmtSum = std::min(AmtSum,
BitWidth - 1);
1887 return BinaryOperator::CreateAShr(
X, ConstantInt::get(Ty, AmtSum));
1891 (Ty->isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1893 Type *SrcTy =
X->getType();
1894 ShAmt = std::min(ShAmt, SrcTy->getScalarSizeInBits() - 1);
1895 Value *NewSh =
Builder.CreateAShr(
X, ConstantInt::get(SrcTy, ShAmt));
1917 (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1922 auto *NewAdd = BinaryOperator::CreateNSWAdd(
1924 Builder.CreateAShr(
X, ConstantInt::get(Ty, ShAmt),
"",
I.isExact()));
1925 NewAdd->setHasNoUnsignedWrap(
1942 Constant *Mask = ConstantInt::get(Ty, 1);
1956 Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q)
static Instruction * dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl, ShiftSemantics Semantics, Instruction *InnerShift, InstCombinerImpl &IC, Instruction *CxtI)
Return true if we can simplify two logical (either left or right) shifts that have constant shift amo...
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 Value * foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt, bool IsOuterShl, ShiftSemantics Semantics, InstCombiner::BuilderTy &Builder)
Fold OuterShift (InnerShift X, C1), C2.
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 SymbolRef::Type getType(const Symbol *Sym)
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.
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)
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
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
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)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
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)
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)
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.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
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)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
match_deferred< 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()...
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.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
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.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
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)
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)
auto m_Cttz(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &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.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
ShiftSemantics
Enum to specify how shift operations should be evaluated in canEvaluateShifted.
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
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.