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(SrcStr,
"str", 0,
919 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
926 Type *CharTy =
B.getIntNTy(CharSize);
936 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
941 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
942 if (BoundCst->isZero())
944 return ConstantInt::get(CI->
getType(), 0);
946 if (BoundCst->isOne()) {
948 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
949 Value *ZeroChar = ConstantInt::get(CharTy, 0);
950 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
951 return B.CreateZExt(Cmp, CI->
getType());
961 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
985 if (Slice.
Array ==
nullptr) {
1004 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
1011 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
1012 NullTermIdx == ArrSize - 1)) {
1014 return B.CreateSub(ConstantInt::get(CI->
getType(), NullTermIdx),
1021 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
1024 if (LenTrue && LenFalse) {
1027 <<
"folded strlen(select) to select of constants";
1029 return B.CreateSelect(
SI->getCondition(),
1030 ConstantInt::get(CI->
getType(), LenTrue - 1),
1031 ConstantInt::get(CI->
getType(), LenFalse - 1));
1039 if (
Value *V = optimizeStringLength(CI,
B, 8))
1047 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1062 return optimizeStringLength(CI,
B, WCharSize);
1072 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1076 if (HasS1 && HasS2) {
1077 size_t I =
S1.find_first_of(S2);
1082 B.getInt64(
I),
"strpbrk");
1086 if (HasS2 && S2.
size() == 1)
1094 if (isa<ConstantPointerNull>(EndPtr)) {
1110 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1114 if (HasS1 && HasS2) {
1115 size_t Pos =
S1.find_first_not_of(S2);
1118 return ConstantInt::get(CI->
getType(), Pos);
1130 if (HasS1 &&
S1.empty())
1134 if (HasS1 && HasS2) {
1135 size_t Pos =
S1.find_first_of(S2);
1138 return ConstantInt::get(CI->
getType(), Pos);
1142 if (HasS2 && S2.
empty())
1159 StrLen,
B, DL, TLI);
1167 replaceAllUsesWith(Old, Cmp);
1178 if (HasStr2 && ToFindStr.
empty())
1182 if (HasStr1 && HasStr2) {
1189 return B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), CI->
getArgOperand(0),
1194 if (HasStr2 && ToFindStr.
size() == 1) {
1215 if (LenC->
isOne()) {
1218 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1220 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1221 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1222 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1230 if (Str.size() == 0)
1239 if (Str.size() < EndOff)
1244 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1254 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1256 if (Str.find(Str[Pos]) == Pos) {
1263 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1264 B.getInt64(Pos),
"memrchr.ptr_plus");
1265 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1270 Str = Str.substr(0, EndOff);
1278 Type *Int8Ty =
B.getInt8Ty();
1279 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1281 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1282 Value *CEqS0 =
B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1283 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1284 Value *SizeM1 =
B.CreateSub(
Size, ConstantInt::get(SizeTy, 1));
1286 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1287 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1301 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1310 if (LenC->
isOne()) {
1313 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1315 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1316 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1317 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1337 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1339 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1342 if (Str.size() == 0)
1351 size_t Pos = Str.find_first_not_of(Str[0]);
1364 Type *Int8Ty =
B.getInt8Ty();
1367 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1369 Value *Sel1 = NullPtr;
1372 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1373 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1374 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1376 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1377 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1378 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1381 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1382 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1383 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1385 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1416 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1417 reinterpret_cast<const unsigned char *
>(Str.end()));
1430 std::string SortedStr = Str.str();
1433 unsigned NonContRanges = 1;
1434 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1435 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1442 if (NonContRanges > 2)
1446 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1449 for (
unsigned char C : SortedStr)
1450 CharCompares.
push_back(
B.CreateICmpEQ(CharVal,
B.getInt8(
C)));
1452 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1457 unsigned char Width =
NextPowerOf2(std::max((
unsigned char)7, Max));
1467 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1474 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1475 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1479 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1504 if (Pos == MinSize ||
1505 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1513 if (LStr[Pos] != RStr[Pos])
1518 typedef unsigned char UChar;
1519 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1520 Value *MaxSize = ConstantInt::get(
Size->getType(), Pos);
1523 return B.CreateSelect(Cmp, Zero, Res);
1535 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1537 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1539 return B.CreateSub(LHSV, RHSV,
"chardiff");
1547 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1550 Value *LHSV =
nullptr;
1551 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1554 Value *RHSV =
nullptr;
1555 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1563 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1565 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1566 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1574Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1594 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1612 return optimizeMemCmpBCmpCommon(CI,
B);
1618 if (isa<IntrinsicInst>(CI))
1638 if (
N->isNullValue())
1651 if (
N->getZExtValue() <= SrcStr.
size()) {
1660 ConstantInt::get(
N->getType(), std::min(
uint64_t(Pos + 1),
N->getZExtValue()));
1663 return Pos + 1 <=
N->getZExtValue()
1664 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1678 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1684 if (isa<IntrinsicInst>(CI))
1697 if (isa<IntrinsicInst>(CI))
1742 case LibFunc_Znwm12__hot_cold_t:
1745 LibFunc_Znwm12__hot_cold_t, HotCold);
1750 LibFunc_Znwm12__hot_cold_t, HotCold);
1752 case LibFunc_Znam12__hot_cold_t:
1755 LibFunc_Znam12__hot_cold_t, HotCold);
1760 LibFunc_Znam12__hot_cold_t, HotCold);
1762 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1766 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1768 case LibFunc_ZnwmRKSt9nothrow_t:
1772 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1774 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1778 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1780 case LibFunc_ZnamRKSt9nothrow_t:
1784 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1786 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1790 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1792 case LibFunc_ZnwmSt11align_val_t:
1796 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1798 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1802 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1804 case LibFunc_ZnamSt11align_val_t:
1808 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1810 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1814 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1817 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1821 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1824 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1828 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1831 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1835 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1838 case LibFunc_size_returning_new:
1841 LibFunc_size_returning_new_hot_cold,
1844 case LibFunc_size_returning_new_hot_cold:
1847 LibFunc_size_returning_new_hot_cold,
1850 case LibFunc_size_returning_new_aligned:
1854 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1856 case LibFunc_size_returning_new_aligned_hot_cold:
1860 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1886 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1887 Value *
Op = Cast->getOperand(0);
1888 if (
Op->getType()->isFloatTy())
1891 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1897 return ConstantFP::get(Const->getContext(),
F);
1905 bool isPrecise =
false) {
1936 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1937 CallerName.
size() == (CalleeName.
size() + 1) &&
1950 R =
isBinary ?
B.CreateIntrinsic(IID,
B.getFloatTy(), V)
1951 :
B.CreateIntrinsic(IID,
B.getFloatTy(), V[0]);
1958 return B.CreateFPExt(R,
B.getDoubleTy());
1964 bool isPrecise =
false) {
1971 bool isPrecise =
false) {
1985 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1987 Real =
B.CreateExtractValue(
Op, 0,
"real");
1988 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
1998 Value *AbsOp =
nullptr;
1999 if (
ConstantFP *ConstReal = dyn_cast<ConstantFP>(Real)) {
2000 if (ConstReal->isZero())
2003 }
else if (
ConstantFP *ConstImag = dyn_cast<ConstantFP>(Imag)) {
2004 if (ConstImag->isZero())
2013 *CI,
B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp,
nullptr,
"cabs"));
2024 Value *RealReal =
B.CreateFMul(Real, Real);
2025 Value *ImagImag =
B.CreateFMul(Imag, Imag);
2027 return copyFlags(*CI,
B.CreateUnaryIntrinsic(Intrinsic::sqrt,
2028 B.CreateFAdd(RealReal, ImagImag),
2035 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
2036 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
2039 unsigned BitWidth =
Op->getType()->getScalarSizeInBits();
2040 if (
BitWidth < DstWidth || (
BitWidth == DstWidth && isa<SIToFPInst>(I2F))) {
2041 Type *IntTy =
Op->getType()->getWithNewBitWidth(DstWidth);
2042 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op, IntTy)
2043 :
B.CreateZExt(
Op, IntTy);
2084 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2092 ExpName = TLI->
getName(LibFunc_exp);
2093 ID = Intrinsic::exp;
2094 LibFnFloat = LibFunc_expf;
2095 LibFnDouble = LibFunc_exp;
2096 LibFnLongDouble = LibFunc_expl;
2101 ExpName = TLI->
getName(LibFunc_exp2);
2102 ID = Intrinsic::exp2;
2103 LibFnFloat = LibFunc_exp2f;
2104 LibFnDouble = LibFunc_exp2;
2105 LibFnLongDouble = LibFunc_exp2l;
2112 ?
B.CreateUnaryIntrinsic(
ID,
FMul,
nullptr, ExpName)
2121 substituteInParent(BaseFn, ExpFn);
2138 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2140 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2145 Constant *One = ConstantFP::get(Ty, 1.0);
2148 return copyFlags(*Pow,
B.CreateIntrinsic(Intrinsic::ldexp,
2149 {Ty, ExpoI->getType()},
2150 {One, ExpoI}, Pow,
"exp2"));
2154 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2155 LibFunc_ldexpl,
B, NoAttrs));
2160 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2163 BaseR = BaseR / *BaseF;
2165 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2167 if ((IsInteger || IsReciprocal) &&
2170 NI > 1 && NI.isPowerOf2()) {
2171 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2172 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2174 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2179 LibFunc_exp2l,
B, NoAttrs));
2185 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l)) {
2189 B.CreateIntrinsic(Intrinsic::exp10, {Ty}, {Expo}, Pow,
"exp10");
2194 LibFunc_exp10f, LibFunc_exp10l,
2204 "pow(1.0, y) should have been simplified earlier!");
2206 Value *Log =
nullptr;
2213 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2215 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2217 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2221 LibFunc_exp2l,
B, NoAttrs));
2233 return B.CreateUnaryIntrinsic(Intrinsic::sqrt, V,
nullptr,
"sqrt");
2236 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2242 LibFunc_sqrtl,
B, Attrs);
2279 Sqrt =
B.CreateUnaryIntrinsic(Intrinsic::fabs, Sqrt,
nullptr,
"abs");
2288 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2289 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2294 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2303 return B.CreateIntrinsic(Intrinsic::powi, Types, Args);
2325 if (
Value *Exp = replacePowWithExp(Pow,
B))
2332 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2336 return ConstantFP::get(Ty, 1.0);
2344 return B.CreateFMul(
Base,
Base,
"square");
2346 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2357 Value *Sqrt =
nullptr;
2358 if (!ExpoA.isInteger()) {
2372 if (!ExpoI.isInteger())
2395 return B.CreateFMul(PowI, Sqrt);
2402 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2409 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2410 hasFloatVersion(M,
Name)) {
2423 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2424 hasFloatVersion(M,
Name))
2433 const bool UseIntrinsic =
Callee->isIntrinsic();
2442 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2444 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2446 Constant *One = ConstantFP::get(Ty, 1.0);
2449 return copyFlags(*CI,
B.CreateIntrinsic(Intrinsic::ldexp,
2450 {Ty, Exp->getType()},
2457 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2472 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2486 B.setFastMathFlags(FMF);
2489 : Intrinsic::maxnum;
2501 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2505 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2511 LogID = Intrinsic::log;
2512 ExpLb = LibFunc_expf;
2513 Exp2Lb = LibFunc_exp2f;
2514 Exp10Lb = LibFunc_exp10f;
2515 PowLb = LibFunc_powf;
2518 LogID = Intrinsic::log;
2519 ExpLb = LibFunc_exp;
2520 Exp2Lb = LibFunc_exp2;
2521 Exp10Lb = LibFunc_exp10;
2522 PowLb = LibFunc_pow;
2525 LogID = Intrinsic::log;
2526 ExpLb = LibFunc_expl;
2527 Exp2Lb = LibFunc_exp2l;
2528 Exp10Lb = LibFunc_exp10l;
2529 PowLb = LibFunc_powl;
2532 LogID = Intrinsic::log2;
2533 ExpLb = LibFunc_expf;
2534 Exp2Lb = LibFunc_exp2f;
2535 Exp10Lb = LibFunc_exp10f;
2536 PowLb = LibFunc_powf;
2539 LogID = Intrinsic::log2;
2540 ExpLb = LibFunc_exp;
2541 Exp2Lb = LibFunc_exp2;
2542 Exp10Lb = LibFunc_exp10;
2543 PowLb = LibFunc_pow;
2546 LogID = Intrinsic::log2;
2547 ExpLb = LibFunc_expl;
2548 Exp2Lb = LibFunc_exp2l;
2549 Exp10Lb = LibFunc_exp10l;
2550 PowLb = LibFunc_powl;
2552 case LibFunc_log10f:
2553 LogID = Intrinsic::log10;
2554 ExpLb = LibFunc_expf;
2555 Exp2Lb = LibFunc_exp2f;
2556 Exp10Lb = LibFunc_exp10f;
2557 PowLb = LibFunc_powf;
2560 LogID = Intrinsic::log10;
2561 ExpLb = LibFunc_exp;
2562 Exp2Lb = LibFunc_exp2;
2563 Exp10Lb = LibFunc_exp10;
2564 PowLb = LibFunc_pow;
2566 case LibFunc_log10l:
2567 LogID = Intrinsic::log10;
2568 ExpLb = LibFunc_expl;
2569 Exp2Lb = LibFunc_exp2l;
2570 Exp10Lb = LibFunc_exp10l;
2571 PowLb = LibFunc_powl;
2579 if (!IsKnownNoErrno) {
2589 if (IsKnownNoErrno) {
2590 auto *NewLog =
B.CreateUnaryIntrinsic(LogID, Log->
getArgOperand(0), Log);
2591 NewLog->copyMetadata(*Log);
2594 }
else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2595 LogID == Intrinsic::log10) {
2597 ExpLb = LibFunc_expf;
2598 Exp2Lb = LibFunc_exp2f;
2599 Exp10Lb = LibFunc_exp10f;
2600 PowLb = LibFunc_powf;
2602 ExpLb = LibFunc_exp;
2603 Exp2Lb = LibFunc_exp2;
2604 Exp10Lb = LibFunc_exp10;
2605 PowLb = LibFunc_pow;
2625 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2628 ?
B.CreateUnaryIntrinsic(LogID, Arg->
getOperand(0),
nullptr,
"log")
2632 if (ArgID == Intrinsic::powi)
2633 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2634 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2637 substituteInParent(Arg, MulY);
2643 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2644 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2646 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2649 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2650 Eul = ConstantFP::get(Log->
getType(), 2.0);
2652 Eul = ConstantFP::get(Log->
getType(), 10.0);
2654 ?
B.CreateUnaryIntrinsic(LogID, Eul,
nullptr,
"log")
2659 substituteInParent(Arg, MulY);
2679 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2684 ExpLb = LibFunc_expf;
2685 Exp2Lb = LibFunc_exp2f;
2686 Exp10Lb = LibFunc_exp10f;
2689 ExpLb = LibFunc_exp;
2690 Exp2Lb = LibFunc_exp2;
2691 Exp10Lb = LibFunc_exp10;
2694 ExpLb = LibFunc_expl;
2695 Exp2Lb = LibFunc_exp2l;
2696 Exp10Lb = LibFunc_exp10l;
2703 ExpLb = LibFunc_expf;
2704 Exp2Lb = LibFunc_exp2f;
2705 Exp10Lb = LibFunc_exp10f;
2707 ExpLb = LibFunc_exp;
2708 Exp2Lb = LibFunc_exp2;
2709 Exp10Lb = LibFunc_exp10;
2715 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2716 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2720 B.SetInsertPoint(Arg);
2723 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2738 (
Callee->getName() ==
"sqrt" ||
2739 Callee->getIntrinsicID() == Intrinsic::sqrt))
2742 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2749 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2755 Value *Op0 =
I->getOperand(0);
2756 Value *Op1 =
I->getOperand(1);
2757 Value *RepeatOp =
nullptr;
2758 Value *OtherOp =
nullptr;
2770 cast<Instruction>(Op0)->isFast()) {
2775 cast<Instruction>(Op1)->isFast()) {
2787 B.setFastMathFlags(
I->getFastMathFlags());
2792 B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp,
nullptr,
"fabs");
2798 B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp,
nullptr,
"sqrt");
2799 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2825 if (
auto *FRemI = dyn_cast<Instruction>(FRem))
2826 FRemI->setHasNoNaNs(
true);
2832Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2838 if (UnsafeFPShrink &&
2841 hasFloatVersion(M,
Name))
2845 auto *OpC = dyn_cast<CallInst>(Op1);
2850 if (!CI->
isFast() || !OpC->isFast())
2863 .
Case(
"tan", LibFunc_atan)
2864 .
Case(
"atanh", LibFunc_tanh)
2865 .
Case(
"sinh", LibFunc_asinh)
2866 .
Case(
"cosh", LibFunc_acosh)
2867 .
Case(
"tanf", LibFunc_atanf)
2868 .
Case(
"atanhf", LibFunc_tanhf)
2869 .
Case(
"sinhf", LibFunc_asinhf)
2870 .
Case(
"coshf", LibFunc_acoshf)
2871 .
Case(
"tanl", LibFunc_atanl)
2872 .
Case(
"atanhl", LibFunc_tanhl)
2873 .
Case(
"sinhl", LibFunc_asinhl)
2874 .
Case(
"coshl", LibFunc_acoshl)
2875 .
Case(
"asinh", LibFunc_sinh)
2876 .
Case(
"asinhf", LibFunc_sinhf)
2877 .
Case(
"asinhl", LibFunc_sinhl)
2879 if (Func == inverseFunc)
2880 Ret = OpC->getArgOperand(0);
2902 Name =
"__sincospif_stret";
2911 Name =
"__sincospi_stret";
2920 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2922 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2925 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2929 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2930 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2933 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2936 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2937 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2939 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2941 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
3023 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
3029 Value *Sin, *Cos, *SinCos;
3037 replaceAllUsesWith(
C, Res);
3040 replaceTrigInsts(SinCalls, Sin);
3041 replaceTrigInsts(CosCalls, Cos);
3042 replaceTrigInsts(SinCosCalls, SinCos);
3044 return IsSin ? Sin : Cos;
3047void LibCallSimplifier::classifyArgUse(
3052 auto *CI = dyn_cast<CallInst>(Val);
3063 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
3069 if (Func == LibFunc_sinpif)
3071 else if (Func == LibFunc_cospif)
3073 else if (Func == LibFunc_sincospif_stret)
3076 if (Func == LibFunc_sinpi)
3078 else if (Func == LibFunc_cospi)
3080 else if (Func == LibFunc_sincospi_stret)
3103 APSInt QuotInt(IntBW,
false);
3110 B.CreateAlignedStore(
3111 ConstantInt::get(
B.getIntNTy(IntBW), QuotInt.getExtValue()),
3113 return ConstantFP::get(CI->
getType(), Rem);
3140 return ConstantFP::get(CI->
getType(), MaxVal);
3152 Type *ArgType =
Op->getType();
3153 Value *
V =
B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {
Op,
B.getTrue()},
3155 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3156 V =
B.CreateIntCast(V, RetType,
false);
3159 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3166 Type *ArgType =
Op->getType();
3167 Value *
V =
B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {
Op,
B.getFalse()},
3171 return B.CreateIntCast(V, CI->
getType(),
false);
3178 Value *IsNeg =
B.CreateIsNeg(
X);
3179 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3180 return B.CreateSelect(IsNeg, NegX,
X);
3186 Type *ArgType =
Op->getType();
3187 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3188 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3195 Type *ArgType =
Op->getType();
3196 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3203 ConstantInt::get(CI->
getType(), 0x7F));
3221 if (isa<ConstantPointerNull>(EndPtr)) {
3234 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3266 if (!Callee || !Callee->isDeclaration())
3275 if (StreamArg >= (
int)CI->
arg_size())
3283 return GV->
getName() ==
"stderr";
3293 if (FormatStr.
empty())
3304 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3308 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3313 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3318 if (OperandStr.
empty())
3321 if (OperandStr.
size() == 1) {
3325 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3329 if (OperandStr.
back() ==
'\n') {
3331 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3338 if (FormatStr.
back() ==
'\n' &&
3343 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3349 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3358 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3369 if (
Value *V = optimizePrintFString(CI,
B)) {
3380 Callee->getAttributes());
3382 New->setCalledFunction(IPrintFFn);
3392 Callee->getAttributes());
3394 New->setCalledFunction(SmallPrintFFn);
3402Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3421 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3426 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3430 if (FormatStr[1] ==
'c') {
3436 B.CreateStore(V,
Ptr);
3437 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3438 B.CreateStore(
B.getInt8(0),
Ptr);
3440 return ConstantInt::get(CI->
getType(), 1);
3443 if (FormatStr[1] ==
's') {
3458 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3461 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3462 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3473 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3477 return B.CreateIntCast(Len, CI->
getType(),
false);
3486 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3497 FT,
Callee->getAttributes());
3499 New->setCalledFunction(SIPrintFFn);
3509 Callee->getAttributes());
3511 New->setCalledFunction(SmallSPrintFFn);
3527 assert(StrArg || (
N < 2 && Str.size() == 1));
3531 if (Str.size() > IntMax)
3537 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3547 NCopy = Str.size() + 1;
3552 if (NCopy && StrArg)
3563 Type *Int8Ty =
B.getInt8Ty();
3564 Value *NulOff =
B.getIntN(IntBits, NCopy);
3565 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3566 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3570Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3599 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3604 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3608 if (FormatStr[1] ==
'c') {
3614 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3622 B.CreateStore(V,
Ptr);
3623 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3624 B.CreateStore(
B.getInt8(0),
Ptr);
3625 return ConstantInt::get(CI->
getType(), 1);
3628 if (FormatStr[1] !=
's')
3637 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3641 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3650Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3652 optimizeErrorReporting(CI,
B, 0);
3679 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3683 if (FormatStr[1] ==
'c') {
3693 if (FormatStr[1] ==
's') {
3707 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3716 FT,
Callee->getAttributes());
3718 New->setCalledFunction(FIPrintFFn);
3727 auto SmallFPrintFFn =
3729 Callee->getAttributes());
3731 New->setCalledFunction(SmallFPrintFFn);
3740 optimizeErrorReporting(CI,
B, 3);
3745 if (SizeC && CountC) {
3750 return ConstantInt::get(CI->
getType(), 0);
3757 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3759 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3767 optimizeErrorReporting(CI,
B, 1);
3790 ConstantInt::get(SizeTTy, Len - 1),
3830bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3832 FloatFuncName +=
'f';
3836Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3848 "Optimizing string/memory libcall would change the calling convention");
3850 case LibFunc_strcat:
3851 return optimizeStrCat(CI, Builder);
3852 case LibFunc_strncat:
3853 return optimizeStrNCat(CI, Builder);
3854 case LibFunc_strchr:
3855 return optimizeStrChr(CI, Builder);
3856 case LibFunc_strrchr:
3857 return optimizeStrRChr(CI, Builder);
3858 case LibFunc_strcmp:
3859 return optimizeStrCmp(CI, Builder);
3860 case LibFunc_strncmp:
3861 return optimizeStrNCmp(CI, Builder);
3862 case LibFunc_strcpy:
3863 return optimizeStrCpy(CI, Builder);
3864 case LibFunc_stpcpy:
3865 return optimizeStpCpy(CI, Builder);
3866 case LibFunc_strlcpy:
3867 return optimizeStrLCpy(CI, Builder);
3868 case LibFunc_stpncpy:
3869 return optimizeStringNCpy(CI,
true, Builder);
3870 case LibFunc_strncpy:
3871 return optimizeStringNCpy(CI,
false, Builder);
3872 case LibFunc_strlen:
3873 return optimizeStrLen(CI, Builder);
3874 case LibFunc_strnlen:
3875 return optimizeStrNLen(CI, Builder);
3876 case LibFunc_strpbrk:
3877 return optimizeStrPBrk(CI, Builder);
3878 case LibFunc_strndup:
3879 return optimizeStrNDup(CI, Builder);
3880 case LibFunc_strtol:
3881 case LibFunc_strtod:
3882 case LibFunc_strtof:
3883 case LibFunc_strtoul:
3884 case LibFunc_strtoll:
3885 case LibFunc_strtold:
3886 case LibFunc_strtoull:
3887 return optimizeStrTo(CI, Builder);
3888 case LibFunc_strspn:
3889 return optimizeStrSpn(CI, Builder);
3890 case LibFunc_strcspn:
3891 return optimizeStrCSpn(CI, Builder);
3892 case LibFunc_strstr:
3893 return optimizeStrStr(CI, Builder);
3894 case LibFunc_memchr:
3895 return optimizeMemChr(CI, Builder);
3896 case LibFunc_memrchr:
3897 return optimizeMemRChr(CI, Builder);
3899 return optimizeBCmp(CI, Builder);
3900 case LibFunc_memcmp:
3901 return optimizeMemCmp(CI, Builder);
3902 case LibFunc_memcpy:
3903 return optimizeMemCpy(CI, Builder);
3904 case LibFunc_memccpy:
3905 return optimizeMemCCpy(CI, Builder);
3906 case LibFunc_mempcpy:
3907 return optimizeMemPCpy(CI, Builder);
3908 case LibFunc_memmove:
3909 return optimizeMemMove(CI, Builder);
3910 case LibFunc_memset:
3911 return optimizeMemSet(CI, Builder);
3912 case LibFunc_realloc:
3913 return optimizeRealloc(CI, Builder);
3914 case LibFunc_wcslen:
3915 return optimizeWcslen(CI, Builder);
3917 return optimizeBCopy(CI, Builder);
3919 case LibFunc_ZnwmRKSt9nothrow_t:
3920 case LibFunc_ZnwmSt11align_val_t:
3921 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3923 case LibFunc_ZnamRKSt9nothrow_t:
3924 case LibFunc_ZnamSt11align_val_t:
3925 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3926 case LibFunc_Znwm12__hot_cold_t:
3927 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3928 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3929 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3930 case LibFunc_Znam12__hot_cold_t:
3931 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3932 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3933 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3934 case LibFunc_size_returning_new:
3935 case LibFunc_size_returning_new_hot_cold:
3936 case LibFunc_size_returning_new_aligned:
3937 case LibFunc_size_returning_new_aligned_hot_cold:
3938 return optimizeNew(CI, Builder, Func);
3954 if (CharSeq.
empty())
3955 Fill =
APInt(32, 0);
3962Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3971 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3975 case LibFunc_sinpif:
3977 return optimizeSinCosPi(CI,
true, Builder);
3978 case LibFunc_cospif:
3980 return optimizeSinCosPi(CI,
false, Builder);
3984 return optimizePow(CI, Builder);
3988 return optimizeExp2(CI, Builder);
3996 return optimizeSqrt(CI, Builder);
4000 return optimizeFMod(CI, Builder);
4004 case LibFunc_log10f:
4006 case LibFunc_log10l:
4007 case LibFunc_log1pf:
4009 case LibFunc_log1pl:
4016 return optimizeLog(CI, Builder);
4024 case LibFunc_asinhf:
4025 case LibFunc_asinhl:
4030 case LibFunc_atanhf:
4031 case LibFunc_atanhl:
4032 return optimizeTrigInversionPairs(CI, Builder);
4039 case LibFunc_roundeven:
4041 case LibFunc_nearbyint:
4061 case LibFunc_copysign:
4068 return optimizeFdim(CI, Builder);
4075 return optimizeFMinFMax(CI, Builder);
4079 return optimizeCAbs(CI, Builder);
4080 case LibFunc_remquo:
4081 case LibFunc_remquof:
4082 case LibFunc_remquol:
4083 return optimizeRemquo(CI, Builder);
4118 else if (isa<FPMathOperator>(CI) && CI->
isFast())
4119 UnsafeFPShrink =
true;
4123 if (!IsCallingConvC)
4127 switch (
II->getIntrinsicID()) {
4128 case Intrinsic::pow:
4129 return optimizePow(CI, Builder);
4130 case Intrinsic::exp2:
4131 return optimizeExp2(CI, Builder);
4132 case Intrinsic::log:
4133 case Intrinsic::log2:
4134 case Intrinsic::log10:
4135 return optimizeLog(CI, Builder);
4136 case Intrinsic::sqrt:
4137 return optimizeSqrt(CI, Builder);
4138 case Intrinsic::memset:
4139 return optimizeMemSet(CI, Builder);
4140 case Intrinsic::memcpy:
4141 return optimizeMemCpy(CI, Builder);
4142 case Intrinsic::memmove:
4143 return optimizeMemMove(CI, Builder);
4150 if (
Value *SimplifiedFortifiedCI =
4152 return SimplifiedFortifiedCI;
4159 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
4161 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4167 return optimizeFFS(CI, Builder);
4171 return optimizeFls(CI, Builder);
4175 return optimizeAbs(CI, Builder);
4176 case LibFunc_isdigit:
4177 return optimizeIsDigit(CI, Builder);
4178 case LibFunc_isascii:
4179 return optimizeIsAscii(CI, Builder);
4180 case LibFunc_toascii:
4181 return optimizeToAscii(CI, Builder);
4185 return optimizeAtoi(CI, Builder);
4186 case LibFunc_strtol:
4187 case LibFunc_strtoll:
4188 return optimizeStrToInt(CI, Builder,
true);
4189 case LibFunc_strtoul:
4190 case LibFunc_strtoull:
4191 return optimizeStrToInt(CI, Builder,
false);
4192 case LibFunc_printf:
4193 return optimizePrintF(CI, Builder);
4194 case LibFunc_sprintf:
4195 return optimizeSPrintF(CI, Builder);
4196 case LibFunc_snprintf:
4197 return optimizeSnPrintF(CI, Builder);
4198 case LibFunc_fprintf:
4199 return optimizeFPrintF(CI, Builder);
4200 case LibFunc_fwrite:
4201 return optimizeFWrite(CI, Builder);
4203 return optimizeFPuts(CI, Builder);
4205 return optimizePuts(CI, Builder);
4206 case LibFunc_perror:
4207 return optimizeErrorReporting(CI, Builder);
4208 case LibFunc_vfprintf:
4209 case LibFunc_fiprintf:
4210 return optimizeErrorReporting(CI, Builder, 0);
4213 return optimizeExit(CI);
4227 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), DT(DT), DC(DC), AC(AC),
4228 ORE(ORE), BFI(BFI), PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4235void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4274bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4275 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4276 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4281 if (!Flag || !
Flag->isZero())
4290 if (ObjSizeCI->isMinusOne())
4293 if (OnlyLowerUnknownSize)
4303 return ObjSizeCI->getZExtValue() >=
Len;
4309 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4315Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4317 if (isFortifiedCallFoldable(CI, 3, 2)) {
4327Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4329 if (isFortifiedCallFoldable(CI, 3, 2)) {
4339Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4341 if (isFortifiedCallFoldable(CI, 3, 2)) {
4351Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4354 if (isFortifiedCallFoldable(CI, 3, 2))
4362Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4370 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4372 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4380 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4381 if (Func == LibFunc_strcpy_chk)
4387 if (OnlyLowerUnknownSize)
4399 Value *LenV = ConstantInt::get(SizeTTy, Len);
4403 if (Ret && Func == LibFunc_stpcpy_chk)
4404 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4405 ConstantInt::get(SizeTTy, Len - 1));
4406 return copyFlags(*CI, cast<CallInst>(Ret));
4409Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4411 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4417Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4420 if (isFortifiedCallFoldable(CI, 3, 2)) {
4421 if (Func == LibFunc_strncpy_chk)
4434Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4436 if (isFortifiedCallFoldable(CI, 4, 3))
4444Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4446 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4456Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4458 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4462 VariadicArgs,
B, TLI));
4468Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4470 if (isFortifiedCallFoldable(CI, 2))
4477Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4479 if (isFortifiedCallFoldable(CI, 3))
4487Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4489 if (isFortifiedCallFoldable(CI, 3))
4497Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4499 if (isFortifiedCallFoldable(CI, 3))
4507Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4509 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4517Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4519 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4562 case LibFunc_memcpy_chk:
4563 return optimizeMemCpyChk(CI, Builder);
4564 case LibFunc_mempcpy_chk:
4565 return optimizeMemPCpyChk(CI, Builder);
4566 case LibFunc_memmove_chk:
4567 return optimizeMemMoveChk(CI, Builder);
4568 case LibFunc_memset_chk:
4569 return optimizeMemSetChk(CI, Builder);
4570 case LibFunc_stpcpy_chk:
4571 case LibFunc_strcpy_chk:
4572 return optimizeStrpCpyChk(CI, Builder, Func);
4573 case LibFunc_strlen_chk:
4574 return optimizeStrLenChk(CI, Builder);
4575 case LibFunc_stpncpy_chk:
4576 case LibFunc_strncpy_chk:
4577 return optimizeStrpNCpyChk(CI, Builder, Func);
4578 case LibFunc_memccpy_chk:
4579 return optimizeMemCCpyChk(CI, Builder);
4580 case LibFunc_snprintf_chk:
4581 return optimizeSNPrintfChk(CI, Builder);
4582 case LibFunc_sprintf_chk:
4583 return optimizeSPrintfChk(CI, Builder);
4584 case LibFunc_strcat_chk:
4585 return optimizeStrCatChk(CI, Builder);
4586 case LibFunc_strlcat_chk:
4587 return optimizeStrLCat(CI, Builder);
4588 case LibFunc_strncat_chk:
4589 return optimizeStrNCatChk(CI, Builder);
4590 case LibFunc_strlcpy_chk:
4591 return optimizeStrLCpyChk(CI, Builder);
4592 case LibFunc_vsnprintf_chk:
4593 return optimizeVSNPrintfChk(CI, Builder);
4594 case LibFunc_vsprintf_chk:
4595 return optimizeVSPrintfChk(CI, Builder);
4604 : 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.