39 #define DEBUG_TYPE "instcombine" 56 FAddendCoef() =
default;
61 void operator=(
const FAddendCoef &A);
63 void operator*=(
const FAddendCoef &S);
66 assert(!insaneIntVal(
C) &&
"Insane coefficient");
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; }
86 {
return reinterpret_cast<APFloat *
>(&FpValBuf.buffer[0]); }
88 const APFloat *getFpValPtr()
const 89 {
return reinterpret_cast<const APFloat *
>(&FpValBuf.buffer[0]); }
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() {}
224 FAddendCoef::~FAddendCoef() {
226 getFpValPtr()->~APFloat();
229 void FAddendCoef::set(
const APFloat&
C) {
239 IsFp = BufHasFpVal =
true;
242 void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
253 IsFp = BufHasFpVal =
true;
266 void FAddendCoef::operator=(
const FAddendCoef &That) {
270 set(That.getFpVal());
275 if (
isInt() == That.isInt()) {
279 getFpVal().add(That.getFpVal(), RndMode);
286 getFpVal().add(T, RndMode);
294 void 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");
311 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
314 convertToFpType(Semantic);
318 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
324 void FAddendCoef::negate() {
328 getFpVal().changeSign();
331 Value *FAddendCoef::getValue(
Type *Ty)
const {
347 unsigned FAddend::drillValueDownOneStep
348 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
350 if (!Val || !(I = dyn_cast<Instruction>(Val)))
355 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
359 if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->
isZero())
362 if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->
isZero())
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) {
393 if (
ConstantFP *C = dyn_cast<ConstantFP>(V0)) {
398 if (
ConstantFP *C = dyn_cast<ConstantFP>(V1)) {
410 unsigned 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);
429 "Expected 'reassoc'+'nsz' instruction");
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) {
459 AllOpnds.push_back(&Opnd0_0);
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;
471 InstQuota = ((!isa<Constant>(V0) && V0->
hasOneUse()) &&
472 (!isa<Constant>(V1) && V1->
hasOneUse())) ? 2 : 1;
474 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
483 const FAddendCoef &CE = Opnd0.getCoef();
484 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
490 AllOpnds.push_back(&Opnd0);
491 AllOpnds.push_back(&Opnd1_0);
492 if (Opnd1_ExpNum == 2)
493 AllOpnds.push_back(&Opnd1_1);
495 if (
Value *R = simplifyFAdd(AllOpnds, 1))
502 AllOpnds.push_back(&Opnd1);
503 AllOpnds.push_back(&Opnd0_0);
504 if (Opnd0_ExpNum == 2)
505 AllOpnds.push_back(&Opnd0_1);
507 if (
Value *R = simplifyFAdd(AllOpnds, 1))
514 Value *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];
527 const FAddend *ConstAdd =
nullptr;
535 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
537 const FAddend *ThisAddend = Addends[SymIdx];
543 Value *Val = ThisAddend->getSymVal();
544 unsigned StartIdx = SimpVect.size();
545 SimpVect.push_back(ThisAddend);
552 for (
unsigned SameSymIdx = SymIdx + 1;
553 SameSymIdx < AddendNum; SameSymIdx++) {
554 const FAddend *
T = Addends[SameSymIdx];
555 if (T && T->getSymVal() == Val) {
558 Addends[SameSymIdx] =
nullptr;
559 SimpVect.push_back(T);
564 if (StartIdx + 1 != SimpVect.size()) {
565 FAddend &R = TmpResult[NextTmpIdx ++];
566 R = *SimpVect[StartIdx];
567 for (
unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
571 SimpVect.resize(StartIdx);
574 SimpVect.push_back(&R);
585 "out-of-bound access");
588 SimpVect.push_back(ConstAdd);
591 if (!SimpVect.empty())
592 Result = createNaryFAdd(SimpVect, InstrQuota);
601 Value *FAddCombine::createNaryFAdd
602 (
const AddendVect &Opnds,
unsigned InstrQuota) {
603 assert(!Opnds.empty() &&
"Expect at least one addend");
607 unsigned InstrNeeded = calcInstrNumber(Opnds);
608 if (InstrNeeded > InstrQuota)
621 Value *LastVal =
nullptr;
622 bool LastValNeedNeg =
false;
625 for (
const FAddend *Opnd : Opnds) {
627 Value *V = createAddendVal(*Opnd, NeedNeg);
630 LastValNeedNeg = NeedNeg;
634 if (LastValNeedNeg == NeedNeg) {
635 LastVal = createFAdd(LastVal, V);
640 LastVal = createFSub(V, LastVal);
642 LastVal = createFSub(LastVal, V);
644 LastValNeedNeg =
false;
647 if (LastValNeedNeg) {
648 LastVal = createFNeg(LastVal);
652 assert(CreateInstrNum == InstrNeeded &&
653 "Inconsistent in instruction numbers");
660 Value *V = Builder.CreateFSub(Opnd0, Opnd1);
662 createInstPostProc(I);
668 Value *NewV = createFSub(Zero, V);
670 createInstPostProc(I,
true);
675 Value *V = Builder.CreateFAdd(Opnd0, Opnd1);
677 createInstPostProc(I);
682 Value *V = Builder.CreateFMul(Opnd0, Opnd1);
684 createInstPostProc(I);
688 void FAddCombine::createInstPostProc(
Instruction *NewInstr,
bool NoNumber) {
701 unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
702 unsigned OpndNum = Opnds.size();
703 unsigned InstrNeeded = OpndNum - 1;
706 unsigned NegOpndNum = 0;
709 for (
const FAddend *Opnd : Opnds) {
710 if (Opnd->isConstant())
715 if (isa<UndefValue>(Opnd->getSymVal()))
718 const FAddendCoef &CE = Opnd->getCoef();
719 if (CE.isMinusOne() || CE.isMinusTwo())
725 if (!CE.isMinusOne() && !CE.isOne())
728 if (NegOpndNum == OpndNum)
741 Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
742 const FAddendCoef &Coeff = Opnd.getCoef();
744 if (Opnd.isConstant()) {
746 return Coeff.getValue(Instr->getType());
749 Value *OpndVal = Opnd.getSymVal();
751 if (Coeff.isMinusOne() || Coeff.isOne()) {
752 NeedNeg = Coeff.isMinusOne();
756 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
757 NeedNeg = Coeff.isMinusTwo();
758 return createFAdd(OpndVal, OpndVal);
762 return createFMul(OpndVal, Coeff.getValue(Instr->getType()));
776 if (!LHS->
hasOneUse() && !RHS->hasOneUse())
779 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
780 const APInt *C1 =
nullptr, *C2 =
nullptr;
796 return Builder.
CreateSub(RHS, NewAnd,
"sub");
801 return Builder.
CreateSub(RHS, NewOr,
"sub");
821 return Builder.
CreateSub(RHS, NewOr,
"sub");
849 return BinaryOperator::CreateSub(
SubOne(Op1C),
X);
859 return BinaryOperator::CreateOr(Op0, Op1);
863 return BinaryOperator::CreateXor(Op0, Op1);
879 return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty);
890 return new ZExtInst(Builder.CreateNot(X), Ty);
897 Value *NotX = Builder.CreateNot(X);
972 (void)C0.
smul_ov(C1, overflow);
974 (
void)C0.
umul_ov(C1, overflow);
993 if (
MatchRem(MulOpV, RemOpV, C1, Rem2IsSigned) &&
994 IsSigned == Rem2IsSigned) {
998 if (
MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) && X == DivOpV &&
1002 return IsSigned ? Builder.CreateSRem(X, NewDivisor,
"srem")
1003 : Builder.CreateURem(X, NewDivisor,
"urem");
1026 if (
auto *BOp = dyn_cast<BinaryOperator>(NotMask)) {
1028 BOp->setHasNoSignedWrap();
1038 SQ.getWithInstruction(&I)))
1039 return replaceInstUsesWith(I, V);
1041 if (SimplifyAssociativeOrCommutative(I))
1048 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1049 return replaceInstUsesWith(I, V);
1058 if (
ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1062 const APInt &RHSVal = CI->getValue();
1063 unsigned ExtendAmt = 0;
1066 if (XorRHS->
getValue() == -RHSVal) {
1068 ExtendAmt = TySizeBits - RHSVal.
logBase2() - 1;
1081 Value *NewShl = Builder.CreateShl(XorLHS, ShAmt,
"sext");
1082 return BinaryOperator::CreateAShr(NewShl, ShAmt);
1089 if ((XorRHS->
getValue() | LHSKnown.
Zero).isAllOnesValue())
1102 return BinaryOperator::CreateXor(LHS, RHS);
1119 return BinaryOperator::CreateSub(RHS, A);
1124 return BinaryOperator::CreateSub(LHS, B);
1127 return replaceInstUsesWith(I, V);
1132 return BinaryOperator::CreateSub(A, B);
1135 if (
Value *V = SimplifyAddWithRemainder(I))
return replaceInstUsesWith(I, V);
1139 return BinaryOperator::CreateOr(LHS, RHS);
1144 if (
ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
1150 CRHS->getValue() == (CRHS->getValue() & C2->
getValue())) {
1153 const APInt &AddRHSV = CRHS->getValue();
1156 APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));
1161 if (AddRHSHighBits == AddRHSHighBitsAnd) {
1163 Value *NewAdd = Builder.CreateAdd(X, CRHS, LHS->
getName());
1164 return BinaryOperator::CreateAnd(NewAdd, C2);
1201 return BinaryOperator::CreateOr(A, B);
1215 bool Changed =
false;
1228 return Changed ? &
I :
nullptr;
1235 I.
getOpcode() == Instruction::FSub) &&
"Expecting fadd/fsub");
1237 "FP factorization requires FMF");
1256 bool IsFAdd = I.
getOpcode() == Instruction::FAdd;
1273 SQ.getWithInstruction(&I)))
1274 return replaceInstUsesWith(I, V);
1276 if (SimplifyAssociativeOrCommutative(I))
1282 if (
Instruction *FoldedFAdd = foldBinOpIntoSelectOrPhi(I))
1296 if (
SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
1297 Value *LHSIntVal = LHSConv->getOperand(0);
1298 Type *FPType = LHSConv->getType();
1303 auto IsValidPromotion = [](
Type *FTy,
Type *ITy) {
1309 unsigned MaxRepresentableBits =
1319 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(RHS))
1320 if (IsValidPromotion(FPType, LHSIntVal->
getType())) {
1323 if (LHSConv->hasOneUse() &&
1325 willNotOverflowSignedAdd(LHSIntVal, CI, I)) {
1327 Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, CI,
"addconv");
1333 if (
SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
1334 Value *RHSIntVal = RHSConv->getOperand(0);
1337 if (IsValidPromotion(FPType, LHSIntVal->
getType())) {
1342 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1343 willNotOverflowSignedAdd(LHSIntVal, RHSIntVal, I)) {
1345 Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, RHSIntVal,
"addconv");
1353 if (
Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS))
1354 return replaceInstUsesWith(I, V);
1359 if (
Value *V = FAddCombine(Builder).simplify(&I))
1360 return replaceInstUsesWith(I, V);
1373 bool Swapped =
false;
1378 if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1380 if (LHSGEP->getOperand(0) == RHS) {
1383 }
else if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1385 if (LHSGEP->getOperand(0)->stripPointerCasts() ==
1386 RHSGEP->getOperand(0)->stripPointerCasts()) {
1394 if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1396 if (RHSGEP->getOperand(0) == LHS) {
1399 }
else if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1401 if (RHSGEP->getOperand(0)->stripPointerCasts() ==
1402 LHSGEP->getOperand(0)->stripPointerCasts()) {
1427 unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices();
1428 if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 &&
1429 ((NumNonConstantIndices1 > 0 && !GEP1->
hasOneUse()) ||
1430 (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) {
1442 Result = Builder.CreateSub(Result, Offset);
1447 Result = Builder.CreateNeg(Result,
"diff.neg");
1449 return Builder.CreateIntCast(Result, Ty,
true);
1455 SQ.getWithInstruction(&I)))
1456 return replaceInstUsesWith(I, V);
1462 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1463 return replaceInstUsesWith(I, V);
1467 if (
Value *V = dyn_castNegVal(Op1)) {
1470 if (
const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
1471 assert(BO->getOpcode() == Instruction::Sub &&
1472 "Expected a subtraction operator!");
1476 if (cast<Constant>(Op1)->isNotMinSignedValue() && I.
hasNoSignedWrap())
1484 return BinaryOperator::CreateXor(Op0, Op1);
1493 return BinaryOperator::CreateSub(Y, X);
1503 if (
Constant *C = dyn_cast<Constant>(Op0)) {
1531 if (
PHINode *PN = dyn_cast<PHINode>(Op1))
1551 *ShAmt == BitWidth - 1) {
1552 Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
1553 return BinaryOperator::CreateAShr(X, ShAmtOp);
1556 *ShAmt == BitWidth - 1) {
1557 Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
1558 return BinaryOperator::CreateLShr(X, ShAmtOp);
1561 if (Op1->hasOneUse()) {
1573 return replaceInstUsesWith(I, SI);
1582 if ((*Op0C | RHSKnown.
Zero).isAllOnesValue())
1583 return BinaryOperator::CreateXor(Op1, Op0);
1603 return BinaryOperator::CreateAnd(A, B);
1610 return BinaryOperator::CreateAnd(
1611 Y, Builder.CreateNot(Op1, Op1->getName() +
".not"));
1614 if (Op1->hasOneUse()) {
1615 Value *X =
nullptr, *Y =
nullptr, *Z =
nullptr;
1621 Builder.CreateSub(Z, Y, Op1->
getName()));
1625 return BinaryOperator::CreateAnd(Op0,
1626 Builder.CreateNot(Y, Y->
getName() +
".not"));
1635 if (
Value *XNeg = dyn_castNegVal(X))
1636 return BinaryOperator::CreateShl(XNeg, Y);
1670 Value *LHS, *RHS, *A;
1671 Value *NotA = Op0, *MinMax = Op1;
1688 Value *Not = Builder.CreateNot(MinMax);
1690 return BinaryOperator::CreateSub(Not, A);
1692 return BinaryOperator::CreateSub(A, Not);
1699 Value *LHSOp, *RHSOp;
1702 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1703 return replaceInstUsesWith(I, Res);
1708 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1709 return replaceInstUsesWith(I, Res);
1735 bool Changed =
false;
1745 return Changed ? &
I :
nullptr;
1751 SQ.getWithInstruction(&I)))
1752 return replaceInstUsesWith(I, V);
1786 Value *NewSub = Builder.CreateFSubFMF(Y, X, &I);
1791 if (isa<Constant>(Op0))
1817 if (
Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
1818 return replaceInstUsesWith(I, V);
1849 return replaceInstUsesWith(I, V);
static BinaryOperator * CreateFMulFMF(Value *V1, Value *V2, BinaryOperator *FMFSource, const Twine &Name="")
Value * EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, OptimizationRemarkEmitter *ORE=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
std::string & operator+=(std::string &buffer, StringRef string)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
static bool isConstant(const MachineInstr &MI)
static bool IsFreeToInvert(Value *V, bool WillInvertAllUses)
Return true if the specified value is free to invert (apply ~ to).
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
APInt sext(unsigned width) const
Sign extend to a new width.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
DiagnosticInfoOptimizationBase::Argument NV
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
This class represents lattice values for constants.
BinaryOps getOpcode() const
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.
static bool MatchRem(Value *E, Value *&Op, APInt &C, bool &IsSigned)
BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FAdd, true > m_c_FAdd(const LHS &L, const RHS &R)
Matches FAdd with LHS and RHS in either order.
This class represents zero extension of integer types.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
const Value * getTrueValue() const
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
static bool MatchDiv(Value *E, Value *&Op, APInt &C, bool IsSigned)
Instruction * visitFSub(BinaryOperator &I)
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
APInt trunc(unsigned width) const
Truncate to new width.
const fltSemantics & getSemantics() const
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
bool isVectorTy() const
True if this is an instance of VectorType.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
static BinaryOperator * CreateFSubFMF(Value *V1, Value *V2, BinaryOperator *FMFSource, const Twine &Name="")
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
unsigned getBitWidth() const
Return the number of bits in the APInt.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
bool match(Val *V, const Pattern &P)
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
This class represents the LLVM 'select' instruction.
roundingMode
IEEE-754R 4.3: Rounding-direction attributes.
CastClass_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static Constant * AddOne(Constant *C)
Add one to a Constant.
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.
Value * CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name="")
Copy fast-math-flags from an instruction rather than using the builder's default FMF.
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if 'V & Mask' is known to be zero.
This file implements a class to represent arbitrary precision integral constant values and operations...
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
Value * SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FAdd, fold the result or return null.
static BinaryOperator * CreateFAddFMF(Value *V1, Value *V2, BinaryOperator *FMFSource, const Twine &Name="")
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
Type * getType() const
All values are typed, get the type of this value.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
CastClass_match< OpTy, Instruction::FPExt > m_FPExt(const OpTy &Op)
Matches FPExt.
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
CastClass_match< OpTy, Instruction::FPTrunc > m_FPTrunc(const OpTy &Op)
Matches FPTrunc.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
const APInt & getValue() const
Return the constant as an APInt value reference.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
Value * getOperand(unsigned i) const
bool CannotBeNegativeZero(const Value *V, const TargetLibraryInfo *TLI, unsigned Depth=0)
Return true if we can prove that the specified FP value is never equal to -0.0.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
Value * OptimizePointerDifference(Value *LHS, Value *RHS, Type *Ty)
Optimize pointer differences into the same array into a size.
OneUse_match< T > m_OneUse(const T &SubPattern)
bool isNegative() const
Determine sign of this APInt.
static Constant * getFNeg(Constant *C)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
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.
The instances of the Type class are immutable: once they are created, they are never changed...
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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.
ConstantFP - Floating Point Values [float, double].
bool isMask(unsigned numBits) const
bool isOneValue() const
Determine if this is a value of 1.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
Value * SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
Value * CreateFSubFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name="")
Copy fast-math-flags from an instruction rather than using the builder's default FMF.
opStatus multiply(const APFloat &RHS, roundingMode RM)
static Instruction * factorizeFAddFSub(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Factor a common operand out of fadd/fsub of fmul/fdiv.
Instruction * visitFAdd(BinaryOperator &I)
const Value * getCondition() const
static Constant * getAllOnesValue(Type *Ty)
NUW NUW NUW NUW Exact static Exact BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
static CastInst * CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a ZExt or BitCast cast instruction.
deferredval_ty< Value > m_Deferred(Value *const &V)
A commutative-friendly version of m_Specific().
const APFloat & getValueAPF() const
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
static Constant * getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced=false)
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
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.
This is the shared class of boolean and integer constants.
SelectPatternFlavor Flavor
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
SelectPatternFlavor
Specific patterns of select instructions we can match.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
static unsigned int semanticsPrecision(const fltSemantics &)
static BinaryOperator * CreateFDivFMF(Value *V1, Value *V2, BinaryOperator *FMFSource, const Twine &Name="")
void setOperand(unsigned i, Value *Val)
unsigned logBase2() const
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Class for arbitrary precision integers.
Value * SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FSub, fold the result or return null.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
CastClass_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
This union template exposes a suitably aligned and sized character array member which can hold elemen...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
const Value * getFalseValue() const
static Constant * getFSub(Constant *C1, Constant *C2)
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 Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
static Value * checkForNegativeOperand(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
opStatus add(const APFloat &RHS, roundingMode RM)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned)
void setTrueValue(Value *V)
unsigned getIntegerBitWidth() const
Instruction * visitAdd(BinaryOperator &I)
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
bool isZero() const
Return true if the value is positive or negative zero.
StringRef getName() const
Return a constant reference to the value's name.
APInt smul_ov(const APInt &RHS, bool &Overflow) const
bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if LHS and RHS have no common bits set.
static Constant * getZeroValueForNegation(Type *Ty)
Floating point negation must be implemented with f(x) = -0.0 - x.
static BinaryOperator * CreateFNegFMF(Value *Op, BinaryOperator *FMFSource, const Twine &Name="")
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void setFalseValue(Value *V)
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
static bool MatchMul(Value *E, Value *&Op, APInt &C)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
APInt umul_ov(const APInt &RHS, bool &Overflow) const
bool isOneValue() const
Returns true if the value is one.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag...
static CastInst * CreateSExtOrBitCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a SExt or BitCast cast instruction.
This class represents a cast from signed integer to floating point.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
This file provides internal interfaces used to implement the InstCombine.
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
bool hasAllowReassoc() const
Determine whether the allow-reassociation flag is set.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static Constant * getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Value * SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.
bool isNotMinSignedValue() const
Return true if the value is not the smallest signed value.
bool hasOneUse() const
Return true if there is exactly one user of this value.
unsigned countNonConstantIndices() const
Instruction * visitSub(BinaryOperator &I)
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
BinaryOp_match< ValTy, cst_pred_ty< is_all_ones >, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
bool isNullValue() const
Determine if all bits are clear.
const fltSemantics & getFltSemantics() const
static Constant * getXor(Constant *C1, Constant *C2)