22#define DEBUG_TYPE "instcombine"
44 unsigned MaximalPossibleTotalShiftAmount =
47 APInt MaximalRepresentableShiftAmount =
49 return MaximalRepresentableShiftAmount.
uge(MaximalPossibleTotalShiftAmount);
65 bool AnalyzeForSignBitExtraction) {
77 Value *Trunc =
nullptr;
96 if (AnalyzeForSignBitExtraction && !HadTwoRightShifts)
103 if (!IdenticalShOpcodes && !AnalyzeForSignBitExtraction)
109 if (Trunc && !AnalyzeForSignBitExtraction &&
116 SQ.getWithInstruction(Sh0)));
119 unsigned NewShAmtBitWidth = NewShAmt->getType()->getScalarSizeInBits();
120 unsigned XBitWidth =
X->getType()->getScalarSizeInBits();
123 APInt(NewShAmtBitWidth, XBitWidth))))
131 if (HadTwoRightShifts && (Trunc || AnalyzeForSignBitExtraction)) {
135 APInt(NewShAmtBitWidth, XBitWidth - 1))))
138 if (AnalyzeForSignBitExtraction)
142 assert(IdenticalShOpcodes &&
"Should not get here with different shifts.");
144 if (NewShAmt->getType() !=
X->getType()) {
146 X->getType(),
SQ.DL);
158 if (ShiftOpcode == Instruction::BinaryOps::Shl) {
198 "The input must be 'shl'!");
213 bool HadTrunc = WidestTy != NarrowestTy;
249 MaskShAmt, ShiftShAmt,
false,
false, Q));
260 SumOfShAmts, ConstantInt::get(SumOfShAmts->getType()->getScalarType(),
263 Instruction::ZExt, SumOfShAmts, ExtendedTy, Q.
DL);
264 if (!ExtendedSumOfShAmts)
270 Instruction::Shl, ExtendedAllOnes, ExtendedSumOfShAmts, Q.
DL);
271 if (!ExtendedInvertedMask)
288 ShiftShAmt, MaskShAmt,
false,
false, Q));
302 -(
int)WidestTyBitWidth));
310 if (!ExtendedNumHighBitsToClear)
316 ExtendedNumHighBitsToClear, Q.
DL);
340 X = Builder.CreateTrunc(
X, NarrowestTy);
349 Builder.Insert(NewShift);
360 assert(
I.isShift() &&
"Expected a shift as input");
363 (!BinInst->isBitwiseLogicOp() &&
364 BinInst->getOpcode() != Instruction::Add &&
365 BinInst->getOpcode() != Instruction::Sub) ||
366 !BinInst->hasOneUse())
375 if ((BinInst->getOpcode() == Instruction::Add ||
376 BinInst->getOpcode() == Instruction::Sub) &&
377 ShiftOpcode != Instruction::Shl)
380 Type *Ty =
I.getType();
385 auto matchFirstShift = [&](
Value *V,
Value *W) {
386 unsigned Size = Ty->getScalarSizeInBits();
397 bool FirstShiftIsOp1 =
false;
398 if (matchFirstShift(BinInst->getOperand(0), BinInst->getOperand(1)))
399 Y = BinInst->getOperand(1);
400 else if (matchFirstShift(BinInst->getOperand(1), BinInst->getOperand(0))) {
401 Y = BinInst->getOperand(0);
402 FirstShiftIsOp1 = BinInst->getOpcode() == Instruction::Sub;
408 Value *NewShift1 = Builder.CreateBinOp(ShiftOpcode,
X, ShiftSumC);
409 Value *NewShift2 = Builder.CreateBinOp(ShiftOpcode,
Y, C1);
410 Value *Op1 = FirstShiftIsOp1 ? NewShift2 : NewShift1;
411 Value *Op2 = FirstShiftIsOp1 ? NewShift1 : NewShift2;
419 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
421 Type *Ty =
I.getType();
457 if (
I.getOpcode() == Instruction::Shl) {
466 unsigned BitWidth = Ty->getScalarSizeInBits();
470 assert(!
AC->isZero() &&
"Expected simplify of shifted zero");
480 unsigned PosOffset = (-*AddC).getZExtValue();
482 auto isSuitableForPreShift = [PosOffset, &
I,
AC]() {
483 switch (
I.getOpcode()) {
486 case Instruction::Shl:
487 return (
I.hasNoSignedWrap() ||
I.hasNoUnsignedWrap()) &&
488 AC->eq(
AC->lshr(PosOffset).shl(PosOffset));
489 case Instruction::LShr:
490 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).lshr(PosOffset));
491 case Instruction::AShr:
492 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).ashr(PosOffset));
495 if (isSuitableForPreShift()) {
496 Constant *NewC = ConstantInt::get(Ty,
I.getOpcode() == Instruction::Shl
497 ?
AC->lshr(PosOffset)
498 :
AC->shl(PosOffset));
501 if (
I.getOpcode() == Instruction::Shl) {
519 if (
I.getOpcode() == Instruction::Shl) {
520 if (
AC->countl_zero() >= C2)
521 return BinaryOperator::CreateExactLShr(
522 ConstantInt::get(Ty,
AC->shl(C2)),
X);
523 if (
AC->countl_one() > C2)
524 return BinaryOperator::CreateExactAShr(
525 ConstantInt::get(Ty,
AC->shl(C2)),
X);
526 }
else if (
AC->countr_zero() >= C2) {
527 if (
AC->isSignBitClear()) {
528 auto *Shl = BinaryOperator::CreateNUWShl(
529 ConstantInt::get(Ty,
AC->lshr(C2)),
X);
530 Shl->setHasNoSignedWrap();
533 if (
I.getOpcode() == Instruction::LShr)
534 return BinaryOperator::CreateNUWShl(
535 ConstantInt::get(Ty,
AC->lshr(C2)),
X);
536 return BinaryOperator::CreateNSWShl(ConstantInt::get(Ty,
AC->ashr(C2)),
561 if ((
I.getOpcode() == Instruction::LShr ||
562 I.getOpcode() == Instruction::AShr) &&
587 const APInt *InnerShiftConst;
594 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
598 *InnerShiftConst == OuterShAmt;
599 if (IsInnerShl == IsOuterShl)
605 if (*InnerShiftConst == OuterShAmt)
615 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
618 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
638bool InstCombinerImpl::canEvaluateShifted(
Value *V,
unsigned NumBits,
649 return C->countr_zero() >= NumBits;
654 if (!
I)
return false;
658 if (!
I->hasOneUse())
return false;
660 switch (
I->getOpcode()) {
661 default:
return false;
662 case Instruction::And:
663 case Instruction::Or:
664 case Instruction::Xor:
666 return canEvaluateShifted(
I->getOperand(0), NumBits, IsLeftShift, Semantics,
668 canEvaluateShifted(
I->getOperand(1), NumBits, IsLeftShift, Semantics,
671 case Instruction::Shl:
672 case Instruction::LShr:
676 case Instruction::Select: {
680 return canEvaluateShifted(TrueVal, NumBits, IsLeftShift, Semantics, SI) &&
681 canEvaluateShifted(FalseVal, NumBits, IsLeftShift, Semantics, SI);
683 case Instruction::PHI: {
689 if (!canEvaluateShifted(IncValue, NumBits, IsLeftShift, Semantics, PN))
693 case Instruction::Mul: {
694 const APInt *MulConst;
700 case Instruction::Add: {
705 return canEvaluateShifted(
I->getOperand(0), NumBits, IsLeftShift,
707 canEvaluateShifted(
I->getOperand(1), NumBits, IsLeftShift,
718 return WrapRequired &&
719 canEvaluateShifted(
I->getOperand(0), NumBits, IsLeftShift, Semantics,
721 canEvaluateShifted(
I->getOperand(1), NumBits, IsLeftShift, Semantics,
732 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
742 auto NewInnerShift = [&](
unsigned ShAmt) {
743 InnerShift->
setOperand(1, ConstantInt::get(ShType, ShAmt));
756 if (IsInnerShl == IsOuterShl) {
758 if (InnerShAmt + OuterShAmt >= TypeWidth)
761 return NewInnerShift(InnerShAmt + OuterShAmt);
767 if (InnerShAmt == OuterShAmt) {
770 "Signed Semantics should have nsw and inner shl per "
771 "canEvaluateShiftedShift");
778 APInt Mask = IsInnerShl
782 ConstantInt::get(ShType, Mask));
785 AndI->takeName(InnerShift);
790 assert(InnerShAmt > OuterShAmt &&
791 "Unexpected opposite direction logical shift pair");
797 return NewInnerShift(InnerShAmt - OuterShAmt);
802Value *InstCombinerImpl::getShiftedValue(
Value *V,
unsigned NumBits,
808 IsLeftShift ? Instruction::Shl
810 : Instruction::LShr);
811 return Builder.CreateBinOp(ShiftOp,
C,
812 ConstantInt::get(
C->getType(), NumBits));
818 switch (
I->getOpcode()) {
820 case Instruction::And:
821 case Instruction::Or:
822 case Instruction::Xor:
825 0, getShiftedValue(
I->getOperand(0), NumBits, IsLeftShift, Semantics));
827 1, getShiftedValue(
I->getOperand(1), NumBits, IsLeftShift, Semantics));
830 case Instruction::Shl:
831 case Instruction::LShr:
835 case Instruction::Select:
837 1, getShiftedValue(
I->getOperand(1), NumBits, IsLeftShift, Semantics));
839 2, getShiftedValue(
I->getOperand(2), NumBits, IsLeftShift, Semantics));
841 case Instruction::PHI: {
848 IsLeftShift, Semantics));
851 case Instruction::Mul: {
852 assert(!IsLeftShift &&
"Unexpected shift direction!");
855 unsigned TypeWidth =
I->getType()->getScalarSizeInBits();
857 auto *
And = BinaryOperator::CreateAnd(Neg,
858 ConstantInt::get(
I->getType(), Mask));
862 case Instruction::Add: {
864 I->dropPoisonGeneratingFlags();
866 0, getShiftedValue(
I->getOperand(0), NumBits, IsLeftShift, Semantics));
868 1, getShiftedValue(
I->getOperand(1), NumBits, IsLeftShift, Semantics));
881 case Instruction::Add:
882 return Shift.
getOpcode() == Instruction::Shl;
883 case Instruction::Or:
884 case Instruction::And:
886 case Instruction::Xor:
899 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
902 I.getOpcode(),
Builder.CreateBinOp(
I.getOpcode(), C2, C1),
X);
905 R->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap() &&
909 R->setIsExact(
I.isExact() && BO0->
isExact());
913 Type *Ty =
I.getType();
914 unsigned TypeBits = Ty->getScalarSizeInBits();
922 Constant *NegDivC = ConstantInt::get(Ty, -(*DivC));
926 auto ExtOpcode = (
I.getOpcode() == Instruction::AShr) ? Instruction::SExt
941 TypeBits == 2 *
A->getType()->getScalarSizeInBits()) {
942 auto IID = ExtA->
getOpcode() == Instruction::SExt ? Intrinsic::smulh
945 auto ExtOp =
I.getOpcode() == Instruction::LShr ? Instruction::ZExt
955 "Shift over the type width should have been removed already");
959 if (
I.getOpcode() != Instruction::AShr) {
960 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
963 if (canEvaluateShifted(Op0, Op1C->
getZExtValue(), IsLeftShift, Semantics,
966 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
967 " to eliminate shift:\n IN: "
968 << *Op0 <<
"\n SH: " <<
I <<
"\n");
971 IsLeftShift, Semantics));
988 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(1), C1);
991 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(0), C1);
1019 Value *NewShift =
Builder.CreateBinOp(
I.getOpcode(), FalseVal, C1);
1022 Cond, NewOp, NewShift,
"",
nullptr,
1038 Value *NewShift =
Builder.CreateBinOp(
I.getOpcode(), TrueVal, C1);
1041 Cond, NewShift, NewOp,
"",
nullptr,
1061 assert(
I.getOpcode() == Instruction::LShr);
1064 Value *ShiftAmt =
I.getOperand(1);
1065 Type *Ty =
I.getType();
1067 if (Ty->getScalarSizeInBits() < 3)
1070 const APInt *ShAmtAPInt =
nullptr;
1071 Value *
X =
nullptr, *
Y =
nullptr;
1082 if (
X->getType()->getScalarSizeInBits() != ShAmt ||
1083 Y->getType()->getScalarSizeInBits() != ShAmt)
1087 if (!
Add->hasOneUse()) {
1088 for (
User *U :
Add->users()) {
1101 Builder.SetInsertPoint(AddInst);
1105 Builder.CreateICmpULT(NarrowAdd,
X,
"add.narrowed.overflow");
1110 if (!
Add->hasOneUse()) {
1116 return new ZExtInst(Overflow, Ty);
1121 assert(
I.isShift() &&
"Expected a shift as input");
1123 if (
I.getOpcode() == Instruction::Shl) {
1124 if (
I.hasNoUnsignedWrap() &&
I.hasNoSignedWrap())
1136 if (
match(
I.getOperand(1),
1153 if (
I.getOpcode() == Instruction::Shl) {
1156 I.setHasNoUnsignedWrap();
1160 if (!
I.hasNoSignedWrap()) {
1164 I.setHasNoSignedWrap();
1183 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
1195 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1196 Type *Ty =
I.getType();
1197 unsigned BitWidth = Ty->getScalarSizeInBits();
1201 unsigned ShAmtC =
C->getZExtValue();
1207 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1208 if (ShAmtC < SrcWidth &&
1216 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1223 if (ShrAmt < ShAmtC) {
1225 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1226 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1227 NewShl->setHasNoUnsignedWrap(
1228 I.hasNoUnsignedWrap() ||
1231 I.hasNoSignedWrap()));
1232 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1235 if (ShrAmt > ShAmtC) {
1237 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1240 NewShr->setIsExact(
true);
1248 if (ShrAmt < ShAmtC) {
1250 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1251 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1252 NewShl->setHasNoUnsignedWrap(
1253 I.hasNoUnsignedWrap() ||
1256 I.hasNoSignedWrap()));
1257 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1260 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1262 if (ShrAmt > ShAmtC) {
1264 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1268 NewShr->setIsExact(OldShr->isExact());
1271 return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
1281 unsigned ShDiff = ShrAmtC > ShAmtC ? ShrAmtC - ShAmtC : ShAmtC - ShrAmtC;
1282 Constant *ShiftDiffC = ConstantInt::get(
X->getType(), ShDiff);
1283 auto ShiftOpc = ShrAmtC > ShAmtC ? Shr->
getOpcode() : Instruction::Shl;
1289 Value *NewShift =
Builder.CreateBinOp(ShiftOpc,
X, ShiftDiffC,
"sh.diff");
1290 Value *Trunc =
Builder.CreateTrunc(NewShift, Ty,
"tr.sh.diff");
1292 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, Mask));
1298 switch (BinOpcode) {
1301 case Instruction::Add:
1302 case Instruction::And:
1303 case Instruction::Or:
1304 case Instruction::Xor:
1305 case Instruction::Sub:
1313 isSuitableBinOpcode(Op0BO->
getOpcode())) {
1334 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1336 Constant *Mask = ConstantInt::get(Ty, Bits);
1337 return BinaryOperator::CreateAnd(
B, Mask);
1348 X->getName() +
".mask");
1351 Disjoint && Disjoint->isDisjoint())
1361 return BinaryOperator::CreateSub(NewLHS, NewShift);
1374 return BinaryOperator::CreateAnd(Mask,
X);
1380 return BinaryOperator::CreateShl(
AllOnes, Op1);
1389 return BinaryOperator::CreateMul(
X,
Builder.CreateShl(C2, C1));
1393 auto *NewC =
Builder.CreateShl(ConstantInt::get(Ty, 1), C1);
1394 return createSelectInstWithUnknownProfile(
X, NewC,
1402 return BinaryOperator::CreateLShr(
1409 return BinaryOperator::CreateAnd(NegX,
X);
1417 auto *
Mul = BinaryOperator::CreateMul(LowBit, Op0);
1419 if (
I.hasNoUnsignedWrap())
1420 Mul->setHasNoUnsignedWrap();
1429 SQ.getWithInstruction(&
I)))
1438 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1439 Type *Ty =
I.getType();
1442 unsigned BitWidth = Ty->getScalarSizeInBits();
1459 auto *NewSub = BinaryOperator::CreateNUWSub(
X, NewLshr);
1460 NewSub->setHasNoSignedWrap(
1469 return BinaryOperator::CreateAnd(
X,
Y);
1476 auto *NewSub = BinaryOperator::CreateNUWSub(NewLshr,
Y);
1477 NewSub->setHasNoSignedWrap(
1483 switch (BinOpcode) {
1486 case Instruction::Add:
1487 case Instruction::And:
1488 case Instruction::Or:
1489 case Instruction::Xor:
1500 if (isSuitableBinOpcode(Op0OB->
getOpcode())) {
1502 !OBO || OBO->hasNoUnsignedWrap()) {
1504 Y, Op1,
"",
I.isExact() && Op0OB->
getOpcode() != Instruction::And);
1507 NewBinOp->setHasNoUnsignedWrap(
true);
1508 NewBinOp->setHasNoSignedWrap(OBO->hasNoSignedWrap());
1511 Disjoint->isDisjoint());
1519 unsigned ShAmtC =
C->getZExtValue();
1522 (
II->getIntrinsicID() == Intrinsic::ctlz ||
1523 II->getIntrinsicID() == Intrinsic::cttz ||
1524 II->getIntrinsicID() == Intrinsic::ctpop)) {
1528 bool IsPop =
II->getIntrinsicID() == Intrinsic::ctpop;
1536 if (C1->
ult(ShAmtC)) {
1538 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShlAmtC);
1541 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1542 NewLShr->setIsExact(
I.isExact());
1547 Value *NewLShr =
Builder.CreateLShr(
X, ShiftDiff,
"",
I.isExact());
1549 return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
1551 }
else if (C1->
ugt(ShAmtC)) {
1553 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmtC - ShAmtC);
1556 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1557 NewShl->setHasNoUnsignedWrap(
true);
1558 NewShl->setHasNoSignedWrap(ShAmtC > 0);
1565 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1571 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1583 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1585 Constant *Mask = ConstantInt::get(Ty, Bits);
1586 return BinaryOperator::CreateAnd(NewAdd, Mask);
1590 (!Ty->isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1592 "Big shift not simplified to zero?");
1599 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1601 if (SrcTyBitWidth == 1) {
1602 auto *NewC = ConstantInt::get(
1609 if ((!Ty->isIntegerTy() || shouldChangeType(Ty,
X->getType())) &&
1619 if (ShAmtC ==
BitWidth - SrcTyBitWidth) {
1621 unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1641 return BinaryOperator::CreateAnd(Signbit,
X);
1653 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1661 if (AmtSum < SrcWidth &&
1663 Value *SumShift =
Builder.CreateLShr(
X, AmtSum,
"sum.shift");
1664 Value *Trunc =
Builder.CreateTrunc(SumShift, Ty,
I.getName());
1669 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, MaskC));
1675 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1685 auto *NewAdd = BinaryOperator::CreateNUWAdd(
1686 X,
Builder.CreateLShr(
X, ConstantInt::get(Ty, ShAmtC),
"",
1688 NewAdd->setHasNoSignedWrap(
1701 if (MulC->
eq(NewMulC.
shl(ShAmtC))) {
1703 BinaryOperator::CreateNUWMul(
X, ConstantInt::get(Ty, NewMulC));
1705 "lshr X, 0 should be handled by simplifyLShrInst.");
1706 NewMul->setHasNoSignedWrap(
true);
1714 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1716 return BinaryOperator::CreateNSWAdd(
1717 X,
Builder.CreateLShr(
X, ConstantInt::get(Ty, ShAmtC),
"",
1727 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1728 unsigned WidthDiff =
BitWidth - SrcWidth;
1729 if (SrcWidth % 16 == 0) {
1730 Value *NarrowSwap =
Builder.CreateUnaryIntrinsic(Intrinsic::bswap,
X);
1731 if (ShAmtC >= WidthDiff) {
1733 Value *NewShift =
Builder.CreateLShr(NarrowSwap, ShAmtC - WidthDiff);
1738 Constant *ShiftDiff = ConstantInt::get(Ty, WidthDiff - ShAmtC);
1739 return BinaryOperator::CreateShl(NewZExt, ShiftDiff);
1746 Value *BoolX, *BoolY;
1751 (
X->hasOneUse() ||
Y->hasOneUse() || Op0->
hasOneUse())) {
1765 return BinaryOperator::CreateAnd(Mask,
X);
1771 return BinaryOperator::CreateLShr(
AllOnes, Op1);
1778 Value *Shl0_Op0, *Shl0_Op1, *Shl1_Op1;
1787 if (HasNUW || HasNSW) {
1789 Shl0_Op1,
"", HasNUW, HasNSW);
1790 return BinaryOperator::CreateLShr(NewShl, Shl1_Op1);
1800 "Must be called with arithmetic right-shift instruction only.");
1813 if (!
match(&OldAShr,
1819 !BitWidthSplat(C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1825 bool HadTrunc = MaybeTrunc != HighBitExtract;
1828 Value *
X, *NumLowBitsToSkip;
1834 if (!
match(NumLowBitsToSkip,
1837 !BitWidthSplat(C0, HighBitExtract))
1865 SQ.getWithInstruction(&
I)))
1874 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1875 Type *Ty =
I.getType();
1876 unsigned BitWidth = Ty->getScalarSizeInBits();
1877 const APInt *ShAmtAPInt;
1886 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1895 if (ShlAmt < ShAmt) {
1897 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShlAmt);
1898 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1899 NewAShr->setIsExact(
I.isExact());
1902 if (ShlAmt > ShAmt) {
1904 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmt - ShAmt);
1906 NewShl->setHasNoSignedWrap(
true);
1915 AmtSum = std::min(AmtSum,
BitWidth - 1);
1917 return BinaryOperator::CreateAShr(
X, ConstantInt::get(Ty, AmtSum));
1921 (Ty->isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1923 Type *SrcTy =
X->getType();
1924 ShAmt = std::min(ShAmt, SrcTy->getScalarSizeInBits() - 1);
1925 Value *NewSh =
Builder.CreateAShr(
X, ConstantInt::get(SrcTy, ShAmt));
1947 (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1952 auto *NewAdd = BinaryOperator::CreateNSWAdd(
1954 Builder.CreateAShr(
X, ConstantInt::get(Ty, ShAmt),
"",
I.isExact()));
1955 NewAdd->setHasNoUnsignedWrap(
1972 Constant *Mask = ConstantInt::get(Ty, 1);
1986 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 bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl, ShiftSemantics Semantics, Instruction *InnerShift, InstCombinerImpl &IC, Instruction *CtxI)
Return true if we can simplify two logical (either left or right) shifts that have constant shift amo...
static Instruction * dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
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
This file contains the declarations for profiling metadata utility functions.
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)
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CtxI=nullptr, unsigned Depth=0)
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.
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CtxI=nullptr, 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.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CtxI, unsigned Depth=0) const
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.
AllOnesConstantMatch m_AllOnes()
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.
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)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
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.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=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...
auto cast_or_null(const Y &Val)
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=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.
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 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.
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.