21 using namespace PatternMatch;
23 #define DEBUG_TYPE "instcombine"
41 FAddendCoef() : IsFp(
false), BufHasFpVal(
false),
IntVal(0) {}
45 assert(!insaneIntVal(C) &&
"Insane coefficient");
58 void operator=(
const FAddendCoef &
A);
60 void operator-=(
const FAddendCoef &A);
61 void operator*=(
const FAddendCoef &S);
63 bool isOne()
const {
return isInt() &&
IntVal == 1; }
64 bool isTwo()
const {
return isInt() &&
IntVal == 2; }
65 bool isMinusOne()
const {
return isInt() &&
IntVal == -1; }
66 bool isMinusTwo()
const {
return isInt() &&
IntVal == -2; }
69 bool insaneIntVal(
int V) {
return V > 4 || V < -4; }
71 {
return reinterpret_cast<APFloat*
>(&FpValBuf.buffer[0]); }
72 const APFloat *getFpValPtr(
void)
const
73 {
return reinterpret_cast<const APFloat*
>(&FpValBuf.buffer[0]); }
75 const APFloat &getFpVal(
void)
const {
76 assert(IsFp && BufHasFpVal &&
"Incorret state");
77 return *getFpValPtr();
81 assert(IsFp && BufHasFpVal &&
"Incorret state");
82 return *getFpValPtr();
85 bool isInt()
const {
return !IsFp; }
117 FAddend() { Val =
nullptr; }
119 Value *getSymVal (
void)
const {
return Val; }
120 const FAddendCoef &getCoef(
void)
const {
return Coeff; }
122 bool isConstant()
const {
return Val ==
nullptr; }
123 bool isZero()
const {
return Coeff.isZero(); }
125 void set(
short Coefficient,
Value *V) { Coeff.set(Coefficient), Val = V; }
127 { Coeff.set(Coefficient); Val = V; }
129 { Coeff.set(Coefficient->
getValueAPF()); Val = V; }
131 void negate() { Coeff.negate(); }
135 static unsigned drillValueDownOneStep(
Value* V, FAddend &A0, FAddend &A1);
139 unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1)
const;
142 assert((Val == T.Val) &&
"Symbolic-values disagree");
147 void Scale(
const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
165 Value *simplifyFAdd(AddendVect& V,
unsigned InstrQuota);
170 Value *createAddendVal(
const FAddend &
A,
bool& NeedNeg);
173 unsigned calcInstrNumber(
const AddendVect& Vect);
179 Value *createNaryFAdd(
const AddendVect& Opnds,
unsigned InstrQuota);
180 void createInstPostProc(
Instruction *NewInst,
bool NoNumber =
false);
188 unsigned CreateInstrNum;
189 void initCreateInstNum() { CreateInstrNum = 0; }
190 void incCreateInstNum() { CreateInstrNum++; }
192 void initCreateInstNum() {}
193 void incCreateInstNum() {}
204 FAddendCoef::~FAddendCoef() {
206 getFpValPtr()->~APFloat();
209 void FAddendCoef::set(
const APFloat& C) {
219 IsFp = BufHasFpVal =
true;
222 void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
233 IsFp = BufHasFpVal =
true;
246 void FAddendCoef::operator=(
const FAddendCoef &That) {
250 set(That.getFpVal());
255 if (
isInt() == That.isInt()) {
259 getFpVal().add(That.getFpVal(), RndMode);
266 getFpVal().add(T, RndMode);
274 void FAddendCoef::operator-=(
const FAddendCoef &That) {
276 if (
isInt() == That.isInt()) {
280 getFpVal().subtract(That.getFpVal(), RndMode);
285 const APFloat &T = That.getFpVal();
287 getFpVal().subtract(T, RndMode);
295 void FAddendCoef::operator*=(
const FAddendCoef &That) {
299 if (That.isMinusOne()) {
304 if (
isInt() && That.isInt()) {
306 assert(!insaneIntVal(Res) &&
"Insane int value");
312 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
315 convertToFpType(Semantic);
319 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
327 void FAddendCoef::negate() {
331 getFpVal().changeSign();
334 Value *FAddendCoef::getValue(
Type *Ty)
const {
337 ConstantFP::get(Ty->getContext(), getFpVal());
351 unsigned FAddend::drillValueDownOneStep
352 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
354 if (!Val || !(I = dyn_cast<Instruction>(Val)))
359 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
363 if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->
isZero())
366 if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->
isZero())
371 Addend0.set(1, Opnd0);
373 Addend0.set(C0,
nullptr);
377 FAddend &Addend = Opnd0 ? Addend1 : Addend0;
379 Addend.set(1, Opnd1);
381 Addend.set(C1,
nullptr);
382 if (Opcode == Instruction::FSub)
387 return Opnd0 && Opnd1 ? 2 : 1;
394 if (I->
getOpcode() == Instruction::FMul) {
397 if (
ConstantFP *C = dyn_cast<ConstantFP>(V0)) {
402 if (
ConstantFP *C = dyn_cast<ConstantFP>(V1)) {
415 unsigned FAddend::drillAddendDownOneStep
416 (FAddend &Addend0, FAddend &Addend1)
const {
420 unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
421 if (!BreakNum || Coeff.isOne())
424 Addend0.Scale(Coeff);
427 Addend1.Scale(Coeff);
441 assert((I->
getOpcode() == Instruction::FAdd ||
442 I->
getOpcode() == Instruction::FSub) &&
"Expect add/sub");
447 if (!I0 || !I1 || I0->
getOpcode() != I1->getOpcode())
451 if (I0->
getOpcode() == Instruction::FMul)
453 else if (I0->
getOpcode() != Instruction::FDiv)
458 Value *Opnd1_0 = I1->getOperand(0);
459 Value *Opnd1_1 = I1->getOperand(1);
466 Value *Factor =
nullptr;
467 Value *AddSub0 =
nullptr, *AddSub1 =
nullptr;
470 if (Opnd0_0 == Opnd1_0 || Opnd0_0 == Opnd1_1)
472 else if (Opnd0_1 == Opnd1_0 || Opnd0_1 == Opnd1_1)
476 AddSub0 = (Factor == Opnd0_0) ? Opnd0_1 : Opnd0_0;
477 AddSub1 = (Factor == Opnd1_0) ? Opnd1_1 : Opnd1_0;
479 }
else if (Opnd0_1 == Opnd1_1) {
495 createFAdd(AddSub0, AddSub1) :
496 createFSub(AddSub0, AddSub1);
497 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(NewAddSub)) {
498 const APFloat &
F = CFP->getValueAPF();
501 }
else if (
Instruction *II = dyn_cast<Instruction>(NewAddSub))
502 II->setFastMathFlags(Flags);
505 Value *RI = createFMul(Factor, NewAddSub);
507 II->setFastMathFlags(Flags);
511 Value *RI = createFDiv(NewAddSub, Factor);
513 II->setFastMathFlags(Flags);
524 assert((I->
getOpcode() == Instruction::FAdd ||
525 I->
getOpcode() == Instruction::FSub) &&
"Expect add/sub");
530 FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
532 unsigned OpndNum = FAddend::drillValueDownOneStep(I, Opnd0, Opnd1);
535 unsigned Opnd0_ExpNum = 0;
536 unsigned Opnd1_ExpNum = 0;
538 if (!Opnd0.isConstant())
539 Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
542 if (OpndNum == 2 && !Opnd1.isConstant())
543 Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);
546 if (Opnd0_ExpNum && Opnd1_ExpNum) {
548 AllOpnds.push_back(&Opnd0_0);
549 AllOpnds.push_back(&Opnd1_0);
550 if (Opnd0_ExpNum == 2)
551 AllOpnds.push_back(&Opnd0_1);
552 if (Opnd1_ExpNum == 2)
553 AllOpnds.push_back(&Opnd1_1);
556 unsigned InstQuota = 0;
560 InstQuota = ((!isa<Constant>(V0) && V0->
hasOneUse()) &&
561 (!isa<Constant>(V1) && V1->
hasOneUse())) ? 2 : 1;
563 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
572 const FAddendCoef &
CE = Opnd0.getCoef();
573 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
579 AllOpnds.push_back(&Opnd0);
580 AllOpnds.push_back(&Opnd1_0);
581 if (Opnd1_ExpNum == 2)
582 AllOpnds.push_back(&Opnd1_1);
584 if (
Value *R = simplifyFAdd(AllOpnds, 1))
591 AllOpnds.push_back(&Opnd1);
592 AllOpnds.push_back(&Opnd0_0);
593 if (Opnd0_ExpNum == 2)
594 AllOpnds.push_back(&Opnd0_1);
596 if (
Value *R = simplifyFAdd(AllOpnds, 1))
601 return performFactorization(I);
604 Value *FAddCombine::simplifyFAdd(AddendVect& Addends,
unsigned InstrQuota) {
606 unsigned AddendNum = Addends.size();
607 assert(AddendNum <= 4 &&
"Too many addends");
610 unsigned NextTmpIdx = 0;
611 FAddend TmpResult[3];
619 const FAddend *ConstAdd =
nullptr;
628 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
630 const FAddend *ThisAddend = Addends[SymIdx];
636 Value *Val = ThisAddend->getSymVal();
637 unsigned StartIdx = SimpVect.size();
638 SimpVect.push_back(ThisAddend);
646 for (
unsigned SameSymIdx = SymIdx + 1;
647 SameSymIdx < AddendNum; SameSymIdx++) {
648 const FAddend *T = Addends[SameSymIdx];
649 if (T && T->getSymVal() == Val) {
652 Addends[SameSymIdx] =
nullptr;
653 SimpVect.push_back(T);
658 if (StartIdx + 1 != SimpVect.size()) {
659 FAddend &R = TmpResult[NextTmpIdx ++];
660 R = *SimpVect[StartIdx];
661 for (
unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
665 SimpVect.resize(StartIdx);
668 SimpVect.push_back(&R);
679 "out-of-bound access");
682 SimpVect.push_back(ConstAdd);
685 if (!SimpVect.empty())
686 Result = createNaryFAdd(SimpVect, InstrQuota);
695 Value *FAddCombine::createNaryFAdd
696 (
const AddendVect &Opnds,
unsigned InstrQuota) {
697 assert(!Opnds.empty() &&
"Expect at least one addend");
701 unsigned InstrNeeded = calcInstrNumber(Opnds);
702 if (InstrNeeded > InstrQuota)
715 Value *LastVal =
nullptr;
716 bool LastValNeedNeg =
false;
719 for (AddendVect::const_iterator I = Opnds.begin(), E = Opnds.end();
722 Value *V = createAddendVal(**I, NeedNeg);
725 LastValNeedNeg = NeedNeg;
729 if (LastValNeedNeg == NeedNeg) {
730 LastVal = createFAdd(LastVal, V);
735 LastVal = createFSub(V, LastVal);
737 LastVal = createFSub(LastVal, V);
739 LastValNeedNeg =
false;
742 if (LastValNeedNeg) {
743 LastVal = createFNeg(LastVal);
747 assert(CreateInstrNum == InstrNeeded &&
748 "Inconsistent in instruction numbers");
755 Value *V = Builder->CreateFSub(Opnd0, Opnd1);
757 createInstPostProc(I);
763 Value *NewV = createFSub(Zero, V);
765 createInstPostProc(I,
true);
770 Value *V = Builder->CreateFAdd(Opnd0, Opnd1);
772 createInstPostProc(I);
777 Value *V = Builder->CreateFMul(Opnd0, Opnd1);
779 createInstPostProc(I);
784 Value *V = Builder->CreateFDiv(Opnd0, Opnd1);
786 createInstPostProc(I);
790 void FAddCombine::createInstPostProc(
Instruction *NewInstr,
bool NoNumber) {
803 unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
804 unsigned OpndNum = Opnds.size();
805 unsigned InstrNeeded = OpndNum - 1;
808 unsigned NegOpndNum = 0;
811 for (AddendVect::const_iterator I = Opnds.begin(), E = Opnds.end();
813 const FAddend *Opnd = *
I;
814 if (Opnd->isConstant())
817 const FAddendCoef &CE = Opnd->getCoef();
818 if (CE.isMinusOne() || CE.isMinusTwo())
824 if (!CE.isMinusOne() && !CE.isOne())
827 if (NegOpndNum == OpndNum)
840 Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
841 const FAddendCoef &Coeff = Opnd.getCoef();
843 if (Opnd.isConstant()) {
845 return Coeff.getValue(Instr->getType());
848 Value *OpndVal = Opnd.getSymVal();
850 if (Coeff.isMinusOne() || Coeff.isOne()) {
851 NeedNeg = Coeff.isMinusOne();
855 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
856 NeedNeg = Coeff.isMinusTwo();
857 return createFAdd(OpndVal, OpndVal);
861 return createFMul(OpndVal, Coeff.getValue(Instr->getType()));
869 const APInt &Op1KnownZero) {
870 APInt Op1MaybeOne = ~Op1KnownZero;
877 APInt Op0KnownZeroTemp(Op0KnownZero);
878 Op0KnownZeroTemp.
clearBit(BitWidth - 1);
882 assert(Op1OnePosition >= 0);
886 return Op0ZeroPosition >= Op1OnePosition;
893 bool InstCombiner::WillNotOverflowSignedAdd(
Value *LHS,
Value *RHS,
917 APInt LHSKnownZero(BitWidth, 0);
918 APInt LHSKnownOne(BitWidth, 0);
921 APInt RHSKnownZero(BitWidth, 0);
922 APInt RHSKnownOne(BitWidth, 0);
927 if ((LHSKnownOne[BitWidth - 1] && RHSKnownZero[BitWidth - 1]) ||
928 (LHSKnownZero[BitWidth - 1] && RHSKnownOne[BitWidth - 1]))
945 bool InstCombiner::WillNotOverflowSignedSub(
Value *LHS,
Value *RHS,
954 APInt LHSKnownZero(BitWidth, 0);
955 APInt LHSKnownOne(BitWidth, 0);
958 APInt RHSKnownZero(BitWidth, 0);
959 APInt RHSKnownOne(BitWidth, 0);
964 if ((LHSKnownOne[BitWidth - 1] && RHSKnownOne[BitWidth - 1]) ||
965 (LHSKnownZero[BitWidth - 1] && RHSKnownZero[BitWidth - 1]))
974 bool InstCombiner::WillNotOverflowUnsignedSub(
Value *LHS,
Value *RHS,
977 bool LHSKnownNonNegative, LHSKnownNegative;
978 bool RHSKnownNonNegative, RHSKnownNegative;
983 if (LHSKnownNegative && RHSKnownNonNegative)
1003 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
1004 const APInt *C1 =
nullptr, *C2 =
nullptr;
1020 return Builder->
CreateSub(RHS, NewAnd,
"sub");
1025 return Builder->
CreateSub(RHS, NewOr,
"sub");
1045 return Builder->
CreateSub(RHS, NewOr,
"sub");
1051 bool Changed = SimplifyAssociativeOrCommutative(I);
1054 if (
Value *V = SimplifyVectorOp(I))
1055 return ReplaceInstUsesWith(I, V);
1059 return ReplaceInstUsesWith(I, V);
1062 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1063 return ReplaceInstUsesWith(I, V);
1065 if (
ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1067 const APInt &Val = CI->getValue();
1069 return BinaryOperator::CreateXor(LHS, RHS);
1073 if (SimplifyDemandedInstructionBits(I))
1077 if (
ZExtInst *ZI = dyn_cast<ZExtInst>(LHS))
1078 if (ZI->getSrcTy()->isIntegerTy(1))
1084 const APInt &RHSVal = CI->getValue();
1085 unsigned ExtendAmt = 0;
1088 if (XorRHS->
getValue() == -RHSVal) {
1090 ExtendAmt = TySizeBits - RHSVal.
logBase2() - 1;
1103 Value *NewShl = Builder->CreateShl(XorLHS, ShAmt,
"sext");
1104 return BinaryOperator::CreateAShr(NewShl, ShAmt);
1114 if ((XorRHS->
getValue() | LHSKnownZero).isAllOnesValue())
1126 if (isa<Constant>(RHS) && isa<PHINode>(LHS))
1131 return BinaryOperator::CreateXor(LHS, RHS);
1144 if (
Value *LHSV = dyn_castNegVal(LHS)) {
1145 if (!isa<Constant>(RHS))
1146 if (
Value *RHSV = dyn_castNegVal(RHS)) {
1147 Value *NewAdd = Builder->CreateAdd(LHSV, RHSV,
"sum");
1151 return BinaryOperator::CreateSub(RHS, LHSV);
1155 if (!isa<Constant>(RHS))
1156 if (
Value *V = dyn_castNegVal(RHS))
1157 return BinaryOperator::CreateSub(LHS, V);
1160 return ReplaceInstUsesWith(I, V);
1164 return BinaryOperator::CreateOr(LHS, RHS);
1166 if (
Constant *CRHS = dyn_cast<Constant>(RHS)) {
1169 return BinaryOperator::CreateSub(
SubOne(CRHS), X);
1172 if (
ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
1178 CRHS->getValue() == (CRHS->getValue() & C2->
getValue())) {
1181 const APInt &AddRHSV = CRHS->getValue();
1184 APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));
1189 if (AddRHSHighBits == AddRHSHighBitsAnd) {
1191 Value *NewAdd = Builder->CreateAdd(X, CRHS, LHS->
getName());
1192 return BinaryOperator::CreateAnd(NewAdd, C2);
1229 if (
SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) {
1231 if (
ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
1234 if (LHSConv->hasOneUse() &&
1236 WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI,
I)) {
1238 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1245 if (
SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) {
1249 if (LHSConv->getOperand(0)->getType() ==
1250 RHSConv->getOperand(0)->getType() &&
1251 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1252 WillNotOverflowSignedAdd(LHSConv->getOperand(0),
1253 RHSConv->getOperand(0),
I)) {
1255 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1256 RHSConv->getOperand(0),
"addconv");
1264 Value *
A =
nullptr, *B =
nullptr;
1268 return BinaryOperator::CreateOr(A, B);
1273 return BinaryOperator::CreateOr(A, B);
1278 Value *
A =
nullptr, *B =
nullptr;
1312 return Changed ? &I :
nullptr;
1316 bool Changed = SimplifyAssociativeOrCommutative(I);
1319 if (
Value *V = SimplifyVectorOp(I))
1320 return ReplaceInstUsesWith(I, V);
1324 return ReplaceInstUsesWith(I, V);
1326 if (isa<Constant>(RHS)) {
1327 if (isa<PHINode>(LHS))
1338 if (
Value *LHSV = dyn_castFNegVal(LHS)) {
1339 Instruction *RI = BinaryOperator::CreateFSub(RHS, LHSV);
1345 if (!isa<Constant>(RHS))
1346 if (
Value *V = dyn_castFNegVal(RHS)) {
1347 Instruction *RI = BinaryOperator::CreateFSub(LHS, V);
1354 if (
SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
1360 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(RHS)) {
1363 if (LHSConv->hasOneUse() &&
1365 WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI,
I)) {
1367 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1374 if (
SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
1378 if (LHSConv->getOperand(0)->getType() ==
1379 RHSConv->getOperand(0)->getType() &&
1380 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1381 WillNotOverflowSignedAdd(LHSConv->getOperand(0),
1382 RHSConv->getOperand(0),
I)) {
1384 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1385 RHSConv->getOperand(0),
"addconv");
1393 Value *A1, *B1, *C1, *A2, *B2, *C2;
1417 if (
Value *V = FAddCombine(Builder).simplify(&I))
1418 return ReplaceInstUsesWith(I, V);
1421 return Changed ? &I :
nullptr;
1433 bool Swapped =
false;
1438 if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1440 if (LHSGEP->getOperand(0) == RHS) {
1443 }
else if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1445 if (LHSGEP->getOperand(0)->stripPointerCasts() ==
1446 RHSGEP->getOperand(0)->stripPointerCasts()) {
1454 if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1456 if (RHSGEP->getOperand(0) == LHS) {
1459 }
else if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1461 if (RHSGEP->getOperand(0)->stripPointerCasts() ==
1462 LHSGEP->getOperand(0)->stripPointerCasts()) {
1473 (GEP2 && !GEP2->hasAllConstantIndices() && !GEP2->hasOneUse()))
1483 Result = Builder->CreateSub(Result, Offset);
1488 Result = Builder->CreateNeg(Result,
"diff.neg");
1490 return Builder->CreateIntCast(Result, Ty,
true);
1496 if (
Value *V = SimplifyVectorOp(I))
1497 return ReplaceInstUsesWith(I, V);
1501 return ReplaceInstUsesWith(I, V);
1504 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1505 return ReplaceInstUsesWith(I, V);
1508 if (
Value *V = dyn_castNegVal(Op1)) {
1511 if (
const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
1512 assert(BO->getOpcode() == Instruction::Sub &&
1513 "Expected a subtraction operator!");
1517 if (cast<Constant>(Op1)->isNotMinSignedValue() && I.
hasNoSignedWrap())
1525 return BinaryOperator::CreateXor(Op0, Op1);
1531 if (
Constant *C = dyn_cast<Constant>(Op0)) {
1547 if (SimplifyDemandedInstructionBits(I))
1561 if (
ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
1570 return BinaryOperator::CreateAShr(X, CI);
1575 return BinaryOperator::CreateLShr(X, CI);
1581 if ((IntVal + 1).isPowerOf2()) {
1583 APInt KnownZero(BitWidth, 0);
1584 APInt KnownOne(BitWidth, 0);
1586 if ((IntVal | KnownZero).isAllOnesValue()) {
1587 return BinaryOperator::CreateXor(Op1, C);
1607 Value *
A =
nullptr, *B =
nullptr;
1611 return BinaryOperator::CreateAnd(A, B);
1616 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
1617 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
1618 if (SI0->getCondition() == SI1->getCondition()) {
1623 SI0->getCondition(),
1624 Builder->CreateSub(SI0->getTrueValue(), SI1->getTrueValue(),
"",
1632 SI0->getCondition(), V,
1633 Builder->CreateSub(SI0->getFalseValue(), SI1->getFalseValue(),
"",
1645 return BinaryOperator::CreateAnd(
1646 Y, Builder->CreateNot(Op1, Op1->getName() +
".not"));
1649 if (Op1->hasOneUse()) {
1650 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
1657 Builder->CreateSub(Z,
Y, Op1->getName()));
1663 return BinaryOperator::CreateAnd(Op0,
1664 Builder->CreateNot(
Y,
Y->getName() +
".not"));
1673 if (
Value *XNeg = dyn_castNegVal(X))
1674 return BinaryOperator::CreateShl(XNeg,
Y);
1694 Value *LHSOp, *RHSOp;
1697 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1698 return ReplaceInstUsesWith(I, Res);
1703 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1704 return ReplaceInstUsesWith(I, Res);
1706 bool Changed =
false;
1716 return Changed ? &I :
nullptr;
1722 if (
Value *V = SimplifyVectorOp(I))
1723 return ReplaceInstUsesWith(I, V);
1727 return ReplaceInstUsesWith(I, V);
1737 if (isa<Constant>(Op0))
1744 if (
Value *V = dyn_castFNegVal(Op1)) {
1745 Instruction *NewI = BinaryOperator::CreateFAdd(Op0, V);
1749 if (
FPTruncInst *FPTI = dyn_cast<FPTruncInst>(Op1)) {
1750 if (
Value *V = dyn_castFNegVal(FPTI->getOperand(0))) {
1751 Value *NewTrunc = Builder->CreateFPTrunc(V, I.
getType());
1752 Instruction *NewI = BinaryOperator::CreateFAdd(Op0, NewTrunc);
1756 }
else if (
FPExtInst *FPEI = dyn_cast<FPExtInst>(Op1)) {
1757 if (
Value *V = dyn_castFNegVal(FPEI->getOperand(0))) {
1759 Instruction *NewI = BinaryOperator::CreateFAdd(Op0, NewExt);
1766 if (
Value *V = FAddCombine(Builder).simplify(&I))
1767 return ReplaceInstUsesWith(I, V);
Value * EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the code necessary to compute th...
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
std::string & operator+=(std::string &buffer, StringRef string)
void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction, which must be an operator which supports these flags.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
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)
bool isOneValue() const
Returns true if the value is one.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
bool haveNoCommonBitsSet(Value *LHS, Value *RHS, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Returns true if LHS and RHS have no common bits set.
Instruction * visitFSub(BinaryOperator &I)
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
This class represents a sign extension of integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Value * SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifyAddInst - Given operands for an Add, see if we can fold the result.
static bool checkRippleForAdd(const APInt &Op0KnownZero, const APInt &Op1KnownZero)
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
StringRef getName() const
Return a constant reference to the value's name.
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
bool isNegativeZeroValue() const
isNegativeZeroValue - Return true if the value is what would be returned by getZeroValueForNegation.
bool match(Val *V, const Pattern &P)
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
SelectInst - This class represents the LLVM 'select' instruction.
bool noSignedZeros() const
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7"), clEnumValEnd))
const APInt & getValue() const
Return the constant as an APInt value reference.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
Value * SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
Given operands for an FSub, see if we can fold the result.
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.
Value * SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
Given operands for an FAdd, see if we can fold the result.
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool MaskedValueIsZero(Value *V, const APInt &Mask, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.
Windows NT (Windows on ARM)
not_match< LHS > m_Not(const LHS &L)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
bool hasUnsafeAlgebra() const
Determine whether the unsafe-algebra flag is set.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
SelectClass_match< Cond, LHS, RHS > m_Select(const Cond &C, const LHS &L, const RHS &R)
bool isZero() const
isZero - Return true if the value is positive or negative zero.
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
bool isNotMinSignedValue() const
Return true if the value is not the smallest signed value.
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
OverflowResult computeOverflowForUnsignedAdd(Value *LHS, Value *RHS, const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT)
Value * OptimizePointerDifference(Value *LHS, Value *RHS, Type *Ty)
Optimize pointer differences into the same array into a size.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
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)
setDebugLoc - Set the debug location information for this instruction.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
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)
bool isVectorTy() const
isVectorTy - True if this is an instance of VectorType.
This is an important base class in LLVM.
const Value * getCondition() const
ConstantFP - Floating Point Values [float, double].
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set to true.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
unsigned getBitWidth() const
Return the number of bits in the APInt.
Value * getOperand(unsigned i) const
Class to represent integer types.
unsigned countPopulation() const
Count the number of bits set.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
ComputeSignBit - Determine whether the sign bit is known to be zero or one.
Instruction * visitFAdd(BinaryOperator &I)
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...
match_combine_or< match_zero, match_neg_zero > m_AnyZero()
Match an arbitrary zero/null constant.
static CastInst * CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a ZExt or BitCast cast instruction.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
const Value * getTrueValue() const
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
neg_match< LHS > m_Neg(const LHS &L)
Match an integer negate.
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
static Constant * getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static BinaryOperator * CreateFNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
roundingMode
IEEE-754R 4.3: Rounding-direction attributes.
This is the shared class of boolean and integer constants.
opStatus add(const APFloat &, roundingMode)
unsigned getScalarSizeInBits() const LLVM_READONLY
getScalarSizeInBits - If this is a vector type, return the getPrimitiveSizeInBits value for the eleme...
unsigned logBase2() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
opStatus multiply(const APFloat &, roundingMode)
unsigned ComputeNumSignBits(Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
ComputeNumSignBits - Return the number of times the sign bit of the register is replicated into the o...
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.
static Constant * get(Type *Ty, double V)
get() - This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in the specified type.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Class for arbitrary precision integers.
bool isIntegerTy() const
isIntegerTy - True if this is an instance of IntegerType.
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...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Value * SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifySubInst - Given operands for a Sub, see if we can fold the result.
const Type * getScalarType() const LLVM_READONLY
getScalarType - If this is a vector type, return the element type, otherwise return 'this'...
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Instruction * visitAdd(BinaryOperator &I)
void clearBit(unsigned bitPosition)
Set a given bit to 0.
bool hasOneUse() const
Return true if there is exactly one user of this value.
static Constant * getZeroValueForNegation(Type *Ty)
Floating point negation must be implemented with f(x) = -0.0 - x.
bool isSignBit() const
Check if the APInt's value is returned by getSignBit.
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
const APFloat & getValueAPF() const
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.
This class represents a truncation of floating point types.
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
getPrimitiveSizeInBits - Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
This file provides internal interfaces used to implement the InstCombine.
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
bool isZero() const
Returns true if and only if the float is plus or minus zero.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
static Constant * getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool isInt(int64_t x)
isInt - Checks if an integer fits into the given bit width.
unsigned countLeadingZeros() const
The APInt version of the countLeadingZeros functions in MathExtras.h.
const Value * getFalseValue() const
Convenience struct for specifying and reasoning about fast-math flags.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
This class represents an extension of floating point types.
static Value * checkForNegativeOperand(BinaryOperator &I, InstCombiner::BuilderTy *Builder)
const fltSemantics & getSemantics() const
opStatus subtract(const APFloat &, roundingMode)
Instruction * visitSub(BinaryOperator &I)
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
bool isNormal() const
IEEE-754R isNormal: Returns true if and only if the current value is normal.
static Constant * getXor(Constant *C1, Constant *C2)