39#define DEBUG_TYPE "instcombine"
56 FAddendCoef() =
default;
61 void operator=(
const FAddendCoef &
A);
66 assert(!insaneIntVal(
C) &&
"Insane coefficient");
67 IsFp =
false; IntVal =
C;
74 bool isZero()
const {
return isInt() ? !IntVal : getFpVal().isZero(); }
77 bool isOne()
const {
return isInt() && IntVal == 1; }
78 bool isTwo()
const {
return isInt() && IntVal == 2; }
79 bool isMinusOne()
const {
return isInt() && IntVal == -1; }
80 bool isMinusTwo()
const {
return isInt() && IntVal == -2; }
83 bool insaneIntVal(
int V) {
return V > 4 || V < -4; }
85 APFloat *getFpValPtr() {
return reinterpret_cast<APFloat *
>(&FpValBuf); }
87 const APFloat *getFpValPtr()
const {
88 return reinterpret_cast<const APFloat *
>(&FpValBuf);
91 const APFloat &getFpVal()
const {
92 assert(IsFp && BufHasFpVal &&
"Incorret state");
93 return *getFpValPtr();
97 assert(IsFp && BufHasFpVal &&
"Incorret state");
98 return *getFpValPtr();
101 bool isInt()
const {
return !IsFp; }
115 bool BufHasFpVal =
false;
134 assert((Val ==
T.Val) &&
"Symbolic-values disagree");
138 Value *getSymVal()
const {
return Val; }
139 const FAddendCoef &getCoef()
const {
return Coeff; }
141 bool isConstant()
const {
return Val ==
nullptr; }
142 bool isZero()
const {
return Coeff.isZero(); }
144 void set(
short Coefficient,
Value *V) {
145 Coeff.set(Coefficient);
149 Coeff.set(Coefficient);
153 Coeff.set(Coefficient->getValueAPF());
157 void negate() { Coeff.negate(); }
161 static unsigned drillValueDownOneStep(
Value* V, FAddend &A0, FAddend &A1);
165 unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1)
const;
168 void Scale(
const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
171 Value *Val =
nullptr;
187 Value *simplifyFAdd(AddendVect& V,
unsigned InstrQuota);
190 Value *createAddendVal(
const FAddend &
A,
bool& NeedNeg);
193 unsigned calcInstrNumber(
const AddendVect& Vect);
199 Value *createNaryFAdd(
const AddendVect& Opnds,
unsigned InstrQuota);
200 void createInstPostProc(
Instruction *NewInst,
bool NoNumber =
false);
204 unsigned CreateInstrNum;
205 void initCreateInstNum() { CreateInstrNum = 0; }
206 void incCreateInstNum() { CreateInstrNum++; }
208 void initCreateInstNum() {}
209 void incCreateInstNum() {}
224FAddendCoef::~FAddendCoef() {
226 getFpValPtr()->~APFloat();
229void FAddendCoef::set(
const APFloat&
C) {
239 IsFp = BufHasFpVal =
true;
242void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
253 IsFp = BufHasFpVal =
true;
256APFloat FAddendCoef::createAPFloatFromInt(
const fltSemantics &Sem,
int Val) {
266void FAddendCoef::operator=(
const FAddendCoef &That) {
270 set(That.getFpVal());
273void FAddendCoef::operator+=(
const FAddendCoef &That) {
275 if (
isInt() == That.isInt()) {
277 IntVal += That.IntVal;
279 getFpVal().add(That.getFpVal(), RndMode);
285 convertToFpType(
T.getSemantics());
286 getFpVal().add(
T, RndMode);
291 T.add(createAPFloatFromInt(
T.getSemantics(), That.IntVal), RndMode);
294void FAddendCoef::operator*=(
const FAddendCoef &That) {
298 if (That.isMinusOne()) {
303 if (
isInt() && That.isInt()) {
304 int Res = IntVal * (int)That.IntVal;
305 assert(!insaneIntVal(Res) &&
"Insane int value");
310 const fltSemantics &Semantic =
311 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
314 convertToFpType(Semantic);
318 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
319 APFloat::rmNearestTiesToEven);
321 F0.
multiply(That.getFpVal(), APFloat::rmNearestTiesToEven);
324void FAddendCoef::negate() {
328 getFpVal().changeSign();
331Value *FAddendCoef::getValue(
Type *Ty)
const {
333 ConstantFP::get(Ty,
float(IntVal)) :
347unsigned FAddend::drillValueDownOneStep
348 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
353 unsigned Opcode =
I->getOpcode();
355 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
357 Value *Opnd0 =
I->getOperand(0);
358 Value *Opnd1 =
I->getOperand(1);
367 Addend0.set(1, Opnd0);
369 Addend0.set(C0,
nullptr);
373 FAddend &Addend = Opnd0 ? Addend1 : Addend0;
375 Addend.set(1, Opnd1);
377 Addend.set(C1,
nullptr);
378 if (Opcode == Instruction::FSub)
383 return Opnd0 && Opnd1 ? 2 : 1;
390 if (
I->getOpcode() == Instruction::FMul) {
391 Value *V0 =
I->getOperand(0);
392 Value *V1 =
I->getOperand(1);
410unsigned FAddend::drillAddendDownOneStep
411 (FAddend &Addend0, FAddend &Addend1)
const {
415 unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
416 if (!BreakNum || Coeff.isOne())
419 Addend0.Scale(Coeff);
422 Addend1.Scale(Coeff);
427Value *FAddCombine::simplify(Instruction *
I) {
428 assert(
I->hasAllowReassoc() &&
I->hasNoSignedZeros() &&
429 "Expected 'reassoc'+'nsz' instruction");
432 if (
I->getType()->isVectorTy())
435 assert((
I->getOpcode() == Instruction::FAdd ||
436 I->getOpcode() == Instruction::FSub) &&
"Expect add/sub");
441 FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
443 unsigned OpndNum = FAddend::drillValueDownOneStep(
I, Opnd0, Opnd1);
446 unsigned Opnd0_ExpNum = 0;
447 unsigned Opnd1_ExpNum = 0;
449 if (!Opnd0.isConstant())
450 Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
453 if (OpndNum == 2 && !Opnd1.isConstant())
454 Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);
457 if (Opnd0_ExpNum && Opnd1_ExpNum) {
460 AllOpnds.push_back(&Opnd1_0);
461 if (Opnd0_ExpNum == 2)
462 AllOpnds.push_back(&Opnd0_1);
463 if (Opnd1_ExpNum == 2)
464 AllOpnds.push_back(&Opnd1_1);
467 unsigned InstQuota = 0;
469 Value *V0 =
I->getOperand(0);
470 Value *V1 =
I->getOperand(1);
474 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
483 const FAddendCoef &
CE = Opnd0.getCoef();
484 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
491 AllOpnds.push_back(&Opnd1_0);
492 if (Opnd1_ExpNum == 2)
493 AllOpnds.push_back(&Opnd1_1);
495 if (
Value *R = simplifyFAdd(AllOpnds, 1))
503 AllOpnds.push_back(&Opnd0_0);
504 if (Opnd0_ExpNum == 2)
505 AllOpnds.push_back(&Opnd0_1);
507 if (
Value *R = simplifyFAdd(AllOpnds, 1))
514Value *FAddCombine::simplifyFAdd(AddendVect& Addends,
unsigned InstrQuota) {
515 unsigned AddendNum = Addends.size();
516 assert(AddendNum <= 4 &&
"Too many addends");
519 unsigned NextTmpIdx = 0;
520 FAddend TmpResult[3];
528 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
530 const FAddend *ThisAddend = Addends[SymIdx];
536 Value *Val = ThisAddend->getSymVal();
545 unsigned StartIdx = SimpVect.size();
546 SimpVect.push_back(ThisAddend);
553 for (
unsigned SameSymIdx = SymIdx + 1;
554 SameSymIdx < AddendNum; SameSymIdx++) {
555 const FAddend *
T = Addends[SameSymIdx];
556 if (
T &&
T->getSymVal() == Val) {
559 Addends[SameSymIdx] =
nullptr;
560 SimpVect.push_back(
T);
565 if (StartIdx + 1 != SimpVect.size()) {
566 FAddend &
R = TmpResult[NextTmpIdx ++];
567 R = *SimpVect[StartIdx];
568 for (
unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
572 SimpVect.resize(StartIdx);
574 SimpVect.push_back(&R);
579 assert((NextTmpIdx <= std::size(TmpResult) + 1) &&
"out-of-bound access");
582 if (!SimpVect.empty())
583 Result = createNaryFAdd(SimpVect, InstrQuota);
592Value *FAddCombine::createNaryFAdd
593 (
const AddendVect &Opnds,
unsigned InstrQuota) {
594 assert(!Opnds.empty() &&
"Expect at least one addend");
598 unsigned InstrNeeded = calcInstrNumber(Opnds);
599 if (InstrNeeded > InstrQuota)
612 Value *LastVal =
nullptr;
613 bool LastValNeedNeg =
false;
616 for (
const FAddend *Opnd : Opnds) {
618 Value *
V = createAddendVal(*Opnd, NeedNeg);
621 LastValNeedNeg = NeedNeg;
625 if (LastValNeedNeg == NeedNeg) {
626 LastVal = createFAdd(LastVal, V);
631 LastVal = createFSub(V, LastVal);
633 LastVal = createFSub(LastVal, V);
635 LastValNeedNeg =
false;
638 if (LastValNeedNeg) {
639 LastVal = createFNeg(LastVal);
643 assert(CreateInstrNum == InstrNeeded &&
644 "Inconsistent in instruction numbers");
651 Value *
V = Builder.CreateFSub(Opnd0, Opnd1);
653 createInstPostProc(
I);
658 Value *NewV = Builder.CreateFNeg(V);
660 createInstPostProc(
I,
true);
665 Value *
V = Builder.CreateFAdd(Opnd0, Opnd1);
667 createInstPostProc(
I);
672 Value *
V = Builder.CreateFMul(Opnd0, Opnd1);
674 createInstPostProc(
I);
678void FAddCombine::createInstPostProc(Instruction *NewInstr,
bool NoNumber) {
691unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
692 unsigned OpndNum = Opnds.size();
693 unsigned InstrNeeded = OpndNum - 1;
696 for (
const FAddend *Opnd : Opnds) {
697 if (Opnd->isConstant())
705 const FAddendCoef &
CE = Opnd->getCoef();
709 if (!
CE.isMinusOne() && !
CE.isOne())
723Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
724 const FAddendCoef &Coeff = Opnd.getCoef();
726 if (Opnd.isConstant()) {
728 return Coeff.getValue(Instr->
getType());
731 Value *OpndVal = Opnd.getSymVal();
733 if (Coeff.isMinusOne() || Coeff.isOne()) {
734 NeedNeg = Coeff.isMinusOne();
738 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
739 NeedNeg = Coeff.isMinusTwo();
740 return createFAdd(OpndVal, OpndVal);
744 return createFMul(OpndVal, Coeff.getValue(Instr->
getType()));
758 if (!
LHS->hasOneUse() && !
RHS->hasOneUse())
761 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
762 const APInt *C1 =
nullptr, *C2 =
nullptr;
777 Value *NewAnd = Builder.CreateAnd(Z, *C1);
778 return Builder.CreateSub(
RHS, NewAnd,
"sub");
782 Value *NewOr = Builder.CreateOr(Z, ~(*C1));
783 return Builder.CreateSub(
RHS, NewOr,
"sub");
789 LHS =
I.getOperand(0);
790 RHS =
I.getOperand(1);
802 Value *NewOr = Builder.CreateOr(Z, ~(*C2));
803 return Builder.CreateSub(
RHS, NewOr,
"sub");
811 Value *Op0 =
Add.getOperand(0), *Op1 =
Add.getOperand(1);
820 const APInt *C1, *C2;
831 Builder.CreateNUWAdd(
X, ConstantInt::get(
X->getType(), NewC)), Ty);
840 Value *WideC = Builder.CreateSExt(NarrowC, Ty);
841 Value *NewC = Builder.CreateAdd(WideC, Op1C);
842 Value *WideX = Builder.CreateSExt(
X, Ty);
843 return BinaryOperator::CreateAdd(WideX, NewC);
848 Value *WideC = Builder.CreateZExt(NarrowC, Ty);
849 Value *NewC = Builder.CreateAdd(WideC, Op1C);
850 Value *WideX = Builder.CreateZExt(
X, Ty);
851 return BinaryOperator::CreateAdd(WideX, NewC);
857 Value *Op0 =
Add.getOperand(0), *Op1 =
Add.getOperand(1);
881 return BinaryOperator::CreateAdd(
Builder.CreateNot(
Y),
X);
885 X->getType()->getScalarSizeInBits() == 1)
890 X->getType()->getScalarSizeInBits() == 1)
897 auto *COne = ConstantInt::get(Op1C->
getType(), 1);
898 bool WillNotSOV = willNotOverflowSignedSub(Op1C, COne,
Add);
907 unsigned BitWidth = Ty->getScalarSizeInBits();
922 willNotOverflowSignedAdd(Op01C, Op1C,
Add));
930 return BinaryOperator::CreateXor(Op0, ConstantInt::get(
Add.getType(), *C2));
932 if (
C->isSignMask()) {
935 if (
Add.hasNoSignedWrap() ||
Add.hasNoUnsignedWrap())
936 return BinaryOperator::CreateDisjointOr(Op0, Op1);
940 return BinaryOperator::CreateXor(Op0, Op1);
952 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *C2 ^ *
C));
958 if ((*C2 | LHSKnown.
Zero).isAllOnes())
959 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *
C),
X);
966 unsigned BitWidth = Ty->getScalarSizeInBits();
974 Constant *ShAmtC = ConstantInt::get(Ty, ShAmt);
976 return BinaryOperator::CreateAShr(NewShl, ShAmtC);
988 X->getType()->getScalarSizeInBits() == 1)
995 C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) {
997 return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1));
1005 Intrinsic::usub_sat,
X, ConstantInt::get(
Add.getType(), -*
C)));
1010 const APInt *InnerC;
1013 if (
C->isIntN(NarrowBW)) {
1014 APInt NarrowC =
C->trunc(NarrowBW);
1016 if (*InnerC == -NarrowC &&
1036template <
bool FP,
typename Mul2Rhs>
1039 constexpr unsigned MulOp =
FP ? Instruction::FMul : Instruction::Mul;
1040 constexpr unsigned AddOp =
FP ? Instruction::FAdd : Instruction::Add;
1041 constexpr unsigned Mul2Op =
FP ? Instruction::FMul : Instruction::Shl;
1074 return BinaryOperator::CreateMul(AB, AB);
1082 assert(
I.hasAllowReassoc() &&
I.hasNoSignedZeros() &&
"Assumption mismatch");
1158 (void)C0.
smul_ov(C1, overflow);
1160 (
void)C0.
umul_ov(C1, overflow);
1169 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
1181 if (
MatchRem(MulOpV, RemOpV, C1, Rem2IsSigned) &&
1182 IsSigned == Rem2IsSigned) {
1186 if (
MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) &&
X == DivOpV &&
1188 Value *NewDivisor = ConstantInt::get(
X->getType(), C0 * C1);
1189 return IsSigned ?
Builder.CreateSRem(
X, NewDivisor,
"srem")
1190 :
Builder.CreateURem(
X, NewDivisor,
"urem");
1198 if (!LHS->hasOneUse() || !
MatchMul(LHS, Div, C1))
1199 Div = LHS, C1 =
APInt(
I.getType()->getScalarSizeInBits(), 1);
1200 if (!RHS->hasOneUse() || !
MatchMul(RHS, Rem, C2))
1201 Rem = RHS, C2 =
APInt(
I.getType()->getScalarSizeInBits(), 1);
1209 MatchDiv(Div, DivOpV, DivOpC, IsSigned) &&
X == DivOpV && C0 == DivOpC &&
1212 APInt NewC = C1 - C2 * C0;
1217 Value *MulXC2 =
Builder.CreateMul(
X, ConstantInt::get(
X->getType(), C2));
1221 Builder.CreateMul(Div, ConstantInt::get(
X->getType(), NewC)), MulXC2);
1240 Value *NotMask = Builder.CreateShl(MinusOne, NBits,
"notmask");
1244 BOp->setHasNoSignedWrap();
1245 BOp->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
1252 assert(
I.getOpcode() == Instruction::Add &&
"Expecting add instruction");
1253 Type *Ty =
I.getType();
1254 auto getUAddSat = [&]() {
1283 Value *NewShl = Builder.CreateShl(
B, Cnt);
1284 return BinaryOperator::CreateSub(
A, NewShl);
1305 const APInt *MaskC, *MaskCCmp;
1318 ? (*MaskC == (
SMin | (*DivC - 1)))
1319 : (*DivC == 2 && *MaskC ==
SMin + 1);
1324 return BinaryOperator::CreateAShr(
1329 bool NSW,
bool NUW) {
1339 R->setHasNoSignedWrap(NSWOut);
1340 R->setHasNoUnsignedWrap(NUWOut);
1345 const APInt *C1, *C2;
1348 APInt MinusC1 = -(*C1);
1349 if (MinusC1 == (One << *C2)) {
1350 Constant *NewRHS = ConstantInt::get(RHS->getType(), MinusC1);
1351 return BinaryOperator::CreateSRem(RHS, NewRHS);
1359 if (!LHS->hasOneUse() && !RHS->hasOneUse())
1366 Instruction *NewAdd = BinaryOperator::CreateAdd(
A, NewOr);
1378 assert((
I.getOpcode() == Instruction::Add ||
1379 I.getOpcode() == Instruction::Or ||
1380 I.getOpcode() == Instruction::Sub) &&
1381 "Expecting add/or/sub instruction");
1394 if (
I.getOpcode() == Instruction::Sub &&
I.getOperand(1) !=
Select)
1397 Type *XTy =
X->getType();
1398 bool HadTrunc =
I.getType() != XTy;
1410 if (!
match(LowBitsToSkip,
1417 auto SkipExtInMagic = [&
I](
Value *&V) {
1418 if (
I.getOpcode() == Instruction::Sub)
1430 Value *SignExtendingValue, *Zero;
1450 SkipExtInMagic(SignExtendingValue);
1451 Constant *SignExtendingValueBaseConstant;
1452 if (!
match(SignExtendingValue,
1457 if (
I.getOpcode() == Instruction::Sub
1458 ? !
match(SignExtendingValueBaseConstant,
m_One())
1462 auto *NewAShr = BinaryOperator::CreateAShr(
X, LowBitsToSkip,
1463 Extract->
getName() +
".sext");
1464 NewAShr->copyIRFlags(Extract);
1478 assert((
I.getOpcode() == Instruction::Add ||
1479 I.getOpcode() == Instruction::Sub) &&
1480 "Expected add/sub");
1483 if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse()))
1492 bool HasNSW =
I.hasNoSignedWrap() && Op0->hasNoSignedWrap() &&
1493 Op1->hasNoSignedWrap();
1494 bool HasNUW =
I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() &&
1495 Op1->hasNoUnsignedWrap();
1498 Value *NewMath = Builder.CreateBinOp(
I.getOpcode(),
X,
Y);
1500 NewI->setHasNoSignedWrap(HasNSW);
1501 NewI->setHasNoUnsignedWrap(HasNUW);
1503 auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt);
1504 NewShl->setHasNoSignedWrap(HasNSW);
1505 NewShl->setHasNoUnsignedWrap(HasNUW);
1512 unsigned BitWidth =
I.getType()->getScalarSizeInBits();
1545 return BinaryOperator::CreateMul(
X,
Y);
1558 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()) {
1770 return BinaryOperator::CreateDisjointOr(LHS, RHS);
1779 return BinaryOperator::CreateOr(
A,
B);
1799 I.hasNoUnsignedWrap(),
I.hasNoSignedWrap());
1800 return BinaryOperator::CreateAnd(
Add,
A);
1811 return BinaryOperator::CreateAnd(Dec, Not);
1822 Type *Ty =
I.getType();
1823 Constant *NewMulC = ConstantInt::get(Ty, 1 - *C1);
1829 const APInt *NegPow2C;
1834 return BinaryOperator::CreateSub(
B, Shl);
1844 Value *Zext =
Builder.CreateZExt(NotZero, Ty,
"isnotnull.zext");
1845 return BinaryOperator::CreateOr(LHS, Zext);
1870 Value *OneConst = ConstantInt::get(
A->getType(), 1);
1883 const APInt *ShiftAmt, *Mask;
1893 Mask->popcount() == *ShiftAmt) {
1896 Constant *MaskC = ConstantInt::get(
X->getType(), *Mask);
1897 if (willNotOverflowUnsignedAdd(
X, MaskC,
I)) {
1900 return BinaryOperator::CreateLShr(
1901 Add, ConstantInt::get(
X->getType(), *ShiftAmt));
1910 bool ConsumesLHS, ConsumesRHS;
1911 if (
isFreeToInvert(LHS, LHS->hasOneUse(), ConsumesLHS) && ConsumesLHS &&
1912 isFreeToInvert(RHS, RHS->hasOneUse(), ConsumesRHS) && ConsumesRHS) {
1915 assert(NotLHS !=
nullptr && NotRHS !=
nullptr &&
1916 "isFreeToInvert desynced with getFreelyInverted");
1918 return BinaryOperator::CreateSub(
1930 if (!
I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHSCache, RHSCache,
I)) {
1932 I.setHasNoSignedWrap(
true);
1934 if (!
I.hasNoUnsignedWrap() &&
1935 willNotOverflowUnsignedAdd(LHSCache, RHSCache,
I)) {
1937 I.setHasNoUnsignedWrap(
true);
1955 Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
1963 I,
Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
1964 {Builder.CreateDisjointOr(A, B)}));
1978 *XorC ==
A->getType()->getScalarSizeInBits() - 1) {
1980 Value *Ctlz =
Builder.CreateIntrinsic(Intrinsic::ctlz, {
A->getType()},
1983 ConstantInt::get(
A->getType(),
A->getType()->getScalarSizeInBits()),
1984 Ctlz,
"",
true,
true);
2004 Value *Start, *Step;
2023 Value *XY = Builder.CreateFSubFMF(
X,
Y, &
I);
2024 Value *MulZ = Builder.CreateFMulFMF(Z, XY, &
I);
2031 assert((
I.getOpcode() == Instruction::FAdd ||
2032 I.getOpcode() == Instruction::FSub) &&
"Expecting fadd/fsub");
2033 assert(
I.hasAllowReassoc() &&
I.hasNoSignedZeros() &&
2034 "FP factorization requires FMF");
2039 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2040 if (!Op0->
hasOneUse() || !Op1->hasOneUse())
2060 bool IsFAdd =
I.getOpcode() == Instruction::FAdd;
2061 Value *XY = IsFAdd ? Builder.CreateFAddFMF(
X,
Y, &
I)
2062 : Builder.CreateFSubFMF(
X,
Y, &
I);
2076 I.getFastMathFlags(),
2077 SQ.getWithInstruction(&
I)))
2130 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
2135 if (
I.hasAllowReassoc() &&
I.hasNoSignedZeros()) {
2148 I,
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
2149 {X->getType()}, {Y, X}, &
I));
2156 Constant *NewStartC = ConstantFP::get(
I.getType(), *
C + *StartC);
2158 I,
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
2159 {X->getType()}, {NewStartC, X}, &
I));
2167 Instruction::FAdd, MulC, ConstantFP::get(
I.getType(), 1.0),
DL))
2189 if (!Result->hasNoNaNs())
2190 Result->setHasNoInfs(
false);
2200 if (LHS->getType() != RHS->getType())
2209 Ptr =
GEP->getPointerOperand();
2226 Base.RHSNW =
GEP->getNoWrapFlags();
2228 Base.RHSNW =
Base.RHSNW.intersectForOffsetAdd(
GEP->getNoWrapFlags());
2230 RHS =
GEP->getPointerOperand();
2240 if (LHS ==
Base.Ptr)
2247 Base.LHSNW =
GEP->getNoWrapFlags();
2249 Base.LHSNW =
Base.LHSNW.intersectForOffsetAdd(
GEP->getNoWrapFlags());
2251 LHS =
GEP->getPointerOperand();
2258 unsigned NumGEPs = 0;
2260 bool SeenMultiUse =
false;
2265 if (!
GEP->hasOneUse()) {
2268 SeenMultiUse =
true;
2281 Type *Ty,
bool IsNUW) {
2283 if (!
Base.Ptr ||
Base.isExpensive())
2289 bool RewriteGEPs = !
Base.LHSGEPs.empty() && !
Base.RHSGEPs.empty();
2291 Type *IdxTy =
DL.getIndexType(LHS->getType());
2292 Value *Result = EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy, RewriteGEPs);
2293 Value *Offset2 = EmitGEPOffsets(
Base.RHSGEPs,
Base.RHSNW, IdxTy, RewriteGEPs);
2299 (
I->use_empty() ||
I->hasOneUse()) &&
I->hasNoSignedWrap() &&
2300 !
I->hasNoUnsignedWrap() &&
2301 ((
I->getOpcode() == Instruction::Mul &&
2303 I->getOpcode() == Instruction::Shl))
2311 Builder.CreateSub(Result, Offset2,
"gepdiff",
2312 IsNUW &&
Base.LHSNW.hasNoUnsignedWrap() &&
2313 Base.RHSNW.hasNoUnsignedWrap(),
2314 Base.LHSNW.isInBounds() &&
Base.RHSNW.isInBounds());
2317 return Builder.CreateIntCast(Result, Ty,
true);
2322 Value *Op0 =
I.getOperand(0);
2323 Value *Op1 =
I.getOperand(1);
2324 Type *Ty =
I.getType();
2345 Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {
Y, Z});
2346 return BinaryOperator::CreateAdd(
X, USub);
2349 Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {Z,
Y});
2350 return BinaryOperator::CreateAdd(
X, USub);
2368 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(),
2369 SQ.getWithInstruction(&
I)))
2378 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2382 if (
Value *V = dyn_castNegVal(Op1)) {
2386 assert(BO->getOpcode() == Instruction::Sub &&
2387 "Expected a subtraction operator!");
2388 if (BO->hasNoSignedWrap() &&
I.hasNoSignedWrap())
2391 if (
cast<Constant>(Op1)->isNotMinSignedValue() &&
I.hasNoSignedWrap())
2411 bool WillNotSOV = willNotOverflowSignedSub(
C, C2,
I);
2420 Op1NSW = OBO1->hasNoSignedWrap();
2421 Op1NUW = OBO1->hasNoUnsignedWrap();
2430 auto TryToNarrowDeduceFlags = [
this, &
I, &Op0, &Op1]() ->
Instruction * {
2435 if (!
I.hasNoSignedWrap() && willNotOverflowSignedSub(Op0, Op1,
I)) {
2437 I.setHasNoSignedWrap(
true);
2439 if (!
I.hasNoUnsignedWrap() && willNotOverflowUnsignedSub(Op0, Op1,
I)) {
2441 I.setHasNoUnsignedWrap(
true);
2454 I.hasNoSignedWrap(),
2456 return BinaryOperator::CreateAdd(NegOp1, Op0);
2459 return TryToNarrowDeduceFlags();
2465 if (
I.getType()->isIntOrIntVectorTy(1))
2466 return BinaryOperator::CreateXor(Op0, Op1);
2475 return BinaryOperator::CreateAdd(
Builder.CreateNot(Op1),
X);
2483 return BinaryOperator::CreateAnd(
2495 return BinaryOperator::CreateSub(XZ, YW);
2506 Sub->setHasNoUnsignedWrap(HasNUW);
2507 Sub->setHasNoSignedWrap(HasNSW);
2518 return BinaryOperator::CreateSub(
X,
Y);
2526 return BinaryOperator::CreateAdd(OpsSub, ConstsSub);
2536 R = BinaryOperator::CreateSub(
X, Z);
2538 R = BinaryOperator::CreateSub(
X,
Y);
2540 R = BinaryOperator::CreateSub(W, Z);
2542 R = BinaryOperator::CreateSub(W,
Y);
2544 bool NSW =
I.hasNoSignedWrap() &&
2548 bool NUW =
I.hasNoUnsignedWrap() &&
2550 R->setHasNoSignedWrap(NSW);
2551 R->setHasNoUnsignedWrap(NUW);
2561 bool ConsumesOp0, ConsumesOp1;
2564 (ConsumesOp0 || ConsumesOp1)) {
2567 assert(NotOp0 !=
nullptr && NotOp1 !=
nullptr &&
2568 "isFreeToInvert desynced with getFreelyInverted");
2569 return BinaryOperator::CreateSub(NotOp1, NotOp0);
2573 auto m_AddRdx = [](
Value *&Vec) {
2577 if (
match(Op0, m_AddRdx(V0)) &&
match(Op1, m_AddRdx(V1)) &&
2582 Value *Rdx =
Builder.CreateIntrinsic(Intrinsic::vector_reduce_add,
2583 {
Sub->getType()}, {
Sub});
2624 Op1,
SQ.getWithInstruction(&
I).getWithoutDomCondCache());
2625 if ((*Op0C | RHSKnown.
Zero).isAllOnes())
2626 return BinaryOperator::CreateXor(Op1, Op0);
2633 const APInt *C2, *C3;
2638 APInt C2AndC3 = *C2 & *C3;
2639 APInt C2AndC3Minus1 = C2AndC3 - 1;
2640 APInt C2AddC3 = *C2 + *C3;
2641 if ((*C3 - C2AndC3Minus1).isPowerOf2() &&
2644 return BinaryOperator::CreateAdd(
2645 And, ConstantInt::get(
I.getType(), *Op0C - C2AndC3));
2666 return BinaryOperator::CreateXor(
A,
B);
2674 return BinaryOperator::CreateAnd(
A,
B);
2682 return BinaryOperator::CreateOr(
A,
B);
2699 return BinaryOperator::CreateAnd(
A,
B);
2715 return BinaryOperator::CreateAnd(
2716 Y,
Builder.CreateNot(Op1, Op1->getName() +
".not"));
2747 if (m_SubXorCmp(Op0, Op1))
2748 return createSelectInstWithUnknownProfile(
C,
Builder.CreateNeg(
X),
X);
2749 if (m_SubXorCmp(Op1, Op0))
2750 return createSelectInstWithUnknownProfile(
C,
X,
Builder.CreateNeg(
X));
2770 auto SinkSubIntoSelect =
2777 if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal)
2782 bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal;
2783 Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal);
2787 OtherHandOfSubIsTrueVal ? NewSub : Zero);
2795 return Builder->CreateSub(OtherHandOfSelect,
2802 return Builder->CreateSub(Op0,
2811 return BinaryOperator::CreateAnd(
2812 Op0,
Builder.CreateNot(
Y,
Y->getName() +
".not"));
2825 return BinaryOperator::CreateSub(Not,
X);
2831 return BinaryOperator::CreateSub(
X, Not);
2839 I.getType()->getScalarSizeInBits() != 1 &&
2840 (Op0->
hasOneUse() || Op1->hasOneUse())) {
2846 I.getType()->getScalarSizeInBits() != 1 &&
2847 (Op0->
hasOneUse() || Op1->hasOneUse())) {
2854 Value *LHSOp, *RHSOp;
2858 I.hasNoUnsignedWrap()))
2868 auto MatchSubOfZExtOfPtrToIntOrAddr = [&]() {
2882 if (MatchSubOfZExtOfPtrToIntOrAddr()) {
2884 if (
GEP->getPointerOperand() == RHSOp) {
2885 if (
GEP->hasNoUnsignedWrap() ||
GEP->hasNoUnsignedSignedWrap()) {
2887 Value *Res =
GEP->hasNoUnsignedWrap()
2890 GEP->hasNoUnsignedSignedWrap())
2905 Type *Ty =
I.getType();
2906 unsigned BitWidth = Ty->getScalarSizeInBits();
2908 Op1->hasNUses(2) && *ShAmt ==
BitWidth - 1 &&
2915 Value *NegA =
I.hasNoUnsignedWrap()
2917 :
Builder.CreateNeg(
A,
"",
I.hasNoSignedWrap());
2925 const APInt *AddC, *AndC;
2930 if ((HighMask & *AndC).
isZero())
2931 return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC)));
2942 I,
Builder.CreateIntrinsic(Intrinsic::umin, {I.getType()}, {Op0, Y}));
2949 I,
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op1}));
2954 I,
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op0, X}));
2958 Value *USub =
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {
X, Op0});
2964 Value *USub =
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op1,
X});
2972 I,
Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
2973 {Builder.CreateNot(X)}));
2981 bool PropagateNSW =
I.hasNoSignedWrap() && OBO0->hasNoSignedWrap() &&
2982 OBO1->hasNoSignedWrap() &&
BitWidth > 2;
2983 bool PropagateNUW =
I.hasNoUnsignedWrap() && OBO0->hasNoUnsignedWrap() &&
2984 OBO1->hasNoUnsignedWrap() &&
BitWidth > 1;
2994 if (
I.hasNoUnsignedWrap() ||
I.hasNoSignedWrap()) {
2996 Builder.CreateSub(
X,
Y,
"sub",
false,
true);
3016 Value *Z, *Add0, *Add1;
3023 unsigned NumOfNewInstrs = 0;
3028 unsigned NumOfDeadInstrs = 0;
3034 NumOfDeadInstrs += Add0->
hasOneUse() ? 1 : 0;
3036 if (Op1->hasOneUse()) {
3038 NumOfDeadInstrs += Add1->
hasOneUse() ? 1 : 0;
3040 if (NumOfDeadInstrs >= NumOfNewInstrs) {
3045 I.hasNoSignedWrap());
3051 return TryToNarrowDeduceFlags();
3118 Instruction &FMFSource) {
3124 X, Builder.CreateFNegFMF(
Y, &FMFSource), &FMFSource));
3129 Builder.CreateFNegFMF(
X, &FMFSource),
Y, &FMFSource));
3136 if (
II->getIntrinsicID() == Intrinsic::ldexp) {
3139 Builder.CreateCall(
II->getCalledFunction(),
3140 {Builder.CreateFNegFMF(II->getArgOperand(0), FMF),
3141 II->getArgOperand(1)});
3142 New->setFastMathFlags(FMF);
3143 New->copyMetadata(*
II);
3164 if (
I.hasNoSignedZeros() &&
3172 if (
Instruction *R = hoistFNegAboveFMulFDiv(OneUse,
I))
3181 auto propagateSelectFMF = [&](
SelectInst *S,
bool CommonOperand) {
3184 FastMathFlags FMF =
I.getFastMathFlags() | OldSel->getFastMathFlags();
3186 if (!OldSel->hasNoSignedZeros() && !CommonOperand &&
3196 propagateSelectFMF(NewSel,
P ==
Y);
3203 propagateSelectFMF(NewSel,
P ==
X);
3213 propagateSelectFMF(NewSel,
true);
3245 I.getFastMathFlags(),
3275 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3282 if (
I.hasNoSignedZeros() ||
3315 Type *Ty =
I.getType();
3342 if (
I.hasAllowReassoc() &&
I.hasNoSignedZeros()) {
3355 Instruction::FSub,
C, ConstantFP::get(Ty, 1.0),
DL))
3361 Instruction::FSub, ConstantFP::get(Ty, 1.0),
C,
DL))
3376 auto m_FaddRdx = [](
Value *&Sum,
Value *&Vec) {
3380 Value *A0, *A1, *V0, *V1;
3381 if (
match(Op0, m_FaddRdx(A0, V0)) &&
match(Op1, m_FaddRdx(A1, V1)) &&
3386 Value *Rdx =
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
3387 {
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< 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 * 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
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
const fltSemantics & getSemantics() const
opStatus multiply(const APFloat &RHS, roundingMode RM)
Class for arbitrary precision integers.
LLVM_ABI APInt umul_ov(const APInt &RHS, bool &Overflow) const
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
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.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned logBase2() const
LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) 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 sge(const APInt &RHS) const
Signed greater or equal comparison.
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)
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
bool isZero() const
Return true if the value is positive or negative zero.
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)
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
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.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
@ C
The default llvm calling convention, compatible with C.
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.
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_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
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)
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.
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.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
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_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)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > m_c_SMin(const LHS &L, const RHS &R)
Matches an SMin with LHS and RHS in either order.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true > m_c_UMax(const LHS &L, const RHS &R)
Matches a UMax with LHS and RHS in either order.
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.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
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.
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > m_c_UMin(const LHS &L, const RHS &R)
Matches a UMin with LHS and RHS in either order.
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".
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true > m_c_SMax(const LHS &L, const RHS &R)
Matches an SMax with LHS and RHS in either order.
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
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)
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".
m_Intrinsic_Ty< Opnd0 >::Ty m_Ctpop(const Opnd0 &Op0)
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)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
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)
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_Ctlz(const Opnd0 &Op0, const Opnd1 &Op1)
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.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
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".
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.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
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)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
@ CE
Windows NT (Windows on ARM)
Context & getContext() const
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)
FunctionAddr VTableAddr Value
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.
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 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.
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 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 void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI 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.
A suitably aligned and sized character array member which can hold elements of any type.
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)