41using namespace PatternMatch;
46 cl::desc(
"Enable unsafe double to float "
47 "shrinking for math lib calls"));
54 cl::desc(
"Enable hot/cold operator new library calls"));
61struct HotColdHintParser :
public cl::parser<unsigned> {
66 return O.error(
"'" + Arg +
"' value invalid for uint argument!");
69 return O.error(
"'" + Arg +
"' value must be in the range [0, 255]!");
83 cl::desc(
"Value to pass to hot/cold operator new for cold allocation"));
86 cl::desc(
"Value to pass to hot/cold operator new for hot allocation"));
93 return Func == LibFunc_abs || Func == LibFunc_labs ||
94 Func == LibFunc_llabs || Func == LibFunc_strlen;
99 for (
User *U : V->users()) {
100 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
101 if (IC->isEquality() && IC->getOperand(1) == With)
111 return OI->getType()->isFloatingPointTy();
117 return OI->getType()->isFP128Ty();
130 if (Base < 2 || Base > 36)
139 if (!isSpace((
unsigned char)Str[
Offset])) {
150 bool Negate = Str[0] ==
'-';
151 if (Str[0] ==
'-' || Str[0] ==
'+') {
152 Str = Str.drop_front();
162 unsigned NBits =
RetTy->getPrimitiveSizeInBits();
163 uint64_t Max = AsSigned && Negate ? 1 : 0;
167 if (Str.size() > 1) {
169 if (toUpper((
unsigned char)Str[1]) ==
'X') {
170 if (Str.size() == 2 || (
Base &&
Base != 16))
175 Str = Str.drop_front(2);
181 }
else if (
Base == 0)
191 for (
unsigned i = 0; i != Str.size(); ++i) {
192 unsigned char DigVal = Str[i];
194 DigVal = DigVal -
'0';
196 DigVal = toUpper(DigVal);
198 DigVal = DigVal -
'A' + 10;
211 if (VFlow || Result > Max)
219 Value *StrEnd =
B.CreateInBoundsGEP(
B.getInt8Ty(), StrBeg, Off,
"endptr");
220 B.CreateStore(StrEnd, EndPtr);
231 for (
User *U : V->users()) {
232 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
233 if (
Constant *
C = dyn_cast<Constant>(IC->getOperand(1)))
234 if (
C->isNullValue())
262 for (
unsigned ArgNo : ArgNos) {
263 uint64_t DerefBytes = DereferenceableBytes;
268 DereferenceableBytes);
287 for (
unsigned ArgNo : ArgNos) {
313 DerefMin = std::min(
X->getZExtValue(),
Y->getZExtValue());
327 if (
auto *NewCI = dyn_cast_or_null<CallInst>(New))
334 NewCI->
getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
341 return Len >= Str.size() ? Str : Str.substr(0, Len);
366 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
380 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
430 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
443 Type *CharTy =
B.getInt8Ty();
444 Value *Char0 =
B.CreateLoad(CharTy, Src);
445 CharVal =
B.CreateTrunc(CharVal, CharTy);
446 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
450 Value *
And =
B.CreateICmpNE(NBytes, Zero);
451 Cmp =
B.CreateLogicalAnd(
And, Cmp);
455 return B.CreateSelect(Cmp, Src, NullPtr);
468 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
479 if (!FT->getParamType(1)->isIntegerTy(IntBits))
495 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
504 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
517 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
523 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
529 if (CharC && CharC->
isZero())
554 if (HasStr1 && HasStr2)
556 std::clamp(Str1.
compare(Str2), -1, 1));
558 if (HasStr1 && Str1.
empty())
559 return B.CreateNeg(
B.CreateZExt(
560 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
562 if (HasStr2 && Str2.
empty())
563 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
578 std::min(Len1, Len2)),
583 if (!HasStr1 && HasStr2) {
590 }
else if (HasStr1 && !HasStr2) {
636 if (HasStr1 && HasStr2) {
641 std::clamp(SubStr1.
compare(SubStr2), -1, 1));
644 if (HasStr1 && Str1.
empty())
645 return B.CreateNeg(
B.CreateZExt(
646 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
648 if (HasStr2 && Str2.
empty())
649 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
660 if (!HasStr1 && HasStr2) {
661 Len2 = std::min(Len2,
Length);
668 }
else if (HasStr1 && !HasStr2) {
669 Len1 = std::min(Len1,
Length);
685 if (SrcLen &&
Size) {
687 if (SrcLen <= Size->getZExtValue() + 1)
726 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
736 Type *PT =
Callee->getFunctionType()->getParamType(0);
738 Value *DstEnd =
B.CreateInBoundsGEP(
762 NBytes = SizeC->getZExtValue();
771 B.CreateStore(
B.getInt8(0), Dst);
787 bool NulTerm = SrcLen < NBytes;
796 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
797 NBytes = std::min(NBytes - 1, SrcLen);
802 B.CreateStore(
B.getInt8(0), Dst);
807 Type *PT =
Callee->getFunctionType()->getParamType(0);
817 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
818 B.CreateStore(
B.getInt8(0), EndPtr);
829Value *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);
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");
907 Type *PT =
Callee->getFunctionType()->getParamType(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())
946 if (BoundCst->isOne()) {
948 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
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)) {
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(),
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) {
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) {
1130 if (HasS1 && S1.
empty())
1134 if (HasS1 && HasS2) {
1142 if (HasS2 && S2.
empty())
1159 StrLen,
B, DL, TLI);
1167 replaceAllUsesWith(Old, Cmp);
1178 if (HasStr2 && ToFindStr.
empty())
1182 if (HasStr1 && HasStr2) {
1191 B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), Result,
Offset,
"strstr");
1192 return B.CreateBitCast(Result, CI->
getType());
1196 if (HasStr2 && ToFindStr.
size() == 1) {
1198 return StrChr ?
B.CreateBitCast(StrChr, CI->
getType()) :
nullptr;
1218 if (LenC->
isOne()) {
1221 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1223 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1224 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1225 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1233 if (Str.size() == 0)
1242 if (Str.size() < EndOff)
1247 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1257 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1259 if (Str.find(Str[Pos]) == Pos) {
1266 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1267 B.getInt64(Pos),
"memrchr.ptr_plus");
1268 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1273 Str = Str.substr(0, EndOff);
1281 Type *Int8Ty =
B.getInt8Ty();
1284 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1286 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1289 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1290 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1304 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1313 if (LenC->
isOne()) {
1316 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1318 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1319 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1320 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1340 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1342 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1345 if (Str.size() == 0)
1354 size_t Pos = Str.find_first_not_of(Str[0]);
1367 Type *Int8Ty =
B.getInt8Ty();
1370 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1372 Value *Sel1 = NullPtr;
1377 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1379 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1380 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1381 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1385 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1388 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1420 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1421 reinterpret_cast<const unsigned char *
>(Str.end()));
1434 std::string SortedStr = Str.str();
1437 unsigned NonContRanges = 1;
1438 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1439 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1446 if (NonContRanges > 2)
1450 for (
unsigned char C : SortedStr)
1454 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1469 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1476 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1477 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1481 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1506 if (Pos == MinSize ||
1507 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1515 if (LStr[Pos] != RStr[Pos])
1520 typedef unsigned char UChar;
1521 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1525 return B.CreateSelect(Cmp, Zero, Res);
1537 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1539 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1541 return B.CreateSub(LHSV, RHSV,
"chardiff");
1549 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1552 Value *LHSV =
nullptr;
1553 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1556 Value *RHSV =
nullptr;
1557 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1565 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1567 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1568 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1576Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1596 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1614 return optimizeMemCmpBCmpCommon(CI,
B);
1620 if (isa<IntrinsicInst>(CI))
1640 if (
N->isNullValue())
1653 if (
N->getZExtValue() <= SrcStr.
size()) {
1665 return Pos + 1 <=
N->getZExtValue()
1666 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1680 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1686 if (isa<IntrinsicInst>(CI))
1699 if (isa<IntrinsicInst>(CI))
1736 LibFunc_Znwm12__hot_cold_t, HotCold);
1739 LibFunc_Znam12__hot_cold_t, HotCold);
1740 case LibFunc_ZnwmRKSt9nothrow_t:
1742 TLI, LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t,
1744 case LibFunc_ZnamRKSt9nothrow_t:
1746 TLI, LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t,
1748 case LibFunc_ZnwmSt11align_val_t:
1750 TLI, LibFunc_ZnwmSt11align_val_t12__hot_cold_t,
1752 case LibFunc_ZnamSt11align_val_t:
1754 TLI, LibFunc_ZnamSt11align_val_t12__hot_cold_t,
1756 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1759 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1760 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1763 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1794 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1795 Value *
Op = Cast->getOperand(0);
1796 if (
Op->getType()->isFloatTy())
1799 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1813 bool isPrecise =
false) {
1844 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1845 CallerName.
size() == (CalleeName.
size() + 1) &&
1860 R =
isBinary ?
B.CreateCall(Fn, V) :
B.CreateCall(Fn, V[0]);
1867 return B.CreateFPExt(R,
B.getDoubleTy());
1873 bool isPrecise =
false) {
1880 bool isPrecise =
false) {
1896 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1897 Real =
B.CreateExtractValue(
Op, 0,
"real");
1898 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
1905 Value *RealReal =
B.CreateFMul(Real, Real);
1906 Value *ImagImag =
B.CreateFMul(Imag, Imag);
1911 *CI,
B.CreateCall(FSqrt,
B.CreateFAdd(RealReal, ImagImag),
"cabs"));
1916 if (!isa<FPMathOperator>(Call))
1920 B.setFastMathFlags(Call->getFastMathFlags());
1934 return B.CreateFNeg(
1935 copyFlags(*Call,
B.CreateCall(Call->getCalledFunction(),
X)));
1943 B.CreateCall(Call->getCalledFunction(),
X,
"cos"));
1954 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
1955 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
1958 unsigned BitWidth =
Op->getType()->getPrimitiveSizeInBits();
1960 (
BitWidth == DstWidth && isa<SIToFPInst>(I2F)))
1961 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op,
B.getIntNTy(DstWidth))
1962 :
B.CreateZExt(
Op,
B.getIntNTy(DstWidth));
2003 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2011 ExpName = TLI->
getName(LibFunc_exp);
2012 ID = Intrinsic::exp;
2013 LibFnFloat = LibFunc_expf;
2014 LibFnDouble = LibFunc_exp;
2015 LibFnLongDouble = LibFunc_expl;
2020 ExpName = TLI->
getName(LibFunc_exp2);
2021 ID = Intrinsic::exp2;
2022 LibFnFloat = LibFunc_exp2f;
2023 LibFnDouble = LibFunc_exp2;
2024 LibFnLongDouble = LibFunc_exp2l;
2041 substituteInParent(BaseFn, ExpFn);
2057 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2058 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2062 TLI, LibFunc_ldexp, LibFunc_ldexpf,
2063 LibFunc_ldexpl,
B, NoAttrs));
2067 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2070 BaseR = BaseR / *BaseF;
2072 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2074 if ((IsInteger || IsReciprocal) &&
2077 NI > 1 && NI.isPowerOf2()) {
2078 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2082 Mod, Intrinsic::exp2, Ty),
2087 LibFunc_exp2l,
B, NoAttrs));
2094 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
2096 LibFunc_exp10f, LibFunc_exp10l,
2105 "pow(1.0, y) should have been simplified earlier!");
2107 Value *Log =
nullptr;
2114 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2117 Mod, Intrinsic::exp2, Ty),
2119 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2123 LibFunc_exp2l,
B, NoAttrs));
2137 return B.CreateCall(SqrtFn, V,
"sqrt");
2141 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2147 LibFunc_sqrtl,
B, Attrs);
2184 Sqrt =
B.CreateCall(FAbsFn, Sqrt,
"abs");
2194 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2195 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2210 return B.CreateCall(
F, Args);
2232 if (
Value *Exp = replacePowWithExp(Pow,
B))
2251 return B.CreateFMul(
Base,
Base,
"square");
2253 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2264 Value *Sqrt =
nullptr;
2265 if (!ExpoA.isInteger()) {
2279 if (!ExpoI.isInteger())
2302 return B.CreateFMul(PowI, Sqrt);
2309 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2316 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2317 hasFloatVersion(M,
Name)) {
2330 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2331 hasFloatVersion(M,
Name))
2343 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2344 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2350 LibFunc_ldexp, LibFunc_ldexpf,
2365 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2379 B.setFastMathFlags(FMF);
2382 : Intrinsic::maxnum;
2385 *CI,
B.CreateCall(
F, {CI->getArgOperand(0), CI->getArgOperand(1)}));
2396 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2404 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2410 LogID = Intrinsic::log;
2411 ExpLb = LibFunc_expf;
2412 Exp2Lb = LibFunc_exp2f;
2413 Exp10Lb = LibFunc_exp10f;
2414 PowLb = LibFunc_powf;
2417 LogID = Intrinsic::log;
2418 ExpLb = LibFunc_exp;
2419 Exp2Lb = LibFunc_exp2;
2420 Exp10Lb = LibFunc_exp10;
2421 PowLb = LibFunc_pow;
2424 LogID = Intrinsic::log;
2425 ExpLb = LibFunc_expl;
2426 Exp2Lb = LibFunc_exp2l;
2427 Exp10Lb = LibFunc_exp10l;
2428 PowLb = LibFunc_powl;
2431 LogID = Intrinsic::log2;
2432 ExpLb = LibFunc_expf;
2433 Exp2Lb = LibFunc_exp2f;
2434 Exp10Lb = LibFunc_exp10f;
2435 PowLb = LibFunc_powf;
2438 LogID = Intrinsic::log2;
2439 ExpLb = LibFunc_exp;
2440 Exp2Lb = LibFunc_exp2;
2441 Exp10Lb = LibFunc_exp10;
2442 PowLb = LibFunc_pow;
2445 LogID = Intrinsic::log2;
2446 ExpLb = LibFunc_expl;
2447 Exp2Lb = LibFunc_exp2l;
2448 Exp10Lb = LibFunc_exp10l;
2449 PowLb = LibFunc_powl;
2451 case LibFunc_log10f:
2452 LogID = Intrinsic::log10;
2453 ExpLb = LibFunc_expf;
2454 Exp2Lb = LibFunc_exp2f;
2455 Exp10Lb = LibFunc_exp10f;
2456 PowLb = LibFunc_powf;
2459 LogID = Intrinsic::log10;
2460 ExpLb = LibFunc_exp;
2461 Exp2Lb = LibFunc_exp2;
2462 Exp10Lb = LibFunc_exp10;
2463 PowLb = LibFunc_pow;
2465 case LibFunc_log10l:
2466 LogID = Intrinsic::log10;
2467 ExpLb = LibFunc_expl;
2468 Exp2Lb = LibFunc_exp2l;
2469 Exp10Lb = LibFunc_exp10l;
2470 PowLb = LibFunc_powl;
2475 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2476 LogID == Intrinsic::log10) {
2478 ExpLb = LibFunc_expf;
2479 Exp2Lb = LibFunc_exp2f;
2480 Exp10Lb = LibFunc_exp10f;
2481 PowLb = LibFunc_powf;
2483 ExpLb = LibFunc_exp;
2484 Exp2Lb = LibFunc_exp2;
2485 Exp10Lb = LibFunc_exp10;
2486 PowLb = LibFunc_pow;
2501 if (ArgLb == PowLb || ArgID == Intrinsic::pow) {
2510 substituteInParent(Arg, MulY);
2516 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2517 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2519 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2522 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2533 substituteInParent(Arg, MulY);
2548 (
Callee->getName() ==
"sqrt" ||
2549 Callee->getIntrinsicID() == Intrinsic::sqrt))
2556 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2562 Value *Op0 =
I->getOperand(0);
2563 Value *Op1 =
I->getOperand(1);
2564 Value *RepeatOp =
nullptr;
2565 Value *OtherOp =
nullptr;
2575 Value *OtherMul0, *OtherMul1;
2578 if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
2580 RepeatOp = OtherMul0;
2591 B.setFastMathFlags(
I->getFastMathFlags());
2595 Type *ArgType =
I->getType();
2597 Value *FabsCall =
B.CreateCall(Fabs, RepeatOp,
"fabs");
2603 Value *SqrtCall =
B.CreateCall(Sqrt, OtherOp,
"sqrt");
2604 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2615 if (UnsafeFPShrink &&
Name ==
"tan" && hasFloatVersion(M,
Name))
2619 auto *OpC = dyn_cast<CallInst>(Op1);
2624 if (!CI->
isFast() || !OpC->isFast())
2634 ((Func == LibFunc_atan &&
Callee->getName() ==
"tan") ||
2635 (Func == LibFunc_atanf &&
Callee->getName() ==
"tanf") ||
2636 (Func == LibFunc_atanl &&
Callee->getName() ==
"tanl")))
2637 Ret = OpC->getArgOperand(0);
2658 Name =
"__sincospif_stret";
2667 Name =
"__sincospi_stret";
2676 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2678 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2681 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2685 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2686 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2689 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2692 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2693 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2722 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2728 Value *Sin, *Cos, *SinCos;
2736 replaceAllUsesWith(
C, Res);
2739 replaceTrigInsts(SinCalls, Sin);
2740 replaceTrigInsts(CosCalls, Cos);
2741 replaceTrigInsts(SinCosCalls, SinCos);
2743 return IsSin ? Sin : Cos;
2746void LibCallSimplifier::classifyArgUse(
2751 auto *CI = dyn_cast<CallInst>(Val);
2762 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
2768 if (Func == LibFunc_sinpif)
2770 else if (Func == LibFunc_cospif)
2772 else if (Func == LibFunc_sincospif_stret)
2775 if (Func == LibFunc_sinpi)
2777 else if (Func == LibFunc_cospi)
2779 else if (Func == LibFunc_sincospi_stret)
2793 Type *ArgType =
Op->getType();
2795 Intrinsic::cttz, ArgType);
2796 Value *
V =
B.CreateCall(
F, {
Op,
B.getTrue()},
"cttz");
2798 V =
B.CreateIntCast(V, RetType,
false);
2808 Type *ArgType =
Op->getType();
2810 Intrinsic::ctlz, ArgType);
2811 Value *
V =
B.CreateCall(
F, {
Op,
B.getFalse()},
"ctlz");
2814 return B.CreateIntCast(V, CI->
getType(),
false);
2821 Value *IsNeg =
B.CreateIsNeg(
X);
2822 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
2823 return B.CreateSelect(IsNeg, NegX,
X);
2829 Type *ArgType =
Op->getType();
2838 Type *ArgType =
Op->getType();
2864 if (isa<ConstantPointerNull>(EndPtr)) {
2877 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
2909 if (!Callee || !Callee->isDeclaration())
2918 if (StreamArg >= (
int)CI->
arg_size())
2926 return GV->
getName() ==
"stderr";
2936 if (FormatStr.
empty())
2947 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
2956 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
2961 if (OperandStr.
empty())
2964 if (OperandStr.
size() == 1) {
2972 if (OperandStr.
back() ==
'\n') {
2974 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
2981 if (FormatStr.
back() ==
'\n' &&
2986 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
2992 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3001 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3012 if (
Value *V = optimizePrintFString(CI,
B)) {
3023 Callee->getAttributes());
3025 New->setCalledFunction(IPrintFFn);
3035 Callee->getAttributes());
3037 New->setCalledFunction(SmallPrintFFn);
3045Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3064 FormatStr.
size() + 1));
3070 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3074 if (FormatStr[1] ==
'c') {
3080 B.CreateStore(V,
Ptr);
3081 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3082 B.CreateStore(
B.getInt8(0),
Ptr);
3087 if (FormatStr[1] ==
's') {
3106 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3107 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3124 return B.CreateIntCast(Len, CI->
getType(),
false);
3133 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3144 FT,
Callee->getAttributes());
3146 New->setCalledFunction(SIPrintFFn);
3156 Callee->getAttributes());
3158 New->setCalledFunction(SmallSPrintFFn);
3174 assert(StrArg || (
N < 2 && Str.size() == 1));
3178 if (Str.size() > IntMax)
3194 NCopy = Str.size() + 1;
3199 if (NCopy && StrArg)
3213 Type *Int8Ty =
B.getInt8Ty();
3214 Value *NulOff =
B.getIntN(IntBits, NCopy);
3215 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3220Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3249 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3254 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3258 if (FormatStr[1] ==
'c') {
3264 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3272 B.CreateStore(V,
Ptr);
3273 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3274 B.CreateStore(
B.getInt8(0),
Ptr);
3278 if (FormatStr[1] !=
's')
3287 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3291 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3300Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3302 optimizeErrorReporting(CI,
B, 0);
3331 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3335 if (FormatStr[1] ==
'c') {
3345 if (FormatStr[1] ==
's') {
3359 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3368 FT,
Callee->getAttributes());
3370 New->setCalledFunction(FIPrintFFn);
3379 auto SmallFPrintFFn =
3381 Callee->getAttributes());
3383 New->setCalledFunction(SmallFPrintFFn);
3392 optimizeErrorReporting(CI,
B, 3);
3397 if (SizeC && CountC) {
3409 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3419 optimizeErrorReporting(CI,
B, 1);
3473bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3475 FloatFuncName +=
'f';
3479Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3490 "Optimizing string/memory libcall would change the calling convention");
3492 case LibFunc_strcat:
3493 return optimizeStrCat(CI, Builder);
3494 case LibFunc_strncat:
3495 return optimizeStrNCat(CI, Builder);
3496 case LibFunc_strchr:
3497 return optimizeStrChr(CI, Builder);
3498 case LibFunc_strrchr:
3499 return optimizeStrRChr(CI, Builder);
3500 case LibFunc_strcmp:
3501 return optimizeStrCmp(CI, Builder);
3502 case LibFunc_strncmp:
3503 return optimizeStrNCmp(CI, Builder);
3504 case LibFunc_strcpy:
3505 return optimizeStrCpy(CI, Builder);
3506 case LibFunc_stpcpy:
3507 return optimizeStpCpy(CI, Builder);
3508 case LibFunc_strlcpy:
3509 return optimizeStrLCpy(CI, Builder);
3510 case LibFunc_stpncpy:
3511 return optimizeStringNCpy(CI,
true, Builder);
3512 case LibFunc_strncpy:
3513 return optimizeStringNCpy(CI,
false, Builder);
3514 case LibFunc_strlen:
3515 return optimizeStrLen(CI, Builder);
3516 case LibFunc_strnlen:
3517 return optimizeStrNLen(CI, Builder);
3518 case LibFunc_strpbrk:
3519 return optimizeStrPBrk(CI, Builder);
3520 case LibFunc_strndup:
3521 return optimizeStrNDup(CI, Builder);
3522 case LibFunc_strtol:
3523 case LibFunc_strtod:
3524 case LibFunc_strtof:
3525 case LibFunc_strtoul:
3526 case LibFunc_strtoll:
3527 case LibFunc_strtold:
3528 case LibFunc_strtoull:
3529 return optimizeStrTo(CI, Builder);
3530 case LibFunc_strspn:
3531 return optimizeStrSpn(CI, Builder);
3532 case LibFunc_strcspn:
3533 return optimizeStrCSpn(CI, Builder);
3534 case LibFunc_strstr:
3535 return optimizeStrStr(CI, Builder);
3536 case LibFunc_memchr:
3537 return optimizeMemChr(CI, Builder);
3538 case LibFunc_memrchr:
3539 return optimizeMemRChr(CI, Builder);
3541 return optimizeBCmp(CI, Builder);
3542 case LibFunc_memcmp:
3543 return optimizeMemCmp(CI, Builder);
3544 case LibFunc_memcpy:
3545 return optimizeMemCpy(CI, Builder);
3546 case LibFunc_memccpy:
3547 return optimizeMemCCpy(CI, Builder);
3548 case LibFunc_mempcpy:
3549 return optimizeMemPCpy(CI, Builder);
3550 case LibFunc_memmove:
3551 return optimizeMemMove(CI, Builder);
3552 case LibFunc_memset:
3553 return optimizeMemSet(CI, Builder);
3554 case LibFunc_realloc:
3555 return optimizeRealloc(CI, Builder);
3556 case LibFunc_wcslen:
3557 return optimizeWcslen(CI, Builder);
3559 return optimizeBCopy(CI, Builder);
3561 case LibFunc_ZnwmRKSt9nothrow_t:
3562 case LibFunc_ZnwmSt11align_val_t:
3563 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3565 case LibFunc_ZnamRKSt9nothrow_t:
3566 case LibFunc_ZnamSt11align_val_t:
3567 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3568 return optimizeNew(CI, Builder, Func);
3576Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3589 case LibFunc_sinpif:
3591 return optimizeSinCosPi(CI,
true, Builder);
3592 case LibFunc_cospif:
3594 return optimizeSinCosPi(CI,
false, Builder);
3598 return optimizePow(CI, Builder);
3602 return optimizeExp2(CI, Builder);
3610 return optimizeSqrt(CI, Builder);
3614 case LibFunc_log10f:
3616 case LibFunc_log10l:
3617 case LibFunc_log1pf:
3619 case LibFunc_log1pl:
3626 return optimizeLog(CI, Builder);
3630 return optimizeTan(CI, Builder);
3637 case LibFunc_roundeven:
3639 case LibFunc_nearbyint:
3663 case LibFunc_copysign:
3673 return optimizeFMinFMax(CI, Builder);
3677 return optimizeCAbs(CI, Builder);
3701 Builder.setDefaultOperandBundles(OpBundles);
3708 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3709 UnsafeFPShrink =
true;
3713 if (!IsCallingConvC)
3717 switch (II->getIntrinsicID()) {
3718 case Intrinsic::pow:
3719 return optimizePow(CI,
Builder);
3720 case Intrinsic::exp2:
3721 return optimizeExp2(CI,
Builder);
3722 case Intrinsic::log:
3723 case Intrinsic::log2:
3724 case Intrinsic::log10:
3725 return optimizeLog(CI,
Builder);
3726 case Intrinsic::sqrt:
3727 return optimizeSqrt(CI,
Builder);
3728 case Intrinsic::memset:
3729 return optimizeMemSet(CI,
Builder);
3730 case Intrinsic::memcpy:
3731 return optimizeMemCpy(CI,
Builder);
3732 case Intrinsic::memmove:
3733 return optimizeMemMove(CI,
Builder);
3740 if (
Value *SimplifiedFortifiedCI =
3743 CallInst *SimplifiedCI = dyn_cast<CallInst>(SimplifiedFortifiedCI);
3747 replaceAllUsesWith(CI, SimplifiedCI);
3752 Builder.SetInsertPoint(SimplifiedCI);
3753 if (
Value *V = optimizeStringMemoryLibCall(SimplifiedCI,
Builder)) {
3755 substituteInParent(SimplifiedCI, V);
3759 return SimplifiedFortifiedCI;
3767 if (
Value *V = optimizeStringMemoryLibCall(CI,
Builder))
3769 if (
Value *V = optimizeFloatingPointLibCall(CI, Func,
Builder))
3775 return optimizeFFS(CI,
Builder);
3779 return optimizeFls(CI,
Builder);
3783 return optimizeAbs(CI,
Builder);
3784 case LibFunc_isdigit:
3785 return optimizeIsDigit(CI,
Builder);
3786 case LibFunc_isascii:
3787 return optimizeIsAscii(CI,
Builder);
3788 case LibFunc_toascii:
3789 return optimizeToAscii(CI,
Builder);
3793 return optimizeAtoi(CI,
Builder);
3794 case LibFunc_strtol:
3795 case LibFunc_strtoll:
3796 return optimizeStrToInt(CI,
Builder,
true);
3797 case LibFunc_strtoul:
3798 case LibFunc_strtoull:
3799 return optimizeStrToInt(CI,
Builder,
false);
3800 case LibFunc_printf:
3801 return optimizePrintF(CI,
Builder);
3802 case LibFunc_sprintf:
3803 return optimizeSPrintF(CI,
Builder);
3804 case LibFunc_snprintf:
3805 return optimizeSnPrintF(CI,
Builder);
3806 case LibFunc_fprintf:
3807 return optimizeFPrintF(CI,
Builder);
3808 case LibFunc_fwrite:
3809 return optimizeFWrite(CI,
Builder);
3811 return optimizeFPuts(CI,
Builder);
3813 return optimizePuts(CI,
Builder);
3814 case LibFunc_perror:
3815 return optimizeErrorReporting(CI,
Builder);
3816 case LibFunc_vfprintf:
3817 case LibFunc_fiprintf:
3818 return optimizeErrorReporting(CI,
Builder, 0);
3832 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
3833 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
3840void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
3879bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
3880 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
3881 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
3886 if (!Flag || !
Flag->isZero())
3895 if (ObjSizeCI->isMinusOne())
3898 if (OnlyLowerUnknownSize)
3908 return ObjSizeCI->getZExtValue() >=
Len;
3914 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
3920Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
3922 if (isFortifiedCallFoldable(CI, 3, 2)) {
3932Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
3934 if (isFortifiedCallFoldable(CI, 3, 2)) {
3944Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
3946 if (isFortifiedCallFoldable(CI, 3, 2)) {
3956Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
3959 if (isFortifiedCallFoldable(CI, 3, 2))
3967Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
3975 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
3977 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
3985 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
3986 if (Func == LibFunc_strcpy_chk)
3992 if (OnlyLowerUnknownSize)
4008 if (Ret && Func == LibFunc_stpcpy_chk)
4009 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4011 return copyFlags(*CI, cast<CallInst>(Ret));
4014Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4016 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4022Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4025 if (isFortifiedCallFoldable(CI, 3, 2)) {
4026 if (Func == LibFunc_strncpy_chk)
4039Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4041 if (isFortifiedCallFoldable(CI, 4, 3))
4049Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4051 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4061Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4063 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4067 VariadicArgs,
B, TLI));
4073Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4075 if (isFortifiedCallFoldable(CI, 2))
4082Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4084 if (isFortifiedCallFoldable(CI, 3))
4092Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4094 if (isFortifiedCallFoldable(CI, 3))
4102Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4104 if (isFortifiedCallFoldable(CI, 3))
4112Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4114 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4122Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4124 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4155 Builder.setDefaultOperandBundles(OpBundles);
4167 case LibFunc_memcpy_chk:
4168 return optimizeMemCpyChk(CI,
Builder);
4169 case LibFunc_mempcpy_chk:
4170 return optimizeMemPCpyChk(CI,
Builder);
4171 case LibFunc_memmove_chk:
4172 return optimizeMemMoveChk(CI,
Builder);
4173 case LibFunc_memset_chk:
4174 return optimizeMemSetChk(CI,
Builder);
4175 case LibFunc_stpcpy_chk:
4176 case LibFunc_strcpy_chk:
4177 return optimizeStrpCpyChk(CI,
Builder, Func);
4178 case LibFunc_strlen_chk:
4179 return optimizeStrLenChk(CI,
Builder);
4180 case LibFunc_stpncpy_chk:
4181 case LibFunc_strncpy_chk:
4182 return optimizeStrpNCpyChk(CI,
Builder, Func);
4183 case LibFunc_memccpy_chk:
4184 return optimizeMemCCpyChk(CI,
Builder);
4185 case LibFunc_snprintf_chk:
4186 return optimizeSNPrintfChk(CI,
Builder);
4187 case LibFunc_sprintf_chk:
4188 return optimizeSPrintfChk(CI,
Builder);
4189 case LibFunc_strcat_chk:
4190 return optimizeStrCatChk(CI,
Builder);
4191 case LibFunc_strlcat_chk:
4192 return optimizeStrLCat(CI,
Builder);
4193 case LibFunc_strncat_chk:
4194 return optimizeStrNCatChk(CI,
Builder);
4195 case LibFunc_strlcpy_chk:
4196 return optimizeStrLCpyChk(CI,
Builder);
4197 case LibFunc_vsnprintf_chk:
4198 return optimizeVSNPrintfChk(CI,
Builder);
4199 case LibFunc_vsprintf_chk:
4200 return optimizeVSPrintfChk(CI,
Builder);
4209 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
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 Value * optimizeTrigReflections(CallInst *Call, LibFunc Func, IRBuilderBase &B)
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 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 * 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 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"))
This file defines the SmallString class.
bool isFiniteNonZero() const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
double convertToDouble() const
Converts this APFloat to host double value.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
opStatus add(const APFloat &RHS, roundingMode RM)
const fltSemantics & getSemantics() const
float convertToFloat() const
Converts this APFloat to host float value.
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Class for arbitrary precision integers.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
Attribute getFnAttr(Attribute::AttrKind Kind) const
Return the attribute object that exists for the function.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &B) const
Add an argument attribute to the list.
MaybeAlign getAlignment() const
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool doesNotAccessMemory(unsigned OpNo) const
void removeRetAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the return value.
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
uint64_t getParamDereferenceableBytes(unsigned i) const
Extract the number of dereferenceable bytes for a call or parameter (0=unknown).
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
bool doesNotThrow() const
Determine if the call cannot unwind.
Value * getArgOperand(unsigned i) const
uint64_t getParamDereferenceableOrNullBytes(unsigned i) const
Extract the number of dereferenceable_or_null bytes for a parameter (0=unknown).
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the parameter attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
bool isNoTailCall() const
TailCallKind getTailCallKind() const
bool isMustTailCall() const
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
uint64_t getElementAsInteger(unsigned i) const
If this is a sequential container of integers (of any size), return the specified element in the low ...
ConstantFP - Floating Point Values [float, double].
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
static Constant * getInfinity(Type *Ty, bool Negative=false)
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.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU.
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
void setNoSignedZeros(bool B=true)
static FastMathFlags getFast()
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize=false)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
Take the given call instruction and return a more optimal value to replace the instruction with or 0 ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
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...
const BasicBlock * getParent() const
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.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, AssumptionCache *AC, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
An instruction for reading from memory.
Value * getPointerOperand()
A Module instance is used to store all the information related to an LLVM module.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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.
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.
bool startswith(StringRef Prefix) const
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
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.
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static bool isCallingConvCCompatible(CallBase *CI)
Returns true if call site / callee has cdecl-compatible calling conventions.
Provides information about what library functions are available for the current target.
unsigned getWCharSize(const Module &M) const
Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
unsigned getSizeTSize(const Module &M) const
Returns the size of the size_t type in bits.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
StringRef getName(LibFunc F) const
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isStructTy() const
True if this is an instance of StructType.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.