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()}));
357 return Len >= Str.size() ? Str : Str.substr(0, Len);
382 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
396 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
401 TLI->
getAsSizeT(Len + 1, *
B.GetInsertBlock()->getModule()));
445 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
458 Type *CharTy =
B.getInt8Ty();
459 Value *Char0 =
B.CreateLoad(CharTy, Src);
460 CharVal =
B.CreateTrunc(CharVal, CharTy);
461 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
465 Value *
And =
B.CreateICmpNE(NBytes, Zero);
466 Cmp =
B.CreateLogicalAnd(
And, Cmp);
470 return B.CreateSelect(Cmp, Src, NullPtr);
483 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
494 if (!FT->getParamType(1)->isIntegerTy(IntBits))
501 ConstantInt::get(SizeTTy, Len),
B,
510 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
519 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
532 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
538 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
544 if (CharC && CharC->
isZero())
555 Value *
Size = ConstantInt::get(SizeTTy, NBytes);
562 return ConstantInt::get(CI->
getType(), 0);
569 if (HasStr1 && HasStr2)
570 return ConstantInt::get(CI->
getType(),
571 std::clamp(Str1.
compare(Str2), -1, 1));
573 if (HasStr1 && Str1.
empty())
574 return B.CreateNeg(
B.CreateZExt(
575 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
577 if (HasStr2 && Str2.
empty())
578 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
597 if (!HasStr1 && HasStr2) {
602 }
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);
676 }
else if (HasStr1 && !HasStr2) {
677 Len1 = std::min(Len1,
Length);
691 if (SrcLen &&
Size) {
693 if (SrcLen <= Size->getZExtValue() + 1)
730 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
741 Value *DstEnd =
B.CreateInBoundsGEP(
765 NBytes = SizeC->getZExtValue();
774 B.CreateStore(
B.getInt8(0), Dst);
790 bool NulTerm = SrcLen < NBytes;
799 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
800 NBytes = std::min(NBytes - 1, SrcLen);
805 B.CreateStore(
B.getInt8(0), Dst);
806 return ConstantInt::get(CI->
getType(), 0);
817 Value *EndOff = ConstantInt::get(CI->
getType(), NBytes);
818 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
819 B.CreateStore(
B.getInt8(0), EndPtr);
825 return ConstantInt::get(CI->
getType(), SrcLen);
830Value *LibCallSimplifier::optimizeStringNCpy(
CallInst *CI,
bool RetEnd,
847 N = SizeC->getZExtValue();
854 Type *CharTy =
B.getInt8Ty();
855 Value *CharVal =
B.CreateLoad(CharTy, Src,
"stxncpy.char0");
856 B.CreateStore(CharVal, Dst);
862 Value *ZeroChar = ConstantInt::get(CharTy, 0);
863 Value *
Cmp =
B.CreateICmpEQ(CharVal, ZeroChar,
"stpncpy.char0cmp");
865 Value *Off1 =
B.getInt32(1);
866 Value *EndPtr =
B.CreateInBoundsGEP(CharTy, Dst, Off1,
"stpncpy.end");
867 return B.CreateSelect(Cmp, Dst, EndPtr,
"stpncpy.sel");
883 CallInst *NewCI =
B.CreateMemSet(Dst,
B.getInt8(
'\0'),
Size, MemSetAlign);
891 if (
N > SrcLen + 1) {
900 std::string SrcStr = Str.str();
903 SrcStr.resize(
N,
'\0');
904 Src =
B.CreateGlobalString(
920 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
927 Type *CharTy =
B.getIntNTy(CharSize);
937 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
942 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
943 if (BoundCst->isZero())
945 return ConstantInt::get(CI->
getType(), 0);
947 if (BoundCst->isOne()) {
949 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
950 Value *ZeroChar = ConstantInt::get(CharTy, 0);
951 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
952 return B.CreateZExt(Cmp, CI->
getType());
962 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
986 if (Slice.
Array ==
nullptr) {
1005 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
1012 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
1013 NullTermIdx == ArrSize - 1)) {
1015 return B.CreateSub(ConstantInt::get(CI->
getType(), NullTermIdx),
1022 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
1025 if (LenTrue && LenFalse) {
1028 <<
"folded strlen(select) to select of constants";
1030 return B.CreateSelect(
SI->getCondition(),
1031 ConstantInt::get(CI->
getType(), LenTrue - 1),
1032 ConstantInt::get(CI->
getType(), LenFalse - 1));
1040 if (
Value *V = optimizeStringLength(CI,
B, 8))
1048 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1063 return optimizeStringLength(CI,
B, WCharSize);
1073 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1077 if (HasS1 && HasS2) {
1078 size_t I =
S1.find_first_of(S2);
1083 B.getInt64(
I),
"strpbrk");
1087 if (HasS2 && S2.
size() == 1)
1095 if (isa<ConstantPointerNull>(EndPtr)) {
1111 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1115 if (HasS1 && HasS2) {
1116 size_t Pos =
S1.find_first_not_of(S2);
1119 return ConstantInt::get(CI->
getType(), Pos);
1131 if (HasS1 &&
S1.empty())
1135 if (HasS1 && HasS2) {
1136 size_t Pos =
S1.find_first_of(S2);
1139 return ConstantInt::get(CI->
getType(), Pos);
1143 if (HasS2 && S2.
empty())
1160 StrLen,
B, DL, TLI);
1168 replaceAllUsesWith(Old, Cmp);
1179 if (HasStr2 && ToFindStr.
empty())
1183 if (HasStr1 && HasStr2) {
1190 return B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), CI->
getArgOperand(0),
1195 if (HasStr2 && ToFindStr.
size() == 1) {
1216 if (LenC->
isOne()) {
1219 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1221 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1222 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1223 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1231 if (Str.size() == 0)
1240 if (Str.size() < EndOff)
1245 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1255 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1257 if (Str.find(Str[Pos]) == Pos) {
1264 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1265 B.getInt64(Pos),
"memrchr.ptr_plus");
1266 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1271 Str = Str.substr(0, EndOff);
1279 Type *Int8Ty =
B.getInt8Ty();
1280 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1282 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1283 Value *CEqS0 =
B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1284 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1285 Value *SizeM1 =
B.CreateSub(
Size, ConstantInt::get(SizeTy, 1));
1287 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1288 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1302 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1311 if (LenC->
isOne()) {
1314 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1316 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1317 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1318 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1338 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1340 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1343 if (Str.size() == 0)
1352 size_t Pos = Str.find_first_not_of(Str[0]);
1365 Type *Int8Ty =
B.getInt8Ty();
1368 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1370 Value *Sel1 = NullPtr;
1373 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1374 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1375 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1377 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1378 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1379 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1382 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1383 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1384 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1386 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1417 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1418 reinterpret_cast<const unsigned char *
>(Str.end()));
1431 std::string SortedStr = Str.str();
1434 unsigned NonContRanges = 1;
1435 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1436 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1443 if (NonContRanges > 2)
1447 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1450 for (
unsigned char C : SortedStr)
1451 CharCompares.
push_back(
B.CreateICmpEQ(CharVal,
B.getInt8(
C)));
1453 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1458 unsigned char Width =
NextPowerOf2(std::max((
unsigned char)7, Max));
1468 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1475 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1476 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1480 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1505 if (Pos == MinSize ||
1506 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1514 if (LStr[Pos] != RStr[Pos])
1519 typedef unsigned char UChar;
1520 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1521 Value *MaxSize = ConstantInt::get(
Size->getType(), Pos);
1524 return B.CreateSelect(Cmp, Zero, Res);
1536 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1538 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1540 return B.CreateSub(LHSV, RHSV,
"chardiff");
1548 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1551 Value *LHSV =
nullptr;
1552 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1555 Value *RHSV =
nullptr;
1556 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1564 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1566 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1567 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1575Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1595 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1613 return optimizeMemCmpBCmpCommon(CI,
B);
1619 if (isa<IntrinsicInst>(CI))
1639 if (
N->isNullValue())
1652 if (
N->getZExtValue() <= SrcStr.
size()) {
1661 ConstantInt::get(
N->getType(), std::min(
uint64_t(Pos + 1),
N->getZExtValue()));
1664 return Pos + 1 <=
N->getZExtValue()
1665 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1679 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1685 if (isa<IntrinsicInst>(CI))
1698 if (isa<IntrinsicInst>(CI))
1744 case LibFunc_Znwm12__hot_cold_t:
1747 LibFunc_Znwm12__hot_cold_t, HotCold);
1752 LibFunc_Znwm12__hot_cold_t, HotCold);
1754 case LibFunc_Znam12__hot_cold_t:
1757 LibFunc_Znam12__hot_cold_t, HotCold);
1762 LibFunc_Znam12__hot_cold_t, HotCold);
1764 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1768 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1770 case LibFunc_ZnwmRKSt9nothrow_t:
1774 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1776 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1780 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1782 case LibFunc_ZnamRKSt9nothrow_t:
1786 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1788 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1792 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1794 case LibFunc_ZnwmSt11align_val_t:
1798 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1800 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1804 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1806 case LibFunc_ZnamSt11align_val_t:
1810 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1812 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1817 LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1819 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1824 LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1826 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1831 LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1833 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1838 LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1840 case LibFunc_size_returning_new:
1844 LibFunc_size_returning_new_hot_cold, HotCold);
1846 case LibFunc_size_returning_new_hot_cold:
1850 LibFunc_size_returning_new_hot_cold, HotCold);
1852 case LibFunc_size_returning_new_aligned:
1857 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1859 case LibFunc_size_returning_new_aligned_hot_cold:
1864 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1890 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1891 Value *
Op = Cast->getOperand(0);
1892 if (
Op->getType()->isFloatTy())
1895 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1901 return ConstantFP::get(Const->getContext(),
F);
1909 bool isPrecise =
false) {
1940 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1941 CallerName.
size() == (CalleeName.
size() + 1) &&
1954 R =
isBinary ?
B.CreateIntrinsic(IID,
B.getFloatTy(), V)
1955 :
B.CreateIntrinsic(IID,
B.getFloatTy(), V[0]);
1962 return B.CreateFPExt(R,
B.getDoubleTy());
1968 bool isPrecise =
false) {
1975 bool isPrecise =
false) {
1989 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1991 Real =
B.CreateExtractValue(
Op, 0,
"real");
1992 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
2002 Value *AbsOp =
nullptr;
2003 if (
ConstantFP *ConstReal = dyn_cast<ConstantFP>(Real)) {
2004 if (ConstReal->isZero())
2007 }
else if (
ConstantFP *ConstImag = dyn_cast<ConstantFP>(Imag)) {
2008 if (ConstImag->isZero())
2017 *CI,
B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp,
nullptr,
"cabs"));
2028 Value *RealReal =
B.CreateFMul(Real, Real);
2029 Value *ImagImag =
B.CreateFMul(Imag, Imag);
2031 return copyFlags(*CI,
B.CreateUnaryIntrinsic(Intrinsic::sqrt,
2032 B.CreateFAdd(RealReal, ImagImag),
2039 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
2040 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
2043 unsigned BitWidth =
Op->getType()->getScalarSizeInBits();
2044 if (
BitWidth < DstWidth || (
BitWidth == DstWidth && isa<SIToFPInst>(I2F))) {
2045 Type *IntTy =
Op->getType()->getWithNewBitWidth(DstWidth);
2046 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op, IntTy)
2047 :
B.CreateZExt(
Op, IntTy);
2088 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2096 ExpName = TLI->
getName(LibFunc_exp);
2097 ID = Intrinsic::exp;
2098 LibFnFloat = LibFunc_expf;
2099 LibFnDouble = LibFunc_exp;
2100 LibFnLongDouble = LibFunc_expl;
2105 ExpName = TLI->
getName(LibFunc_exp2);
2106 ID = Intrinsic::exp2;
2107 LibFnFloat = LibFunc_exp2f;
2108 LibFnDouble = LibFunc_exp2;
2109 LibFnLongDouble = LibFunc_exp2l;
2116 ?
B.CreateUnaryIntrinsic(
ID,
FMul,
nullptr, ExpName)
2125 substituteInParent(BaseFn, ExpFn);
2142 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2144 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2149 Constant *One = ConstantFP::get(Ty, 1.0);
2152 return copyFlags(*Pow,
B.CreateIntrinsic(Intrinsic::ldexp,
2153 {Ty, ExpoI->getType()},
2154 {One, ExpoI}, Pow,
"exp2"));
2158 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2159 LibFunc_ldexpl,
B, NoAttrs));
2164 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2167 BaseR = BaseR / *BaseF;
2169 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2171 if ((IsInteger || IsReciprocal) &&
2174 NI > 1 && NI.isPowerOf2()) {
2175 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2176 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2178 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2183 LibFunc_exp2l,
B, NoAttrs));
2189 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l)) {
2193 B.CreateIntrinsic(Intrinsic::exp10, {Ty}, {Expo}, Pow,
"exp10");
2198 LibFunc_exp10f, LibFunc_exp10l,
2208 "pow(1.0, y) should have been simplified earlier!");
2210 Value *Log =
nullptr;
2217 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2219 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2221 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2225 LibFunc_exp2l,
B, NoAttrs));
2237 return B.CreateUnaryIntrinsic(Intrinsic::sqrt, V,
nullptr,
"sqrt");
2240 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2246 LibFunc_sqrtl,
B, Attrs);
2283 Sqrt =
B.CreateUnaryIntrinsic(Intrinsic::fabs, Sqrt,
nullptr,
"abs");
2292 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2293 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2298 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2307 return B.CreateIntrinsic(Intrinsic::powi, Types, Args);
2329 if (
Value *Exp = replacePowWithExp(Pow,
B))
2336 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2340 return ConstantFP::get(Ty, 1.0);
2348 return B.CreateFMul(
Base,
Base,
"square");
2350 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2361 Value *Sqrt =
nullptr;
2362 if (!ExpoA.isInteger()) {
2376 if (!ExpoI.isInteger())
2399 return B.CreateFMul(PowI, Sqrt);
2406 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2413 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2414 hasFloatVersion(M,
Name)) {
2427 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2428 hasFloatVersion(M,
Name))
2437 const bool UseIntrinsic =
Callee->isIntrinsic();
2446 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2448 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2450 Constant *One = ConstantFP::get(Ty, 1.0);
2453 return copyFlags(*CI,
B.CreateIntrinsic(Intrinsic::ldexp,
2454 {Ty, Exp->getType()},
2461 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2476 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2490 B.setFastMathFlags(FMF);
2493 : Intrinsic::maxnum;
2505 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2509 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2515 LogID = Intrinsic::log;
2516 ExpLb = LibFunc_expf;
2517 Exp2Lb = LibFunc_exp2f;
2518 Exp10Lb = LibFunc_exp10f;
2519 PowLb = LibFunc_powf;
2522 LogID = Intrinsic::log;
2523 ExpLb = LibFunc_exp;
2524 Exp2Lb = LibFunc_exp2;
2525 Exp10Lb = LibFunc_exp10;
2526 PowLb = LibFunc_pow;
2529 LogID = Intrinsic::log;
2530 ExpLb = LibFunc_expl;
2531 Exp2Lb = LibFunc_exp2l;
2532 Exp10Lb = LibFunc_exp10l;
2533 PowLb = LibFunc_powl;
2536 LogID = Intrinsic::log2;
2537 ExpLb = LibFunc_expf;
2538 Exp2Lb = LibFunc_exp2f;
2539 Exp10Lb = LibFunc_exp10f;
2540 PowLb = LibFunc_powf;
2543 LogID = Intrinsic::log2;
2544 ExpLb = LibFunc_exp;
2545 Exp2Lb = LibFunc_exp2;
2546 Exp10Lb = LibFunc_exp10;
2547 PowLb = LibFunc_pow;
2550 LogID = Intrinsic::log2;
2551 ExpLb = LibFunc_expl;
2552 Exp2Lb = LibFunc_exp2l;
2553 Exp10Lb = LibFunc_exp10l;
2554 PowLb = LibFunc_powl;
2556 case LibFunc_log10f:
2557 LogID = Intrinsic::log10;
2558 ExpLb = LibFunc_expf;
2559 Exp2Lb = LibFunc_exp2f;
2560 Exp10Lb = LibFunc_exp10f;
2561 PowLb = LibFunc_powf;
2564 LogID = Intrinsic::log10;
2565 ExpLb = LibFunc_exp;
2566 Exp2Lb = LibFunc_exp2;
2567 Exp10Lb = LibFunc_exp10;
2568 PowLb = LibFunc_pow;
2570 case LibFunc_log10l:
2571 LogID = Intrinsic::log10;
2572 ExpLb = LibFunc_expl;
2573 Exp2Lb = LibFunc_exp2l;
2574 Exp10Lb = LibFunc_exp10l;
2575 PowLb = LibFunc_powl;
2583 if (!IsKnownNoErrno) {
2593 if (IsKnownNoErrno) {
2594 auto *NewLog =
B.CreateUnaryIntrinsic(LogID, Log->
getArgOperand(0), Log);
2595 NewLog->copyMetadata(*Log);
2598 }
else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2599 LogID == Intrinsic::log10) {
2601 ExpLb = LibFunc_expf;
2602 Exp2Lb = LibFunc_exp2f;
2603 Exp10Lb = LibFunc_exp10f;
2604 PowLb = LibFunc_powf;
2606 ExpLb = LibFunc_exp;
2607 Exp2Lb = LibFunc_exp2;
2608 Exp10Lb = LibFunc_exp10;
2609 PowLb = LibFunc_pow;
2629 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2632 ?
B.CreateUnaryIntrinsic(LogID, Arg->
getOperand(0),
nullptr,
"log")
2636 if (ArgID == Intrinsic::powi)
2637 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2638 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2641 substituteInParent(Arg, MulY);
2647 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2648 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2650 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2653 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2654 Eul = ConstantFP::get(Log->
getType(), 2.0);
2656 Eul = ConstantFP::get(Log->
getType(), 10.0);
2658 ?
B.CreateUnaryIntrinsic(LogID, Eul,
nullptr,
"log")
2663 substituteInParent(Arg, MulY);
2683 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2688 ExpLb = LibFunc_expf;
2689 Exp2Lb = LibFunc_exp2f;
2690 Exp10Lb = LibFunc_exp10f;
2693 ExpLb = LibFunc_exp;
2694 Exp2Lb = LibFunc_exp2;
2695 Exp10Lb = LibFunc_exp10;
2698 ExpLb = LibFunc_expl;
2699 Exp2Lb = LibFunc_exp2l;
2700 Exp10Lb = LibFunc_exp10l;
2707 ExpLb = LibFunc_expf;
2708 Exp2Lb = LibFunc_exp2f;
2709 Exp10Lb = LibFunc_exp10f;
2711 ExpLb = LibFunc_exp;
2712 Exp2Lb = LibFunc_exp2;
2713 Exp10Lb = LibFunc_exp10;
2719 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2720 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2724 B.SetInsertPoint(Arg);
2727 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2742 (
Callee->getName() ==
"sqrt" ||
2743 Callee->getIntrinsicID() == Intrinsic::sqrt))
2746 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2753 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2759 Value *Op0 =
I->getOperand(0);
2760 Value *Op1 =
I->getOperand(1);
2761 Value *RepeatOp =
nullptr;
2762 Value *OtherOp =
nullptr;
2774 cast<Instruction>(Op0)->isFast()) {
2779 cast<Instruction>(Op1)->isFast()) {
2791 B.setFastMathFlags(
I->getFastMathFlags());
2796 B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp,
nullptr,
"fabs");
2802 B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp,
nullptr,
"sqrt");
2803 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2829 if (
auto *FRemI = dyn_cast<Instruction>(FRem))
2830 FRemI->setHasNoNaNs(
true);
2836Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2842 if (UnsafeFPShrink &&
2845 hasFloatVersion(M,
Name))
2849 auto *OpC = dyn_cast<CallInst>(Op1);
2854 if (!CI->
isFast() || !OpC->isFast())
2867 .
Case(
"tan", LibFunc_atan)
2868 .
Case(
"atanh", LibFunc_tanh)
2869 .
Case(
"sinh", LibFunc_asinh)
2870 .
Case(
"cosh", LibFunc_acosh)
2871 .
Case(
"tanf", LibFunc_atanf)
2872 .
Case(
"atanhf", LibFunc_tanhf)
2873 .
Case(
"sinhf", LibFunc_asinhf)
2874 .
Case(
"coshf", LibFunc_acoshf)
2875 .
Case(
"tanl", LibFunc_atanl)
2876 .
Case(
"atanhl", LibFunc_tanhl)
2877 .
Case(
"sinhl", LibFunc_asinhl)
2878 .
Case(
"coshl", LibFunc_acoshl)
2879 .
Case(
"asinh", LibFunc_sinh)
2880 .
Case(
"asinhf", LibFunc_sinhf)
2881 .
Case(
"asinhl", LibFunc_sinhl)
2883 if (Func == inverseFunc)
2884 Ret = OpC->getArgOperand(0);
2906 Name =
"__sincospif_stret";
2915 Name =
"__sincospi_stret";
2924 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2926 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2929 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2933 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2934 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2937 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2940 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2941 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2943 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2945 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
3027 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
3033 Value *Sin, *Cos, *SinCos;
3041 replaceAllUsesWith(
C, Res);
3044 replaceTrigInsts(SinCalls, Sin);
3045 replaceTrigInsts(CosCalls, Cos);
3046 replaceTrigInsts(SinCosCalls, SinCos);
3048 return IsSin ? Sin : Cos;
3051void LibCallSimplifier::classifyArgUse(
3056 auto *CI = dyn_cast<CallInst>(Val);
3067 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
3073 if (Func == LibFunc_sinpif)
3075 else if (Func == LibFunc_cospif)
3077 else if (Func == LibFunc_sincospif_stret)
3080 if (Func == LibFunc_sinpi)
3082 else if (Func == LibFunc_cospi)
3084 else if (Func == LibFunc_sincospi_stret)
3107 APSInt QuotInt(IntBW,
false);
3114 B.CreateAlignedStore(
3115 ConstantInt::get(
B.getIntNTy(IntBW), QuotInt.getExtValue()),
3117 return ConstantFP::get(CI->
getType(), Rem);
3144 return ConstantFP::get(CI->
getType(), MaxVal);
3156 Type *ArgType =
Op->getType();
3157 Value *
V =
B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {
Op,
B.getTrue()},
3159 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3160 V =
B.CreateIntCast(V, RetType,
false);
3163 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3170 Type *ArgType =
Op->getType();
3171 Value *
V =
B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {
Op,
B.getFalse()},
3175 return B.CreateIntCast(V, CI->
getType(),
false);
3182 Value *IsNeg =
B.CreateIsNeg(
X);
3183 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3184 return B.CreateSelect(IsNeg, NegX,
X);
3190 Type *ArgType =
Op->getType();
3191 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3192 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3199 Type *ArgType =
Op->getType();
3200 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3207 ConstantInt::get(CI->
getType(), 0x7F));
3225 if (isa<ConstantPointerNull>(EndPtr)) {
3238 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3270 if (!Callee || !Callee->isDeclaration())
3279 if (StreamArg >= (
int)CI->
arg_size())
3287 return GV->
getName() ==
"stderr";
3297 if (FormatStr.
empty())
3308 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3312 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3317 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3322 if (OperandStr.
empty())
3325 if (OperandStr.
size() == 1) {
3329 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3333 if (OperandStr.
back() ==
'\n') {
3335 Value *GV =
B.CreateGlobalString(OperandStr,
"str",
3343 if (FormatStr.
back() ==
'\n' &&
3348 Value *GV =
B.CreateGlobalString(FormatStr,
"str",
3355 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3364 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3375 if (
Value *V = optimizePrintFString(CI,
B)) {
3386 Callee->getAttributes());
3388 New->setCalledFunction(IPrintFFn);
3398 Callee->getAttributes());
3400 New->setCalledFunction(SmallPrintFFn);
3408Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3427 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3432 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3436 if (FormatStr[1] ==
'c') {
3442 B.CreateStore(V,
Ptr);
3443 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3444 B.CreateStore(
B.getInt8(0),
Ptr);
3446 return ConstantInt::get(CI->
getType(), 1);
3449 if (FormatStr[1] ==
's') {
3464 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3467 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3468 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3479 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3483 return B.CreateIntCast(Len, CI->
getType(),
false);
3492 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3503 FT,
Callee->getAttributes());
3505 New->setCalledFunction(SIPrintFFn);
3515 Callee->getAttributes());
3517 New->setCalledFunction(SmallSPrintFFn);
3533 assert(StrArg || (
N < 2 && Str.size() == 1));
3537 if (Str.size() > IntMax)
3543 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3553 NCopy = Str.size() + 1;
3558 if (NCopy && StrArg)
3569 Type *Int8Ty =
B.getInt8Ty();
3570 Value *NulOff =
B.getIntN(IntBits, NCopy);
3571 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3572 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3576Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3605 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3610 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3614 if (FormatStr[1] ==
'c') {
3620 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3628 B.CreateStore(V,
Ptr);
3629 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3630 B.CreateStore(
B.getInt8(0),
Ptr);
3631 return ConstantInt::get(CI->
getType(), 1);
3634 if (FormatStr[1] !=
's')
3643 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3647 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3656Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3658 optimizeErrorReporting(CI,
B, 0);
3685 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3689 if (FormatStr[1] ==
'c') {
3699 if (FormatStr[1] ==
's') {
3713 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3722 FT,
Callee->getAttributes());
3724 New->setCalledFunction(FIPrintFFn);
3733 auto SmallFPrintFFn =
3735 Callee->getAttributes());
3737 New->setCalledFunction(SmallFPrintFFn);
3746 optimizeErrorReporting(CI,
B, 3);
3751 if (SizeC && CountC) {
3756 return ConstantInt::get(CI->
getType(), 0);
3763 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3765 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3773 optimizeErrorReporting(CI,
B, 1);
3796 ConstantInt::get(SizeTTy, Len - 1),
3836bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3838 FloatFuncName +=
'f';
3842Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3854 "Optimizing string/memory libcall would change the calling convention");
3856 case LibFunc_strcat:
3857 return optimizeStrCat(CI, Builder);
3858 case LibFunc_strncat:
3859 return optimizeStrNCat(CI, Builder);
3860 case LibFunc_strchr:
3861 return optimizeStrChr(CI, Builder);
3862 case LibFunc_strrchr:
3863 return optimizeStrRChr(CI, Builder);
3864 case LibFunc_strcmp:
3865 return optimizeStrCmp(CI, Builder);
3866 case LibFunc_strncmp:
3867 return optimizeStrNCmp(CI, Builder);
3868 case LibFunc_strcpy:
3869 return optimizeStrCpy(CI, Builder);
3870 case LibFunc_stpcpy:
3871 return optimizeStpCpy(CI, Builder);
3872 case LibFunc_strlcpy:
3873 return optimizeStrLCpy(CI, Builder);
3874 case LibFunc_stpncpy:
3875 return optimizeStringNCpy(CI,
true, Builder);
3876 case LibFunc_strncpy:
3877 return optimizeStringNCpy(CI,
false, Builder);
3878 case LibFunc_strlen:
3879 return optimizeStrLen(CI, Builder);
3880 case LibFunc_strnlen:
3881 return optimizeStrNLen(CI, Builder);
3882 case LibFunc_strpbrk:
3883 return optimizeStrPBrk(CI, Builder);
3884 case LibFunc_strndup:
3885 return optimizeStrNDup(CI, Builder);
3886 case LibFunc_strtol:
3887 case LibFunc_strtod:
3888 case LibFunc_strtof:
3889 case LibFunc_strtoul:
3890 case LibFunc_strtoll:
3891 case LibFunc_strtold:
3892 case LibFunc_strtoull:
3893 return optimizeStrTo(CI, Builder);
3894 case LibFunc_strspn:
3895 return optimizeStrSpn(CI, Builder);
3896 case LibFunc_strcspn:
3897 return optimizeStrCSpn(CI, Builder);
3898 case LibFunc_strstr:
3899 return optimizeStrStr(CI, Builder);
3900 case LibFunc_memchr:
3901 return optimizeMemChr(CI, Builder);
3902 case LibFunc_memrchr:
3903 return optimizeMemRChr(CI, Builder);
3905 return optimizeBCmp(CI, Builder);
3906 case LibFunc_memcmp:
3907 return optimizeMemCmp(CI, Builder);
3908 case LibFunc_memcpy:
3909 return optimizeMemCpy(CI, Builder);
3910 case LibFunc_memccpy:
3911 return optimizeMemCCpy(CI, Builder);
3912 case LibFunc_mempcpy:
3913 return optimizeMemPCpy(CI, Builder);
3914 case LibFunc_memmove:
3915 return optimizeMemMove(CI, Builder);
3916 case LibFunc_memset:
3917 return optimizeMemSet(CI, Builder);
3918 case LibFunc_realloc:
3919 return optimizeRealloc(CI, Builder);
3920 case LibFunc_wcslen:
3921 return optimizeWcslen(CI, Builder);
3923 return optimizeBCopy(CI, Builder);
3925 case LibFunc_ZnwmRKSt9nothrow_t:
3926 case LibFunc_ZnwmSt11align_val_t:
3927 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3929 case LibFunc_ZnamRKSt9nothrow_t:
3930 case LibFunc_ZnamSt11align_val_t:
3931 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3932 case LibFunc_Znwm12__hot_cold_t:
3933 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3934 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3935 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3936 case LibFunc_Znam12__hot_cold_t:
3937 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3938 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3939 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3940 case LibFunc_size_returning_new:
3941 case LibFunc_size_returning_new_hot_cold:
3942 case LibFunc_size_returning_new_aligned:
3943 case LibFunc_size_returning_new_aligned_hot_cold:
3944 return optimizeNew(CI, Builder, Func);
3960 if (CharSeq.
empty())
3961 Fill =
APInt(32, 0);
3968Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3977 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3981 case LibFunc_sinpif:
3983 return optimizeSinCosPi(CI,
true, Builder);
3984 case LibFunc_cospif:
3986 return optimizeSinCosPi(CI,
false, Builder);
3990 return optimizePow(CI, Builder);
3994 return optimizeExp2(CI, Builder);
4002 return optimizeSqrt(CI, Builder);
4006 return optimizeFMod(CI, Builder);
4010 case LibFunc_log10f:
4012 case LibFunc_log10l:
4013 case LibFunc_log1pf:
4015 case LibFunc_log1pl:
4022 return optimizeLog(CI, Builder);
4030 case LibFunc_asinhf:
4031 case LibFunc_asinhl:
4036 case LibFunc_atanhf:
4037 case LibFunc_atanhl:
4038 return optimizeTrigInversionPairs(CI, Builder);
4045 case LibFunc_roundeven:
4047 case LibFunc_nearbyint:
4067 case LibFunc_copysign:
4074 return optimizeFdim(CI, Builder);
4081 return optimizeFMinFMax(CI, Builder);
4085 return optimizeCAbs(CI, Builder);
4086 case LibFunc_remquo:
4087 case LibFunc_remquof:
4088 case LibFunc_remquol:
4089 return optimizeRemquo(CI, Builder);
4124 else if (isa<FPMathOperator>(CI) && CI->
isFast())
4125 UnsafeFPShrink =
true;
4129 if (!IsCallingConvC)
4133 switch (
II->getIntrinsicID()) {
4134 case Intrinsic::pow:
4135 return optimizePow(CI, Builder);
4136 case Intrinsic::exp2:
4137 return optimizeExp2(CI, Builder);
4138 case Intrinsic::log:
4139 case Intrinsic::log2:
4140 case Intrinsic::log10:
4141 return optimizeLog(CI, Builder);
4142 case Intrinsic::sqrt:
4143 return optimizeSqrt(CI, Builder);
4144 case Intrinsic::memset:
4145 return optimizeMemSet(CI, Builder);
4146 case Intrinsic::memcpy:
4147 return optimizeMemCpy(CI, Builder);
4148 case Intrinsic::memmove:
4149 return optimizeMemMove(CI, Builder);
4156 if (
Value *SimplifiedFortifiedCI =
4158 return SimplifiedFortifiedCI;
4165 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
4167 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4173 return optimizeFFS(CI, Builder);
4177 return optimizeFls(CI, Builder);
4181 return optimizeAbs(CI, Builder);
4182 case LibFunc_isdigit:
4183 return optimizeIsDigit(CI, Builder);
4184 case LibFunc_isascii:
4185 return optimizeIsAscii(CI, Builder);
4186 case LibFunc_toascii:
4187 return optimizeToAscii(CI, Builder);
4191 return optimizeAtoi(CI, Builder);
4192 case LibFunc_strtol:
4193 case LibFunc_strtoll:
4194 return optimizeStrToInt(CI, Builder,
true);
4195 case LibFunc_strtoul:
4196 case LibFunc_strtoull:
4197 return optimizeStrToInt(CI, Builder,
false);
4198 case LibFunc_printf:
4199 return optimizePrintF(CI, Builder);
4200 case LibFunc_sprintf:
4201 return optimizeSPrintF(CI, Builder);
4202 case LibFunc_snprintf:
4203 return optimizeSnPrintF(CI, Builder);
4204 case LibFunc_fprintf:
4205 return optimizeFPrintF(CI, Builder);
4206 case LibFunc_fwrite:
4207 return optimizeFWrite(CI, Builder);
4209 return optimizeFPuts(CI, Builder);
4211 return optimizePuts(CI, Builder);
4212 case LibFunc_perror:
4213 return optimizeErrorReporting(CI, Builder);
4214 case LibFunc_vfprintf:
4215 case LibFunc_fiprintf:
4216 return optimizeErrorReporting(CI, Builder, 0);
4219 return optimizeExit(CI);
4233 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), DT(DT), DC(DC), AC(AC),
4234 ORE(ORE), BFI(BFI), PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4241void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4280bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4281 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4282 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4287 if (!Flag || !
Flag->isZero())
4296 if (ObjSizeCI->isMinusOne())
4299 if (OnlyLowerUnknownSize)
4309 return ObjSizeCI->getZExtValue() >=
Len;
4315 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4321Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4323 if (isFortifiedCallFoldable(CI, 3, 2)) {
4333Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4335 if (isFortifiedCallFoldable(CI, 3, 2)) {
4345Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4347 if (isFortifiedCallFoldable(CI, 3, 2)) {
4357Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4360 if (isFortifiedCallFoldable(CI, 3, 2))
4368Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4376 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4378 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4386 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4387 if (Func == LibFunc_strcpy_chk)
4393 if (OnlyLowerUnknownSize)
4405 Value *LenV = ConstantInt::get(SizeTTy, Len);
4409 if (Ret && Func == LibFunc_stpcpy_chk)
4410 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4411 ConstantInt::get(SizeTTy, Len - 1));
4412 return copyFlags(*CI, cast<CallInst>(Ret));
4415Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4417 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4423Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4426 if (isFortifiedCallFoldable(CI, 3, 2)) {
4427 if (Func == LibFunc_strncpy_chk)
4440Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4442 if (isFortifiedCallFoldable(CI, 4, 3))
4450Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4452 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4462Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4464 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4468 VariadicArgs,
B, TLI));
4474Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4476 if (isFortifiedCallFoldable(CI, 2))
4483Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4485 if (isFortifiedCallFoldable(CI, 3))
4493Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4495 if (isFortifiedCallFoldable(CI, 3))
4503Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4505 if (isFortifiedCallFoldable(CI, 3))
4513Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4515 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4523Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4525 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4568 case LibFunc_memcpy_chk:
4569 return optimizeMemCpyChk(CI, Builder);
4570 case LibFunc_mempcpy_chk:
4571 return optimizeMemPCpyChk(CI, Builder);
4572 case LibFunc_memmove_chk:
4573 return optimizeMemMoveChk(CI, Builder);
4574 case LibFunc_memset_chk:
4575 return optimizeMemSetChk(CI, Builder);
4576 case LibFunc_stpcpy_chk:
4577 case LibFunc_strcpy_chk:
4578 return optimizeStrpCpyChk(CI, Builder, Func);
4579 case LibFunc_strlen_chk:
4580 return optimizeStrLenChk(CI, Builder);
4581 case LibFunc_stpncpy_chk:
4582 case LibFunc_strncpy_chk:
4583 return optimizeStrpNCpyChk(CI, Builder, Func);
4584 case LibFunc_memccpy_chk:
4585 return optimizeMemCCpyChk(CI, Builder);
4586 case LibFunc_snprintf_chk:
4587 return optimizeSNPrintfChk(CI, Builder);
4588 case LibFunc_sprintf_chk:
4589 return optimizeSPrintfChk(CI, Builder);
4590 case LibFunc_strcat_chk:
4591 return optimizeStrCatChk(CI, Builder);
4592 case LibFunc_strlcat_chk:
4593 return optimizeStrLCat(CI, Builder);
4594 case LibFunc_strncat_chk:
4595 return optimizeStrNCatChk(CI, Builder);
4596 case LibFunc_strlcpy_chk:
4597 return optimizeStrLCpyChk(CI, Builder);
4598 case LibFunc_vsnprintf_chk:
4599 return optimizeVSNPrintfChk(CI, Builder);
4600 case LibFunc_vsprintf_chk:
4601 return optimizeVSPrintfChk(CI, Builder);
4610 : 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)
opStatus subtract(const APFloat &RHS, roundingMode RM)
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
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
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 removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove)
Removes the attributes from the given argument.
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.
AttributeSet getParamAttributes(unsigned ArgNo) const
Return the param attributes for this call.
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).
AttributeSet getRetAttributes() const
Return the return attributes for this call.
void setAttributes(AttributeList A)
Set the 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 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.
unsigned getDefaultGlobalsAddressSpace() const
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
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...
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.
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, DominatorTree *DT, DomConditionCache *DC, AssumptionCache *AC, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
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.
ConstantInt * getAsSizeT(uint64_t V, const Module &M) const
Returns a constant materialized as a size_t type.
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
Type * getStructElementType(unsigned N) const
const fltSemantics & getFltSemantics() 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, AttributeSet AS, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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 * emitHotColdNewNoThrow(Type *RetTy, Value *Num, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
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.
Value * emitMalloc(Type *RetTy, Value *Num, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the malloc function.
bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI)
Value * emitHotColdSizeReturningNew(Type *RetTy, Value *Num, 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.
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
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 * emitHotColdNew(Type *RetTy, Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Emit a call to the hot/cold operator new function.
Value * emitHotColdNewAlignedNoThrow(Type *RetTy, Value *Num, Value *Align, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
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 * emitHotColdSizeReturningNewAligned(Type *RetTy, Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
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
@ NearestTiesToEven
roundTiesToEven.
constexpr unsigned BitWidth
Value * emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memchr function.
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.
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 * 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.
KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, unsigned Depth, const SimplifyQuery &SQ)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
Value * emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the mempcpy function.
Value * emitHotColdNewAligned(Type *RetTy, Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
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.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
static constexpr FPClassTest OrderedLessThanZeroMask
bool isKnownNeverLogicalZero(const Function &F, Type *Ty) const
Return true if it's know this can never be interpreted as a zero.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.