40#define DEBUG_TYPE "instcombine"
57 FAddendCoef() =
default;
62 void operator=(
const FAddendCoef &
A);
67 assert(!insaneIntVal(
C) &&
"Insane coefficient");
68 IsFp =
false; IntVal =
C;
75 bool isZero()
const {
return isInt() ? !IntVal : getFpVal().isZero(); }
78 bool isOne()
const {
return isInt() && IntVal == 1; }
79 bool isTwo()
const {
return isInt() && IntVal == 2; }
80 bool isMinusOne()
const {
return isInt() && IntVal == -1; }
81 bool isMinusTwo()
const {
return isInt() && IntVal == -2; }
84 bool insaneIntVal(
int V) {
return V > 4 || V < -4; }
86 APFloat *getFpValPtr() {
return reinterpret_cast<APFloat *
>(&FpValBuf); }
88 const APFloat *getFpValPtr()
const {
89 return reinterpret_cast<const APFloat *
>(&FpValBuf);
92 const APFloat &getFpVal()
const {
93 assert(IsFp && BufHasFpVal &&
"Incorrect state");
94 return *getFpValPtr();
98 assert(IsFp && BufHasFpVal &&
"Incorrect state");
99 return *getFpValPtr();
102 bool isInt()
const {
return !IsFp; }
116 bool BufHasFpVal =
false;
135 assert((Val ==
T.Val) &&
"Symbolic-values disagree");
139 Value *getSymVal()
const {
return Val; }
140 const FAddendCoef &getCoef()
const {
return Coeff; }
142 bool isConstant()
const {
return Val ==
nullptr; }
143 bool isZero()
const {
return Coeff.isZero(); }
145 void set(
short Coefficient,
Value *V) {
146 Coeff.set(Coefficient);
150 Coeff.set(Coefficient);
154 Coeff.set(Coefficient->getValueAPF());
158 void negate() { Coeff.negate(); }
162 static unsigned drillValueDownOneStep(
Value* V, FAddend &A0, FAddend &A1);
166 unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1)
const;
169 void Scale(
const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
172 Value *Val =
nullptr;
188 Value *simplifyFAdd(AddendVect& V,
unsigned InstrQuota);
191 Value *createAddendVal(
const FAddend &
A,
bool& NeedNeg);
194 unsigned calcInstrNumber(
const AddendVect& Vect);
200 Value *createNaryFAdd(
const AddendVect& Opnds,
unsigned InstrQuota);
201 void createInstPostProc(
Instruction *NewInst,
bool NoNumber =
false);
205 unsigned CreateInstrNum;
206 void initCreateInstNum() { CreateInstrNum = 0; }
207 void incCreateInstNum() { CreateInstrNum++; }
209 void initCreateInstNum() {}
210 void incCreateInstNum() {}
225FAddendCoef::~FAddendCoef() {
227 getFpValPtr()->~APFloat();
230void FAddendCoef::set(
const APFloat&
C) {
240 IsFp = BufHasFpVal =
true;
243void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
254 IsFp = BufHasFpVal =
true;
257APFloat FAddendCoef::createAPFloatFromInt(
const fltSemantics &Sem,
int Val) {
267void FAddendCoef::operator=(
const FAddendCoef &That) {
271 set(That.getFpVal());
274void FAddendCoef::operator+=(
const FAddendCoef &That) {
276 if (
isInt() == That.isInt()) {
278 IntVal += That.IntVal;
280 getFpVal().add(That.getFpVal(), RndMode);
286 convertToFpType(
T.getSemantics());
287 getFpVal().add(
T, RndMode);
292 T.add(createAPFloatFromInt(
T.getSemantics(), That.IntVal), RndMode);
295void FAddendCoef::operator*=(
const FAddendCoef &That) {
299 if (That.isMinusOne()) {
304 if (
isInt() && That.isInt()) {
305 int Res = IntVal * (int)That.IntVal;
306 assert(!insaneIntVal(Res) &&
"Insane int value");
311 const fltSemantics &Semantic =
312 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
315 convertToFpType(Semantic);
319 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
320 APFloat::rmNearestTiesToEven);
322 F0.
multiply(That.getFpVal(), APFloat::rmNearestTiesToEven);
325void FAddendCoef::negate() {
329 getFpVal().changeSign();
332Value *FAddendCoef::getValue(
Type *Ty)
const {
334 ConstantFP::get(Ty,
float(IntVal)) :
348unsigned FAddend::drillValueDownOneStep
349 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
354 unsigned Opcode =
I->getOpcode();
356 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
358 Value *Opnd0 =
I->getOperand(0);
359 Value *Opnd1 =
I->getOperand(1);
368 Addend0.set(1, Opnd0);
370 Addend0.set(C0,
nullptr);
374 FAddend &Addend = Opnd0 ? Addend1 : Addend0;
376 Addend.set(1, Opnd1);
378 Addend.set(C1,
nullptr);
379 if (Opcode == Instruction::FSub)
384 return Opnd0 && Opnd1 ? 2 : 1;
391 if (
I->getOpcode() == Instruction::FMul) {
411unsigned FAddend::drillAddendDownOneStep
412 (FAddend &Addend0, FAddend &Addend1)
const {
416 unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
417 if (!BreakNum || Coeff.isOne())
420 Addend0.Scale(Coeff);
423 Addend1.Scale(Coeff);
428Value *FAddCombine::simplify(Instruction *
I) {
429 assert(
I->hasAllowReassoc() &&
I->hasNoSignedZeros() &&
430 "Expected 'reassoc'+'nsz' instruction");
433 if (
I->getType()->isVectorTy())
436 assert((
I->getOpcode() == Instruction::FAdd ||
437 I->getOpcode() == Instruction::FSub) &&
"Expect add/sub");
442 FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
444 unsigned OpndNum = FAddend::drillValueDownOneStep(
I, Opnd0, Opnd1);
447 unsigned Opnd0_ExpNum = 0;
448 unsigned Opnd1_ExpNum = 0;
450 if (!Opnd0.isConstant())
451 Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
454 if (OpndNum == 2 && !Opnd1.isConstant())
455 Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);
458 if (Opnd0_ExpNum && Opnd1_ExpNum) {
461 AllOpnds.push_back(&Opnd1_0);
462 if (Opnd0_ExpNum == 2)
463 AllOpnds.push_back(&Opnd0_1);
464 if (Opnd1_ExpNum == 2)
465 AllOpnds.push_back(&Opnd1_1);
468 unsigned InstQuota = 0;
475 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
484 const FAddendCoef &
CE = Opnd0.getCoef();
485 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
492 AllOpnds.push_back(&Opnd1_0);
493 if (Opnd1_ExpNum == 2)
494 AllOpnds.push_back(&Opnd1_1);
496 if (
Value *R = simplifyFAdd(AllOpnds, 1))
504 AllOpnds.push_back(&Opnd0_0);
505 if (Opnd0_ExpNum == 2)
506 AllOpnds.push_back(&Opnd0_1);
508 if (
Value *R = simplifyFAdd(AllOpnds, 1))
515Value *FAddCombine::simplifyFAdd(AddendVect& Addends,
unsigned InstrQuota) {
516 unsigned AddendNum = Addends.size();
517 assert(AddendNum <= 4 &&
"Too many addends");
520 unsigned NextTmpIdx = 0;
521 FAddend TmpResult[3];
529 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
531 const FAddend *ThisAddend = Addends[SymIdx];
537 Value *Val = ThisAddend->getSymVal();
546 unsigned StartIdx = SimpVect.size();
547 SimpVect.push_back(ThisAddend);
554 for (
unsigned SameSymIdx = SymIdx + 1;
555 SameSymIdx < AddendNum; SameSymIdx++) {
556 const FAddend *
T = Addends[SameSymIdx];
557 if (
T &&
T->getSymVal() == Val) {
560 Addends[SameSymIdx] =
nullptr;
561 SimpVect.push_back(
T);
566 if (StartIdx + 1 != SimpVect.size()) {
567 FAddend &
R = TmpResult[NextTmpIdx ++];
568 R = *SimpVect[StartIdx];
569 for (
unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
573 SimpVect.resize(StartIdx);
575 SimpVect.push_back(&R);
580 assert((NextTmpIdx <= std::size(TmpResult) + 1) &&
"out-of-bound access");
583 if (!SimpVect.empty())
584 Result = createNaryFAdd(SimpVect, InstrQuota);
593Value *FAddCombine::createNaryFAdd
594 (
const AddendVect &Opnds,
unsigned InstrQuota) {
595 assert(!Opnds.empty() &&
"Expect at least one addend");
599 unsigned InstrNeeded = calcInstrNumber(Opnds);
600 if (InstrNeeded > InstrQuota)
613 Value *LastVal =
nullptr;
614 bool LastValNeedNeg =
false;
617 for (
const FAddend *Opnd : Opnds) {
619 Value *
V = createAddendVal(*Opnd, NeedNeg);
622 LastValNeedNeg = NeedNeg;
626 if (LastValNeedNeg == NeedNeg) {
627 LastVal = createFAdd(LastVal, V);
632 LastVal = createFSub(V, LastVal);
634 LastVal = createFSub(LastVal, V);
636 LastValNeedNeg =
false;
639 if (LastValNeedNeg) {
640 LastVal = createFNeg(LastVal);
644 assert(CreateInstrNum == InstrNeeded &&
645 "Inconsistent in instruction numbers");
652 Value *
V = Builder.CreateFSub(Opnd0, Opnd1);
654 createInstPostProc(
I);
659 Value *NewV = Builder.CreateFNeg(V);
661 createInstPostProc(
I,
true);
666 Value *
V = Builder.CreateFAdd(Opnd0, Opnd1);
668 createInstPostProc(
I);
673 Value *
V = Builder.CreateFMul(Opnd0, Opnd1);
675 createInstPostProc(
I);
679void FAddCombine::createInstPostProc(Instruction *NewInstr,
bool NoNumber) {
692unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
693 unsigned OpndNum = Opnds.size();
694 unsigned InstrNeeded = OpndNum - 1;
697 for (
const FAddend *Opnd : Opnds) {
698 if (Opnd->isConstant())
706 const FAddendCoef &
CE = Opnd->getCoef();
710 if (!
CE.isMinusOne() && !
CE.isOne())
724Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
725 const FAddendCoef &Coeff = Opnd.getCoef();
727 if (Opnd.isConstant()) {
729 return Coeff.getValue(Instr->
getType());
732 Value *OpndVal = Opnd.getSymVal();
734 if (Coeff.isMinusOne() || Coeff.isOne()) {
735 NeedNeg = Coeff.isMinusOne();
739 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
740 NeedNeg = Coeff.isMinusTwo();
741 return createFAdd(OpndVal, OpndVal);
745 return createFMul(OpndVal, Coeff.getValue(Instr->
getType()));
759 if (!
LHS->hasOneUse() && !
RHS->hasOneUse())
762 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
763 const APInt *C1 =
nullptr, *C2 =
nullptr;
778 Value *NewAnd = Builder.CreateAnd(Z, *C1);
779 return Builder.CreateSub(
RHS, NewAnd,
"sub");
783 Value *NewOr = Builder.CreateOr(Z, ~(*C1));
784 return Builder.CreateSub(
RHS, NewOr,
"sub");
790 LHS =
I.getOperand(0);
791 RHS =
I.getOperand(1);
803 Value *NewOr = Builder.CreateOr(Z, ~(*C2));
804 return Builder.CreateSub(
RHS, NewOr,
"sub");
812 Value *Op0 =
Add.getOperand(0), *Op1 =
Add.getOperand(1);
821 const APInt *C1, *C2;
832 Builder.CreateNUWAdd(
X, ConstantInt::get(
X->getType(), NewC)), Ty);
841 Value *WideC = Builder.CreateSExt(NarrowC, Ty);
842 Value *NewC = Builder.CreateAdd(WideC, Op1C);
843 Value *WideX = Builder.CreateSExt(
X, Ty);
844 return BinaryOperator::CreateAdd(WideX, NewC);
849 Value *WideC = Builder.CreateZExt(NarrowC, Ty);
850 Value *NewC = Builder.CreateAdd(WideC, Op1C);
851 Value *WideX = Builder.CreateZExt(
X, Ty);
852 return BinaryOperator::CreateAdd(WideX, NewC);
858 Value *Op0 =
Add.getOperand(0), *Op1 =
Add.getOperand(1);
882 return BinaryOperator::CreateAdd(
Builder.CreateNot(
Y),
X);
886 X->getType()->getScalarSizeInBits() == 1)
891 X->getType()->getScalarSizeInBits() == 1)
898 auto *COne = ConstantInt::get(Op1C->
getType(), 1);
899 bool WillNotSOV = willNotOverflowSignedSub(Op1C, COne,
Add);
908 unsigned BitWidth = Ty->getScalarSizeInBits();
923 willNotOverflowSignedAdd(Op01C, Op1C,
Add));
931 return BinaryOperator::CreateXor(Op0, ConstantInt::get(
Add.getType(), *C2));
933 if (
C->isSignMask()) {
936 if (
Add.hasNoSignedWrap() ||
Add.hasNoUnsignedWrap())
937 return BinaryOperator::CreateDisjointOr(Op0, Op1);
941 return BinaryOperator::CreateXor(Op0, Op1);
953 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *C2 ^ *
C));
959 if ((*C2 | LHSKnown.
Zero).isAllOnes())
960 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *
C),
X);
967 unsigned BitWidth = Ty->getScalarSizeInBits();
975 Constant *ShAmtC = ConstantInt::get(Ty, ShAmt);
977 return BinaryOperator::CreateAShr(NewShl, ShAmtC);
989 X->getType()->getScalarSizeInBits() == 1)
996 C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) {
998 return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1));
1006 Intrinsic::usub_sat,
X, ConstantInt::get(
Add.getType(), -*
C)));
1015 Add,
Builder.CreateBinaryIntrinsic(Intrinsic::umin,
X,
1016 ConstantInt::get(Ty, ~SatC)));
1021 const APInt *InnerC;
1024 if (
C->isIntN(NarrowBW)) {
1025 APInt NarrowC =
C->trunc(NarrowBW);
1027 if (*InnerC == -NarrowC &&
1047template <
bool FP,
typename Mul2Rhs>
1050 constexpr unsigned MulOp =
FP ? Instruction::FMul : Instruction::Mul;
1051 constexpr unsigned AddOp =
FP ? Instruction::FAdd : Instruction::Add;
1052 constexpr unsigned Mul2Op =
FP ? Instruction::FMul : Instruction::Shl;
1085 return BinaryOperator::CreateMul(AB, AB);
1093 assert(
I.hasAllowReassoc() &&
I.hasNoSignedZeros() &&
"Assumption mismatch");
1169 (void)C0.
smul_ov(C1, overflow);
1171 (
void)C0.
umul_ov(C1, overflow);
1180 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
1192 if (
MatchRem(MulOpV, RemOpV, C1, Rem2IsSigned) &&
1193 IsSigned == Rem2IsSigned) {
1197 if (
MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) &&
X == DivOpV &&
1199 Value *NewDivisor = ConstantInt::get(
X->getType(), C0 * C1);
1200 return IsSigned ?
Builder.CreateSRem(
X, NewDivisor,
"srem")
1201 :
Builder.CreateURem(
X, NewDivisor,
"urem");
1211 Div = DivSide, C1 =
APInt(
I.getType()->getScalarSizeInBits(), 1);
1212 if (!RemSide->hasOneUse() || !
MatchMul(RemSide, Rem, C2))
1213 Rem = RemSide, C2 =
APInt(
I.getType()->getScalarSizeInBits(), 1);
1217 MatchDiv(Div, DivOpV, DivOpC, IsSigned) &&
X == DivOpV &&
1221 APInt NewC = C1 - C2 * C0;
1226 Value *MulXC2 =
Builder.CreateMul(
X, ConstantInt::get(
X->getType(), C2));
1230 Builder.CreateMul(Div, ConstantInt::get(
X->getType(), NewC)), MulXC2);
1234 if (
Value *V = FoldDivRem(LHS, RHS))
1236 if (
Value *V = FoldDivRem(RHS, LHS))
1255 Value *NotMask = Builder.CreateShl(MinusOne, NBits,
"notmask");
1259 BOp->setHasNoSignedWrap();
1260 BOp->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
1267 assert(
I.getOpcode() == Instruction::Add &&
"Expecting add instruction");
1268 Type *Ty =
I.getType();
1269 auto getUAddSat = [&]() {
1298 Value *NewShl = Builder.CreateShl(
B, Cnt);
1299 return BinaryOperator::CreateSub(
A, NewShl);
1320 const APInt *MaskC, *MaskCCmp;
1333 ? (*MaskC == (
SMin | (*DivC - 1)))
1334 : (*DivC == 2 && *MaskC ==
SMin + 1);
1339 return BinaryOperator::CreateAShr(
1344 bool NSW,
bool NUW) {
1354 R->setHasNoSignedWrap(NSWOut);
1355 R->setHasNoUnsignedWrap(NUWOut);
1360 const APInt *C1, *C2;
1363 APInt MinusC1 = -(*C1);
1364 if (MinusC1 == (One << *C2)) {
1365 Constant *NewRHS = ConstantInt::get(RHS->getType(), MinusC1);
1366 return BinaryOperator::CreateSRem(RHS, NewRHS);
1374 if (!LHS->hasOneUse() && !RHS->hasOneUse())
1381 Instruction *NewAdd = BinaryOperator::CreateAdd(
A, NewOr);
1393 assert((
I.getOpcode() == Instruction::Add ||
1394 I.getOpcode() == Instruction::Or ||
1395 I.getOpcode() == Instruction::Sub) &&
1396 "Expecting add/or/sub instruction");
1409 if (
I.getOpcode() == Instruction::Sub &&
I.getOperand(1) !=
Select)
1412 Type *XTy =
X->getType();
1413 bool HadTrunc =
I.getType() != XTy;
1425 if (!
match(LowBitsToSkip,
1432 auto SkipExtInMagic = [&
I](
Value *&V) {
1433 if (
I.getOpcode() == Instruction::Sub)
1445 Value *SignExtendingValue, *Zero;
1465 SkipExtInMagic(SignExtendingValue);
1466 Constant *SignExtendingValueBaseConstant;
1467 if (!
match(SignExtendingValue,
1472 if (
I.getOpcode() == Instruction::Sub
1473 ? !
match(SignExtendingValueBaseConstant,
m_One())
1477 auto *NewAShr = BinaryOperator::CreateAShr(
X, LowBitsToSkip,
1478 Extract->
getName() +
".sext");
1479 NewAShr->copyIRFlags(Extract);
1493 assert((
I.getOpcode() == Instruction::Add ||
1494 I.getOpcode() == Instruction::Sub) &&
1495 "Expected add/sub");
1498 if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse()))
1507 bool HasNSW =
I.hasNoSignedWrap() && Op0->hasNoSignedWrap() &&
1508 Op1->hasNoSignedWrap();
1509 bool HasNUW =
I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() &&
1510 Op1->hasNoUnsignedWrap();
1513 Value *NewMath = Builder.CreateBinOp(
I.getOpcode(),
X,
Y);
1515 NewI->setHasNoSignedWrap(HasNSW);
1516 NewI->setHasNoUnsignedWrap(HasNUW);
1518 auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt);
1519 NewShl->setHasNoSignedWrap(HasNSW);
1520 NewShl->setHasNoUnsignedWrap(HasNUW);
1527 unsigned BitWidth =
I.getType()->getScalarSizeInBits();
1560 return BinaryOperator::CreateMul(
X,
Y);
1573 return !MinY.
isZero() && !MaxX.
ugt(-MaxY);
1599 if (
X->getType() !=
I.getType()) {
1603 return BinaryOperator::CreateUDiv(NUWAdd,
Y);
1608 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(),
1609 SQ.getWithInstruction(&
I)))
1643 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
1645 I.hasNoUnsignedWrap()))
1648 I.hasNoUnsignedWrap()))
1650 Type *Ty =
I.getType();
1651 if (Ty->isIntOrIntVectorTy(1))
1652 return BinaryOperator::CreateXor(LHS, RHS);
1656 auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1));
1657 Shl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1658 Shl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
1669 auto *
Sub = BinaryOperator::CreateSub(RHS,
A);
1671 Sub->setHasNoSignedWrap(
I.hasNoSignedWrap() && OB0->hasNoSignedWrap());
1678 auto *
Sub = BinaryOperator::CreateSub(LHS,
B);
1680 Sub->setHasNoSignedWrap(
I.hasNoSignedWrap() && OBO->hasNoSignedWrap());
1694 return BinaryOperator::CreateSub(
A,
B);
1709 return BinaryOperator::CreateAdd(
Sub, ConstantInt::get(Ty, *
C - 1));
1715 return BinaryOperator::CreateAdd(
A,
Builder.CreateShl(RHS, 1,
"reass.add"));
1719 return BinaryOperator::CreateAdd(
A,
Builder.CreateShl(LHS, 1,
"reass.add"));
1726 (LHS->hasOneUse() || RHS->hasOneUse())) {
1736 return BinaryOperator::CreateAdd(
Sub, C1);
1747 Constant *NewMask = ConstantInt::get(RHS->getType(), *C1 - 1);
1748 return BinaryOperator::CreateAnd(
A, NewMask);
1760 A->getType()->isIntOrIntVectorTy(1))
1768 A->getType()->isIntOrIntVectorTy()) {
1788 return BinaryOperator::CreateDisjointOr(LHS, RHS);
1790 return BinaryOperator::CreateOr(LHS, RHS);
1802 return BinaryOperator::CreateOr(
A,
B);
1822 I.hasNoUnsignedWrap(),
I.hasNoSignedWrap());
1823 return BinaryOperator::CreateAnd(
Add,
A);
1832 const APInt *LowMask;
1841 Value *NewAdd =
Builder.CreateAdd(
A, ConstantInt::get(Ty, *LowMask));
1842 return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, ~*LowMask));
1854 return BinaryOperator::CreateAnd(Dec, Not);
1865 Type *Ty =
I.getType();
1866 Constant *NewMulC = ConstantInt::get(Ty, 1 - *C1);
1872 const APInt *NegPow2C;
1877 return BinaryOperator::CreateSub(
B, Shl);
1882 uint64_t
BitWidth = Ty->getScalarSizeInBits();
1887 Value *Zext =
Builder.CreateZExt(NotZero, Ty,
"isnotnull.zext");
1888 return BinaryOperator::CreateOr(LHS, Zext);
1913 Value *OneConst = ConstantInt::get(
A->getType(), 1);
1926 const APInt *ShiftAmt, *Mask;
1937 Mask->popcount() == *ShiftAmt) {
1940 unsigned Xbits =
X->getType()->getScalarSizeInBits();
1941 unsigned Ibits = Ty->getScalarSizeInBits();
1942 bool NeedZext = Ibits > Xbits;
1943 Constant *MaskC = ConstantInt::get(Ty, Mask->zext(Ibits));
1944 if (NeedZext || willNotOverflowUnsignedAdd(
X, MaskC,
I)) {
1949 return BinaryOperator::CreateLShr(
1950 Add, ConstantInt::get(Ty, ShiftAmt->
zext(Ibits)));
1959 bool ConsumesLHS, ConsumesRHS;
1960 if (
isFreeToInvert(LHS, LHS->hasOneUse(), ConsumesLHS) && ConsumesLHS &&
1961 isFreeToInvert(RHS, RHS->hasOneUse(), ConsumesRHS) && ConsumesRHS) {
1964 assert(NotLHS !=
nullptr && NotRHS !=
nullptr &&
1965 "isFreeToInvert desynced with getFreelyInverted");
1967 return BinaryOperator::CreateSub(
1979 if (!
I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHSCache, RHSCache,
I)) {
1981 I.setHasNoSignedWrap(
true);
1983 if (!
I.hasNoUnsignedWrap() &&
1984 willNotOverflowUnsignedAdd(LHSCache, RHSCache,
I)) {
1986 I.setHasNoUnsignedWrap(
true);
2004 Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
2012 I,
Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
2013 {Builder.CreateDisjointOr(A, B)}));
2027 *XorC ==
A->getType()->getScalarSizeInBits() - 1) {
2029 Value *Ctlz =
Builder.CreateIntrinsic(Intrinsic::ctlz, {
A->getType()},
2032 ConstantInt::get(
A->getType(),
A->getType()->getScalarSizeInBits()),
2033 Ctlz,
"",
true,
true);
2053 Value *Start, *Step;
2072 Value *XY = Builder.CreateFSubFMF(
X,
Y, &
I);
2073 Value *MulZ = Builder.CreateFMulFMF(Z, XY, &
I);
2080 assert((
I.getOpcode() == Instruction::FAdd ||
2081 I.getOpcode() == Instruction::FSub) &&
"Expecting fadd/fsub");
2082 assert(
I.hasAllowReassoc() &&
I.hasNoSignedZeros() &&
2083 "FP factorization requires FMF");
2088 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2089 if (!Op0->
hasOneUse() || !Op1->hasOneUse())
2109 bool IsFAdd =
I.getOpcode() == Instruction::FAdd;
2110 Value *XY = IsFAdd ? Builder.CreateFAddFMF(
X,
Y, &
I)
2111 : Builder.CreateFSubFMF(
X,
Y, &
I);
2125 I.getFastMathFlags(),
2126 SQ.getWithInstruction(&
I)))
2179 Value *LHS =
I.getOperand(0), *RHS =
I.getOperand(1);
2184 if (
I.hasAllowReassoc() &&
I.hasNoSignedZeros()) {
2197 I,
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
2198 {X->getType()}, {Y, X}, &
I));
2205 Constant *NewStartC = ConstantFP::get(
I.getType(), *
C + *StartC);
2207 I,
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
2208 {X->getType()}, {NewStartC, X}, &
I));
2216 Instruction::FAdd, MulC, ConstantFP::get(
I.getType(), 1.0),
DL))
2238 if (!Result->hasNoNaNs())
2239 Result->setHasNoInfs(
false);
2249 if (LHS->getType() != RHS->getType())
2258 Ptr =
GEP->getPointerOperand();
2275 Base.RHSNW =
GEP->getNoWrapFlags();
2277 Base.RHSNW =
Base.RHSNW.intersectForOffsetAdd(
GEP->getNoWrapFlags());
2279 RHS =
GEP->getPointerOperand();
2289 if (LHS ==
Base.Ptr)
2296 Base.LHSNW =
GEP->getNoWrapFlags();
2298 Base.LHSNW =
Base.LHSNW.intersectForOffsetAdd(
GEP->getNoWrapFlags());
2300 LHS =
GEP->getPointerOperand();
2307 unsigned NumGEPs = 0;
2309 bool SeenMultiUse =
false;
2314 if (!
GEP->hasOneUse()) {
2317 SeenMultiUse =
true;
2330 Type *Ty,
bool IsNUW) {
2332 if (!
Base.Ptr ||
Base.isExpensive())
2338 bool RewriteGEPs = !
Base.LHSGEPs.empty() && !
Base.RHSGEPs.empty();
2340 Type *IdxTy =
DL.getIndexType(LHS->getType());
2341 Value *Result = EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy, RewriteGEPs);
2342 Value *Offset2 = EmitGEPOffsets(
Base.RHSGEPs,
Base.RHSNW, IdxTy, RewriteGEPs);
2348 (
I->use_empty() ||
I->hasOneUse()) &&
I->hasNoSignedWrap() &&
2349 !
I->hasNoUnsignedWrap() &&
2350 ((
I->getOpcode() == Instruction::Mul &&
2352 I->getOpcode() == Instruction::Shl))
2360 Builder.CreateSub(Result, Offset2,
"gepdiff",
2361 IsNUW &&
Base.LHSNW.hasNoUnsignedWrap() &&
2362 Base.RHSNW.hasNoUnsignedWrap(),
2363 Base.LHSNW.isInBounds() &&
Base.RHSNW.isInBounds());
2366 return Builder.CreateIntCast(Result, Ty,
true);
2371 Value *Op0 =
I.getOperand(0);
2372 Value *Op1 =
I.getOperand(1);
2373 Type *Ty =
I.getType();
2394 Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {
Y, Z});
2395 return BinaryOperator::CreateAdd(
X, USub);
2398 Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {Z,
Y});
2399 return BinaryOperator::CreateAdd(
X, USub);
2417 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(),
2418 SQ.getWithInstruction(&
I)))
2427 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2431 if (
Value *V = dyn_castNegVal(Op1)) {
2435 assert(BO->getOpcode() == Instruction::Sub &&
2436 "Expected a subtraction operator!");
2437 if (BO->hasNoSignedWrap() &&
I.hasNoSignedWrap())
2440 if (
cast<Constant>(Op1)->isNotMinSignedValue() &&
I.hasNoSignedWrap())
2460 bool WillNotSOV = willNotOverflowSignedSub(
C, C2,
I);
2469 Op1NSW = OBO1->hasNoSignedWrap();
2470 Op1NUW = OBO1->hasNoUnsignedWrap();
2479 auto TryToNarrowDeduceFlags = [
this, &
I, &Op0, &Op1]() ->
Instruction * {
2484 if (!
I.hasNoSignedWrap() && willNotOverflowSignedSub(Op0, Op1,
I)) {
2486 I.setHasNoSignedWrap(
true);
2488 if (!
I.hasNoUnsignedWrap() && willNotOverflowUnsignedSub(Op0, Op1,
I)) {
2490 I.setHasNoUnsignedWrap(
true);
2503 I.hasNoSignedWrap(),
2505 return BinaryOperator::CreateAdd(NegOp1, Op0);
2508 return TryToNarrowDeduceFlags();
2514 if (
I.getType()->isIntOrIntVectorTy(1))
2515 return BinaryOperator::CreateXor(Op0, Op1);
2524 return BinaryOperator::CreateAdd(
Builder.CreateNot(Op1),
X);
2532 return BinaryOperator::CreateAnd(
2544 return BinaryOperator::CreateSub(XZ, YW);
2555 Sub->setHasNoUnsignedWrap(HasNUW);
2556 Sub->setHasNoSignedWrap(HasNSW);
2567 return BinaryOperator::CreateAdd(OpsSub, ConstsSub);
2578 R = BinaryOperator::CreateSub(
X, Z);
2580 R = BinaryOperator::CreateSub(
X,
Y);
2582 R = BinaryOperator::CreateSub(W, Z);
2584 R = BinaryOperator::CreateSub(W,
Y);
2586 bool NSW =
I.hasNoSignedWrap() &&
2590 bool NUW =
I.hasNoUnsignedWrap() &&
2592 R->setHasNoSignedWrap(NSW);
2593 R->setHasNoUnsignedWrap(NUW);
2603 bool ConsumesOp0, ConsumesOp1;
2606 (ConsumesOp0 || ConsumesOp1)) {
2609 assert(NotOp0 !=
nullptr && NotOp1 !=
nullptr &&
2610 "isFreeToInvert desynced with getFreelyInverted");
2611 return BinaryOperator::CreateSub(NotOp1, NotOp0);
2615 auto m_AddRdx = [](
Value *&Vec) {
2619 if (
match(Op0, m_AddRdx(V0)) &&
match(Op1, m_AddRdx(
V1)) &&
2620 V0->getType() ==
V1->getType()) {
2624 Value *Rdx =
Builder.CreateIntrinsic(Intrinsic::vector_reduce_add,
2625 {
Sub->getType()}, {
Sub});
2676 Op1,
SQ.getWithInstruction(&
I).getWithoutDomCondCache());
2677 if ((*Op0C | RHSKnown.
Zero).isAllOnes())
2678 return BinaryOperator::CreateXor(Op1, Op0);
2685 const APInt *C2, *C3;
2690 APInt C2AndC3 = *C2 & *C3;
2691 APInt C2AndC3Minus1 = C2AndC3 - 1;
2692 APInt C2AddC3 = *C2 + *C3;
2693 if ((*C3 - C2AndC3Minus1).isPowerOf2() &&
2696 return BinaryOperator::CreateAdd(
2697 And, ConstantInt::get(
I.getType(), *Op0C - C2AndC3));
2718 return BinaryOperator::CreateXor(
A,
B);
2726 return BinaryOperator::CreateAnd(
A,
B);
2734 return BinaryOperator::CreateOr(
A,
B);
2751 return BinaryOperator::CreateAnd(
A,
B);
2767 return BinaryOperator::CreateAnd(
2768 Y,
Builder.CreateNot(Op1, Op1->getName() +
".not"));
2799 if (m_SubXorCmp(Op0, Op1))
2800 return createSelectInstWithUnknownProfile(
C,
Builder.CreateNeg(
X),
X);
2801 if (m_SubXorCmp(Op1, Op0))
2802 return createSelectInstWithUnknownProfile(
C,
X,
Builder.CreateNeg(
X));
2822 auto SinkSubIntoSelect =
2829 if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal)
2834 bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal;
2835 Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal);
2839 OtherHandOfSubIsTrueVal ? NewSub : Zero);
2847 return Builder->CreateSub(OtherHandOfSelect,
2854 return Builder->CreateSub(Op0,
2863 return BinaryOperator::CreateAnd(
2864 Op0,
Builder.CreateNot(
Y,
Y->getName() +
".not"));
2877 return BinaryOperator::CreateSub(Not,
X);
2883 return BinaryOperator::CreateSub(
X, Not);
2891 I.getType()->getScalarSizeInBits() != 1 &&
2892 (Op0->
hasOneUse() || Op1->hasOneUse())) {
2898 I.getType()->getScalarSizeInBits() != 1 &&
2899 (Op0->
hasOneUse() || Op1->hasOneUse())) {
2906 Value *LHSOp, *RHSOp;
2910 I.hasNoUnsignedWrap()))
2920 auto MatchSubOfZExtOfPtrToIntOrAddr = [&]() {
2934 if (MatchSubOfZExtOfPtrToIntOrAddr()) {
2936 if (
GEP->getPointerOperand() == RHSOp) {
2937 if (
GEP->hasNoUnsignedWrap() ||
GEP->hasNoUnsignedSignedWrap()) {
2939 Value *Res =
GEP->hasNoUnsignedWrap()
2942 GEP->hasNoUnsignedSignedWrap())
2957 Type *Ty =
I.getType();
2958 unsigned BitWidth = Ty->getScalarSizeInBits();
2960 Op1->hasNUses(2) && *ShAmt ==
BitWidth - 1 &&
2967 Value *NegA =
I.hasNoUnsignedWrap()
2969 :
Builder.CreateNeg(
A,
"",
I.hasNoSignedWrap());
2977 const APInt *AddC, *AndC;
2982 if ((HighMask & *AndC).
isZero())
2983 return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC)));
2994 I,
Builder.CreateIntrinsic(Intrinsic::umin, {I.getType()}, {Op0, Y}));
3001 I,
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op1}));
3006 I,
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op0, X}));
3010 Value *USub =
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {
X, Op0});
3016 Value *USub =
Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op1,
X});
3024 I,
Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
3025 {Builder.CreateNot(X)}));
3033 bool PropagateNSW =
I.hasNoSignedWrap() && OBO0->hasNoSignedWrap() &&
3034 OBO1->hasNoSignedWrap() &&
BitWidth > 2;
3035 bool PropagateNUW =
I.hasNoUnsignedWrap() && OBO0->hasNoUnsignedWrap() &&
3036 OBO1->hasNoUnsignedWrap() &&
BitWidth > 1;
3046 if (
I.hasNoUnsignedWrap() ||
I.hasNoSignedWrap()) {
3048 Builder.CreateSub(
X,
Y,
"sub",
false,
true);
3068 Value *Z, *Add0, *Add1;
3075 unsigned NumOfNewInstrs = 0;
3080 unsigned NumOfDeadInstrs = 0;
3086 NumOfDeadInstrs += Add0->
hasOneUse() ? 1 : 0;
3088 if (Op1->hasOneUse()) {
3090 NumOfDeadInstrs += Add1->
hasOneUse() ? 1 : 0;
3092 if (NumOfDeadInstrs >= NumOfNewInstrs) {
3097 I.hasNoSignedWrap());
3103 return TryToNarrowDeduceFlags();
3170 Instruction &FMFSource) {
3176 X, Builder.CreateFNegFMF(
Y, &FMFSource), &FMFSource));
3181 Builder.CreateFNegFMF(
X, &FMFSource),
Y, &FMFSource));
3188 if (
II->getIntrinsicID() == Intrinsic::ldexp) {
3191 Builder.CreateCall(
II->getCalledFunction(),
3192 {Builder.CreateFNegFMF(II->getArgOperand(0), FMF),
3193 II->getArgOperand(1)});
3194 New->setFastMathFlags(FMF);
3195 New->copyMetadata(*
II);
3216 if (
I.hasNoSignedZeros() &&
3224 if (
Instruction *R = hoistFNegAboveFMulFDiv(OneUse,
I))
3233 auto propagateSelectFMF = [&](
SelectInst *S,
bool CommonOperand) {
3236 FastMathFlags FMF =
I.getFastMathFlags() | OldSel->getFastMathFlags();
3238 if (!OldSel->hasNoSignedZeros() && !CommonOperand &&
3248 propagateSelectFMF(NewSel,
P ==
Y);
3255 propagateSelectFMF(NewSel,
P ==
X);
3265 propagateSelectFMF(NewSel,
true);
3297 I.getFastMathFlags(),
3327 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3334 if (
I.hasNoSignedZeros() ||
3367 Type *Ty =
I.getType();
3394 if (
I.hasAllowReassoc() &&
I.hasNoSignedZeros()) {
3407 Instruction::FSub,
C, ConstantFP::get(Ty, 1.0),
DL))
3413 Instruction::FSub, ConstantFP::get(Ty, 1.0),
C,
DL))
3428 auto m_FaddRdx = [](
Value *&Sum,
Value *&Vec) {
3433 if (
match(Op0, m_FaddRdx(A0, V0)) &&
match(Op1, m_FaddRdx(A1,
V1)) &&
3434 V0->getType() ==
V1->getType()) {
3438 Value *Rdx =
Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
3439 {
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 * 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.
const SmallVectorImpl< MachineOperand > & 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")
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.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
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)
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)
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.
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)
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)
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)
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)
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.
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".
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)
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.
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.
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)