40#define DEBUG_TYPE "instcombine"
61 FAddendCoef() =
default;
66 void operator=(
const FAddendCoef &
A);
71 assert(!insaneIntVal(
C) &&
"Insane coefficient");
72 IsFp =
false; IntVal =
C;
75 void set(
const APFloat&
C);
79 bool isZero()
const {
return isInt() ? !IntVal : getFpVal().isZero(); }
82 bool isOne()
const {
return isInt() && IntVal == 1; }
83 bool isTwo()
const {
return isInt() && IntVal == 2; }
84 bool isMinusOne()
const {
return isInt() && IntVal == -1; }
85 bool isMinusTwo()
const {
return isInt() && IntVal == -2; }
88 bool insaneIntVal(
int V) {
return V > 4 ||
V < -4; }
90 APFloat *getFpValPtr() {
return reinterpret_cast<APFloat *
>(&FpValBuf); }
92 const APFloat *getFpValPtr()
const {
93 return reinterpret_cast<const APFloat *
>(&FpValBuf);
96 const APFloat &getFpVal()
const {
97 assert(IsFp && BufHasFpVal &&
"Incorrect state");
98 return *getFpValPtr();
102 assert(IsFp && BufHasFpVal &&
"Incorrect state");
103 return *getFpValPtr();
106 bool isInt()
const {
return !IsFp; }
110 void convertToFpType(
const fltSemantics &Sem);
115 APFloat createAPFloatFromInt(
const fltSemantics &Sem,
int Val);
120 bool BufHasFpVal =
false;
128 AlignedCharArrayUnion<APFloat> FpValBuf;
139 assert((Val ==
T.Val) &&
"Symbolic-values disagree");
143 Value *getSymVal()
const {
return Val; }
144 const FAddendCoef &getCoef()
const {
return Coeff; }
146 bool isConstant()
const {
return Val ==
nullptr; }
147 bool isZero()
const {
return Coeff.isZero(); }
149 void set(
short Coefficient,
Value *V) {
150 Coeff.set(Coefficient);
153 void set(
const APFloat &Coefficient,
Value *V) {
154 Coeff.set(Coefficient);
157 void set(
const ConstantFP *Coefficient,
Value *V) {
162 void negate() { Coeff.negate(); }
166 static unsigned drillValueDownOneStep(
Value* V, FAddend &A0, FAddend &A1);
170 unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1)
const;
173 void Scale(
const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
176 Value *Val =
nullptr;
185 FAddCombine(InstCombiner::BuilderTy &
B) : Builder(
B) {}
190 using AddendVect = SmallVector<const FAddend *, 4>;
192 Value *simplifyFAdd(AddendVect& V,
unsigned InstrQuota);
195 Value *createAddendVal(
const FAddend &
A,
bool& NeedNeg);
198 unsigned calcInstrNumber(
const AddendVect& Vect);
204 Value *createNaryFAdd(
const AddendVect& Opnds,
unsigned InstrQuota);
205 void createInstPostProc(Instruction *NewInst,
bool NoNumber =
false);
209 unsigned CreateInstrNum;
210 void initCreateInstNum() { CreateInstrNum = 0; }
211 void incCreateInstNum() { CreateInstrNum++; }
213 void initCreateInstNum() {}
214 void incCreateInstNum() {}
217 InstCombiner::BuilderTy &Builder;
229FAddendCoef::~FAddendCoef() {
231 getFpValPtr()->~APFloat();
234void FAddendCoef::set(
const APFloat&
C) {
244 IsFp = BufHasFpVal =
true;
247void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
258 IsFp = BufHasFpVal =
true;
261APFloat FAddendCoef::createAPFloatFromInt(
const fltSemantics &Sem,
int Val) {
271void FAddendCoef::operator=(
const FAddendCoef &That) {
275 set(That.getFpVal());
278void FAddendCoef::operator+=(
const FAddendCoef &That) {
280 if (
isInt() == That.isInt()) {
282 IntVal += That.IntVal;
284 getFpVal().add(That.getFpVal(), RndMode);
290 convertToFpType(
T.getSemantics());
291 getFpVal().add(
T, RndMode);
296 T.add(createAPFloatFromInt(
T.getSemantics(), That.IntVal), RndMode);
299void FAddendCoef::operator*=(
const FAddendCoef &That) {
303 if (That.isMinusOne()) {
308 if (
isInt() && That.isInt()) {
309 int Res = IntVal * (int)That.IntVal;
310 assert(!insaneIntVal(Res) &&
"Insane int value");
315 const fltSemantics &Semantic =
316 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
319 convertToFpType(Semantic);
323 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
324 APFloat::rmNearestTiesToEven);
326 F0.
multiply(That.getFpVal(), APFloat::rmNearestTiesToEven);
329void FAddendCoef::negate() {
333 getFpVal().changeSign();
336Value *FAddendCoef::getValue(
Type *Ty)
const {
338 ConstantFP::get(Ty,
float(IntVal)) :
352unsigned FAddend::drillValueDownOneStep
353 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
358 unsigned Opcode =
I->getOpcode();
360 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
362 Value *Opnd0 =
I->getOperand(0);
363 Value *Opnd1 =
I->getOperand(1);
372 Addend0.set(1, Opnd0);
374 Addend0.set(
C0,
nullptr);
378 FAddend &Addend = Opnd0 ? Addend1 : Addend0;
380 Addend.set(1, Opnd1);
382 Addend.set(
C1,
nullptr);
383 if (Opcode == Instruction::FSub)
388 return Opnd0 && Opnd1 ? 2 : 1;
391 Addend0.set(
APFloat(
C0->getValueAPF().getSemantics()),
nullptr);
395 if (
I->getOpcode() == Instruction::FMul) {
415unsigned FAddend::drillAddendDownOneStep
416 (FAddend &Addend0, FAddend &Addend1)
const {
420 unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
421 if (!BreakNum || Coeff.isOne())
424 Addend0.Scale(Coeff);
427 Addend1.Scale(Coeff);
432Value *FAddCombine::simplify(Instruction *
I) {
433 assert(
I->hasAllowReassoc() &&
I->hasNoSignedZeros() &&
434 "Expected 'reassoc'+'nsz' instruction");
437 if (
I->getType()->isVectorTy())
440 assert((
I->getOpcode() == Instruction::FAdd ||
441 I->getOpcode() == Instruction::FSub) &&
"Expect add/sub");
446 FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
448 unsigned OpndNum = FAddend::drillValueDownOneStep(
I, Opnd0, Opnd1);
451 unsigned Opnd0_ExpNum = 0;
452 unsigned Opnd1_ExpNum = 0;
454 if (!Opnd0.isConstant())
455 Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
458 if (OpndNum == 2 && !Opnd1.isConstant())
459 Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);
462 if (Opnd0_ExpNum && Opnd1_ExpNum) {
465 AllOpnds.push_back(&Opnd1_0);
466 if (Opnd0_ExpNum == 2)
467 AllOpnds.push_back(&Opnd0_1);
468 if (Opnd1_ExpNum == 2)
469 AllOpnds.push_back(&Opnd1_1);
472 unsigned InstQuota = 0;
479 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
488 const FAddendCoef &
CE = Opnd0.getCoef();
489 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
496 AllOpnds.push_back(&Opnd1_0);
497 if (Opnd1_ExpNum == 2)
498 AllOpnds.push_back(&Opnd1_1);
500 if (
Value *R = simplifyFAdd(AllOpnds, 1))
508 AllOpnds.push_back(&Opnd0_0);
509 if (Opnd0_ExpNum == 2)
510 AllOpnds.push_back(&Opnd0_1);
512 if (
Value *R = simplifyFAdd(AllOpnds, 1))
519Value *FAddCombine::simplifyFAdd(AddendVect& Addends,
unsigned InstrQuota) {
520 unsigned AddendNum = Addends.size();
521 assert(AddendNum <= 4 &&
"Too many addends");
524 unsigned NextTmpIdx = 0;
525 FAddend TmpResult[3];
533 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
535 const FAddend *ThisAddend = Addends[SymIdx];
541 Value *Val = ThisAddend->getSymVal();
550 unsigned StartIdx = SimpVect.size();
551 SimpVect.push_back(ThisAddend);
558 for (
unsigned SameSymIdx = SymIdx + 1;
559 SameSymIdx < AddendNum; SameSymIdx++) {
560 const FAddend *
T = Addends[SameSymIdx];
561 if (
T &&
T->getSymVal() == Val) {
564 Addends[SameSymIdx] =
nullptr;
565 SimpVect.push_back(
T);
570 if (StartIdx + 1 != SimpVect.size()) {
571 FAddend &
R = TmpResult[NextTmpIdx ++];
572 R = *SimpVect[StartIdx];
573 for (
unsigned Idx = StartIdx + 1;
Idx < SimpVect.size();
Idx++)
577 SimpVect.resize(StartIdx);
579 SimpVect.push_back(&R);
584 assert((NextTmpIdx <= std::size(TmpResult) + 1) &&
"out-of-bound access");
587 if (!SimpVect.empty())
588 Result = createNaryFAdd(SimpVect, InstrQuota);
597Value *FAddCombine::createNaryFAdd
598 (
const AddendVect &Opnds,
unsigned InstrQuota) {
599 assert(!Opnds.empty() &&
"Expect at least one addend");
603 unsigned InstrNeeded = calcInstrNumber(Opnds);
604 if (InstrNeeded > InstrQuota)
617 Value *LastVal =
nullptr;
618 bool LastValNeedNeg =
false;
621 for (
const FAddend *Opnd : Opnds) {
623 Value *
V = createAddendVal(*Opnd, NeedNeg);
626 LastValNeedNeg = NeedNeg;
630 if (LastValNeedNeg == NeedNeg) {
631 LastVal = createFAdd(LastVal, V);
636 LastVal = createFSub(V, LastVal);
638 LastVal = createFSub(LastVal, V);
640 LastValNeedNeg =
false;
643 if (LastValNeedNeg) {
644 LastVal = createFNeg(LastVal);
648 assert(CreateInstrNum == InstrNeeded &&
649 "Inconsistent in instruction numbers");
656 Value *
V = Builder.CreateFSub(Opnd0, Opnd1);
658 createInstPostProc(
I);
663 Value *NewV = Builder.CreateFNeg(V);
665 createInstPostProc(
I,
true);
670 Value *
V = Builder.CreateFAdd(Opnd0, Opnd1);
672 createInstPostProc(
I);
677 Value *
V = Builder.CreateFMul(Opnd0, Opnd1);
679 createInstPostProc(
I);
683void FAddCombine::createInstPostProc(Instruction *NewInstr,
bool NoNumber) {
696unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
697 unsigned OpndNum = Opnds.size();
698 unsigned InstrNeeded = OpndNum - 1;
701 for (
const FAddend *Opnd : Opnds) {
702 if (Opnd->isConstant())
710 const FAddendCoef &
CE = Opnd->getCoef();
714 if (!
CE.isMinusOne() && !
CE.isOne())
728Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
729 const FAddendCoef &Coeff = Opnd.getCoef();
731 if (Opnd.isConstant()) {
733 return Coeff.getValue(Instr->
getType());
736 Value *OpndVal = Opnd.getSymVal();
738 if (Coeff.isMinusOne() || Coeff.isOne()) {
739 NeedNeg = Coeff.isMinusOne();
743 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
744 NeedNeg = Coeff.isMinusTwo();
745 return createFAdd(OpndVal, OpndVal);
749 return createFMul(OpndVal, Coeff.getValue(Instr->
getType()));
763 if (!
LHS->hasOneUse() && !
RHS->hasOneUse())
766 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
767 const APInt *
C1 =
nullptr, *C2 =
nullptr;
782 Value *NewAnd = Builder.CreateAnd(Z, *
C1);
783 return Builder.CreateSub(
RHS, NewAnd,
"sub");
787 Value *NewOr = Builder.CreateOr(Z, ~(*
C1));
788 return Builder.CreateSub(
RHS, NewOr,
"sub");
794 LHS =
I.getOperand(0);
795 RHS =
I.getOperand(1);
805 if (
C1->countr_zero() == 0)
807 Value *NewOr = Builder.CreateOr(Z, ~(*C2));
808 return Builder.CreateSub(
RHS, NewOr,
"sub");
816 Value *Op0 =
Add.getOperand(0), *Op1 =
Add.getOperand(1);
828 C1->isNegative() &&
C1->sge(-C2->
sext(
C1->getBitWidth()))) {
836 Builder.CreateNUWAdd(
X, ConstantInt::get(
X->getType(), NewC)), Ty);
845 Value *WideC = Builder.CreateSExt(NarrowC, Ty);
846 Value *NewC = Builder.CreateAdd(WideC, Op1C);
847 Value *WideX = Builder.CreateSExt(
X, Ty);
848 return BinaryOperator::CreateAdd(WideX, NewC);
853 Value *WideC = Builder.CreateZExt(NarrowC, Ty);
854 Value *NewC = Builder.CreateAdd(WideC, Op1C);
855 Value *WideX = Builder.CreateZExt(
X, Ty);
856 return BinaryOperator::CreateAdd(WideX, NewC);
862 Value *Op0 =
Add.getOperand(0), *Op1 =
Add.getOperand(1);
886 return BinaryOperator::CreateAdd(
Builder.CreateNot(
Y),
X);
890 X->getType()->getScalarSizeInBits() == 1)
895 X->getType()->getScalarSizeInBits() == 1)
902 auto *COne = ConstantInt::get(Op1C->
getType(), 1);
903 bool WillNotSOV = willNotOverflowSignedSub(Op1C, COne,
Add);
912 unsigned BitWidth = Ty->getScalarSizeInBits();
927 willNotOverflowSignedAdd(Op01C, Op1C,
Add));
935 return BinaryOperator::CreateXor(Op0, ConstantInt::get(
Add.getType(), *C2));
937 if (
C->isSignMask()) {
940 if (
Add.hasNoSignedWrap() ||
Add.hasNoUnsignedWrap())
941 return BinaryOperator::CreateDisjointOr(Op0, Op1);
945 return BinaryOperator::CreateXor(Op0, Op1);
957 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *C2 ^ *
C));
963 if ((*C2 | LHSKnown.
Zero).isAllOnes())
964 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *
C),
X);
971 unsigned BitWidth = Ty->getScalarSizeInBits();
979 Constant *ShAmtC = ConstantInt::get(Ty, ShAmt);
981 return BinaryOperator::CreateAShr(NewShl, ShAmtC);
990 Intrinsic::usub_sat,
X, ConstantInt::get(
Add.getType(), -*
C)));
999 Add,
Builder.CreateBinaryIntrinsic(Intrinsic::umin,
X,
1000 ConstantInt::get(Ty, ~SatC)));
1005 const APInt *InnerC;
1008 if (
C->isIntN(NarrowBW)) {
1009 APInt NarrowC =
C->trunc(NarrowBW);
1011 if (*InnerC == -NarrowC &&
1031template <
bool FP,
typename Mul2Rhs>
1034 constexpr unsigned MulOp =
FP ? Instruction::FMul : Instruction::Mul;
1035 constexpr unsigned AddOp =
FP ? Instruction::FAdd : Instruction::Add;
1036 constexpr unsigned Mul2Op =
FP ? Instruction::FMul : Instruction::Shl;
1069 return BinaryOperator::CreateMul(AB, AB);
1077 assert(
I.hasAllowReassoc() &&
I.hasNoSignedZeros() &&
"Assumption mismatch");
1153 (void)
C0.smul_ov(
C1, overflow);
1155 (
void)
C0.umul_ov(
C1, overflow);
1164 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
1176 if (
MatchRem(MulOpV, RemOpV,
C1, Rem2IsSigned) &&
1177 IsSigned == Rem2IsSigned) {
1181 if (
MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) &&
X == DivOpV &&
1183 Value *NewDivisor = ConstantInt::get(
X->getType(),
C0 *
C1);
1184 return IsSigned ?
Builder.CreateSRem(
X, NewDivisor,
"srem")
1185 :
Builder.CreateURem(
X, NewDivisor,
"urem");
1195 Div = DivSide,
C1 =
APInt(
I.getType()->getScalarSizeInBits(), 1);
1196 if (!RemSide->hasOneUse() || !
MatchMul(RemSide, Rem, C2))
1197 Rem = RemSide, C2 =
APInt(
I.getType()->getScalarSizeInBits(), 1);
1201 MatchDiv(Div, DivOpV, DivOpC, IsSigned) &&
X == DivOpV &&
1204 !(
C1.isOne() && !IsSigned && DivOpC.
isPowerOf2() && DivOpC != 2)) {
1210 Value *MulXC2 =
Builder.CreateMul(
X, ConstantInt::get(
X->getType(), C2));
1214 Builder.CreateMul(Div, ConstantInt::get(
X->getType(), NewC)), MulXC2);
1218 if (
Value *V = FoldDivRem(LHS, RHS))
1220 if (
Value *V = FoldDivRem(RHS, LHS))
1239 Value *NotMask = Builder.CreateShl(MinusOne, NBits,
"notmask");
1243 BOp->setHasNoSignedWrap();
1244 BOp->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
1251 assert(
I.getOpcode() == Instruction::Add &&
"Expecting add instruction");
1252 Type *Ty =
I.getType();
1253 auto getUAddSat = [&]() {
1282 Value *NewShl = Builder.CreateShl(
B, Cnt);
1283 return BinaryOperator::CreateSub(
A, NewShl);
1304 const APInt *MaskC, *MaskCCmp;
1317 ? (*MaskC == (
SMin | (*DivC - 1)))
1318 : (*DivC == 2 && *MaskC ==
SMin + 1);
1323 return BinaryOperator::CreateAShr(
1328 bool NSW,
bool NUW) {
1338 R->setHasNoSignedWrap(NSWOut);
1339 R->setHasNoUnsignedWrap(NUWOut);
1347 APInt MinusC1 = -(*C1);
1348 if (MinusC1 == (One << *C2)) {
1349 Constant *NewRHS = ConstantInt::get(RHS->getType(), MinusC1);
1350 return BinaryOperator::CreateSRem(RHS, NewRHS);
1358 if (!LHS->hasOneUse() && !RHS->hasOneUse())
1365 Instruction *NewAdd = BinaryOperator::CreateAdd(
A, NewOr);
1377 assert((
I.getOpcode() == Instruction::Add ||
1378 I.getOpcode() == Instruction::Or ||
1379 I.getOpcode() == Instruction::Sub) &&
1380 "Expecting add/or/sub instruction");
1393 if (
I.getOpcode() == Instruction::Sub &&
I.getOperand(1) !=
Select)
1396 Type *XTy =
X->getType();
1397 bool HadTrunc =
I.getType() != XTy;
1409 if (!
match(LowBitsToSkip,
1416 auto SkipExtInMagic = [&
I](
Value *&V) {
1417 if (
I.getOpcode() == Instruction::Sub)
1429 Value *SignExtendingValue, *Zero;
1449 SkipExtInMagic(SignExtendingValue);
1450 Constant *SignExtendingValueBaseConstant;
1451 if (!
match(SignExtendingValue,
1456 if (
I.getOpcode() == Instruction::Sub
1457 ? !
match(SignExtendingValueBaseConstant,
m_One())
1461 auto *NewAShr = BinaryOperator::CreateAShr(
X, LowBitsToSkip,
1462 Extract->
getName() +
".sext");
1463 NewAShr->copyIRFlags(Extract);
1477 assert((
I.getOpcode() == Instruction::Add ||
1478 I.getOpcode() == Instruction::Sub) &&
1479 "Expected add/sub");
1482 if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse()))
1491 bool HasNSW =
I.hasNoSignedWrap() && Op0->hasNoSignedWrap() &&
1492 Op1->hasNoSignedWrap();
1493 bool HasNUW =
I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() &&
1494 Op1->hasNoUnsignedWrap();
1497 Value *NewMath = Builder.CreateBinOp(
I.getOpcode(),
X,
Y);
1499 NewI->setHasNoSignedWrap(HasNSW);
1500 NewI->setHasNoUnsignedWrap(HasNUW);
1502 auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt);
1503 NewShl->setHasNoSignedWrap(HasNSW);
1504 NewShl->setHasNoUnsignedWrap(HasNUW);
1511 unsigned BitWidth =
I.getType()->getScalarSizeInBits();
1544 return BinaryOperator::CreateMul(
X,
Y);
1557 return !MinY.
isZero() && !MaxX.
ugt(-MaxY);
1583 if (
X->getType() !=
I.getType()) {
1587 return BinaryOperator::CreateUDiv(NUWAdd,
Y);
1592 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(),
1593 SQ.getWithInstruction(&
I)))
1627 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
1629 I.hasNoUnsignedWrap()))
1632 I.hasNoUnsignedWrap()))
1634 Type *Ty =
I.getType();
1635 if (Ty->isIntOrIntVectorTy(1))
1636 return BinaryOperator::CreateXor(LHS, RHS);
1640 auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1));
1641 Shl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1642 Shl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
1653 auto *
Sub = BinaryOperator::CreateSub(RHS,
A);
1655 Sub->setHasNoSignedWrap(
I.hasNoSignedWrap() && OB0->hasNoSignedWrap());
1662 auto *
Sub = BinaryOperator::CreateSub(LHS,
B);
1664 Sub->setHasNoSignedWrap(
I.hasNoSignedWrap() && OBO->hasNoSignedWrap());
1678 return BinaryOperator::CreateSub(
A,
B);
1693 return BinaryOperator::CreateAdd(
Sub, ConstantInt::get(Ty, *
C - 1));
1699 return BinaryOperator::CreateAdd(
A,
Builder.CreateShl(RHS, 1,
"reass.add"));
1703 return BinaryOperator::CreateAdd(
A,
Builder.CreateShl(LHS, 1,
"reass.add"));
1710 (LHS->hasOneUse() || RHS->hasOneUse())) {
1720 return BinaryOperator::CreateAdd(
Sub,
C1);
1731 Constant *NewMask = ConstantInt::get(RHS->getType(), *
C1 - 1);
1732 return BinaryOperator::CreateAnd(
A, NewMask);
1744 A->getType()->isIntOrIntVectorTy(1))
1752 A->getType()->isIntOrIntVectorTy()) {
1772 return BinaryOperator::CreateDisjointOr(LHS, RHS);
1774 return BinaryOperator::CreateOr(LHS, RHS);
1786 return BinaryOperator::CreateOr(
A,
B);
1806 I.hasNoUnsignedWrap(),
I.hasNoSignedWrap());
1807 return BinaryOperator::CreateAnd(
Add,
A);
1816 const APInt *LowMask;
1825 Value *NewAdd =
Builder.CreateAdd(
A, ConstantInt::get(Ty, *LowMask));
1826 return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, ~*LowMask));
1838 return BinaryOperator::CreateAnd(Dec, Not);
1849 Type *Ty =
I.getType();
1850 Constant *NewMulC = ConstantInt::get(Ty, 1 - *
C1);
1856 const APInt *NegPow2C;
1861 return BinaryOperator::CreateSub(
B, Shl);
1866 uint64_t
BitWidth = Ty->getScalarSizeInBits();
1871 Value *Zext =
Builder.CreateZExt(NotZero, Ty,
"isnotnull.zext");
1872 return BinaryOperator::CreateOr(LHS, Zext);
1897 Value *OneConst = ConstantInt::get(
A->getType(), 1);
1910 const APInt *ShiftAmt, *Mask;
1921 Mask->popcount() == *ShiftAmt) {
1924 unsigned Xbits =
X->getType()->getScalarSizeInBits();
1925 unsigned Ibits = Ty->getScalarSizeInBits();
1926 bool NeedZext = Ibits > Xbits;
1927 Constant *MaskC = ConstantInt::get(Ty, Mask->zext(Ibits));
1928 if (NeedZext || willNotOverflowUnsignedAdd(
X, MaskC,
I)) {
1933 return BinaryOperator::CreateLShr(
1934 Add, ConstantInt::get(Ty, ShiftAmt->
zext(Ibits)));
1943 bool ConsumesLHS, ConsumesRHS;
1944 if (
isFreeToInvert(LHS, LHS->hasOneUse(), ConsumesLHS) && ConsumesLHS &&
1945 isFreeToInvert(RHS, RHS->hasOneUse(), ConsumesRHS) && ConsumesRHS) {
1948 assert(NotLHS !=
nullptr && NotRHS !=
nullptr &&
1949 "isFreeToInvert desynced with getFreelyInverted");
1951 return BinaryOperator::CreateSub(
1963 if (!
I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHSCache, RHSCache,
I)) {
1965 I.setHasNoSignedWrap(
true);
1967 if (!
I.hasNoUnsignedWrap() &&
1968 willNotOverflowUnsignedAdd(LHSCache, RHSCache,
I)) {
1970 I.setHasNoUnsignedWrap(
true);
1988 Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
1996 I,
Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
1997 {Builder.CreateDisjointOr(A, B)}));
2011 *XorC ==
A->getType()->getScalarSizeInBits() - 1 &&
2014 Value *Ctlz =
Builder.CreateIntrinsic(Intrinsic::ctlz, {
A->getType()},
2017 ConstantInt::get(
A->getType(),
A->getType()->getScalarSizeInBits()),
2018 Ctlz,
"",
true,
true);
2035 APInt NegTwo(Ty->getScalarSizeInBits(), -2,
true);
2039 A, ConstantInt::get(
2040 Ty,
APInt(Ty->getScalarSizeInBits(), -1,
true)));
2041 return BinaryOperator::CreateAnd(Ret, ConstantInt::get(Ty, NegTwo));
2048 Value *Start, *Step;
2067 Value *XY = Builder.CreateFSubFMF(
X,
Y, &
I);
2068 Value *MulZ = Builder.CreateFMulFMF(Z, XY, &
I);
2075 assert((
I.getOpcode() == Instruction::FAdd ||
2076 I.getOpcode() == Instruction::FSub) &&
"Expecting fadd/fsub");
2077 assert(
I.hasAllowReassoc() &&
I.hasNoSignedZeros() &&
2078 "FP factorization requires FMF");
2083 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2084 if (!Op0->
hasOneUse() || !Op1->hasOneUse())
2104 bool IsFAdd =
I.getOpcode() == Instruction::FAdd;
2105 Value *XY = IsFAdd ? Builder.CreateFAddFMF(
X,
Y, &
I)
2106 : Builder.CreateFSubFMF(
X,
Y, &
I);
2120 I.getFastMathFlags(),
2121 SQ.getWithInstruction(&
I)))
2180 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
2185 if (
I.hasAllowReassoc() &&
I.hasNoSignedZeros()) {
2198 I,
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
2199 {X->getType()}, {Y, X}, &
I));
2206 Constant *NewStartC = ConstantFP::get(
I.getType(), *
C + *StartC);
2208 I,
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
2209 {X->getType()}, {NewStartC, X}, &
I));
2217 Instruction::FAdd, MulC, ConstantFP::get(
I.getType(), 1.0),
DL))
2240 if (!Result->hasNoNaNs())
2241 Result->setHasNoInfs(
false);
2251 if (LHS->getType() != RHS->getType())
2260 Ptr =
GEP->getPointerOperand();
2277 Base.RHSNW =
GEP->getNoWrapFlags();
2279 Base.RHSNW =
Base.RHSNW.intersectForOffsetAdd(
GEP->getNoWrapFlags());
2281 RHS =
GEP->getPointerOperand();
2291 if (LHS ==
Base.Ptr)
2298 Base.LHSNW =
GEP->getNoWrapFlags();
2300 Base.LHSNW =
Base.LHSNW.intersectForOffsetAdd(
GEP->getNoWrapFlags());
2302 LHS =
GEP->getPointerOperand();
2309 unsigned NumGEPs = 0;
2311 bool SeenMultiUse =
false;
2316 if (!
GEP->hasOneUse()) {
2319 SeenMultiUse =
true;
2332 Type *Ty,
bool IsNUW) {
2334 if (!
Base.Ptr ||
Base.isExpensive())
2340 bool RewriteGEPs = !
Base.LHSGEPs.empty() && !
Base.RHSGEPs.empty();
2342 Type *IdxTy =
DL.getIndexType(LHS->getType());
2343 Value *Result = EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy, RewriteGEPs);
2344 Value *Offset2 = EmitGEPOffsets(
Base.RHSGEPs,
Base.RHSNW, IdxTy, RewriteGEPs);
2350 (
I->use_empty() ||
I->hasOneUse()) &&
I->hasNoSignedWrap() &&
2351 !
I->hasNoUnsignedWrap() &&
2352 ((
I->getOpcode() == Instruction::Mul &&
2354 I->getOpcode() == Instruction::Shl))
2362 Builder.CreateSub(Result, Offset2,
"gepdiff",
2363 IsNUW &&
Base.LHSNW.hasNoUnsignedWrap() &&
2364 Base.RHSNW.hasNoUnsignedWrap(),
2365 Base.LHSNW.isInBounds() &&
Base.RHSNW.isInBounds());
2368 return Builder.CreateIntCast(Result, Ty,
true);
2373 Value *Op0 =
I.getOperand(0);
2374 Value *Op1 =
I.getOperand(1);
2375 Type *Ty =
I.getType();
2396 Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {
Y, Z});
2397 return BinaryOperator::CreateAdd(
X, USub);
2400 Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {Z,
Y});
2401 return BinaryOperator::CreateAdd(
X, USub);
2423 if (!
I.hasNoUnsignedWrap())
2430 bool MaskIsLHS =
match(&
I,
m_Sub(MaskPat, ZExtPat));
2431 if ((!MaskIsLHS && !
match(&
I,
m_Sub(ZExtPat, MaskPat))) ||
2432 Mask->countr_one() !=
Y->getType()->getScalarSizeInBits())
2435 Value *TruncX = Builder.CreateTrunc(
X,
Y->getType());
2436 Value *NarrowSub = MaskIsLHS ? Builder.CreateNUWSub(TruncX,
Y)
2437 : Builder.CreateNUWSub(
Y, TruncX);
2438 return new ZExtInst(NarrowSub,
I.getType());
2443 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(),
2444 SQ.getWithInstruction(&
I)))
2453 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2457 if (
Value *V = dyn_castNegVal(Op1)) {
2461 assert(BO->getOpcode() == Instruction::Sub &&
2462 "Expected a subtraction operator!");
2463 if (BO->hasNoSignedWrap() &&
I.hasNoSignedWrap())
2466 if (
cast<Constant>(Op1)->isNotMinSignedValue() &&
I.hasNoSignedWrap())
2486 bool WillNotSOV = willNotOverflowSignedSub(
C, C2,
I);
2495 Op1NSW = OBO1->hasNoSignedWrap();
2496 Op1NUW = OBO1->hasNoUnsignedWrap();
2505 auto TryToNarrowDeduceFlags = [
this, &
I, &Op0, &Op1]() ->
Instruction * {
2510 if (!
I.hasNoSignedWrap() && willNotOverflowSignedSub(Op0, Op1,
I)) {
2512 I.setHasNoSignedWrap(
true);
2514 if (!
I.hasNoUnsignedWrap() && willNotOverflowUnsignedSub(Op0, Op1,
I)) {
2516 I.setHasNoUnsignedWrap(
true);
2532 I.hasNoSignedWrap(),
2534 return BinaryOperator::CreateAdd(NegOp1, Op0);
2537 return TryToNarrowDeduceFlags();
2543 if (
I.getType()->isIntOrIntVectorTy(1))
2544 return BinaryOperator::CreateXor(Op0, Op1);
2553 return BinaryOperator::CreateAdd(
Builder.CreateNot(Op1),
X);
2561 return BinaryOperator::CreateAnd(
2573 return BinaryOperator::CreateSub(XZ, YW);
2584 Sub->setHasNoUnsignedWrap(HasNUW);
2585 Sub->setHasNoSignedWrap(HasNSW);
2596 return BinaryOperator::CreateAdd(OpsSub, ConstsSub);
2607 R = BinaryOperator::CreateSub(
X, Z);
2609 R = BinaryOperator::CreateSub(
X,
Y);
2611 R = BinaryOperator::CreateSub(W, Z);
2613 R = BinaryOperator::CreateSub(W,
Y);
2615 bool NSW =
I.hasNoSignedWrap() &&
2619 bool NUW =
I.hasNoUnsignedWrap() &&
2621 R->setHasNoSignedWrap(NSW);
2622 R->setHasNoUnsignedWrap(NUW);
2632 bool ConsumesOp0, ConsumesOp1;
2635 (ConsumesOp0 || ConsumesOp1)) {
2638 assert(NotOp0 !=
nullptr && NotOp1 !=
nullptr &&
2639 "isFreeToInvert desynced with getFreelyInverted");
2640 return BinaryOperator::CreateSub(NotOp1, NotOp0);
2644 auto m_AddRdx = [](
Value *&Vec) {
2648 if (
match(Op0, m_AddRdx(V0)) &&
match(Op1, m_AddRdx(
V1)) &&
2649 V0->getType() ==
V1->getType()) {
2653 Value *Rdx =
Builder.CreateIntrinsic(Intrinsic::vector_reduce_add,
2654 {
Sub->getType()}, {
Sub});
2705 Op1,
SQ.getWithInstruction(&
I).getWithoutDomCondCache());
2706 if ((*Op0C | RHSKnown.
Zero).isAllOnes())
2707 return BinaryOperator::CreateXor(Op1, Op0);
2714 const APInt *C2, *C3;
2719 APInt C2AndC3 = *C2 & *C3;
2720 APInt C2AndC3Minus1 = C2AndC3 - 1;
2721 APInt C2AddC3 = *C2 + *C3;
2722 if ((*C3 - C2AndC3Minus1).isPowerOf2() &&
2725 return BinaryOperator::CreateAdd(
2726 And, ConstantInt::get(
I.getType(), *Op0C - C2AndC3));
2747 return BinaryOperator::CreateXor(
A,
B);
2755 return BinaryOperator::CreateAnd(
A,
B);
2763 return BinaryOperator::CreateOr(
A,
B);
2780 return BinaryOperator::CreateAnd(
A,
B);
2796 return BinaryOperator::CreateAnd(
2797 Y,
Builder.CreateNot(Op1, Op1->getName() +
".not"));
2828 if (m_SubXorCmp(Op0, Op1))
2829 return createSelectInstWithUnknownProfile(
C,
Builder.CreateNeg(
X),
X);
2830 if (m_SubXorCmp(Op1, Op0))
2831 return createSelectInstWithUnknownProfile(
C,
X,
Builder.CreateNeg(
X));
2851 auto SinkSubIntoSelect =
2858 if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal)
2863 bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal;
2864 Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal);
2868 OtherHandOfSubIsTrueVal ? NewSub : Zero);
2876 return Builder->CreateSub(OtherHandOfSelect,
2883 return Builder->CreateSub(Op0,
2892 return BinaryOperator::CreateAnd(
2893 Op0,
Builder.CreateNot(
Y,
Y->getName() +
".not"));
2906 return BinaryOperator::CreateSub(Not,
X);
2912 return BinaryOperator::CreateSub(
X, Not);
2920 I.getType()->getScalarSizeInBits() != 1 &&
2921 (Op0->
hasOneUse() || Op1->hasOneUse())) {
2927 I.getType()->getScalarSizeInBits() != 1 &&
2928 (Op0->
hasOneUse() || Op1->hasOneUse())) {
2935 Value *LHSOp, *RHSOp;
2939 I.hasNoUnsignedWrap()))
2949 auto MatchSubOfZExtOfPtrToIntOrAddr = [&]() {
2963 if (MatchSubOfZExtOfPtrToIntOrAddr()) {
2965 if (
GEP->getPointerOperand() == RHSOp) {
2966 if (
GEP->hasNoUnsignedWrap() ||
GEP->hasNoUnsignedSignedWrap()) {
2968 Value *Res =
GEP->hasNoUnsignedWrap()
2971 GEP->hasNoUnsignedSignedWrap())
2986 Type *Ty =
I.getType();
2987 unsigned BitWidth = Ty->getScalarSizeInBits();
2989 Op1->hasNUses(2) && *ShAmt ==
BitWidth - 1 &&
2996 Value *NegA =
I.hasNoUnsignedWrap()
2998 :
Builder.CreateNeg(
A,
"",
I.hasNoSignedWrap());
3006 const APInt *AddC, *AndC;
3011 if ((HighMask & *AndC).
isZero())
3012 return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC)));
3023 I,
Builder.CreateIntrinsic(Intrinsic::umin, {I.getType()}, {Op0, Y}));
3030 I,
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op1}));
3035 I,
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op0, X}));
3039 Value *USub =
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {
X, Op0});
3045 Value *USub =
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op1,
X});
3053 I,
Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
3054 {Builder.CreateNot(X)}));
3062 bool PropagateNSW =
I.hasNoSignedWrap() && OBO0->hasNoSignedWrap() &&
3063 OBO1->hasNoSignedWrap() &&
BitWidth > 2;
3064 bool PropagateNUW =
I.hasNoUnsignedWrap() && OBO0->hasNoUnsignedWrap() &&
3065 OBO1->hasNoUnsignedWrap() &&
BitWidth > 1;
3075 if (
I.hasNoUnsignedWrap() ||
I.hasNoSignedWrap()) {
3077 Builder.CreateSub(
X,
Y,
"sub",
false,
true);
3097 Value *Z, *Add0, *Add1;
3104 unsigned NumOfNewInstrs = 0;
3109 unsigned NumOfDeadInstrs = 0;
3115 NumOfDeadInstrs += Add0->
hasOneUse() ? 1 : 0;
3117 if (Op1->hasOneUse()) {
3119 NumOfDeadInstrs += Add1->
hasOneUse() ? 1 : 0;
3121 if (NumOfDeadInstrs >= NumOfNewInstrs) {
3126 I.hasNoSignedWrap());
3136 return BinaryOperator::CreateAnd(Op1, ConstantInt::get(Ty, *AddC));
3139 return TryToNarrowDeduceFlags();
3207 Instruction &FMFSource) {
3213 X, Builder.CreateFNegFMF(
Y, &FMFSource), &FMFSource));
3218 Builder.CreateFNegFMF(
X, &FMFSource),
Y, &FMFSource));
3225 if (
II->getIntrinsicID() == Intrinsic::ldexp) {
3228 Builder.CreateCall(
II->getCalledFunction(),
3229 {Builder.CreateFNegFMF(II->getArgOperand(0), FMF),
3230 II->getArgOperand(1)});
3231 New->setFastMathFlags(FMF);
3232 New->copyMetadata(*
II);
3253 if (
I.hasNoSignedZeros() &&
3261 if (
Instruction *R = hoistFNegAboveFMulFDiv(OneUse,
I))
3270 auto propagateSelectFMF = [&](
SelectInst *S,
bool CommonOperand) {
3273 FastMathFlags FMF =
I.getFastMathFlags() | OldSel->getFastMathFlags();
3275 if (!OldSel->hasNoSignedZeros() && !CommonOperand &&
3286 Cond,
P, NegY,
"",
nullptr,
3288 propagateSelectFMF(NewSel,
P ==
Y);
3296 Cond, NegX,
P,
"",
nullptr,
3298 propagateSelectFMF(NewSel,
P ==
X);
3308 Cond, NegX, NegY,
"",
nullptr,
3310 propagateSelectFMF(NewSel,
true);
3342 I.getFastMathFlags(),
3373 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3380 if (
I.hasNoSignedZeros() ||
3415 Type *Ty =
I.getType();
3449 if (
I.hasAllowReassoc() &&
I.hasNoSignedZeros()) {
3462 Instruction::FSub,
C, ConstantFP::get(Ty, 1.0),
DL))
3468 Instruction::FSub, ConstantFP::get(Ty, 1.0),
C,
DL))
3483 auto m_FaddRdx = [](
Value *&Sum,
Value *&Vec) {
3488 if (
match(Op0, m_FaddRdx(A0, V0)) &&
match(Op1, m_FaddRdx(A1,
V1)) &&
3489 V0->getType() ==
V1->getType()) {
3493 Value *Rdx =
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
3494 {
Sub->getType()}, {A0,
Sub}, &
I);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
AMDGPU Register Bank Select
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Instruction * factorizeFAddFSub(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Factor a common operand out of fadd/fsub of fmul/fdiv.
static Instruction * foldAddToAshr(BinaryOperator &Add)
Try to reduce signed division by power-of-2 to an arithmetic shift right.
static bool MatchMul(Value *E, Value *&Op, APInt &C)
static bool MatchDiv(Value *E, Value *&Op, APInt &C, bool IsSigned)
static Instruction * foldFNegIntoConstant(Instruction &I, const DataLayout &DL)
This eliminates floating-point negation in either 'fneg(X)' or 'fsub(-0.0, X)' form by combining into...
static Instruction * combineAddSubWithShlAddSub(InstCombiner::BuilderTy &Builder, const BinaryOperator &I)
static Instruction * factorizeLerp(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Eliminate an op from a linear interpolation (lerp) pattern.
static Instruction * foldSubOfMinMax(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Instruction * foldSubNUWOfMaskAndZExt(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
sub nuw (and X, LowMask), (zext Y) --> zext (sub nuw (trunc X), Y) sub nuw (zext Y),...
static Instruction * foldBoxMultiply(BinaryOperator &I)
Reduce a sequence of masked half-width multiplies to a single multiply.
static Value * checkForNegativeOperand(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned)
static Instruction * foldNoWrapAdd(BinaryOperator &Add, InstCombiner::BuilderTy &Builder)
Wrapping flags may allow combining constants separated by an extend.
static bool matchesSquareSum(BinaryOperator &I, Mul2Rhs M2Rhs, Value *&A, Value *&B)
static Instruction * factorizeMathWithShlOps(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
This is a specialization of a more general transform from foldUsingDistributiveLaws.
static Instruction * canonicalizeLowbitMask(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Fold (1 << NBits) - 1 Into: ~(-(1 << NBits)) Because a 'not' is better for bit-tracking analysis and ...
static bool checkDivCeilNUW(Value *X, Value *Y, const SimplifyQuery &SQ)
Return true if X + (Y-1) is provably non-wrapping in X's type.
static Instruction * foldToUnsignedSaturatedAdd(BinaryOperator &I)
static bool MatchRem(Value *E, Value *&Op, APInt &C, bool &IsSigned)
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
static constexpr Value * getValue(Ty &ValueOrUse)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
uint64_t IntrinsicInst * II
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
opStatus multiply(const APFloat &RHS, roundingMode RM)
Class for arbitrary precision integers.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
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 isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
int32_t exactLogBase2() const
unsigned countr_zero() const
Count the number of trailing zero bits.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned logBase2() const
bool isMask(unsigned numBits) const
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
bool isOne() const
Determine if this is a value of 1.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
static BinaryOperator * CreateFAddFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")
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...
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static BinaryOperator * CreateFMulFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")
static BinaryOperator * CreateFDivFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")
static BinaryOperator * CreateFSubFMF(Value *V1, Value *V2, FastMathFlags FMF, const Twine &Name="")
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
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 ...
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
const APFloat & getValueAPF() const
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
This class represents a range of values.
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
This is an important base class in LLVM.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isElementWiseEqual(Value *Y) const
Return true if this constant and a constant 'Y' are element-wise equal.
A parsed version of the target data layout string in and methods for querying it.
Convenience struct for specifying and reasoning about fast-math flags.
static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)
Intersect rewrite-based flags.
bool noSignedZeros() const
static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)
Union value flags.
void setNoInfs(bool B=true)
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
Instruction * foldBinOpOfSelectAndCastOfSelectCondition(BinaryOperator &I)
Tries to simplify binops of select and cast of the select condition.
Instruction * visitAdd(BinaryOperator &I)
Instruction * canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(BinaryOperator &I)
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
bool SimplifyAssociativeOrCommutative(BinaryOperator &I)
Performs a few simplifications for operators which are associative or commutative.
Value * foldUsingDistributiveLaws(BinaryOperator &I)
Tries to simplify binary operations which some other binary operation distributes over.
Instruction * foldBinOpShiftWithShift(BinaryOperator &I)
Instruction * foldSquareSumInt(BinaryOperator &I)
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Instruction * foldBinOpSelectBinOp(BinaryOperator &Op)
In some cases it is beneficial to fold a select into a binary operator.
Instruction * foldSquareSumFP(BinaryOperator &I)
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 * visitSub(BinaryOperator &I)
Instruction * foldDivCeil(BinaryOperator &I)
Fold both forms of the div_ceil idiom: (add (udiv X, Y), (zext (icmp ne (urem X, Y),...
Value * OptimizePointerDifference(Value *LHS, Value *RHS, Type *Ty, bool isNUW)
Optimize pointer differences into the same array into a size.
Instruction * visitFAdd(BinaryOperator &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Instruction * foldAddLikeCommutative(Value *LHS, Value *RHS, bool NSW, bool NUW)
Common transforms for add / disjoint or.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Value * SimplifyAddWithRemainder(BinaryOperator &I)
Tries to simplify add operations using the definition of remainder.
Instruction * foldAddWithConstant(BinaryOperator &Add)
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Value * SimplifySelectsFeedingBinaryOp(BinaryOperator &I, Value *LHS, Value *RHS)
Instruction * visitFNeg(UnaryOperator &I)
Instruction * visitFSub(BinaryOperator &I)
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
unsigned ComputeNumSignBits(const Value *Op, const Instruction *CtxI=nullptr, unsigned Depth=0) const
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
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
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
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 void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
LLVM_ABI void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
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.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
static Value * Negate(bool LHSIsZero, bool IsNSW, Value *Root, InstCombinerImpl &IC)
Attempt to negate Root.
Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
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 instruction constructs a fixed permutation of two input vectors.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
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 bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
This class represents zero extension of integer types.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
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.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrToIntSameSize_match< OpTy > m_PtrToIntSameSize(const DataLayout &DL, const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
auto m_c_UMax(const LHS &L, const RHS &R)
Matches a UMax with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)
Matches FMul with LHS and RHS in either order.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
auto m_PtrToIntOrAddr(const OpTy &Op)
Matches PtrToInt or PtrToAddr.
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap, true > m_c_NSWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
CommutativeBinaryIntrinsic_match< IntrID, T0, T1 > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)
auto m_Poison()
Match an arbitrary poison constant.
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)
CastOperator_match< OpTy, Instruction::PtrToAddr > m_PtrToAddr(const OpTy &Op)
Matches PtrToAddr.
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.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
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.
auto m_UMin(const Opnd0 &Op0, const Opnd1 &Op1)
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()...
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
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_UMax(const Opnd0 &Op0, const Opnd1 &Op1)
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
auto m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
auto m_Ctpop(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)
Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
auto m_Ctlz(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
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.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
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)
auto m_c_MaxOrMin(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
FNeg_match< OpTy, true > m_FNegOrFSubNegZero(const OpTy &X)
Match fneg X or fsub -0.0, X.
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap >, DisjointOr_match< LHS, RHS > > m_NSWAddLike(const LHS &L, const RHS &R)
Match either "add nsw" or "or disjoint".
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::FAdd, true > m_c_FAdd(const LHS &L, const RHS &R)
Matches FAdd with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)
auto m_c_UMin(const LHS &L, const RHS &R)
Matches a UMin with LHS and RHS in either order.
auto m_c_SMax(const LHS &L, const RHS &R)
Matches an SMax with LHS and RHS in either order.
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_VecReverse(const Opnd0 &Op0)
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".
auto m_c_SMin(const LHS &L, const RHS &R)
Matches an SMin with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
@ CE
Windows NT (Windows on ARM)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool haveNoCommonBitsSet(const WithCache< const Value * > &LHSCache, const WithCache< const Value * > &RHSCache, const SimplifyQuery &SQ)
Return true if LHS and RHS have no common bits set.
LLVM_ABI Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
@ Known
Known to have no common set bits.
@ Unknown
Not known to have no common set bits.
@ OnlyIfUndefIgnored
Known to have no common set bits only if undef values are ignored.
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_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
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...
LLVM_ABI bool canIgnoreSignBitOfZero(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is zero.
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
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 bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
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.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
LLVM_ABI NoCommonBitsSetResult getNoCommonBitsSetResult(const WithCache< const Value * > &LHSCache, const WithCache< const Value * > &RHSCache, const SimplifyQuery &SQ)
Return how strongly LHS and RHS are known to have no common set bits.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q)
Given operand for an FNeg, fold the result or return null.
LLVM_ABI Value * simplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FSub, fold the result or return null.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI Value * simplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)
Given operands for an FAdd, fold the result or return null.
LLVM_ABI bool cannotBeNegativeZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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 bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Mul
Product of integers.
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ Sub
Subtraction of integers.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Value * Ptr
Common base pointer.
SmallVector< GEPOperator * > RHSGEPs
RHS GEPs until common base.
SmallVector< GEPOperator * > LHSGEPs
LHS GEPs until common base.
bool isExpensive() const
Whether expanding the GEP chains is expensive.
static CommonPointerBase compute(Value *LHS, Value *RHS)