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);
192 Value *createAddendVal(
const FAddend &A,
bool& NeedNeg);
195 unsigned calcInstrNumber(
const AddendVect& Vect);
202 Value *createNaryFAdd(
const AddendVect& Opnds,
unsigned InstrQuota);
203 void createInstPostProc(
Instruction *NewInst,
bool NoNumber =
false);
207 unsigned CreateInstrNum;
208 void initCreateInstNum() { CreateInstrNum = 0; }
209 void incCreateInstNum() { CreateInstrNum++; }
211 void initCreateInstNum() {}
212 void incCreateInstNum() {}
227 FAddendCoef::~FAddendCoef() {
229 getFpValPtr()->~APFloat();
232 void FAddendCoef::set(
const APFloat&
C) {
242 IsFp = BufHasFpVal =
true;
245 void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
256 IsFp = BufHasFpVal =
true;
269 void FAddendCoef::operator=(
const FAddendCoef &That) {
273 set(That.getFpVal());
278 if (
isInt() == That.isInt()) {
282 getFpVal().add(That.getFpVal(), RndMode);
289 getFpVal().add(T, RndMode);
297 void FAddendCoef::operator*=(
const FAddendCoef &That) {
301 if (That.isMinusOne()) {
306 if (
isInt() && That.isInt()) {
307 int Res =
IntVal * (int)That.IntVal;
308 assert(!insaneIntVal(Res) &&
"Insane int value");
314 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
317 convertToFpType(Semantic);
321 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
327 void FAddendCoef::negate() {
331 getFpVal().changeSign();
334 Value *FAddendCoef::getValue(
Type *Ty)
const {
350 unsigned FAddend::drillValueDownOneStep
351 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
353 if (!Val || !(I = dyn_cast<Instruction>(Val)))
358 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
362 if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->
isZero())
365 if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->
isZero())
370 Addend0.set(1, Opnd0);
372 Addend0.set(C0,
nullptr);
376 FAddend &Addend = Opnd0 ? Addend1 : Addend0;
378 Addend.set(1, Opnd1);
380 Addend.set(C1,
nullptr);
381 if (Opcode == Instruction::FSub)
386 return Opnd0 && Opnd1 ? 2 : 1;
393 if (I->
getOpcode() == Instruction::FMul) {
396 if (
ConstantFP *C = dyn_cast<ConstantFP>(V0)) {
401 if (
ConstantFP *C = dyn_cast<ConstantFP>(V1)) {
413 unsigned FAddend::drillAddendDownOneStep
414 (FAddend &Addend0, FAddend &Addend1)
const {
418 unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
419 if (!BreakNum || Coeff.isOne())
422 Addend0.Scale(Coeff);
425 Addend1.Scale(Coeff);
439 I->
getOpcode() == Instruction::FSub) &&
"Expect add/sub");
444 if (!I0 || !I1 || I0->
getOpcode() != I1->getOpcode())
448 if (I0->
getOpcode() == Instruction::FMul)
450 else if (I0->
getOpcode() != Instruction::FDiv)
455 Value *Opnd1_0 = I1->getOperand(0);
456 Value *Opnd1_1 = I1->getOperand(1);
462 Value *Factor =
nullptr;
463 Value *AddSub0 =
nullptr, *AddSub1 =
nullptr;
466 if (Opnd0_0 == Opnd1_0 || Opnd0_0 == Opnd1_1)
468 else if (Opnd0_1 == Opnd1_0 || Opnd0_1 == Opnd1_1)
472 AddSub0 = (Factor == Opnd0_0) ? Opnd0_1 : Opnd0_0;
473 AddSub1 = (Factor == Opnd1_0) ? Opnd1_1 : Opnd1_0;
475 }
else if (Opnd0_1 == Opnd1_1) {
491 createFAdd(AddSub0, AddSub1) :
492 createFSub(AddSub0, AddSub1);
493 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(NewAddSub)) {
494 const APFloat &
F = CFP->getValueAPF();
497 }
else if (
Instruction *II = dyn_cast<Instruction>(NewAddSub))
498 II->setFastMathFlags(Flags);
501 Value *RI = createFMul(Factor, NewAddSub);
503 II->setFastMathFlags(Flags);
507 Value *RI = createFDiv(NewAddSub, Factor);
509 II->setFastMathFlags(Flags);
515 "Expected 'reassoc'+'nsz' instruction");
522 I->
getOpcode() == Instruction::FSub) &&
"Expect add/sub");
527 FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
529 unsigned OpndNum = FAddend::drillValueDownOneStep(I, Opnd0, Opnd1);
532 unsigned Opnd0_ExpNum = 0;
533 unsigned Opnd1_ExpNum = 0;
535 if (!Opnd0.isConstant())
536 Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
539 if (OpndNum == 2 && !Opnd1.isConstant())
540 Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);
543 if (Opnd0_ExpNum && Opnd1_ExpNum) {
545 AllOpnds.push_back(&Opnd0_0);
546 AllOpnds.push_back(&Opnd1_0);
547 if (Opnd0_ExpNum == 2)
548 AllOpnds.push_back(&Opnd0_1);
549 if (Opnd1_ExpNum == 2)
550 AllOpnds.push_back(&Opnd1_1);
553 unsigned InstQuota = 0;
557 InstQuota = ((!isa<Constant>(V0) && V0->
hasOneUse()) &&
558 (!isa<Constant>(V1) && V1->
hasOneUse())) ? 2 : 1;
560 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
569 const FAddendCoef &CE = Opnd0.getCoef();
570 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
576 AllOpnds.push_back(&Opnd0);
577 AllOpnds.push_back(&Opnd1_0);
578 if (Opnd1_ExpNum == 2)
579 AllOpnds.push_back(&Opnd1_1);
581 if (
Value *R = simplifyFAdd(AllOpnds, 1))
588 AllOpnds.push_back(&Opnd1);
589 AllOpnds.push_back(&Opnd0_0);
590 if (Opnd0_ExpNum == 2)
591 AllOpnds.push_back(&Opnd0_1);
593 if (
Value *R = simplifyFAdd(AllOpnds, 1))
598 return performFactorization(I);
601 Value *FAddCombine::simplifyFAdd(AddendVect& Addends,
unsigned InstrQuota) {
602 unsigned AddendNum = Addends.size();
603 assert(AddendNum <= 4 &&
"Too many addends");
606 unsigned NextTmpIdx = 0;
607 FAddend TmpResult[3];
614 const FAddend *ConstAdd =
nullptr;
622 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
624 const FAddend *ThisAddend = Addends[SymIdx];
630 Value *Val = ThisAddend->getSymVal();
631 unsigned StartIdx = SimpVect.size();
632 SimpVect.push_back(ThisAddend);
639 for (
unsigned SameSymIdx = SymIdx + 1;
640 SameSymIdx < AddendNum; SameSymIdx++) {
641 const FAddend *
T = Addends[SameSymIdx];
642 if (T && T->getSymVal() == Val) {
645 Addends[SameSymIdx] =
nullptr;
646 SimpVect.push_back(T);
651 if (StartIdx + 1 != SimpVect.size()) {
652 FAddend &R = TmpResult[NextTmpIdx ++];
653 R = *SimpVect[StartIdx];
654 for (
unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
658 SimpVect.resize(StartIdx);
661 SimpVect.push_back(&R);
672 "out-of-bound access");
675 SimpVect.push_back(ConstAdd);
678 if (!SimpVect.empty())
679 Result = createNaryFAdd(SimpVect, InstrQuota);
688 Value *FAddCombine::createNaryFAdd
689 (
const AddendVect &Opnds,
unsigned InstrQuota) {
690 assert(!Opnds.empty() &&
"Expect at least one addend");
694 unsigned InstrNeeded = calcInstrNumber(Opnds);
695 if (InstrNeeded > InstrQuota)
708 Value *LastVal =
nullptr;
709 bool LastValNeedNeg =
false;
712 for (
const FAddend *Opnd : Opnds) {
714 Value *V = createAddendVal(*Opnd, NeedNeg);
717 LastValNeedNeg = NeedNeg;
721 if (LastValNeedNeg == NeedNeg) {
722 LastVal = createFAdd(LastVal, V);
727 LastVal = createFSub(V, LastVal);
729 LastVal = createFSub(LastVal, V);
731 LastValNeedNeg =
false;
734 if (LastValNeedNeg) {
735 LastVal = createFNeg(LastVal);
739 assert(CreateInstrNum == InstrNeeded &&
740 "Inconsistent in instruction numbers");
747 Value *V = Builder.CreateFSub(Opnd0, Opnd1);
749 createInstPostProc(I);
755 Value *NewV = createFSub(Zero, V);
757 createInstPostProc(I,
true);
762 Value *V = Builder.CreateFAdd(Opnd0, Opnd1);
764 createInstPostProc(I);
769 Value *V = Builder.CreateFMul(Opnd0, Opnd1);
771 createInstPostProc(I);
776 Value *V = Builder.CreateFDiv(Opnd0, Opnd1);
778 createInstPostProc(I);
782 void FAddCombine::createInstPostProc(
Instruction *NewInstr,
bool NoNumber) {
795 unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
796 unsigned OpndNum = Opnds.size();
797 unsigned InstrNeeded = OpndNum - 1;
800 unsigned NegOpndNum = 0;
803 for (
const FAddend *Opnd : Opnds) {
804 if (Opnd->isConstant())
809 if (isa<UndefValue>(Opnd->getSymVal()))
812 const FAddendCoef &CE = Opnd->getCoef();
813 if (CE.isMinusOne() || CE.isMinusTwo())
819 if (!CE.isMinusOne() && !CE.isOne())
822 if (NegOpndNum == OpndNum)
835 Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
836 const FAddendCoef &Coeff = Opnd.getCoef();
838 if (Opnd.isConstant()) {
840 return Coeff.getValue(Instr->getType());
843 Value *OpndVal = Opnd.getSymVal();
845 if (Coeff.isMinusOne() || Coeff.isOne()) {
846 NeedNeg = Coeff.isMinusOne();
850 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
851 NeedNeg = Coeff.isMinusTwo();
852 return createFAdd(OpndVal, OpndVal);
856 return createFMul(OpndVal, Coeff.getValue(Instr->getType()));
864 bool InstCombiner::willNotOverflowSignedSub(
const Value *LHS,
889 bool InstCombiner::willNotOverflowUnsignedSub(
const Value *LHS,
915 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
916 const APInt *C1 =
nullptr, *C2 =
nullptr;
932 return Builder.
CreateSub(RHS, NewAnd,
"sub");
937 return Builder.
CreateSub(RHS, NewOr,
"sub");
957 return Builder.
CreateSub(RHS, NewOr,
"sub");
979 return BinaryOperator::CreateSub(
SubOne(Op1C),
X);
989 return BinaryOperator::CreateOr(Op0, Op1);
993 return BinaryOperator::CreateXor(Op0, Op1);
1009 return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty);
1020 return new ZExtInst(Builder.CreateNot(X), Ty);
1027 Value *NotX = Builder.CreateNot(X);
1036 bool Changed = SimplifyAssociativeOrCommutative(I);
1037 if (
Value *V = SimplifyVectorOp(I))
1038 return replaceInstUsesWith(I, V);
1043 SQ.getWithInstruction(&I)))
1044 return replaceInstUsesWith(I, V);
1047 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1048 return replaceInstUsesWith(I, V);
1056 if (
ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1060 const APInt &RHSVal = CI->getValue();
1061 unsigned ExtendAmt = 0;
1064 if (XorRHS->
getValue() == -RHSVal) {
1066 ExtendAmt = TySizeBits - RHSVal.
logBase2() - 1;
1079 Value *NewShl = Builder.CreateShl(XorLHS, ShAmt,
"sext");
1080 return BinaryOperator::CreateAShr(NewShl, ShAmt);
1087 if ((XorRHS->
getValue() | LHSKnown.
Zero).isAllOnesValue())
1100 return BinaryOperator::CreateXor(LHS, RHS);
1117 return BinaryOperator::CreateSub(RHS, A);
1122 return BinaryOperator::CreateSub(LHS, B);
1125 return replaceInstUsesWith(I, V);
1129 return BinaryOperator::CreateOr(LHS, RHS);
1134 if (
ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
1140 CRHS->getValue() == (CRHS->getValue() & C2->
getValue())) {
1143 const APInt &AddRHSV = CRHS->getValue();
1146 APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));
1151 if (AddRHSHighBits == AddRHSHighBitsAnd) {
1153 Value *NewAdd = Builder.CreateAdd(X, CRHS, LHS->
getName());
1154 return BinaryOperator::CreateAnd(NewAdd, C2);
1186 if (
SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) {
1188 if (
ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
1189 if (LHSConv->hasOneUse()) {
1193 willNotOverflowSignedAdd(LHSConv->getOperand(0), CI,
I)) {
1196 Builder.CreateNSWAdd(LHSConv->getOperand(0), CI,
"addconv");
1203 if (
SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) {
1207 if (LHSConv->getOperand(0)->getType() ==
1208 RHSConv->getOperand(0)->getType() &&
1209 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1210 willNotOverflowSignedAdd(LHSConv->getOperand(0),
1211 RHSConv->getOperand(0),
I)) {
1213 Value *NewAdd = Builder.CreateNSWAdd(LHSConv->getOperand(0),
1214 RHSConv->getOperand(0),
"addconv");
1222 if (
auto *LHSConv = dyn_cast<ZExtInst>(LHS)) {
1224 if (
ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
1225 if (LHSConv->hasOneUse()) {
1229 willNotOverflowUnsignedAdd(LHSConv->getOperand(0), CI,
I)) {
1232 Builder.CreateNUWAdd(LHSConv->getOperand(0), CI,
"addconv");
1239 if (
auto *RHSConv = dyn_cast<ZExtInst>(RHS)) {
1243 if (LHSConv->getOperand(0)->getType() ==
1244 RHSConv->getOperand(0)->getType() &&
1245 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1246 willNotOverflowUnsignedAdd(LHSConv->getOperand(0),
1247 RHSConv->getOperand(0),
I)) {
1249 Value *NewAdd = Builder.CreateNUWAdd(
1250 LHSConv->getOperand(0), RHSConv->getOperand(0),
"addconv");
1259 return BinaryOperator::CreateOr(A, B);
1264 return BinaryOperator::CreateOr(A, B);
1294 return Changed ? &
I :
nullptr;
1298 bool Changed = SimplifyAssociativeOrCommutative(I);
1301 if (
Value *V = SimplifyVectorOp(I))
1302 return replaceInstUsesWith(I, V);
1305 SQ.getWithInstruction(&I)))
1306 return replaceInstUsesWith(I, V);
1308 if (
Instruction *FoldedFAdd = foldBinOpIntoSelectOrPhi(I))
1321 if (
SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
1322 Value *LHSIntVal = LHSConv->getOperand(0);
1323 Type *FPType = LHSConv->getType();
1328 auto IsValidPromotion = [](
Type *FTy,
Type *ITy) {
1334 unsigned MaxRepresentableBits =
1344 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(RHS))
1345 if (IsValidPromotion(FPType, LHSIntVal->
getType())) {
1348 if (LHSConv->hasOneUse() &&
1350 willNotOverflowSignedAdd(LHSIntVal, CI, I)) {
1352 Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, CI,
"addconv");
1358 if (
SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
1359 Value *RHSIntVal = RHSConv->getOperand(0);
1362 if (IsValidPromotion(FPType, LHSIntVal->
getType())) {
1367 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1368 willNotOverflowSignedAdd(LHSIntVal, RHSIntVal, I)) {
1370 Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, RHSIntVal,
"addconv");
1378 if (
Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS))
1379 return replaceInstUsesWith(I, V);
1382 if (
Value *V = FAddCombine(Builder).simplify(&I))
1383 return replaceInstUsesWith(I, V);
1386 return Changed ? &
I :
nullptr;
1396 bool Swapped =
false;
1401 if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1403 if (LHSGEP->getOperand(0) == RHS) {
1406 }
else if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1408 if (LHSGEP->getOperand(0)->stripPointerCasts() ==
1409 RHSGEP->getOperand(0)->stripPointerCasts()) {
1417 if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1419 if (RHSGEP->getOperand(0) == LHS) {
1422 }
else if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1424 if (RHSGEP->getOperand(0)->stripPointerCasts() ==
1425 LHSGEP->getOperand(0)->stripPointerCasts()) {
1450 unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices();
1451 if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 &&
1452 ((NumNonConstantIndices1 > 0 && !GEP1->
hasOneUse()) ||
1453 (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) {
1465 Result = Builder.CreateSub(Result, Offset);
1470 Result = Builder.CreateNeg(Result,
"diff.neg");
1472 return Builder.CreateIntCast(Result, Ty,
true);
1478 if (
Value *V = SimplifyVectorOp(I))
1479 return replaceInstUsesWith(I, V);
1483 SQ.getWithInstruction(&I)))
1484 return replaceInstUsesWith(I, V);
1487 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1488 return replaceInstUsesWith(I, V);
1491 if (
Value *V = dyn_castNegVal(Op1)) {
1494 if (
const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
1495 assert(BO->getOpcode() == Instruction::Sub &&
1496 "Expected a subtraction operator!");
1500 if (cast<Constant>(Op1)->isNotMinSignedValue() && I.
hasNoSignedWrap())
1508 return BinaryOperator::CreateXor(Op0, Op1);
1517 return BinaryOperator::CreateSub(Y, X);
1519 if (
Constant *C = dyn_cast<Constant>(Op0)) {
1536 if (
PHINode *PN = dyn_cast<PHINode>(Op1))
1566 *ShAmt == BitWidth - 1) {
1567 Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
1568 return BinaryOperator::CreateAShr(X, ShAmtOp);
1571 *ShAmt == BitWidth - 1) {
1572 Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
1573 return BinaryOperator::CreateLShr(X, ShAmtOp);
1581 if ((*Op0C | RHSKnown.
Zero).isAllOnesValue())
1582 return BinaryOperator::CreateXor(Op1, Op0);
1602 return BinaryOperator::CreateAnd(A, B);
1609 return BinaryOperator::CreateAnd(
1610 Y, Builder.CreateNot(Op1, Op1->getName() +
".not"));
1613 if (Op1->hasOneUse()) {
1614 Value *X =
nullptr, *Y =
nullptr, *Z =
nullptr;
1620 Builder.CreateSub(Z, Y, Op1->
getName()));
1624 return BinaryOperator::CreateAnd(Op0,
1625 Builder.CreateNot(Y, Y->
getName() +
".not"));
1634 if (
Value *XNeg = dyn_castNegVal(X))
1635 return BinaryOperator::CreateShl(XNeg, Y);
1666 Value *LHSOp, *RHSOp;
1669 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1670 return replaceInstUsesWith(I, Res);
1675 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1676 return replaceInstUsesWith(I, Res);
1678 bool Changed =
false;
1688 return Changed ? &
I :
nullptr;
1694 if (
Value *V = SimplifyVectorOp(I))
1695 return replaceInstUsesWith(I, V);
1698 SQ.getWithInstruction(&I)))
1699 return replaceInstUsesWith(I, V);
1715 Value *NewSub = Builder.CreateFSubFMF(Y, X, &I);
1720 if (isa<Constant>(Op0))
1747 if (
Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
1748 return replaceInstUsesWith(I, V);
1751 if (
Value *V = FAddCombine(Builder).simplify(&I))
1752 return replaceInstUsesWith(I, V);
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)
BinaryOp_match< cstfp_pred_ty< is_neg_zero_fp >, RHS, Instruction::FSub > m_FNeg(const RHS &X)
Match 'fneg X' as 'fsub -0.0, X'.
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)
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)
DiagnosticInfoOptimizationBase::Argument NV
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Compute iterated dominance frontiers using a linear time algorithm.
match_zero m_Zero()
Match an arbitrary zero/null constant.
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)
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
This class represents a sign extension of integer types.
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.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
static BinaryOperator * CreateFSubFMF(Value *V1, Value *V2, BinaryOperator *FMFSource, const Twine &Name="")
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 * 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.
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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)
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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.
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.
bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Return true if LHS and RHS have no common bits set.
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'.
bool isNegative() const
Returns true if this value is known to be negative.
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)
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.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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)
Return true if 'V & Mask' is known to be zero.
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)
opStatus multiply(const APFloat &RHS, roundingMode RM)
Instruction * visitFAdd(BinaryOperator &I)
const Value * getCondition() const
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.
neg_match< LHS > m_Neg(const LHS &L)
Match an integer negate.
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.
unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Return the number of times the sign bit of the register is replicated into the other bits...
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...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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...
static unsigned int semanticsPrecision(const fltSemantics &)
void setOperand(unsigned i, Value *Val)
unsigned logBase2() const
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...
const Value * getFalseValue() const
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)
unsigned getIntegerBitWidth() const
Instruction * visitAdd(BinaryOperator &I)
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.
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)
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
bool isOneValue() const
Returns true if the value is one.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nsw 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.
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.
Convenience struct for specifying and reasoning about fast-math flags.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
unsigned countNonConstantIndices() const
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)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
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)