22 using namespace PatternMatch;
24 #define DEBUG_TYPE "instcombine"
42 FAddendCoef() : IsFp(
false), BufHasFpVal(
false),
IntVal(0) {}
46 assert(!insaneIntVal(C) &&
"Insane coefficient");
59 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()
const
73 {
return reinterpret_cast<const APFloat*
>(&FpValBuf.buffer[0]); }
75 const APFloat &getFpVal()
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()
const {
return Val; }
120 const FAddendCoef &getCoef()
const {
return Coeff; }
122 bool isConstant()
const {
return Val ==
nullptr; }
123 bool isZero()
const {
return Coeff.isZero(); }
125 void set(
short Coefficient,
Value *V) {
126 Coeff.set(Coefficient);
130 Coeff.set(Coefficient);
138 void negate() { Coeff.negate(); }
142 static unsigned drillValueDownOneStep(
Value* V, FAddend &A0, FAddend &A1);
146 unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1)
const;
149 assert((Val == T.Val) &&
"Symbolic-values disagree");
154 void Scale(
const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
172 Value *simplifyFAdd(AddendVect& V,
unsigned InstrQuota);
177 Value *createAddendVal(
const FAddend &
A,
bool& NeedNeg);
180 unsigned calcInstrNumber(
const AddendVect& Vect);
186 Value *createNaryFAdd(
const AddendVect& Opnds,
unsigned InstrQuota);
187 void createInstPostProc(
Instruction *NewInst,
bool NoNumber =
false);
194 unsigned CreateInstrNum;
195 void initCreateInstNum() { CreateInstrNum = 0; }
196 void incCreateInstNum() { CreateInstrNum++; }
198 void initCreateInstNum() {}
199 void incCreateInstNum() {}
211 FAddendCoef::~FAddendCoef() {
213 getFpValPtr()->~APFloat();
216 void FAddendCoef::set(
const APFloat&
C) {
226 IsFp = BufHasFpVal =
true;
229 void FAddendCoef::convertToFpType(
const fltSemantics &Sem) {
240 IsFp = BufHasFpVal =
true;
253 void FAddendCoef::operator=(
const FAddendCoef &That) {
257 set(That.getFpVal());
262 if (
isInt() == That.isInt()) {
266 getFpVal().add(That.getFpVal(), RndMode);
273 getFpVal().add(T, RndMode);
281 void FAddendCoef::operator*=(
const FAddendCoef &That) {
285 if (That.isMinusOne()) {
290 if (
isInt() && That.isInt()) {
291 int Res =
IntVal * (int)That.IntVal;
292 assert(!insaneIntVal(Res) &&
"Insane int value");
298 isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
301 convertToFpType(Semantic);
305 F0.
multiply(createAPFloatFromInt(Semantic, That.IntVal),
311 void FAddendCoef::negate() {
315 getFpVal().changeSign();
318 Value *FAddendCoef::getValue(
Type *Ty)
const {
321 ConstantFP::get(Ty->getContext(), getFpVal());
335 unsigned FAddend::drillValueDownOneStep
336 (
Value *Val, FAddend &Addend0, FAddend &Addend1) {
338 if (!Val || !(I = dyn_cast<Instruction>(Val)))
343 if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
347 if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->
isZero())
350 if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->
isZero())
355 Addend0.set(1, Opnd0);
357 Addend0.set(C0,
nullptr);
361 FAddend &Addend = Opnd0 ? Addend1 : Addend0;
363 Addend.set(1, Opnd1);
365 Addend.set(C1,
nullptr);
366 if (Opcode == Instruction::FSub)
371 return Opnd0 && Opnd1 ? 2 : 1;
378 if (I->
getOpcode() == Instruction::FMul) {
381 if (
ConstantFP *C = dyn_cast<ConstantFP>(V0)) {
386 if (
ConstantFP *C = dyn_cast<ConstantFP>(V1)) {
399 unsigned FAddend::drillAddendDownOneStep
400 (FAddend &Addend0, FAddend &Addend1)
const {
404 unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
405 if (!BreakNum || Coeff.isOne())
408 Addend0.Scale(Coeff);
411 Addend1.Scale(Coeff);
426 I->
getOpcode() == Instruction::FSub) &&
"Expect add/sub");
431 if (!I0 || !I1 || I0->
getOpcode() != I1->getOpcode())
435 if (I0->
getOpcode() == Instruction::FMul)
437 else if (I0->
getOpcode() != Instruction::FDiv)
442 Value *Opnd1_0 = I1->getOperand(0);
443 Value *Opnd1_1 = I1->getOperand(1);
450 Value *Factor =
nullptr;
451 Value *AddSub0 =
nullptr, *AddSub1 =
nullptr;
454 if (Opnd0_0 == Opnd1_0 || Opnd0_0 == Opnd1_1)
456 else if (Opnd0_1 == Opnd1_0 || Opnd0_1 == Opnd1_1)
460 AddSub0 = (Factor == Opnd0_0) ? Opnd0_1 : Opnd0_0;
461 AddSub1 = (Factor == Opnd1_0) ? Opnd1_1 : Opnd1_0;
463 }
else if (Opnd0_1 == Opnd1_1) {
479 createFAdd(AddSub0, AddSub1) :
480 createFSub(AddSub0, AddSub1);
481 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(NewAddSub)) {
482 const APFloat &
F = CFP->getValueAPF();
485 }
else if (
Instruction *II = dyn_cast<Instruction>(NewAddSub))
486 II->setFastMathFlags(Flags);
489 Value *RI = createFMul(Factor, NewAddSub);
491 II->setFastMathFlags(Flags);
495 Value *RI = createFDiv(NewAddSub, Factor);
497 II->setFastMathFlags(Flags);
509 I->
getOpcode() == Instruction::FSub) &&
"Expect add/sub");
514 FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
516 unsigned OpndNum = FAddend::drillValueDownOneStep(I, Opnd0, Opnd1);
519 unsigned Opnd0_ExpNum = 0;
520 unsigned Opnd1_ExpNum = 0;
522 if (!Opnd0.isConstant())
523 Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
526 if (OpndNum == 2 && !Opnd1.isConstant())
527 Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);
530 if (Opnd0_ExpNum && Opnd1_ExpNum) {
532 AllOpnds.push_back(&Opnd0_0);
533 AllOpnds.push_back(&Opnd1_0);
534 if (Opnd0_ExpNum == 2)
535 AllOpnds.push_back(&Opnd0_1);
536 if (Opnd1_ExpNum == 2)
537 AllOpnds.push_back(&Opnd1_1);
540 unsigned InstQuota = 0;
544 InstQuota = ((!isa<Constant>(V0) && V0->
hasOneUse()) &&
545 (!isa<Constant>(V1) && V1->
hasOneUse())) ? 2 : 1;
547 if (
Value *R = simplifyFAdd(AllOpnds, InstQuota))
556 const FAddendCoef &
CE = Opnd0.getCoef();
557 return CE.isOne() ? Opnd0.getSymVal() :
nullptr;
563 AllOpnds.push_back(&Opnd0);
564 AllOpnds.push_back(&Opnd1_0);
565 if (Opnd1_ExpNum == 2)
566 AllOpnds.push_back(&Opnd1_1);
568 if (
Value *R = simplifyFAdd(AllOpnds, 1))
575 AllOpnds.push_back(&Opnd1);
576 AllOpnds.push_back(&Opnd0_0);
577 if (Opnd0_ExpNum == 2)
578 AllOpnds.push_back(&Opnd0_1);
580 if (
Value *R = simplifyFAdd(AllOpnds, 1))
585 return performFactorization(I);
588 Value *FAddCombine::simplifyFAdd(AddendVect& Addends,
unsigned InstrQuota) {
589 unsigned AddendNum = Addends.size();
590 assert(AddendNum <= 4 &&
"Too many addends");
593 unsigned NextTmpIdx = 0;
594 FAddend TmpResult[3];
602 const FAddend *ConstAdd =
nullptr;
611 for (
unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
613 const FAddend *ThisAddend = Addends[SymIdx];
619 Value *Val = ThisAddend->getSymVal();
620 unsigned StartIdx = SimpVect.size();
621 SimpVect.push_back(ThisAddend);
629 for (
unsigned SameSymIdx = SymIdx + 1;
630 SameSymIdx < AddendNum; SameSymIdx++) {
631 const FAddend *T = Addends[SameSymIdx];
632 if (T && T->getSymVal() == Val) {
635 Addends[SameSymIdx] =
nullptr;
636 SimpVect.push_back(T);
641 if (StartIdx + 1 != SimpVect.size()) {
642 FAddend &R = TmpResult[NextTmpIdx ++];
643 R = *SimpVect[StartIdx];
644 for (
unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
648 SimpVect.resize(StartIdx);
651 SimpVect.push_back(&R);
662 "out-of-bound access");
665 SimpVect.push_back(ConstAdd);
668 if (!SimpVect.empty())
669 Result = createNaryFAdd(SimpVect, InstrQuota);
678 Value *FAddCombine::createNaryFAdd
679 (
const AddendVect &Opnds,
unsigned InstrQuota) {
680 assert(!Opnds.empty() &&
"Expect at least one addend");
684 unsigned InstrNeeded = calcInstrNumber(Opnds);
685 if (InstrNeeded > InstrQuota)
698 Value *LastVal =
nullptr;
699 bool LastValNeedNeg =
false;
702 for (
const FAddend *Opnd : Opnds) {
704 Value *V = createAddendVal(*Opnd, NeedNeg);
707 LastValNeedNeg = NeedNeg;
711 if (LastValNeedNeg == NeedNeg) {
712 LastVal = createFAdd(LastVal, V);
717 LastVal = createFSub(V, LastVal);
719 LastVal = createFSub(LastVal, V);
721 LastValNeedNeg =
false;
724 if (LastValNeedNeg) {
725 LastVal = createFNeg(LastVal);
729 assert(CreateInstrNum == InstrNeeded &&
730 "Inconsistent in instruction numbers");
737 Value *V = Builder->CreateFSub(Opnd0, Opnd1);
739 createInstPostProc(I);
745 Value *NewV = createFSub(Zero, V);
747 createInstPostProc(I,
true);
752 Value *V = Builder->CreateFAdd(Opnd0, Opnd1);
754 createInstPostProc(I);
759 Value *V = Builder->CreateFMul(Opnd0, Opnd1);
761 createInstPostProc(I);
766 Value *V = Builder->CreateFDiv(Opnd0, Opnd1);
768 createInstPostProc(I);
772 void FAddCombine::createInstPostProc(
Instruction *NewInstr,
bool NoNumber) {
785 unsigned FAddCombine::calcInstrNumber(
const AddendVect &Opnds) {
786 unsigned OpndNum = Opnds.size();
787 unsigned InstrNeeded = OpndNum - 1;
790 unsigned NegOpndNum = 0;
793 for (
const FAddend *Opnd : Opnds) {
794 if (Opnd->isConstant())
797 const FAddendCoef &CE = Opnd->getCoef();
798 if (CE.isMinusOne() || CE.isMinusTwo())
804 if (!CE.isMinusOne() && !CE.isOne())
807 if (NegOpndNum == OpndNum)
820 Value *FAddCombine::createAddendVal(
const FAddend &Opnd,
bool &NeedNeg) {
821 const FAddendCoef &Coeff = Opnd.getCoef();
823 if (Opnd.isConstant()) {
825 return Coeff.getValue(Instr->getType());
828 Value *OpndVal = Opnd.getSymVal();
830 if (Coeff.isMinusOne() || Coeff.isOne()) {
831 NeedNeg = Coeff.isMinusOne();
835 if (Coeff.isTwo() || Coeff.isMinusTwo()) {
836 NeedNeg = Coeff.isMinusTwo();
837 return createFAdd(OpndVal, OpndVal);
841 return createFMul(OpndVal, Coeff.getValue(Instr->getType()));
849 const APInt &Op1KnownZero) {
850 APInt Op1MaybeOne = ~Op1KnownZero;
857 APInt Op0KnownZeroTemp(Op0KnownZero);
858 Op0KnownZeroTemp.
clearBit(BitWidth - 1);
862 assert(Op1OnePosition >= 0);
866 return Op0ZeroPosition >= Op1OnePosition;
873 bool InstCombiner::WillNotOverflowSignedAdd(
Value *LHS,
Value *RHS,
897 APInt LHSKnownZero(BitWidth, 0);
898 APInt LHSKnownOne(BitWidth, 0);
901 APInt RHSKnownZero(BitWidth, 0);
902 APInt RHSKnownOne(BitWidth, 0);
907 if ((LHSKnownOne[BitWidth - 1] && RHSKnownZero[BitWidth - 1]) ||
908 (LHSKnownZero[BitWidth - 1] && RHSKnownOne[BitWidth - 1]))
925 bool InstCombiner::WillNotOverflowSignedSub(
Value *LHS,
Value *RHS,
934 APInt LHSKnownZero(BitWidth, 0);
935 APInt LHSKnownOne(BitWidth, 0);
938 APInt RHSKnownZero(BitWidth, 0);
939 APInt RHSKnownOne(BitWidth, 0);
944 if ((LHSKnownOne[BitWidth - 1] && RHSKnownOne[BitWidth - 1]) ||
945 (LHSKnownZero[BitWidth - 1] && RHSKnownZero[BitWidth - 1]))
954 bool InstCombiner::WillNotOverflowUnsignedSub(
Value *LHS,
Value *RHS,
957 bool LHSKnownNonNegative, LHSKnownNegative;
958 bool RHSKnownNonNegative, RHSKnownNegative;
963 if (LHSKnownNegative && RHSKnownNonNegative)
983 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
984 const APInt *C1 =
nullptr, *C2 =
nullptr;
1000 return Builder->
CreateSub(RHS, NewAnd,
"sub");
1005 return Builder->
CreateSub(RHS, NewOr,
"sub");
1025 return Builder->
CreateSub(RHS, NewOr,
"sub");
1031 bool Changed = SimplifyAssociativeOrCommutative(I);
1034 if (
Value *V = SimplifyVectorOp(I))
1035 return replaceInstUsesWith(I, V);
1039 return replaceInstUsesWith(I, V);
1042 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1043 return replaceInstUsesWith(I, V);
1049 return BinaryOperator::CreateXor(LHS, RHS);
1067 Builder->CreateNUWAdd(
1076 if (
ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1079 if (SimplifyDemandedInstructionBits(I))
1083 if (
ZExtInst *ZI = dyn_cast<ZExtInst>(LHS))
1084 if (ZI->getSrcTy()->isIntegerTy(1))
1090 const APInt &RHSVal = CI->getValue();
1091 unsigned ExtendAmt = 0;
1094 if (XorRHS->
getValue() == -RHSVal) {
1096 ExtendAmt = TySizeBits - RHSVal.
logBase2() - 1;
1109 Value *NewShl = Builder->CreateShl(XorLHS, ShAmt,
"sext");
1110 return BinaryOperator::CreateAShr(NewShl, ShAmt);
1120 if ((XorRHS->
getValue() | LHSKnownZero).isAllOnesValue())
1132 if (isa<Constant>(RHS) && isa<PHINode>(LHS))
1137 return BinaryOperator::CreateXor(LHS, RHS);
1150 if (
Value *LHSV = dyn_castNegVal(LHS)) {
1151 if (!isa<Constant>(RHS))
1152 if (
Value *RHSV = dyn_castNegVal(RHS)) {
1153 Value *NewAdd = Builder->CreateAdd(LHSV, RHSV,
"sum");
1157 return BinaryOperator::CreateSub(RHS, LHSV);
1161 if (!isa<Constant>(RHS))
1162 if (
Value *V = dyn_castNegVal(RHS))
1163 return BinaryOperator::CreateSub(LHS, V);
1166 return replaceInstUsesWith(I, V);
1170 return BinaryOperator::CreateOr(LHS, RHS);
1172 if (
Constant *CRHS = dyn_cast<Constant>(RHS)) {
1175 return BinaryOperator::CreateSub(
SubOne(CRHS), X);
1181 if (
ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
1187 CRHS->getValue() == (CRHS->getValue() & C2->
getValue())) {
1190 const APInt &AddRHSV = CRHS->getValue();
1193 APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));
1198 if (AddRHSHighBits == AddRHSHighBitsAnd) {
1200 Value *NewAdd = Builder->CreateAdd(X, CRHS, LHS->
getName());
1201 return BinaryOperator::CreateAnd(NewAdd, C2);
1238 if (
SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) {
1240 if (
ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
1241 if (LHSConv->hasOneUse()) {
1245 WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI,
I)) {
1248 Builder->CreateNSWAdd(LHSConv->getOperand(0), CI,
"addconv");
1255 if (
SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) {
1259 if (LHSConv->getOperand(0)->getType() ==
1260 RHSConv->getOperand(0)->getType() &&
1261 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1262 WillNotOverflowSignedAdd(LHSConv->getOperand(0),
1263 RHSConv->getOperand(0),
I)) {
1265 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1266 RHSConv->getOperand(0),
"addconv");
1274 if (
auto *LHSConv = dyn_cast<ZExtInst>(LHS)) {
1276 if (
ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
1277 if (LHSConv->hasOneUse()) {
1285 Builder->CreateNUWAdd(LHSConv->getOperand(0), CI,
"addconv");
1292 if (
auto *RHSConv = dyn_cast<ZExtInst>(RHS)) {
1296 if (LHSConv->getOperand(0)->getType() ==
1297 RHSConv->getOperand(0)->getType() &&
1298 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1300 RHSConv->getOperand(0),
1303 Value *NewAdd = Builder->CreateNUWAdd(
1304 LHSConv->getOperand(0), RHSConv->getOperand(0),
"addconv");
1312 Value *
A =
nullptr, *
B =
nullptr;
1316 return BinaryOperator::CreateOr(A,
B);
1321 return BinaryOperator::CreateOr(A,
B);
1326 Value *
A =
nullptr, *
B =
nullptr;
1360 return Changed ? &I :
nullptr;
1364 bool Changed = SimplifyAssociativeOrCommutative(I);
1367 if (
Value *V = SimplifyVectorOp(I))
1368 return replaceInstUsesWith(I, V);
1372 return replaceInstUsesWith(I, V);
1374 if (isa<Constant>(RHS))
1375 if (
Instruction *FoldedFAdd = foldOpWithConstantIntoOperand(I))
1380 if (
Value *LHSV = dyn_castFNegVal(LHS)) {
1381 Instruction *RI = BinaryOperator::CreateFSub(RHS, LHSV);
1387 if (!isa<Constant>(RHS))
1388 if (
Value *V = dyn_castFNegVal(RHS)) {
1389 Instruction *RI = BinaryOperator::CreateFSub(LHS, V);
1396 if (
SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
1402 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(RHS)) {
1405 if (LHSConv->hasOneUse() &&
1407 WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI,
I)) {
1409 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1416 if (
SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
1420 if (LHSConv->getOperand(0)->getType() ==
1421 RHSConv->getOperand(0)->getType() &&
1422 (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1423 WillNotOverflowSignedAdd(LHSConv->getOperand(0),
1424 RHSConv->getOperand(0),
I)) {
1426 Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
1427 RHSConv->getOperand(0),
"addconv");
1435 Value *A1, *B1, *C1, *A2, *B2, *C2;
1459 if (
Value *V = FAddCombine(Builder).simplify(&I))
1460 return replaceInstUsesWith(I, V);
1463 return Changed ? &I :
nullptr;
1474 bool Swapped =
false;
1479 if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1481 if (LHSGEP->getOperand(0) == RHS) {
1484 }
else if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1486 if (LHSGEP->getOperand(0)->stripPointerCasts() ==
1487 RHSGEP->getOperand(0)->stripPointerCasts()) {
1495 if (
GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
1497 if (RHSGEP->getOperand(0) == LHS) {
1500 }
else if (
GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
1502 if (RHSGEP->getOperand(0)->stripPointerCasts() ==
1503 LHSGEP->getOperand(0)->stripPointerCasts()) {
1514 (GEP2 && !GEP2->hasAllConstantIndices() && !GEP2->hasOneUse()))
1524 Result = Builder->CreateSub(Result, Offset);
1529 Result = Builder->CreateNeg(Result,
"diff.neg");
1531 return Builder->CreateIntCast(Result, Ty,
true);
1537 if (
Value *V = SimplifyVectorOp(I))
1538 return replaceInstUsesWith(I, V);
1542 return replaceInstUsesWith(I, V);
1545 if (
Value *V = SimplifyUsingDistributiveLaws(I))
1546 return replaceInstUsesWith(I, V);
1549 if (
Value *V = dyn_castNegVal(Op1)) {
1552 if (
const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
1553 assert(BO->getOpcode() == Instruction::Sub &&
1554 "Expected a subtraction operator!");
1558 if (cast<Constant>(Op1)->isNotMinSignedValue() && I.
hasNoSignedWrap())
1566 return BinaryOperator::CreateXor(Op0, Op1);
1572 if (
Constant *C = dyn_cast<Constant>(Op0)) {
1588 if (SimplifyDemandedInstructionBits(I))
1612 *ShAmt == BitWidth - 1) {
1613 Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
1614 return BinaryOperator::CreateAShr(X, ShAmtOp);
1617 *ShAmt == BitWidth - 1) {
1618 Value *ShAmtOp = cast<Instruction>(Op1)->getOperand(1);
1619 return BinaryOperator::CreateLShr(X, ShAmtOp);
1625 if ((*Op0C + 1).isPowerOf2()) {
1626 APInt KnownZero(BitWidth, 0);
1627 APInt KnownOne(BitWidth, 0);
1629 if ((*Op0C | KnownZero).isAllOnesValue())
1630 return BinaryOperator::CreateXor(Op1, Op0);
1648 Value *
A =
nullptr, *
B =
nullptr;
1652 return BinaryOperator::CreateAnd(A,
B);
1660 return BinaryOperator::CreateAnd(
1661 Y, Builder->CreateNot(Op1, Op1->getName() +
".not"));
1664 if (Op1->hasOneUse()) {
1665 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
1672 Builder->CreateSub(Z,
Y, Op1->getName()));
1678 return BinaryOperator::CreateAnd(Op0,
1679 Builder->CreateNot(
Y,
Y->getName() +
".not"));
1688 if (
Value *XNeg = dyn_castNegVal(X))
1689 return BinaryOperator::CreateShl(XNeg,
Y);
1695 Y->getType()->getScalarSizeInBits() == 1) {
1720 Value *LHSOp, *RHSOp;
1723 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1724 return replaceInstUsesWith(I, Res);
1729 if (
Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.
getType()))
1730 return replaceInstUsesWith(I, Res);
1732 bool Changed =
false;
1742 return Changed ? &I :
nullptr;
1748 if (
Value *V = SimplifyVectorOp(I))
1749 return replaceInstUsesWith(I, V);
1753 return replaceInstUsesWith(I, V);
1763 if (isa<Constant>(Op0))
1770 if (
Value *V = dyn_castFNegVal(Op1)) {
1771 Instruction *NewI = BinaryOperator::CreateFAdd(Op0, V);
1775 if (
FPTruncInst *FPTI = dyn_cast<FPTruncInst>(Op1)) {
1776 if (
Value *V = dyn_castFNegVal(FPTI->getOperand(0))) {
1777 Value *NewTrunc = Builder->CreateFPTrunc(V, I.
getType());
1778 Instruction *NewI = BinaryOperator::CreateFAdd(Op0, NewTrunc);
1782 }
else if (
FPExtInst *FPEI = dyn_cast<FPExtInst>(Op1)) {
1783 if (
Value *V = dyn_castFNegVal(FPEI->getOperand(0))) {
1785 Instruction *NewI = BinaryOperator::CreateFAdd(Op0, NewExt);
1792 if (
Value *V = FAddCombine(Builder).simplify(&I))
1793 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)
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")))
std::string & operator+=(std::string &buffer, StringRef string)
void computeKnownBits(const 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...
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 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)
DiagnosticInfoOptimizationBase::Argument NV
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.
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)
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)
Given operands for an Add, fold the result or return null.
static bool checkRippleForAdd(const APInt &Op0KnownZero, const APInt &Op1KnownZero)
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 isNegative() const
Determine sign of this APInt.
bool isNegativeZeroValue() const
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)
This class represents the LLVM 'select' instruction.
bool noSignedZeros() const
struct fuzzer::@269 Flags
const APInt & getValue() const
Return the constant as an APInt value reference.
roundingMode
IEEE-754R 4.3: Rounding-direction attributes.
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, fold the result or return null.
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, fold the result or return null.
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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)
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)
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.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
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.
SelectClass_match< Cond, LHS, RHS > m_Select(const Cond &C, const LHS &L, const RHS &R)
bool isZero() const
Return true if the value is positive or negative zero.
Type * getScalarType() const LLVM_READONLY
If this is a vector type, return the element type, otherwise return 'this'.
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
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.
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)
Set the debug location information for this instruction.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
APInt trunc(unsigned width) const
Truncate to new width.
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)
isInt - Checks if an integer fits into the given bit width.
bool isVectorTy() const
True if this is an instance of VectorType.
bool sge(const APInt &RHS) const
Signed greather or equal comparison.
This is an important base class in LLVM.
const Value * getCondition() const
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.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
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.
APInt sext(unsigned width) const
Sign extend to a new width.
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.
opStatus multiply(const APFloat &RHS, roundingMode RM)
Value * getOperand(unsigned i) const
Class to represent integer types.
unsigned countPopulation() const
Count the number of bits set.
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.
const Value * getTrueValue() const
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
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)
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
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...
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
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.
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.
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 GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Class for arbitrary precision integers.
bool isIntegerTy() const
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...
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)
Given operands for a Sub, fold the result or return null.
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
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)
void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Determine whether the sign bit is known to be zero or one.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
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.
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 hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
OverflowResult computeOverflowForUnsignedAdd(const Value *LHS, const Value *RHS, const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT)
const APFloat & getValueAPF() const
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())
This class represents a truncation of floating point types.
LLVM Value Representation.
This file provides internal interfaces used to implement the InstCombine.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
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)
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)
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const fltSemantics & getSemantics() const
Instruction * visitSub(BinaryOperator &I)
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
static Constant * getXor(Constant *C1, Constant *C2)