43using namespace PatternMatch;
48 cl::desc(
"Enable unsafe double to float "
49 "shrinking for math lib calls"));
56 cl::desc(
"Enable hot/cold operator new library calls"));
60 "Enable optimization of existing hot/cold operator new library calls"));
67struct HotColdHintParser :
public cl::parser<unsigned> {
72 return O.error(
"'" + Arg +
"' value invalid for uint argument!");
75 return O.error(
"'" + Arg +
"' value must be in the range [0, 255]!");
89 cl::desc(
"Value to pass to hot/cold operator new for cold allocation"));
92 cl::desc(
"Value to pass to hot/cold operator new for "
93 "notcold (warm) allocation"));
96 cl::desc(
"Value to pass to hot/cold operator new for hot allocation"));
103 return Func == LibFunc_abs || Func == LibFunc_labs ||
104 Func == LibFunc_llabs || Func == LibFunc_strlen;
109 for (
User *U : V->users()) {
110 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
111 if (IC->isEquality() && IC->getOperand(1) == With)
121 return OI->getType()->isFloatingPointTy();
127 return OI->getType()->isFP128Ty();
140 if (Base < 2 || Base > 36)
149 if (!isSpace((
unsigned char)Str[
Offset])) {
160 bool Negate = Str[0] ==
'-';
161 if (Str[0] ==
'-' || Str[0] ==
'+') {
162 Str = Str.drop_front();
172 unsigned NBits =
RetTy->getPrimitiveSizeInBits();
173 uint64_t Max = AsSigned && Negate ? 1 : 0;
177 if (Str.size() > 1) {
179 if (toUpper((
unsigned char)Str[1]) ==
'X') {
180 if (Str.size() == 2 || (
Base &&
Base != 16))
185 Str = Str.drop_front(2);
191 }
else if (
Base == 0)
201 for (
unsigned i = 0; i != Str.size(); ++i) {
202 unsigned char DigVal = Str[i];
204 DigVal = DigVal -
'0';
206 DigVal = toUpper(DigVal);
208 DigVal = DigVal -
'A' + 10;
221 if (VFlow || Result > Max)
229 Value *StrEnd =
B.CreateInBoundsGEP(
B.getInt8Ty(), StrBeg, Off,
"endptr");
230 B.CreateStore(StrEnd, EndPtr);
237 return ConstantInt::get(
RetTy, Result);
241 for (
User *U : V->users()) {
242 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
243 if (
Constant *
C = dyn_cast<Constant>(IC->getOperand(1)))
244 if (
C->isNullValue())
272 for (
unsigned ArgNo : ArgNos) {
273 uint64_t DerefBytes = DereferenceableBytes;
278 DereferenceableBytes);
297 for (
unsigned ArgNo : ArgNos) {
323 DerefMin = std::min(
X->getZExtValue(),
Y->getZExtValue());
337 if (
auto *NewCI = dyn_cast_or_null<CallInst>(New))
344 NewCI->
getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
351 return Len >= Str.size() ? Str : Str.substr(0, Len);
376 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
390 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
396 ConstantInt::get(DL.
getIntPtrType(Src->getContext()), Len + 1));
440 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
453 Type *CharTy =
B.getInt8Ty();
454 Value *Char0 =
B.CreateLoad(CharTy, Src);
455 CharVal =
B.CreateTrunc(CharVal, CharTy);
456 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
460 Value *
And =
B.CreateICmpNE(NBytes, Zero);
461 Cmp =
B.CreateLogicalAnd(
And, Cmp);
465 return B.CreateSelect(Cmp, Src, NullPtr);
478 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
489 if (!FT->getParamType(1)->isIntegerTy(IntBits))
496 ConstantInt::get(SizeTTy, Len),
B,
505 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
514 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
527 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
533 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
539 if (CharC && CharC->
isZero())
550 Value *
Size = ConstantInt::get(SizeTTy, NBytes);
557 return ConstantInt::get(CI->
getType(), 0);
564 if (HasStr1 && HasStr2)
565 return ConstantInt::get(CI->
getType(),
566 std::clamp(Str1.
compare(Str2), -1, 1));
568 if (HasStr1 && Str1.
empty())
569 return B.CreateNeg(
B.CreateZExt(
570 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
572 if (HasStr2 && Str2.
empty())
573 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
588 std::min(Len1, Len2)),
593 if (!HasStr1 && HasStr2) {
600 }
else if (HasStr1 && !HasStr2) {
624 return ConstantInt::get(CI->
getType(), 0);
636 return ConstantInt::get(CI->
getType(), 0);
646 if (HasStr1 && HasStr2) {
650 return ConstantInt::get(CI->
getType(),
651 std::clamp(SubStr1.
compare(SubStr2), -1, 1));
654 if (HasStr1 && Str1.
empty())
655 return B.CreateNeg(
B.CreateZExt(
656 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
658 if (HasStr2 && Str2.
empty())
659 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
670 if (!HasStr1 && HasStr2) {
671 Len2 = std::min(Len2,
Length);
678 }
else if (HasStr1 && !HasStr2) {
679 Len1 = std::min(Len1,
Length);
695 if (SrcLen &&
Size) {
697 if (SrcLen <= Size->getZExtValue() + 1)
736 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
746 Type *PT =
Callee->getFunctionType()->getParamType(0);
748 Value *DstEnd =
B.CreateInBoundsGEP(
749 B.getInt8Ty(), Dst, ConstantInt::get(DL.
getIntPtrType(PT), Len - 1));
772 NBytes = SizeC->getZExtValue();
781 B.CreateStore(
B.getInt8(0), Dst);
797 bool NulTerm = SrcLen < NBytes;
806 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
807 NBytes = std::min(NBytes - 1, SrcLen);
812 B.CreateStore(
B.getInt8(0), Dst);
813 return ConstantInt::get(CI->
getType(), 0);
817 Type *PT =
Callee->getFunctionType()->getParamType(0);
826 Value *EndOff = ConstantInt::get(CI->
getType(), NBytes);
827 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
828 B.CreateStore(
B.getInt8(0), EndPtr);
834 return ConstantInt::get(CI->
getType(), SrcLen);
839Value *LibCallSimplifier::optimizeStringNCpy(
CallInst *CI,
bool RetEnd,
857 N = SizeC->getZExtValue();
864 Type *CharTy =
B.getInt8Ty();
865 Value *CharVal =
B.CreateLoad(CharTy, Src,
"stxncpy.char0");
866 B.CreateStore(CharVal, Dst);
872 Value *ZeroChar = ConstantInt::get(CharTy, 0);
873 Value *
Cmp =
B.CreateICmpEQ(CharVal, ZeroChar,
"stpncpy.char0cmp");
875 Value *Off1 =
B.getInt32(1);
876 Value *EndPtr =
B.CreateInBoundsGEP(CharTy, Dst, Off1,
"stpncpy.end");
877 return B.CreateSelect(Cmp, Dst, EndPtr,
"stpncpy.sel");
893 CallInst *NewCI =
B.CreateMemSet(Dst,
B.getInt8(
'\0'),
Size, MemSetAlign);
901 if (
N > SrcLen + 1) {
910 std::string SrcStr = Str.str();
913 SrcStr.resize(
N,
'\0');
914 Src =
B.CreateGlobalString(SrcStr,
"str", 0,
918 Type *PT =
Callee->getFunctionType()->getParamType(0);
930 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
937 Type *CharTy =
B.getIntNTy(CharSize);
947 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
952 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
953 if (BoundCst->isZero())
955 return ConstantInt::get(CI->
getType(), 0);
957 if (BoundCst->isOne()) {
959 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
960 Value *ZeroChar = ConstantInt::get(CharTy, 0);
961 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
962 return B.CreateZExt(Cmp, CI->
getType());
972 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
996 if (Slice.
Array ==
nullptr) {
1015 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
1022 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
1023 NullTermIdx == ArrSize - 1)) {
1025 return B.CreateSub(ConstantInt::get(CI->
getType(), NullTermIdx),
1032 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
1035 if (LenTrue && LenFalse) {
1038 <<
"folded strlen(select) to select of constants";
1040 return B.CreateSelect(
SI->getCondition(),
1041 ConstantInt::get(CI->
getType(), LenTrue - 1),
1042 ConstantInt::get(CI->
getType(), LenFalse - 1));
1050 if (
Value *V = optimizeStringLength(CI,
B, 8))
1058 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1073 return optimizeStringLength(CI,
B, WCharSize);
1083 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1087 if (HasS1 && HasS2) {
1088 size_t I =
S1.find_first_of(S2);
1093 B.getInt64(
I),
"strpbrk");
1097 if (HasS2 && S2.
size() == 1)
1105 if (isa<ConstantPointerNull>(EndPtr)) {
1121 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1125 if (HasS1 && HasS2) {
1126 size_t Pos =
S1.find_first_not_of(S2);
1129 return ConstantInt::get(CI->
getType(), Pos);
1141 if (HasS1 &&
S1.empty())
1145 if (HasS1 && HasS2) {
1146 size_t Pos =
S1.find_first_of(S2);
1149 return ConstantInt::get(CI->
getType(), Pos);
1153 if (HasS2 && S2.
empty())
1170 StrLen,
B, DL, TLI);
1178 replaceAllUsesWith(Old, Cmp);
1189 if (HasStr2 && ToFindStr.
empty())
1193 if (HasStr1 && HasStr2) {
1200 return B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), CI->
getArgOperand(0),
1205 if (HasStr2 && ToFindStr.
size() == 1) {
1226 if (LenC->
isOne()) {
1229 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1231 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1232 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1233 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1241 if (Str.size() == 0)
1250 if (Str.size() < EndOff)
1255 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1265 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1267 if (Str.find(Str[Pos]) == Pos) {
1274 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1275 B.getInt64(Pos),
"memrchr.ptr_plus");
1276 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1281 Str = Str.substr(0, EndOff);
1289 Type *Int8Ty =
B.getInt8Ty();
1290 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1292 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1293 Value *CEqS0 =
B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1294 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1295 Value *SizeM1 =
B.CreateSub(
Size, ConstantInt::get(SizeTy, 1));
1297 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1298 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1312 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1321 if (LenC->
isOne()) {
1324 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1326 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1327 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1328 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1348 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1350 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1353 if (Str.size() == 0)
1362 size_t Pos = Str.find_first_not_of(Str[0]);
1375 Type *Int8Ty =
B.getInt8Ty();
1378 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1380 Value *Sel1 = NullPtr;
1383 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1384 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1385 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1387 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1388 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1389 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1392 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1393 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1394 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1396 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1428 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1429 reinterpret_cast<const unsigned char *
>(Str.end()));
1442 std::string SortedStr = Str.str();
1445 unsigned NonContRanges = 1;
1446 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1447 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1454 if (NonContRanges > 2)
1458 for (
unsigned char C : SortedStr)
1460 B.CreateICmpEQ(CharVal, ConstantInt::get(CharVal->
getType(),
C)));
1462 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1467 unsigned char Width =
NextPowerOf2(std::max((
unsigned char)7, Max));
1477 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1484 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1485 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1489 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1514 if (Pos == MinSize ||
1515 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1523 if (LStr[Pos] != RStr[Pos])
1528 typedef unsigned char UChar;
1529 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1530 Value *MaxSize = ConstantInt::get(
Size->getType(), Pos);
1533 return B.CreateSelect(Cmp, Zero, Res);
1545 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1547 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1549 return B.CreateSub(LHSV, RHSV,
"chardiff");
1557 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1560 Value *LHSV =
nullptr;
1561 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1564 Value *RHSV =
nullptr;
1565 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1573 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1575 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1576 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1584Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1604 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1622 return optimizeMemCmpBCmpCommon(CI,
B);
1628 if (isa<IntrinsicInst>(CI))
1648 if (
N->isNullValue())
1661 if (
N->getZExtValue() <= SrcStr.
size()) {
1670 ConstantInt::get(
N->getType(), std::min(
uint64_t(Pos + 1),
N->getZExtValue()));
1673 return Pos + 1 <=
N->getZExtValue()
1674 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1688 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1694 if (isa<IntrinsicInst>(CI))
1707 if (isa<IntrinsicInst>(CI))
1752 case LibFunc_Znwm12__hot_cold_t:
1755 LibFunc_Znwm12__hot_cold_t, HotCold);
1760 LibFunc_Znwm12__hot_cold_t, HotCold);
1762 case LibFunc_Znam12__hot_cold_t:
1765 LibFunc_Znam12__hot_cold_t, HotCold);
1770 LibFunc_Znam12__hot_cold_t, HotCold);
1772 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1776 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1778 case LibFunc_ZnwmRKSt9nothrow_t:
1782 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1784 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1788 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1790 case LibFunc_ZnamRKSt9nothrow_t:
1794 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1796 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1800 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1802 case LibFunc_ZnwmSt11align_val_t:
1806 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1808 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1812 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1814 case LibFunc_ZnamSt11align_val_t:
1818 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1820 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1824 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1827 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1831 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1834 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1838 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1841 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1845 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1848 case LibFunc_size_returning_new:
1851 LibFunc_size_returning_new_hot_cold,
1854 case LibFunc_size_returning_new_hot_cold:
1857 LibFunc_size_returning_new_hot_cold,
1860 case LibFunc_size_returning_new_aligned:
1864 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1866 case LibFunc_size_returning_new_aligned_hot_cold:
1870 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1896 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1897 Value *
Op = Cast->getOperand(0);
1898 if (
Op->getType()->isFloatTy())
1901 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1907 return ConstantFP::get(Const->getContext(),
F);
1915 bool isPrecise =
false) {
1946 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1947 CallerName.
size() == (CalleeName.
size() + 1) &&
1962 R =
isBinary ?
B.CreateCall(Fn, V) :
B.CreateCall(Fn, V[0]);
1969 return B.CreateFPExt(R,
B.getDoubleTy());
1975 bool isPrecise =
false) {
1982 bool isPrecise =
false) {
1996 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1998 Real =
B.CreateExtractValue(
Op, 0,
"real");
1999 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
2009 Value *AbsOp =
nullptr;
2010 if (
ConstantFP *ConstReal = dyn_cast<ConstantFP>(Real)) {
2011 if (ConstReal->isZero())
2014 }
else if (
ConstantFP *ConstImag = dyn_cast<ConstantFP>(Imag)) {
2015 if (ConstImag->isZero())
2024 *CI,
B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp,
nullptr,
"cabs"));
2035 Value *RealReal =
B.CreateFMul(Real, Real);
2036 Value *ImagImag =
B.CreateFMul(Imag, Imag);
2038 return copyFlags(*CI,
B.CreateUnaryIntrinsic(Intrinsic::sqrt,
2039 B.CreateFAdd(RealReal, ImagImag),
2046 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
2047 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
2050 unsigned BitWidth =
Op->getType()->getScalarSizeInBits();
2051 if (
BitWidth < DstWidth || (
BitWidth == DstWidth && isa<SIToFPInst>(I2F))) {
2052 Type *IntTy =
Op->getType()->getWithNewBitWidth(DstWidth);
2053 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op, IntTy)
2054 :
B.CreateZExt(
Op, IntTy);
2095 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2103 ExpName = TLI->
getName(LibFunc_exp);
2104 ID = Intrinsic::exp;
2105 LibFnFloat = LibFunc_expf;
2106 LibFnDouble = LibFunc_exp;
2107 LibFnLongDouble = LibFunc_expl;
2112 ExpName = TLI->
getName(LibFunc_exp2);
2113 ID = Intrinsic::exp2;
2114 LibFnFloat = LibFunc_exp2f;
2115 LibFnDouble = LibFunc_exp2;
2116 LibFnLongDouble = LibFunc_exp2l;
2123 ?
B.CreateUnaryIntrinsic(
ID,
FMul,
nullptr, ExpName)
2132 substituteInParent(BaseFn, ExpFn);
2149 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2151 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2156 Constant *One = ConstantFP::get(Ty, 1.0);
2159 return copyFlags(*Pow,
B.CreateIntrinsic(Intrinsic::ldexp,
2160 {Ty, ExpoI->getType()},
2161 {One, ExpoI}, Pow,
"exp2"));
2165 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2166 LibFunc_ldexpl,
B, NoAttrs));
2171 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2174 BaseR = BaseR / *BaseF;
2176 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2178 if ((IsInteger || IsReciprocal) &&
2181 NI > 1 && NI.isPowerOf2()) {
2182 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2183 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2185 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2190 LibFunc_exp2l,
B, NoAttrs));
2196 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l)) {
2200 B.CreateIntrinsic(Intrinsic::exp10, {Ty}, {Expo}, Pow,
"exp10");
2205 LibFunc_exp10f, LibFunc_exp10l,
2215 "pow(1.0, y) should have been simplified earlier!");
2217 Value *Log =
nullptr;
2224 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2226 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2228 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2232 LibFunc_exp2l,
B, NoAttrs));
2244 return B.CreateUnaryIntrinsic(Intrinsic::sqrt, V,
nullptr,
"sqrt");
2247 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2253 LibFunc_sqrtl,
B, Attrs);
2290 Sqrt =
B.CreateUnaryIntrinsic(Intrinsic::fabs, Sqrt,
nullptr,
"abs");
2299 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2300 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2305 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2314 return B.CreateIntrinsic(Intrinsic::powi, Types, Args);
2336 if (
Value *Exp = replacePowWithExp(Pow,
B))
2343 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2347 return ConstantFP::get(Ty, 1.0);
2355 return B.CreateFMul(
Base,
Base,
"square");
2357 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2368 Value *Sqrt =
nullptr;
2369 if (!ExpoA.isInteger()) {
2383 if (!ExpoI.isInteger())
2406 return B.CreateFMul(PowI, Sqrt);
2413 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2420 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2421 hasFloatVersion(M,
Name)) {
2434 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2435 hasFloatVersion(M,
Name))
2444 const bool UseIntrinsic =
Callee->isIntrinsic();
2453 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2455 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2457 Constant *One = ConstantFP::get(Ty, 1.0);
2460 return copyFlags(*CI,
B.CreateIntrinsic(Intrinsic::ldexp,
2461 {Ty, Exp->getType()},
2468 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2483 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2497 B.setFastMathFlags(FMF);
2500 : Intrinsic::maxnum;
2513 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2521 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2527 LogID = Intrinsic::log;
2528 ExpLb = LibFunc_expf;
2529 Exp2Lb = LibFunc_exp2f;
2530 Exp10Lb = LibFunc_exp10f;
2531 PowLb = LibFunc_powf;
2534 LogID = Intrinsic::log;
2535 ExpLb = LibFunc_exp;
2536 Exp2Lb = LibFunc_exp2;
2537 Exp10Lb = LibFunc_exp10;
2538 PowLb = LibFunc_pow;
2541 LogID = Intrinsic::log;
2542 ExpLb = LibFunc_expl;
2543 Exp2Lb = LibFunc_exp2l;
2544 Exp10Lb = LibFunc_exp10l;
2545 PowLb = LibFunc_powl;
2548 LogID = Intrinsic::log2;
2549 ExpLb = LibFunc_expf;
2550 Exp2Lb = LibFunc_exp2f;
2551 Exp10Lb = LibFunc_exp10f;
2552 PowLb = LibFunc_powf;
2555 LogID = Intrinsic::log2;
2556 ExpLb = LibFunc_exp;
2557 Exp2Lb = LibFunc_exp2;
2558 Exp10Lb = LibFunc_exp10;
2559 PowLb = LibFunc_pow;
2562 LogID = Intrinsic::log2;
2563 ExpLb = LibFunc_expl;
2564 Exp2Lb = LibFunc_exp2l;
2565 Exp10Lb = LibFunc_exp10l;
2566 PowLb = LibFunc_powl;
2568 case LibFunc_log10f:
2569 LogID = Intrinsic::log10;
2570 ExpLb = LibFunc_expf;
2571 Exp2Lb = LibFunc_exp2f;
2572 Exp10Lb = LibFunc_exp10f;
2573 PowLb = LibFunc_powf;
2576 LogID = Intrinsic::log10;
2577 ExpLb = LibFunc_exp;
2578 Exp2Lb = LibFunc_exp2;
2579 Exp10Lb = LibFunc_exp10;
2580 PowLb = LibFunc_pow;
2582 case LibFunc_log10l:
2583 LogID = Intrinsic::log10;
2584 ExpLb = LibFunc_expl;
2585 Exp2Lb = LibFunc_exp2l;
2586 Exp10Lb = LibFunc_exp10l;
2587 PowLb = LibFunc_powl;
2592 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2593 LogID == Intrinsic::log10) {
2595 ExpLb = LibFunc_expf;
2596 Exp2Lb = LibFunc_exp2f;
2597 Exp10Lb = LibFunc_exp10f;
2598 PowLb = LibFunc_powf;
2600 ExpLb = LibFunc_exp;
2601 Exp2Lb = LibFunc_exp2;
2602 Exp10Lb = LibFunc_exp10;
2603 PowLb = LibFunc_pow;
2618 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2621 ?
B.CreateUnaryIntrinsic(LogID, Arg->
getOperand(0),
nullptr,
"log")
2625 if (ArgID == Intrinsic::powi)
2626 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2627 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2630 substituteInParent(Arg, MulY);
2636 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2637 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2639 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2642 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2643 Eul = ConstantFP::get(Log->
getType(), 2.0);
2645 Eul = ConstantFP::get(Log->
getType(), 10.0);
2647 ?
B.CreateUnaryIntrinsic(LogID, Eul,
nullptr,
"log")
2652 substituteInParent(Arg, MulY);
2672 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2677 ExpLb = LibFunc_expf;
2678 Exp2Lb = LibFunc_exp2f;
2679 Exp10Lb = LibFunc_exp10f;
2682 ExpLb = LibFunc_exp;
2683 Exp2Lb = LibFunc_exp2;
2684 Exp10Lb = LibFunc_exp10;
2687 ExpLb = LibFunc_expl;
2688 Exp2Lb = LibFunc_exp2l;
2689 Exp10Lb = LibFunc_exp10l;
2696 ExpLb = LibFunc_expf;
2697 Exp2Lb = LibFunc_exp2f;
2698 Exp10Lb = LibFunc_exp10f;
2700 ExpLb = LibFunc_exp;
2701 Exp2Lb = LibFunc_exp2;
2702 Exp10Lb = LibFunc_exp10;
2708 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2709 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2713 B.SetInsertPoint(Arg);
2716 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2731 (
Callee->getName() ==
"sqrt" ||
2732 Callee->getIntrinsicID() == Intrinsic::sqrt))
2735 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2742 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2748 Value *Op0 =
I->getOperand(0);
2749 Value *Op1 =
I->getOperand(1);
2750 Value *RepeatOp =
nullptr;
2751 Value *OtherOp =
nullptr;
2763 cast<Instruction>(Op0)->isFast()) {
2768 cast<Instruction>(Op1)->isFast()) {
2780 B.setFastMathFlags(
I->getFastMathFlags());
2785 B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp,
nullptr,
"fabs");
2791 B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp,
nullptr,
"sqrt");
2792 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2797Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2803 if (UnsafeFPShrink &&
2806 hasFloatVersion(M,
Name))
2810 auto *OpC = dyn_cast<CallInst>(Op1);
2815 if (!CI->
isFast() || !OpC->isFast())
2828 .
Case(
"tan", LibFunc_atan)
2829 .
Case(
"atanh", LibFunc_tanh)
2830 .
Case(
"sinh", LibFunc_asinh)
2831 .
Case(
"cosh", LibFunc_acosh)
2832 .
Case(
"tanf", LibFunc_atanf)
2833 .
Case(
"atanhf", LibFunc_tanhf)
2834 .
Case(
"sinhf", LibFunc_asinhf)
2835 .
Case(
"coshf", LibFunc_acoshf)
2836 .
Case(
"tanl", LibFunc_atanl)
2837 .
Case(
"atanhl", LibFunc_tanhl)
2838 .
Case(
"sinhl", LibFunc_asinhl)
2839 .
Case(
"coshl", LibFunc_acoshl)
2840 .
Case(
"asinh", LibFunc_sinh)
2841 .
Case(
"asinhf", LibFunc_sinhf)
2842 .
Case(
"asinhl", LibFunc_sinhl)
2844 if (Func == inverseFunc)
2845 Ret = OpC->getArgOperand(0);
2867 Name =
"__sincospif_stret";
2876 Name =
"__sincospi_stret";
2885 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2887 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2890 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2894 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2895 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2898 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2901 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2902 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2904 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2906 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
2988 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2994 Value *Sin, *Cos, *SinCos;
3002 replaceAllUsesWith(
C, Res);
3005 replaceTrigInsts(SinCalls, Sin);
3006 replaceTrigInsts(CosCalls, Cos);
3007 replaceTrigInsts(SinCosCalls, SinCos);
3009 return IsSin ? Sin : Cos;
3012void LibCallSimplifier::classifyArgUse(
3017 auto *CI = dyn_cast<CallInst>(Val);
3028 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
3034 if (Func == LibFunc_sinpif)
3036 else if (Func == LibFunc_cospif)
3038 else if (Func == LibFunc_sincospif_stret)
3041 if (Func == LibFunc_sinpi)
3043 else if (Func == LibFunc_cospi)
3045 else if (Func == LibFunc_sincospi_stret)
3068 APSInt QuotInt(IntBW,
false);
3075 B.CreateAlignedStore(
3076 ConstantInt::get(
B.getIntNTy(IntBW), QuotInt.getExtValue()),
3078 return ConstantFP::get(CI->
getType(), Rem);
3090 Type *ArgType =
Op->getType();
3091 Value *
V =
B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {
Op,
B.getTrue()},
3093 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3094 V =
B.CreateIntCast(V, RetType,
false);
3097 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3104 Type *ArgType =
Op->getType();
3105 Value *
V =
B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {
Op,
B.getFalse()},
3109 return B.CreateIntCast(V, CI->
getType(),
false);
3116 Value *IsNeg =
B.CreateIsNeg(
X);
3117 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3118 return B.CreateSelect(IsNeg, NegX,
X);
3124 Type *ArgType =
Op->getType();
3125 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3126 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3133 Type *ArgType =
Op->getType();
3134 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3141 ConstantInt::get(CI->
getType(), 0x7F));
3159 if (isa<ConstantPointerNull>(EndPtr)) {
3172 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3204 if (!Callee || !Callee->isDeclaration())
3213 if (StreamArg >= (
int)CI->
arg_size())
3221 return GV->
getName() ==
"stderr";
3231 if (FormatStr.
empty())
3242 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3246 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3251 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3256 if (OperandStr.
empty())
3259 if (OperandStr.
size() == 1) {
3263 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3267 if (OperandStr.
back() ==
'\n') {
3269 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3276 if (FormatStr.
back() ==
'\n' &&
3281 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3287 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3296 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3307 if (
Value *V = optimizePrintFString(CI,
B)) {
3318 Callee->getAttributes());
3320 New->setCalledFunction(IPrintFFn);
3330 Callee->getAttributes());
3332 New->setCalledFunction(SmallPrintFFn);
3340Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3359 FormatStr.
size() + 1));
3360 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3365 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3369 if (FormatStr[1] ==
'c') {
3375 B.CreateStore(V,
Ptr);
3376 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3377 B.CreateStore(
B.getInt8(0),
Ptr);
3379 return ConstantInt::get(CI->
getType(), 1);
3382 if (FormatStr[1] ==
's') {
3398 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3401 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3402 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3415 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3419 return B.CreateIntCast(Len, CI->
getType(),
false);
3428 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3439 FT,
Callee->getAttributes());
3441 New->setCalledFunction(SIPrintFFn);
3451 Callee->getAttributes());
3453 New->setCalledFunction(SmallSPrintFFn);
3469 assert(StrArg || (
N < 2 && Str.size() == 1));
3473 if (Str.size() > IntMax)
3479 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3489 NCopy = Str.size() + 1;
3494 if (NCopy && StrArg)
3508 Type *Int8Ty =
B.getInt8Ty();
3509 Value *NulOff =
B.getIntN(IntBits, NCopy);
3510 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3511 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3515Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3544 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3549 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3553 if (FormatStr[1] ==
'c') {
3559 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3567 B.CreateStore(V,
Ptr);
3568 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3569 B.CreateStore(
B.getInt8(0),
Ptr);
3570 return ConstantInt::get(CI->
getType(), 1);
3573 if (FormatStr[1] !=
's')
3582 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3586 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3595Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3597 optimizeErrorReporting(CI,
B, 0);
3620 ConstantInt::get(SizeTTy, FormatStr.
size()),
3626 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3630 if (FormatStr[1] ==
'c') {
3640 if (FormatStr[1] ==
's') {
3654 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3663 FT,
Callee->getAttributes());
3665 New->setCalledFunction(FIPrintFFn);
3674 auto SmallFPrintFFn =
3676 Callee->getAttributes());
3678 New->setCalledFunction(SmallFPrintFFn);
3687 optimizeErrorReporting(CI,
B, 3);
3692 if (SizeC && CountC) {
3697 return ConstantInt::get(CI->
getType(), 0);
3704 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3706 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3714 optimizeErrorReporting(CI,
B, 1);
3739 ConstantInt::get(SizeTTy, Len - 1),
3779bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3781 FloatFuncName +=
'f';
3785Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3797 "Optimizing string/memory libcall would change the calling convention");
3799 case LibFunc_strcat:
3800 return optimizeStrCat(CI, Builder);
3801 case LibFunc_strncat:
3802 return optimizeStrNCat(CI, Builder);
3803 case LibFunc_strchr:
3804 return optimizeStrChr(CI, Builder);
3805 case LibFunc_strrchr:
3806 return optimizeStrRChr(CI, Builder);
3807 case LibFunc_strcmp:
3808 return optimizeStrCmp(CI, Builder);
3809 case LibFunc_strncmp:
3810 return optimizeStrNCmp(CI, Builder);
3811 case LibFunc_strcpy:
3812 return optimizeStrCpy(CI, Builder);
3813 case LibFunc_stpcpy:
3814 return optimizeStpCpy(CI, Builder);
3815 case LibFunc_strlcpy:
3816 return optimizeStrLCpy(CI, Builder);
3817 case LibFunc_stpncpy:
3818 return optimizeStringNCpy(CI,
true, Builder);
3819 case LibFunc_strncpy:
3820 return optimizeStringNCpy(CI,
false, Builder);
3821 case LibFunc_strlen:
3822 return optimizeStrLen(CI, Builder);
3823 case LibFunc_strnlen:
3824 return optimizeStrNLen(CI, Builder);
3825 case LibFunc_strpbrk:
3826 return optimizeStrPBrk(CI, Builder);
3827 case LibFunc_strndup:
3828 return optimizeStrNDup(CI, Builder);
3829 case LibFunc_strtol:
3830 case LibFunc_strtod:
3831 case LibFunc_strtof:
3832 case LibFunc_strtoul:
3833 case LibFunc_strtoll:
3834 case LibFunc_strtold:
3835 case LibFunc_strtoull:
3836 return optimizeStrTo(CI, Builder);
3837 case LibFunc_strspn:
3838 return optimizeStrSpn(CI, Builder);
3839 case LibFunc_strcspn:
3840 return optimizeStrCSpn(CI, Builder);
3841 case LibFunc_strstr:
3842 return optimizeStrStr(CI, Builder);
3843 case LibFunc_memchr:
3844 return optimizeMemChr(CI, Builder);
3845 case LibFunc_memrchr:
3846 return optimizeMemRChr(CI, Builder);
3848 return optimizeBCmp(CI, Builder);
3849 case LibFunc_memcmp:
3850 return optimizeMemCmp(CI, Builder);
3851 case LibFunc_memcpy:
3852 return optimizeMemCpy(CI, Builder);
3853 case LibFunc_memccpy:
3854 return optimizeMemCCpy(CI, Builder);
3855 case LibFunc_mempcpy:
3856 return optimizeMemPCpy(CI, Builder);
3857 case LibFunc_memmove:
3858 return optimizeMemMove(CI, Builder);
3859 case LibFunc_memset:
3860 return optimizeMemSet(CI, Builder);
3861 case LibFunc_realloc:
3862 return optimizeRealloc(CI, Builder);
3863 case LibFunc_wcslen:
3864 return optimizeWcslen(CI, Builder);
3866 return optimizeBCopy(CI, Builder);
3868 case LibFunc_ZnwmRKSt9nothrow_t:
3869 case LibFunc_ZnwmSt11align_val_t:
3870 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3872 case LibFunc_ZnamRKSt9nothrow_t:
3873 case LibFunc_ZnamSt11align_val_t:
3874 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3875 case LibFunc_Znwm12__hot_cold_t:
3876 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3877 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3878 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3879 case LibFunc_Znam12__hot_cold_t:
3880 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3881 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3882 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3883 case LibFunc_size_returning_new:
3884 case LibFunc_size_returning_new_hot_cold:
3885 case LibFunc_size_returning_new_aligned:
3886 case LibFunc_size_returning_new_aligned_hot_cold:
3887 return optimizeNew(CI, Builder, Func);
3903 if (CharSeq.
empty())
3904 Fill =
APInt(32, 0);
3911Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3920 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3924 case LibFunc_sinpif:
3926 return optimizeSinCosPi(CI,
true, Builder);
3927 case LibFunc_cospif:
3929 return optimizeSinCosPi(CI,
false, Builder);
3933 return optimizePow(CI, Builder);
3937 return optimizeExp2(CI, Builder);
3945 return optimizeSqrt(CI, Builder);
3949 case LibFunc_log10f:
3951 case LibFunc_log10l:
3952 case LibFunc_log1pf:
3954 case LibFunc_log1pl:
3961 return optimizeLog(CI, Builder);
3969 case LibFunc_asinhf:
3970 case LibFunc_asinhl:
3975 case LibFunc_atanhf:
3976 case LibFunc_atanhl:
3977 return optimizeTrigInversionPairs(CI, Builder);
3984 case LibFunc_roundeven:
3986 case LibFunc_nearbyint:
4006 case LibFunc_copysign:
4016 return optimizeFMinFMax(CI, Builder);
4020 return optimizeCAbs(CI, Builder);
4021 case LibFunc_remquo:
4022 case LibFunc_remquof:
4023 case LibFunc_remquol:
4024 return optimizeRemquo(CI, Builder);
4059 else if (isa<FPMathOperator>(CI) && CI->
isFast())
4060 UnsafeFPShrink =
true;
4064 if (!IsCallingConvC)
4068 switch (
II->getIntrinsicID()) {
4069 case Intrinsic::pow:
4070 return optimizePow(CI, Builder);
4071 case Intrinsic::exp2:
4072 return optimizeExp2(CI, Builder);
4073 case Intrinsic::log:
4074 case Intrinsic::log2:
4075 case Intrinsic::log10:
4076 return optimizeLog(CI, Builder);
4077 case Intrinsic::sqrt:
4078 return optimizeSqrt(CI, Builder);
4079 case Intrinsic::memset:
4080 return optimizeMemSet(CI, Builder);
4081 case Intrinsic::memcpy:
4082 return optimizeMemCpy(CI, Builder);
4083 case Intrinsic::memmove:
4084 return optimizeMemMove(CI, Builder);
4091 if (
Value *SimplifiedFortifiedCI =
4093 return SimplifiedFortifiedCI;
4100 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
4102 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4108 return optimizeFFS(CI, Builder);
4112 return optimizeFls(CI, Builder);
4116 return optimizeAbs(CI, Builder);
4117 case LibFunc_isdigit:
4118 return optimizeIsDigit(CI, Builder);
4119 case LibFunc_isascii:
4120 return optimizeIsAscii(CI, Builder);
4121 case LibFunc_toascii:
4122 return optimizeToAscii(CI, Builder);
4126 return optimizeAtoi(CI, Builder);
4127 case LibFunc_strtol:
4128 case LibFunc_strtoll:
4129 return optimizeStrToInt(CI, Builder,
true);
4130 case LibFunc_strtoul:
4131 case LibFunc_strtoull:
4132 return optimizeStrToInt(CI, Builder,
false);
4133 case LibFunc_printf:
4134 return optimizePrintF(CI, Builder);
4135 case LibFunc_sprintf:
4136 return optimizeSPrintF(CI, Builder);
4137 case LibFunc_snprintf:
4138 return optimizeSnPrintF(CI, Builder);
4139 case LibFunc_fprintf:
4140 return optimizeFPrintF(CI, Builder);
4141 case LibFunc_fwrite:
4142 return optimizeFWrite(CI, Builder);
4144 return optimizeFPuts(CI, Builder);
4146 return optimizePuts(CI, Builder);
4147 case LibFunc_perror:
4148 return optimizeErrorReporting(CI, Builder);
4149 case LibFunc_vfprintf:
4150 case LibFunc_fiprintf:
4151 return optimizeErrorReporting(CI, Builder, 0);
4154 return optimizeExit(CI);
4168 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
4169 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4176void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4215bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4216 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4217 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4222 if (!Flag || !
Flag->isZero())
4231 if (ObjSizeCI->isMinusOne())
4234 if (OnlyLowerUnknownSize)
4244 return ObjSizeCI->getZExtValue() >=
Len;
4250 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4256Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4258 if (isFortifiedCallFoldable(CI, 3, 2)) {
4268Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4270 if (isFortifiedCallFoldable(CI, 3, 2)) {
4280Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4282 if (isFortifiedCallFoldable(CI, 3, 2)) {
4292Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4295 if (isFortifiedCallFoldable(CI, 3, 2))
4303Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4311 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4313 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4321 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4322 if (Func == LibFunc_strcpy_chk)
4328 if (OnlyLowerUnknownSize)
4340 Value *LenV = ConstantInt::get(SizeTTy, Len);
4344 if (Ret && Func == LibFunc_stpcpy_chk)
4345 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4346 ConstantInt::get(SizeTTy, Len - 1));
4347 return copyFlags(*CI, cast<CallInst>(Ret));
4350Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4352 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4358Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4361 if (isFortifiedCallFoldable(CI, 3, 2)) {
4362 if (Func == LibFunc_strncpy_chk)
4375Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4377 if (isFortifiedCallFoldable(CI, 4, 3))
4385Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4387 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4397Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4399 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4403 VariadicArgs,
B, TLI));
4409Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4411 if (isFortifiedCallFoldable(CI, 2))
4418Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4420 if (isFortifiedCallFoldable(CI, 3))
4428Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4430 if (isFortifiedCallFoldable(CI, 3))
4438Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4440 if (isFortifiedCallFoldable(CI, 3))
4448Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4450 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4458Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4460 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4503 case LibFunc_memcpy_chk:
4504 return optimizeMemCpyChk(CI, Builder);
4505 case LibFunc_mempcpy_chk:
4506 return optimizeMemPCpyChk(CI, Builder);
4507 case LibFunc_memmove_chk:
4508 return optimizeMemMoveChk(CI, Builder);
4509 case LibFunc_memset_chk:
4510 return optimizeMemSetChk(CI, Builder);
4511 case LibFunc_stpcpy_chk:
4512 case LibFunc_strcpy_chk:
4513 return optimizeStrpCpyChk(CI, Builder, Func);
4514 case LibFunc_strlen_chk:
4515 return optimizeStrLenChk(CI, Builder);
4516 case LibFunc_stpncpy_chk:
4517 case LibFunc_strncpy_chk:
4518 return optimizeStrpNCpyChk(CI, Builder, Func);
4519 case LibFunc_memccpy_chk:
4520 return optimizeMemCCpyChk(CI, Builder);
4521 case LibFunc_snprintf_chk:
4522 return optimizeSNPrintfChk(CI, Builder);
4523 case LibFunc_sprintf_chk:
4524 return optimizeSPrintfChk(CI, Builder);
4525 case LibFunc_strcat_chk:
4526 return optimizeStrCatChk(CI, Builder);
4527 case LibFunc_strlcat_chk:
4528 return optimizeStrLCat(CI, Builder);
4529 case LibFunc_strncat_chk:
4530 return optimizeStrNCatChk(CI, Builder);
4531 case LibFunc_strlcpy_chk:
4532 return optimizeStrLCpyChk(CI, Builder);
4533 case LibFunc_vsnprintf_chk:
4534 return optimizeVSNPrintfChk(CI, Builder);
4535 case LibFunc_vsprintf_chk:
4536 return optimizeVSPrintfChk(CI, Builder);
4545 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static bool isBinary(MachineInstr &MI)
const SmallVectorImpl< MachineOperand > & Cond
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With)
Return true if it is only used in equality comparisons with With.
static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef< unsigned > ArgNos, Value *Size, const DataLayout &DL)
static cl::opt< unsigned, false, HotColdHintParser > ColdNewHintValue("cold-new-hint-value", cl::Hidden, cl::init(1), cl::desc("Value to pass to hot/cold operator new for cold allocation"))
static bool insertSinCosCall(IRBuilderBase &B, Function *OrigCallee, Value *Arg, bool UseFloat, Value *&Sin, Value *&Cos, Value *&SinCos, const TargetLibraryInfo *TLI)
static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len, const DataLayout &DL)
static Value * mergeAttributesAndFlags(CallInst *NewCI, const CallInst &Old)
static cl::opt< bool > OptimizeHotColdNew("optimize-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable hot/cold operator new library calls"))
static Value * optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for binary functions.
static bool ignoreCallingConv(LibFunc Func)
static cl::opt< bool > OptimizeExistingHotColdNew("optimize-existing-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable optimization of existing hot/cold operator new library calls"))
static void annotateDereferenceableBytes(CallInst *CI, ArrayRef< unsigned > ArgNos, uint64_t DereferenceableBytes)
static bool isReportingError(Function *Callee, CallInst *CI, int StreamArg)
static Value * optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, bool isBinary, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float functions.
static Value * optimizeSymmetricCall(CallInst *CI, bool IsEven, IRBuilderBase &B)
static Value * getSqrtCall(Value *V, AttributeList Attrs, bool NoErrno, Module *M, IRBuilderBase &B, const TargetLibraryInfo *TLI)
static Value * valueHasFloatPrecision(Value *Val)
Return a variant of Val with float type.
static Value * optimizeMemCmpConstantSize(CallInst *CI, Value *LHS, Value *RHS, uint64_t Len, IRBuilderBase &B, const DataLayout &DL)
static Value * createPowWithIntegerExponent(Value *Base, Value *Expo, Module *M, IRBuilderBase &B)
static Value * convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, uint64_t Base, bool AsSigned, IRBuilderBase &B)
static Value * memChrToCharCompare(CallInst *CI, Value *NBytes, IRBuilderBase &B, const DataLayout &DL)
static Value * copyFlags(const CallInst &Old, Value *New)
static StringRef substr(StringRef Str, uint64_t Len)
static cl::opt< unsigned, false, HotColdHintParser > HotNewHintValue("hot-new-hint-value", cl::Hidden, cl::init(254), cl::desc("Value to pass to hot/cold operator new for hot allocation"))
static bool isTrigLibCall(CallInst *CI)
static Value * optimizeNaN(CallInst *CI)
Constant folding nan/nanf/nanl.
static bool isOnlyUsedInComparisonWithZero(Value *V)
static Value * replaceUnaryCall(CallInst *CI, IRBuilderBase &B, Intrinsic::ID IID)
static bool callHasFloatingPointArgument(const CallInst *CI)
static Value * optimizeUnaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for unary functions.
static bool callHasFP128Argument(const CallInst *CI)
static void annotateNonNullNoUndefBasedOnAccess(CallInst *CI, ArrayRef< unsigned > ArgNos)
static Value * optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, Value *Size, bool StrNCmp, IRBuilderBase &B, const DataLayout &DL)
static Value * getIntToFPVal(Value *I2F, IRBuilderBase &B, unsigned DstWidth)
static cl::opt< bool > EnableUnsafeFPShrink("enable-double-float-shrink", cl::Hidden, cl::init(false), cl::desc("Enable unsafe double to float " "shrinking for math lib calls"))
static cl::opt< unsigned, false, HotColdHintParser > NotColdNewHintValue("notcold-new-hint-value", cl::Hidden, cl::init(128), cl::desc("Value to pass to hot/cold operator new for " "notcold (warm) allocation"))
This file defines the SmallString class.
opStatus divide(const APFloat &RHS, roundingMode RM)
bool isFiniteNonZero() const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
double convertToDouble() const
Converts this APFloat to host double value.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
opStatus add(const APFloat &RHS, roundingMode RM)
const fltSemantics & getSemantics() const
float convertToFloat() const
Converts this APFloat to host float value.
opStatus remainder(const APFloat &RHS)
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Class for arbitrary precision integers.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
Attribute getFnAttr(Attribute::AttrKind Kind) const
Return the attribute object that exists for the function.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &B) const
Add an argument attribute to the list.
MaybeAlign getAlignment() const
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool doesNotAccessMemory(unsigned OpNo) const
void removeRetAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the return value.
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
uint64_t getParamDereferenceableBytes(unsigned i) const
Extract the number of dereferenceable bytes for a call or parameter (0=unknown).
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
bool doesNotThrow() const
Determine if the call cannot unwind.
Value * getArgOperand(unsigned i) const
uint64_t getParamDereferenceableOrNullBytes(unsigned i) const
Extract the number of dereferenceable_or_null bytes for a parameter (0=unknown).
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the parameter attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
bool isNoTailCall() const
TailCallKind getTailCallKind() const
bool isMustTailCall() const
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
uint64_t getElementAsInteger(unsigned i) const
If this is a sequential container of integers (of any size), return the specified element in the low ...
ConstantFP - Floating Point Values [float, double].
static Constant * getInfinity(Type *Ty, bool Negative=false)
static Constant * getQNaN(Type *Ty, bool Negative=false, APInt *Payload=nullptr)
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU.
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
void setNoSignedZeros(bool B=true)
static FastMathFlags getFast()
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize=false)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
Take the given call instruction and return a more optimal value to replace the instruction with or 0 ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
void setDefaultOperandBundles(ArrayRef< OperandBundleDef > OpBundles)
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool isFast() const LLVM_READONLY
Determine whether all fast-math-flags are set.
const Function * getFunction() const
Return the function this instruction belongs to.
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, AssumptionCache *AC, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
An instruction for reading from memory.
Value * getPointerOperand()
A Module instance is used to store all the information related to an LLVM module.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Analysis providing profile information.
This class represents the LLVM 'select' instruction.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static bool isCallingConvCCompatible(CallBase *CI)
Returns true if call site / callee has cdecl-compatible calling conventions.
Provides information about what library functions are available for the current target.
unsigned getWCharSize(const Module &M) const
Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
unsigned getSizeTSize(const Module &M) const
Returns the size of the size_t type in bits.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
StringRef getName(LibFunc F) const
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isStructTy() const
True if this is an instance of StructType.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
OneUse_match< T > m_OneUse(const T &SubPattern)
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
Value * emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)
Emit a call to the unary function named 'Name' (e.g.
Value * emitStrChr(Value *Ptr, char C, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strchr function to the builder, for the specified pointer and character.
Value * emitPutChar(Value *Char, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the putchar function. This assumes that Char is an 'int'.
Value * emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the __memcpy_chk function to the builder.
Value * emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncpy function to the builder, for the specified pointer arguments and length.
bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI)
Value * emitHotColdNewAlignedNoThrow(Value *Num, Value *Align, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
bool isKnownNeverInfinity(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
Value * emitSPrintf(Value *Dest, Value *Fmt, ArrayRef< Value * > VariadicArgs, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the sprintf function.
bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice, unsigned ElementSize, uint64_t Offset=0)
Returns true if the value V is a pointer into a ConstantDataArray.
Value * emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memrchr function, analogously to emitMemChr.
Value * emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcat function.
bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty, LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn)
Check whether the overloaded floating point function corresponding to Ty is available.
Value * emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncat function.
bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
Value * emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsnprintf function.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Value * emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strncmp function to the builder.
Value * emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memcmp function.
Value * emitBinaryFloatFnCall(Value *Op1, Value *Op2, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)
Emit a call to the binary function named 'Name' (e.g.
Value * emitFPutS(Value *Str, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputs function.
Value * emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strdup function to the builder, for the specified pointer.
void sort(IteratorTy Start, IteratorTy End)
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Value * emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the bcmp function.
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, and add the unsigned integer, A to the product.
uint64_t GetStringLength(const Value *V, unsigned CharSize=8)
If we can compute the length of the string pointed to by the specified pointer, return 'len+1'.
FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, LibFunc TheLibFunc, FunctionType *T, AttributeList AttributeList)
Calls getOrInsertFunction() and then makes sure to add mandatory argument attributes.
Value * emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strlen function to the builder, for the specified pointer.
Value * emitFPutC(Value *Char, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputc function.
Value * emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the stpncpy function to the builder, for the specified pointer arguments and length.
Value * emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcat function.
Value * emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsprintf function.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
Value * emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the fwrite function.
Value * emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, ArrayRef< Value * > Args, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the snprintf function.
@ Mod
The access may modify the value stored in memory.
Value * emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the stpcpy function to the builder, for the specified pointer arguments.
@ And
Bitwise or logical AND of integers.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
Value * emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the malloc function.
Value * emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memchr function.
Value * emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitPutS(Value *Str, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the puts function. This assumes that Str is some pointer.
Value * emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the memccpy function.
Value * emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitHotColdNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Emit a call to the hot/cold operator new function.
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
bool isGEPBasedOnPointerToString(const GEPOperator *GEP, unsigned CharSize=8)
Returns true if the GEP is based on a pointer to a string (array of.
Value * emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcpy function.
Value * emitHotColdSizeReturningNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcpy function to the builder, for the specified pointer arguments.
Value * emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the mempcpy function.
uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmTowardNegative
static constexpr roundingMode rmNearestTiesToEven
static constexpr roundingMode rmTowardZero
opStatus
IEEE-754R 7: Default exception handling.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Holds functions to get, set or test bitfields.
Represents offset+length into a ConstantDataArray.
uint64_t Length
Length of the slice.
uint64_t Offset
Slice starts at this Offset.
const ConstantDataArray * Array
ConstantDataArray pointer.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.