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())
2010 *CI,
B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp, CI,
"cabs"));
2017 Value *RealReal =
B.CreateFMulFMF(Real, Real, CI);
2018 Value *ImagImag =
B.CreateFMulFMF(Imag, Imag, CI);
2020 *CI,
B.CreateUnaryIntrinsic(Intrinsic::sqrt,
2021 B.CreateFAddFMF(RealReal, ImagImag, CI), CI,
2028 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
2029 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
2032 unsigned BitWidth =
Op->getType()->getScalarSizeInBits();
2033 if (
BitWidth < DstWidth || (
BitWidth == DstWidth && isa<SIToFPInst>(I2F))) {
2034 Type *IntTy =
Op->getType()->getWithNewBitWidth(DstWidth);
2035 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op, IntTy)
2036 :
B.CreateZExt(
Op, IntTy);
2077 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2085 ExpName = TLI->
getName(LibFunc_exp);
2086 ID = Intrinsic::exp;
2087 LibFnFloat = LibFunc_expf;
2088 LibFnDouble = LibFunc_exp;
2089 LibFnLongDouble = LibFunc_expl;
2094 ExpName = TLI->
getName(LibFunc_exp2);
2095 ID = Intrinsic::exp2;
2096 LibFnFloat = LibFunc_exp2f;
2097 LibFnDouble = LibFunc_exp2;
2098 LibFnLongDouble = LibFunc_exp2l;
2105 ?
B.CreateUnaryIntrinsic(
ID,
FMul,
nullptr, ExpName)
2114 substituteInParent(BaseFn, ExpFn);
2131 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2133 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2138 Constant *One = ConstantFP::get(Ty, 1.0);
2141 return copyFlags(*Pow,
B.CreateIntrinsic(Intrinsic::ldexp,
2142 {Ty, ExpoI->getType()},
2143 {One, ExpoI}, Pow,
"exp2"));
2147 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2148 LibFunc_ldexpl,
B, NoAttrs));
2153 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2156 BaseR = BaseR / *BaseF;
2158 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2160 if ((IsInteger || IsReciprocal) &&
2163 NI > 1 && NI.isPowerOf2()) {
2164 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2165 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2167 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2172 LibFunc_exp2l,
B, NoAttrs));
2178 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l)) {
2182 B.CreateIntrinsic(Intrinsic::exp10, {Ty}, {Expo}, Pow,
"exp10");
2187 LibFunc_exp10f, LibFunc_exp10l,
2197 "pow(1.0, y) should have been simplified earlier!");
2199 Value *Log =
nullptr;
2206 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2208 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2210 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2214 LibFunc_exp2l,
B, NoAttrs));
2226 return B.CreateUnaryIntrinsic(Intrinsic::sqrt, V,
nullptr,
"sqrt");
2229 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2235 LibFunc_sqrtl,
B, Attrs);
2272 Sqrt =
B.CreateUnaryIntrinsic(Intrinsic::fabs, Sqrt,
nullptr,
"abs");
2281 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2282 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2287 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2296 return B.CreateIntrinsic(Intrinsic::powi, Types, Args);
2318 if (
Value *Exp = replacePowWithExp(Pow,
B))
2325 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2329 return ConstantFP::get(Ty, 1.0);
2337 return B.CreateFMul(
Base,
Base,
"square");
2339 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2350 Value *Sqrt =
nullptr;
2351 if (!ExpoA.isInteger()) {
2365 if (!ExpoI.isInteger())
2388 return B.CreateFMul(PowI, Sqrt);
2395 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2402 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2403 hasFloatVersion(M,
Name)) {
2416 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2417 hasFloatVersion(M,
Name))
2426 const bool UseIntrinsic =
Callee->isIntrinsic();
2435 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2437 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2439 Constant *One = ConstantFP::get(Ty, 1.0);
2442 return copyFlags(*CI,
B.CreateIntrinsic(Intrinsic::ldexp,
2443 {Ty, Exp->getType()},
2450 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2465 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2480 : Intrinsic::maxnum;
2492 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2496 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2502 LogID = Intrinsic::log;
2503 ExpLb = LibFunc_expf;
2504 Exp2Lb = LibFunc_exp2f;
2505 Exp10Lb = LibFunc_exp10f;
2506 PowLb = LibFunc_powf;
2509 LogID = Intrinsic::log;
2510 ExpLb = LibFunc_exp;
2511 Exp2Lb = LibFunc_exp2;
2512 Exp10Lb = LibFunc_exp10;
2513 PowLb = LibFunc_pow;
2516 LogID = Intrinsic::log;
2517 ExpLb = LibFunc_expl;
2518 Exp2Lb = LibFunc_exp2l;
2519 Exp10Lb = LibFunc_exp10l;
2520 PowLb = LibFunc_powl;
2523 LogID = Intrinsic::log2;
2524 ExpLb = LibFunc_expf;
2525 Exp2Lb = LibFunc_exp2f;
2526 Exp10Lb = LibFunc_exp10f;
2527 PowLb = LibFunc_powf;
2530 LogID = Intrinsic::log2;
2531 ExpLb = LibFunc_exp;
2532 Exp2Lb = LibFunc_exp2;
2533 Exp10Lb = LibFunc_exp10;
2534 PowLb = LibFunc_pow;
2537 LogID = Intrinsic::log2;
2538 ExpLb = LibFunc_expl;
2539 Exp2Lb = LibFunc_exp2l;
2540 Exp10Lb = LibFunc_exp10l;
2541 PowLb = LibFunc_powl;
2543 case LibFunc_log10f:
2544 LogID = Intrinsic::log10;
2545 ExpLb = LibFunc_expf;
2546 Exp2Lb = LibFunc_exp2f;
2547 Exp10Lb = LibFunc_exp10f;
2548 PowLb = LibFunc_powf;
2551 LogID = Intrinsic::log10;
2552 ExpLb = LibFunc_exp;
2553 Exp2Lb = LibFunc_exp2;
2554 Exp10Lb = LibFunc_exp10;
2555 PowLb = LibFunc_pow;
2557 case LibFunc_log10l:
2558 LogID = Intrinsic::log10;
2559 ExpLb = LibFunc_expl;
2560 Exp2Lb = LibFunc_exp2l;
2561 Exp10Lb = LibFunc_exp10l;
2562 PowLb = LibFunc_powl;
2570 if (!IsKnownNoErrno) {
2580 if (IsKnownNoErrno) {
2581 auto *NewLog =
B.CreateUnaryIntrinsic(LogID, Log->
getArgOperand(0), Log);
2582 NewLog->copyMetadata(*Log);
2585 }
else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2586 LogID == Intrinsic::log10) {
2588 ExpLb = LibFunc_expf;
2589 Exp2Lb = LibFunc_exp2f;
2590 Exp10Lb = LibFunc_exp10f;
2591 PowLb = LibFunc_powf;
2593 ExpLb = LibFunc_exp;
2594 Exp2Lb = LibFunc_exp2;
2595 Exp10Lb = LibFunc_exp10;
2596 PowLb = LibFunc_pow;
2616 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2619 ?
B.CreateUnaryIntrinsic(LogID, Arg->
getOperand(0),
nullptr,
"log")
2623 if (ArgID == Intrinsic::powi)
2624 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2625 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2628 substituteInParent(Arg, MulY);
2634 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2635 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2637 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2640 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2641 Eul = ConstantFP::get(Log->
getType(), 2.0);
2643 Eul = ConstantFP::get(Log->
getType(), 10.0);
2645 ?
B.CreateUnaryIntrinsic(LogID, Eul,
nullptr,
"log")
2650 substituteInParent(Arg, MulY);
2670 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2675 ExpLb = LibFunc_expf;
2676 Exp2Lb = LibFunc_exp2f;
2677 Exp10Lb = LibFunc_exp10f;
2680 ExpLb = LibFunc_exp;
2681 Exp2Lb = LibFunc_exp2;
2682 Exp10Lb = LibFunc_exp10;
2685 ExpLb = LibFunc_expl;
2686 Exp2Lb = LibFunc_exp2l;
2687 Exp10Lb = LibFunc_exp10l;
2694 ExpLb = LibFunc_expf;
2695 Exp2Lb = LibFunc_exp2f;
2696 Exp10Lb = LibFunc_exp10f;
2698 ExpLb = LibFunc_exp;
2699 Exp2Lb = LibFunc_exp2;
2700 Exp10Lb = LibFunc_exp10;
2706 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2707 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2711 B.SetInsertPoint(Arg);
2714 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2729 (
Callee->getName() ==
"sqrt" ||
2730 Callee->getIntrinsicID() == Intrinsic::sqrt))
2733 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2740 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2746 Value *Op0 =
I->getOperand(0);
2747 Value *Op1 =
I->getOperand(1);
2748 Value *RepeatOp =
nullptr;
2749 Value *OtherOp =
nullptr;
2761 cast<Instruction>(Op0)->isFast()) {
2766 cast<Instruction>(Op1)->isFast()) {
2781 B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp,
I,
"fabs");
2787 B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp,
I,
"sqrt");
2788 return copyFlags(*CI,
B.CreateFMulFMF(FabsCall, SqrtCall,
I));
2814 if (
auto *FRemI = dyn_cast<Instruction>(FRem))
2815 FRemI->setHasNoNaNs(
true);
2821Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2827 if (UnsafeFPShrink &&
2830 hasFloatVersion(M,
Name))
2834 auto *OpC = dyn_cast<CallInst>(Op1);
2839 if (!CI->
isFast() || !OpC->isFast())
2852 .
Case(
"tan", LibFunc_atan)
2853 .
Case(
"atanh", LibFunc_tanh)
2854 .
Case(
"sinh", LibFunc_asinh)
2855 .
Case(
"cosh", LibFunc_acosh)
2856 .
Case(
"tanf", LibFunc_atanf)
2857 .
Case(
"atanhf", LibFunc_tanhf)
2858 .
Case(
"sinhf", LibFunc_asinhf)
2859 .
Case(
"coshf", LibFunc_acoshf)
2860 .
Case(
"tanl", LibFunc_atanl)
2861 .
Case(
"atanhl", LibFunc_tanhl)
2862 .
Case(
"sinhl", LibFunc_asinhl)
2863 .
Case(
"coshl", LibFunc_acoshl)
2864 .
Case(
"asinh", LibFunc_sinh)
2865 .
Case(
"asinhf", LibFunc_sinhf)
2866 .
Case(
"asinhl", LibFunc_sinhl)
2868 if (Func == inverseFunc)
2869 Ret = OpC->getArgOperand(0);
2891 Name =
"__sincospif_stret";
2900 Name =
"__sincospi_stret";
2909 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2911 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2914 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2918 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2919 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2922 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2925 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2926 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2928 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2930 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
2944 Call->copyFastMathFlags(CI);
2958 Call->copyFastMathFlags(CI);
3009 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
3015 Value *Sin, *Cos, *SinCos;
3023 replaceAllUsesWith(
C, Res);
3026 replaceTrigInsts(SinCalls, Sin);
3027 replaceTrigInsts(CosCalls, Cos);
3028 replaceTrigInsts(SinCosCalls, SinCos);
3030 return IsSin ? Sin : Cos;
3033void LibCallSimplifier::classifyArgUse(
3038 auto *CI = dyn_cast<CallInst>(Val);
3049 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
3055 if (Func == LibFunc_sinpif)
3057 else if (Func == LibFunc_cospif)
3059 else if (Func == LibFunc_sincospif_stret)
3062 if (Func == LibFunc_sinpi)
3064 else if (Func == LibFunc_cospi)
3066 else if (Func == LibFunc_sincospi_stret)
3089 APSInt QuotInt(IntBW,
false);
3096 B.CreateAlignedStore(
3097 ConstantInt::get(
B.getIntNTy(IntBW), QuotInt.getExtValue()),
3099 return ConstantFP::get(CI->
getType(), Rem);
3126 return ConstantFP::get(CI->
getType(), MaxVal);
3138 Type *ArgType =
Op->getType();
3139 Value *
V =
B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {
Op,
B.getTrue()},
3141 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3142 V =
B.CreateIntCast(V, RetType,
false);
3145 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3152 Type *ArgType =
Op->getType();
3153 Value *
V =
B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {
Op,
B.getFalse()},
3157 return B.CreateIntCast(V, CI->
getType(),
false);
3164 Value *IsNeg =
B.CreateIsNeg(
X);
3165 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3166 return B.CreateSelect(IsNeg, NegX,
X);
3172 Type *ArgType =
Op->getType();
3173 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3174 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3181 Type *ArgType =
Op->getType();
3182 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3189 ConstantInt::get(CI->
getType(), 0x7F));
3207 if (isa<ConstantPointerNull>(EndPtr)) {
3220 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3252 if (!Callee || !Callee->isDeclaration())
3261 if (StreamArg >= (
int)CI->
arg_size())
3269 return GV->
getName() ==
"stderr";
3279 if (FormatStr.
empty())
3290 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3294 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3299 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3304 if (OperandStr.
empty())
3307 if (OperandStr.
size() == 1) {
3311 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3315 if (OperandStr.
back() ==
'\n') {
3317 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3324 if (FormatStr.
back() ==
'\n' &&
3329 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3335 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3344 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3355 if (
Value *V = optimizePrintFString(CI,
B)) {
3366 Callee->getAttributes());
3368 New->setCalledFunction(IPrintFFn);
3378 Callee->getAttributes());
3380 New->setCalledFunction(SmallPrintFFn);
3388Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3407 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3412 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3416 if (FormatStr[1] ==
'c') {
3422 B.CreateStore(V,
Ptr);
3423 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3424 B.CreateStore(
B.getInt8(0),
Ptr);
3426 return ConstantInt::get(CI->
getType(), 1);
3429 if (FormatStr[1] ==
's') {
3444 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3447 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3448 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3459 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3463 return B.CreateIntCast(Len, CI->
getType(),
false);
3472 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3483 FT,
Callee->getAttributes());
3485 New->setCalledFunction(SIPrintFFn);
3495 Callee->getAttributes());
3497 New->setCalledFunction(SmallSPrintFFn);
3513 assert(StrArg || (
N < 2 && Str.size() == 1));
3517 if (Str.size() > IntMax)
3523 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3533 NCopy = Str.size() + 1;
3538 if (NCopy && StrArg)
3549 Type *Int8Ty =
B.getInt8Ty();
3550 Value *NulOff =
B.getIntN(IntBits, NCopy);
3551 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3552 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3556Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3585 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3590 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3594 if (FormatStr[1] ==
'c') {
3600 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3608 B.CreateStore(V,
Ptr);
3609 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3610 B.CreateStore(
B.getInt8(0),
Ptr);
3611 return ConstantInt::get(CI->
getType(), 1);
3614 if (FormatStr[1] !=
's')
3623 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3627 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3636Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3638 optimizeErrorReporting(CI,
B, 0);
3665 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3669 if (FormatStr[1] ==
'c') {
3679 if (FormatStr[1] ==
's') {
3693 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3702 FT,
Callee->getAttributes());
3704 New->setCalledFunction(FIPrintFFn);
3713 auto SmallFPrintFFn =
3715 Callee->getAttributes());
3717 New->setCalledFunction(SmallFPrintFFn);
3726 optimizeErrorReporting(CI,
B, 3);
3731 if (SizeC && CountC) {
3736 return ConstantInt::get(CI->
getType(), 0);
3743 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3745 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3753 optimizeErrorReporting(CI,
B, 1);
3776 ConstantInt::get(SizeTTy, Len - 1),
3816bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3818 FloatFuncName +=
'f';
3822Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3834 "Optimizing string/memory libcall would change the calling convention");
3836 case LibFunc_strcat:
3837 return optimizeStrCat(CI, Builder);
3838 case LibFunc_strncat:
3839 return optimizeStrNCat(CI, Builder);
3840 case LibFunc_strchr:
3841 return optimizeStrChr(CI, Builder);
3842 case LibFunc_strrchr:
3843 return optimizeStrRChr(CI, Builder);
3844 case LibFunc_strcmp:
3845 return optimizeStrCmp(CI, Builder);
3846 case LibFunc_strncmp:
3847 return optimizeStrNCmp(CI, Builder);
3848 case LibFunc_strcpy:
3849 return optimizeStrCpy(CI, Builder);
3850 case LibFunc_stpcpy:
3851 return optimizeStpCpy(CI, Builder);
3852 case LibFunc_strlcpy:
3853 return optimizeStrLCpy(CI, Builder);
3854 case LibFunc_stpncpy:
3855 return optimizeStringNCpy(CI,
true, Builder);
3856 case LibFunc_strncpy:
3857 return optimizeStringNCpy(CI,
false, Builder);
3858 case LibFunc_strlen:
3859 return optimizeStrLen(CI, Builder);
3860 case LibFunc_strnlen:
3861 return optimizeStrNLen(CI, Builder);
3862 case LibFunc_strpbrk:
3863 return optimizeStrPBrk(CI, Builder);
3864 case LibFunc_strndup:
3865 return optimizeStrNDup(CI, Builder);
3866 case LibFunc_strtol:
3867 case LibFunc_strtod:
3868 case LibFunc_strtof:
3869 case LibFunc_strtoul:
3870 case LibFunc_strtoll:
3871 case LibFunc_strtold:
3872 case LibFunc_strtoull:
3873 return optimizeStrTo(CI, Builder);
3874 case LibFunc_strspn:
3875 return optimizeStrSpn(CI, Builder);
3876 case LibFunc_strcspn:
3877 return optimizeStrCSpn(CI, Builder);
3878 case LibFunc_strstr:
3879 return optimizeStrStr(CI, Builder);
3880 case LibFunc_memchr:
3881 return optimizeMemChr(CI, Builder);
3882 case LibFunc_memrchr:
3883 return optimizeMemRChr(CI, Builder);
3885 return optimizeBCmp(CI, Builder);
3886 case LibFunc_memcmp:
3887 return optimizeMemCmp(CI, Builder);
3888 case LibFunc_memcpy:
3889 return optimizeMemCpy(CI, Builder);
3890 case LibFunc_memccpy:
3891 return optimizeMemCCpy(CI, Builder);
3892 case LibFunc_mempcpy:
3893 return optimizeMemPCpy(CI, Builder);
3894 case LibFunc_memmove:
3895 return optimizeMemMove(CI, Builder);
3896 case LibFunc_memset:
3897 return optimizeMemSet(CI, Builder);
3898 case LibFunc_realloc:
3899 return optimizeRealloc(CI, Builder);
3900 case LibFunc_wcslen:
3901 return optimizeWcslen(CI, Builder);
3903 return optimizeBCopy(CI, Builder);
3905 case LibFunc_ZnwmRKSt9nothrow_t:
3906 case LibFunc_ZnwmSt11align_val_t:
3907 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3909 case LibFunc_ZnamRKSt9nothrow_t:
3910 case LibFunc_ZnamSt11align_val_t:
3911 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3912 case LibFunc_Znwm12__hot_cold_t:
3913 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3914 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3915 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3916 case LibFunc_Znam12__hot_cold_t:
3917 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3918 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3919 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3920 case LibFunc_size_returning_new:
3921 case LibFunc_size_returning_new_hot_cold:
3922 case LibFunc_size_returning_new_aligned:
3923 case LibFunc_size_returning_new_aligned_hot_cold:
3924 return optimizeNew(CI, Builder, Func);
3940 if (CharSeq.
empty())
3941 Fill =
APInt(32, 0);
3948Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3957 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3961 case LibFunc_sinpif:
3963 return optimizeSinCosPi(CI,
true, Builder);
3964 case LibFunc_cospif:
3966 return optimizeSinCosPi(CI,
false, Builder);
3970 return optimizePow(CI, Builder);
3974 return optimizeExp2(CI, Builder);
3982 return optimizeSqrt(CI, Builder);
3986 return optimizeFMod(CI, Builder);
3990 case LibFunc_log10f:
3992 case LibFunc_log10l:
3993 case LibFunc_log1pf:
3995 case LibFunc_log1pl:
4002 return optimizeLog(CI, Builder);
4010 case LibFunc_asinhf:
4011 case LibFunc_asinhl:
4016 case LibFunc_atanhf:
4017 case LibFunc_atanhl:
4018 return optimizeTrigInversionPairs(CI, Builder);
4025 case LibFunc_roundeven:
4027 case LibFunc_nearbyint:
4047 case LibFunc_copysign:
4054 return optimizeFdim(CI, Builder);
4061 return optimizeFMinFMax(CI, Builder);
4065 return optimizeCAbs(CI, Builder);
4066 case LibFunc_remquo:
4067 case LibFunc_remquof:
4068 case LibFunc_remquol:
4069 return optimizeRemquo(CI, Builder);
4104 else if (isa<FPMathOperator>(CI) && CI->
isFast())
4105 UnsafeFPShrink =
true;
4109 if (!IsCallingConvC)
4113 switch (
II->getIntrinsicID()) {
4114 case Intrinsic::pow:
4115 return optimizePow(CI, Builder);
4116 case Intrinsic::exp2:
4117 return optimizeExp2(CI, Builder);
4118 case Intrinsic::log:
4119 case Intrinsic::log2:
4120 case Intrinsic::log10:
4121 return optimizeLog(CI, Builder);
4122 case Intrinsic::sqrt:
4123 return optimizeSqrt(CI, Builder);
4124 case Intrinsic::memset:
4125 return optimizeMemSet(CI, Builder);
4126 case Intrinsic::memcpy:
4127 return optimizeMemCpy(CI, Builder);
4128 case Intrinsic::memmove:
4129 return optimizeMemMove(CI, Builder);
4136 if (
Value *SimplifiedFortifiedCI =
4138 return SimplifiedFortifiedCI;
4145 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
4147 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4153 return optimizeFFS(CI, Builder);
4157 return optimizeFls(CI, Builder);
4161 return optimizeAbs(CI, Builder);
4162 case LibFunc_isdigit:
4163 return optimizeIsDigit(CI, Builder);
4164 case LibFunc_isascii:
4165 return optimizeIsAscii(CI, Builder);
4166 case LibFunc_toascii:
4167 return optimizeToAscii(CI, Builder);
4171 return optimizeAtoi(CI, Builder);
4172 case LibFunc_strtol:
4173 case LibFunc_strtoll:
4174 return optimizeStrToInt(CI, Builder,
true);
4175 case LibFunc_strtoul:
4176 case LibFunc_strtoull:
4177 return optimizeStrToInt(CI, Builder,
false);
4178 case LibFunc_printf:
4179 return optimizePrintF(CI, Builder);
4180 case LibFunc_sprintf:
4181 return optimizeSPrintF(CI, Builder);
4182 case LibFunc_snprintf:
4183 return optimizeSnPrintF(CI, Builder);
4184 case LibFunc_fprintf:
4185 return optimizeFPrintF(CI, Builder);
4186 case LibFunc_fwrite:
4187 return optimizeFWrite(CI, Builder);
4189 return optimizeFPuts(CI, Builder);
4191 return optimizePuts(CI, Builder);
4192 case LibFunc_perror:
4193 return optimizeErrorReporting(CI, Builder);
4194 case LibFunc_vfprintf:
4195 case LibFunc_fiprintf:
4196 return optimizeErrorReporting(CI, Builder, 0);
4199 return optimizeExit(CI);
4213 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), DT(DT), DC(DC), AC(AC),
4214 ORE(ORE), BFI(BFI), PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4221void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4260bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4261 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4262 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4267 if (!Flag || !
Flag->isZero())
4276 if (ObjSizeCI->isMinusOne())
4279 if (OnlyLowerUnknownSize)
4289 return ObjSizeCI->getZExtValue() >=
Len;
4295 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4301Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4303 if (isFortifiedCallFoldable(CI, 3, 2)) {
4313Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4315 if (isFortifiedCallFoldable(CI, 3, 2)) {
4325Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4327 if (isFortifiedCallFoldable(CI, 3, 2)) {
4337Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4340 if (isFortifiedCallFoldable(CI, 3, 2))
4348Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4356 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4358 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4366 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4367 if (Func == LibFunc_strcpy_chk)
4373 if (OnlyLowerUnknownSize)
4385 Value *LenV = ConstantInt::get(SizeTTy, Len);
4389 if (Ret && Func == LibFunc_stpcpy_chk)
4390 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4391 ConstantInt::get(SizeTTy, Len - 1));
4392 return copyFlags(*CI, cast<CallInst>(Ret));
4395Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4397 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4403Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4406 if (isFortifiedCallFoldable(CI, 3, 2)) {
4407 if (Func == LibFunc_strncpy_chk)
4420Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4422 if (isFortifiedCallFoldable(CI, 4, 3))
4430Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4432 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4442Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4444 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4448 VariadicArgs,
B, TLI));
4454Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4456 if (isFortifiedCallFoldable(CI, 2))
4463Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4465 if (isFortifiedCallFoldable(CI, 3))
4473Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4475 if (isFortifiedCallFoldable(CI, 3))
4483Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4485 if (isFortifiedCallFoldable(CI, 3))
4493Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4495 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4503Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4505 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4548 case LibFunc_memcpy_chk:
4549 return optimizeMemCpyChk(CI, Builder);
4550 case LibFunc_mempcpy_chk:
4551 return optimizeMemPCpyChk(CI, Builder);
4552 case LibFunc_memmove_chk:
4553 return optimizeMemMoveChk(CI, Builder);
4554 case LibFunc_memset_chk:
4555 return optimizeMemSetChk(CI, Builder);
4556 case LibFunc_stpcpy_chk:
4557 case LibFunc_strcpy_chk:
4558 return optimizeStrpCpyChk(CI, Builder, Func);
4559 case LibFunc_strlen_chk:
4560 return optimizeStrLenChk(CI, Builder);
4561 case LibFunc_stpncpy_chk:
4562 case LibFunc_strncpy_chk:
4563 return optimizeStrpNCpyChk(CI, Builder, Func);
4564 case LibFunc_memccpy_chk:
4565 return optimizeMemCCpyChk(CI, Builder);
4566 case LibFunc_snprintf_chk:
4567 return optimizeSNPrintfChk(CI, Builder);
4568 case LibFunc_sprintf_chk:
4569 return optimizeSPrintfChk(CI, Builder);
4570 case LibFunc_strcat_chk:
4571 return optimizeStrCatChk(CI, Builder);
4572 case LibFunc_strlcat_chk:
4573 return optimizeStrLCat(CI, Builder);
4574 case LibFunc_strncat_chk:
4575 return optimizeStrNCatChk(CI, Builder);
4576 case LibFunc_strlcpy_chk:
4577 return optimizeStrLCpyChk(CI, Builder);
4578 case LibFunc_vsnprintf_chk:
4579 return optimizeVSNPrintfChk(CI, Builder);
4580 case LibFunc_vsprintf_chk:
4581 return optimizeVSPrintfChk(CI, Builder);
4590 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static bool isBinary(MachineInstr &MI)
const SmallVectorImpl< MachineOperand > & Cond
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With)
Return true if it is only used in equality comparisons with With.
static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef< unsigned > ArgNos, Value *Size, const DataLayout &DL)
static cl::opt< unsigned, false, HotColdHintParser > ColdNewHintValue("cold-new-hint-value", cl::Hidden, cl::init(1), cl::desc("Value to pass to hot/cold operator new for cold allocation"))
static bool insertSinCosCall(IRBuilderBase &B, Function *OrigCallee, Value *Arg, bool UseFloat, Value *&Sin, Value *&Cos, Value *&SinCos, const TargetLibraryInfo *TLI)
static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len, const DataLayout &DL)
static Value * mergeAttributesAndFlags(CallInst *NewCI, const CallInst &Old)
static cl::opt< bool > OptimizeHotColdNew("optimize-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable hot/cold operator new library calls"))
static Value * optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for binary functions.
static bool ignoreCallingConv(LibFunc Func)
static cl::opt< bool > OptimizeExistingHotColdNew("optimize-existing-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable optimization of existing hot/cold operator new library calls"))
static void annotateDereferenceableBytes(CallInst *CI, ArrayRef< unsigned > ArgNos, uint64_t DereferenceableBytes)
static bool isReportingError(Function *Callee, CallInst *CI, int StreamArg)
static Value * optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, bool isBinary, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float functions.
static Value * optimizeSymmetricCall(CallInst *CI, bool IsEven, IRBuilderBase &B)
static Value * getSqrtCall(Value *V, AttributeList Attrs, bool NoErrno, Module *M, IRBuilderBase &B, const TargetLibraryInfo *TLI)
static Value * valueHasFloatPrecision(Value *Val)
Return a variant of Val with float type.
static Value * optimizeMemCmpConstantSize(CallInst *CI, Value *LHS, Value *RHS, uint64_t Len, IRBuilderBase &B, const DataLayout &DL)
static Value * createPowWithIntegerExponent(Value *Base, Value *Expo, Module *M, IRBuilderBase &B)
static Value * convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, uint64_t Base, bool AsSigned, IRBuilderBase &B)
static Value * memChrToCharCompare(CallInst *CI, Value *NBytes, IRBuilderBase &B, const DataLayout &DL)
static Value * copyFlags(const CallInst &Old, Value *New)
static StringRef substr(StringRef Str, uint64_t Len)
static cl::opt< unsigned, false, HotColdHintParser > HotNewHintValue("hot-new-hint-value", cl::Hidden, cl::init(254), cl::desc("Value to pass to hot/cold operator new for hot allocation"))
static bool isTrigLibCall(CallInst *CI)
static Value * optimizeNaN(CallInst *CI)
Constant folding nan/nanf/nanl.
static bool isOnlyUsedInComparisonWithZero(Value *V)
static Value * replaceUnaryCall(CallInst *CI, IRBuilderBase &B, Intrinsic::ID IID)
static bool callHasFloatingPointArgument(const CallInst *CI)
static Value * optimizeUnaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for unary functions.
static bool callHasFP128Argument(const CallInst *CI)
static void annotateNonNullNoUndefBasedOnAccess(CallInst *CI, ArrayRef< unsigned > ArgNos)
static Value * optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, Value *Size, bool StrNCmp, IRBuilderBase &B, const DataLayout &DL)
static Value * getIntToFPVal(Value *I2F, IRBuilderBase &B, unsigned DstWidth)
static cl::opt< bool > EnableUnsafeFPShrink("enable-double-float-shrink", cl::Hidden, cl::init(false), cl::desc("Enable unsafe double to float " "shrinking for math lib calls"))
static cl::opt< unsigned, false, HotColdHintParser > NotColdNewHintValue("notcold-new-hint-value", cl::Hidden, cl::init(128), cl::desc("Value to pass to hot/cold operator new for " "notcold (warm) allocation"))
This file defines the SmallString class.
opStatus divide(const APFloat &RHS, roundingMode RM)
bool isFiniteNonZero() const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
opStatus subtract(const APFloat &RHS, roundingMode RM)
double convertToDouble() const
Converts this APFloat to host double value.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
opStatus add(const APFloat &RHS, roundingMode RM)
const fltSemantics & getSemantics() const
float convertToFloat() const
Converts this APFloat to host float value.
opStatus remainder(const APFloat &RHS)
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
Attribute getFnAttr(Attribute::AttrKind Kind) const
Return the attribute object that exists for the function.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &B) const
Add an argument attribute to the list.
MaybeAlign getAlignment() const
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
void removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove)
Removes the attributes from the given argument.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool doesNotAccessMemory(unsigned OpNo) const
void removeRetAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the return value.
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
AttributeSet getParamAttributes(unsigned ArgNo) const
Return the param attributes for this call.
uint64_t getParamDereferenceableBytes(unsigned i) const
Extract the number of dereferenceable bytes for a call or parameter (0=unknown).
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
AttributeSet getRetAttributes() const
Return the return attributes for this call.
void setAttributes(AttributeList A)
Set the attributes for this call.
bool doesNotThrow() const
Determine if the call cannot unwind.
Value * getArgOperand(unsigned i) const
uint64_t getParamDereferenceableOrNullBytes(unsigned i) const
Extract the number of dereferenceable_or_null bytes for a parameter (0=unknown).
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
bool isNoTailCall() const
TailCallKind getTailCallKind() const
bool isMustTailCall() const
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
uint64_t getElementAsInteger(unsigned i) const
If this is a sequential container of integers (of any size), return the specified element in the low ...
ConstantFP - Floating Point Values [float, double].
static Constant * getInfinity(Type *Ty, bool Negative=false)
static Constant * getQNaN(Type *Ty, bool Negative=false, APInt *Payload=nullptr)
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
void setNoSignedZeros(bool B=true)
static FastMathFlags getFast()
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize=false)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
Take the given call instruction and return a more optimal value to replace the instruction with or 0 ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
void setDefaultOperandBundles(ArrayRef< OperandBundleDef > OpBundles)
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool isFast() const LLVM_READONLY
Determine whether all fast-math-flags are set.
const Function * getFunction() const
Return the function this instruction belongs to.
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, DominatorTree *DT, DomConditionCache *DC, AssumptionCache *AC, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
An instruction for reading from memory.
Value * getPointerOperand()
A Module instance is used to store all the information related to an LLVM module.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Analysis providing profile information.
This class represents the LLVM 'select' instruction.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static bool isCallingConvCCompatible(CallBase *CI)
Returns true if call site / callee has cdecl-compatible calling conventions.
Provides information about what library functions are available for the current target.
unsigned getWCharSize(const Module &M) const
Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
ConstantInt * getAsSizeT(uint64_t V, const Module &M) const
Returns a constant materialized as a size_t type.
unsigned getSizeTSize(const Module &M) const
Returns the size of the size_t type in bits.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
StringRef getName(LibFunc F) const
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
const fltSemantics & getFltSemantics() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isStructTy() const
True if this is an instance of StructType.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
AttributeMask typeIncompatible(Type *Ty, AttributeSet AS, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
OneUse_match< T > m_OneUse(const T &SubPattern)
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
Value * emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)
Emit a call to the unary function named 'Name' (e.g.
Value * emitStrChr(Value *Ptr, char C, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strchr function to the builder, for the specified pointer and character.
Value * emitPutChar(Value *Char, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the putchar function. This assumes that Char is an 'int'.
Value * emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the __memcpy_chk function to the builder.
Value * emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncpy function to the builder, for the specified pointer arguments and length.
bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI)
Value * emitHotColdNewAlignedNoThrow(Value *Num, Value *Align, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
bool isKnownNeverInfinity(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
Value * emitSPrintf(Value *Dest, Value *Fmt, ArrayRef< Value * > VariadicArgs, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the sprintf function.
bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice, unsigned ElementSize, uint64_t Offset=0)
Returns true if the value V is a pointer into a ConstantDataArray.
Value * emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memrchr function, analogously to emitMemChr.
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
Value * emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcat function.
bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty, LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn)
Check whether the overloaded floating point function corresponding to Ty is available.
Value * emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncat function.
bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
Value * emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsnprintf function.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Value * emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strncmp function to the builder.
Value * emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memcmp function.
Value * emitBinaryFloatFnCall(Value *Op1, Value *Op2, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)
Emit a call to the binary function named 'Name' (e.g.
Value * emitFPutS(Value *Str, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputs function.
Value * emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strdup function to the builder, for the specified pointer.
void sort(IteratorTy Start, IteratorTy End)
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Value * emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the bcmp function.
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, and add the unsigned integer, A to the product.
uint64_t GetStringLength(const Value *V, unsigned CharSize=8)
If we can compute the length of the string pointed to by the specified pointer, return 'len+1'.
FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, LibFunc TheLibFunc, FunctionType *T, AttributeList AttributeList)
Calls getOrInsertFunction() and then makes sure to add mandatory argument attributes.
Value * emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strlen function to the builder, for the specified pointer.
Value * emitFPutC(Value *Char, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputc function.
Value * emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the stpncpy function to the builder, for the specified pointer arguments and length.
Value * emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcat function.
Value * emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsprintf function.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
Value * emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the fwrite function.
Value * emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, ArrayRef< Value * > Args, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the snprintf function.
@ Mod
The access may modify the value stored in memory.
Value * emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the stpcpy function to the builder, for the specified pointer arguments.
@ And
Bitwise or logical AND of integers.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
@ NearestTiesToEven
roundTiesToEven.
constexpr unsigned BitWidth
Value * emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the malloc function.
Value * emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memchr function.
Value * emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitPutS(Value *Str, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the puts function. This assumes that Str is some pointer.
Value * emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the memccpy function.
Value * emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitHotColdNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Emit a call to the hot/cold operator new function.
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
bool isGEPBasedOnPointerToString(const GEPOperator *GEP, unsigned CharSize=8)
Returns true if the GEP is based on a pointer to a string (array of.
Value * emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcpy function.
Value * emitHotColdSizeReturningNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcpy function to the builder, for the specified pointer arguments.
KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, unsigned Depth, const SimplifyQuery &SQ)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
Value * emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the mempcpy function.
uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmTowardNegative
static constexpr roundingMode rmNearestTiesToEven
static constexpr roundingMode rmTowardZero
opStatus
IEEE-754R 7: Default exception handling.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Holds functions to get, set or test bitfields.
Represents offset+length into a ConstantDataArray.
uint64_t Length
Length of the slice.
uint64_t Offset
Slice starts at this Offset.
const ConstantDataArray * Array
ConstantDataArray pointer.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
static constexpr FPClassTest OrderedLessThanZeroMask
bool isKnownNeverLogicalZero(const Function &F, Type *Ty) const
Return true if it's know this can never be interpreted as a zero.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.