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"));
58 "Enable optimization of existing hot/cold operator new library calls"));
65struct HotColdHintParser :
public cl::parser<unsigned> {
70 return O.error(
"'" + Arg +
"' value invalid for uint argument!");
73 return O.error(
"'" + Arg +
"' value must be in the range [0, 255]!");
87 cl::desc(
"Value to pass to hot/cold operator new for cold allocation"));
90 cl::desc(
"Value to pass to hot/cold operator new for "
91 "notcold (warm) allocation"));
94 cl::desc(
"Value to pass to hot/cold operator new for hot allocation"));
101 return Func == LibFunc_abs || Func == LibFunc_labs ||
102 Func == LibFunc_llabs || Func == LibFunc_strlen;
107 for (
User *U : V->users()) {
108 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
109 if (IC->isEquality() && IC->getOperand(1) == With)
119 return OI->getType()->isFloatingPointTy();
125 return OI->getType()->isFP128Ty();
138 if (Base < 2 || Base > 36)
147 if (!isSpace((
unsigned char)Str[
Offset])) {
158 bool Negate = Str[0] ==
'-';
159 if (Str[0] ==
'-' || Str[0] ==
'+') {
160 Str = Str.drop_front();
170 unsigned NBits =
RetTy->getPrimitiveSizeInBits();
171 uint64_t Max = AsSigned && Negate ? 1 : 0;
175 if (Str.size() > 1) {
177 if (toUpper((
unsigned char)Str[1]) ==
'X') {
178 if (Str.size() == 2 || (
Base &&
Base != 16))
183 Str = Str.drop_front(2);
189 }
else if (
Base == 0)
199 for (
unsigned i = 0; i != Str.size(); ++i) {
200 unsigned char DigVal = Str[i];
202 DigVal = DigVal -
'0';
204 DigVal = toUpper(DigVal);
206 DigVal = DigVal -
'A' + 10;
219 if (VFlow || Result > Max)
227 Value *StrEnd =
B.CreateInBoundsGEP(
B.getInt8Ty(), StrBeg, Off,
"endptr");
228 B.CreateStore(StrEnd, EndPtr);
235 return ConstantInt::get(
RetTy, Result);
239 for (
User *U : V->users()) {
240 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
241 if (
Constant *
C = dyn_cast<Constant>(IC->getOperand(1)))
242 if (
C->isNullValue())
270 for (
unsigned ArgNo : ArgNos) {
271 uint64_t DerefBytes = DereferenceableBytes;
276 DereferenceableBytes);
295 for (
unsigned ArgNo : ArgNos) {
321 DerefMin = std::min(
X->getZExtValue(),
Y->getZExtValue());
335 if (
auto *NewCI = dyn_cast_or_null<CallInst>(New))
342 NewCI->
getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
349 return Len >= Str.size() ? Str : Str.substr(0, Len);
374 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
388 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
394 ConstantInt::get(DL.
getIntPtrType(Src->getContext()), Len + 1));
438 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
451 Type *CharTy =
B.getInt8Ty();
452 Value *Char0 =
B.CreateLoad(CharTy, Src);
453 CharVal =
B.CreateTrunc(CharVal, CharTy);
454 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
458 Value *
And =
B.CreateICmpNE(NBytes, Zero);
459 Cmp =
B.CreateLogicalAnd(
And, Cmp);
463 return B.CreateSelect(Cmp, Src, NullPtr);
476 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
487 if (!FT->getParamType(1)->isIntegerTy(IntBits))
494 ConstantInt::get(SizeTTy, Len),
B,
503 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
512 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
525 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
531 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
537 if (CharC && CharC->
isZero())
548 Value *
Size = ConstantInt::get(SizeTTy, NBytes);
555 return ConstantInt::get(CI->
getType(), 0);
562 if (HasStr1 && HasStr2)
563 return ConstantInt::get(CI->
getType(),
564 std::clamp(Str1.
compare(Str2), -1, 1));
566 if (HasStr1 && Str1.
empty())
567 return B.CreateNeg(
B.CreateZExt(
568 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
570 if (HasStr2 && Str2.
empty())
571 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
586 std::min(Len1, Len2)),
591 if (!HasStr1 && HasStr2) {
598 }
else if (HasStr1 && !HasStr2) {
622 return ConstantInt::get(CI->
getType(), 0);
634 return ConstantInt::get(CI->
getType(), 0);
644 if (HasStr1 && HasStr2) {
648 return ConstantInt::get(CI->
getType(),
649 std::clamp(SubStr1.
compare(SubStr2), -1, 1));
652 if (HasStr1 && Str1.
empty())
653 return B.CreateNeg(
B.CreateZExt(
654 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
656 if (HasStr2 && Str2.
empty())
657 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
668 if (!HasStr1 && HasStr2) {
669 Len2 = std::min(Len2,
Length);
676 }
else if (HasStr1 && !HasStr2) {
677 Len1 = std::min(Len1,
Length);
693 if (SrcLen &&
Size) {
695 if (SrcLen <= Size->getZExtValue() + 1)
734 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
744 Type *PT =
Callee->getFunctionType()->getParamType(0);
746 Value *DstEnd =
B.CreateInBoundsGEP(
747 B.getInt8Ty(), Dst, ConstantInt::get(DL.
getIntPtrType(PT), Len - 1));
770 NBytes = SizeC->getZExtValue();
779 B.CreateStore(
B.getInt8(0), Dst);
795 bool NulTerm = SrcLen < NBytes;
804 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
805 NBytes = std::min(NBytes - 1, SrcLen);
810 B.CreateStore(
B.getInt8(0), Dst);
811 return ConstantInt::get(CI->
getType(), 0);
815 Type *PT =
Callee->getFunctionType()->getParamType(0);
824 Value *EndOff = ConstantInt::get(CI->
getType(), NBytes);
825 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
826 B.CreateStore(
B.getInt8(0), EndPtr);
832 return ConstantInt::get(CI->
getType(), SrcLen);
837Value *LibCallSimplifier::optimizeStringNCpy(
CallInst *CI,
bool RetEnd,
855 N = SizeC->getZExtValue();
862 Type *CharTy =
B.getInt8Ty();
863 Value *CharVal =
B.CreateLoad(CharTy, Src,
"stxncpy.char0");
864 B.CreateStore(CharVal, Dst);
870 Value *ZeroChar = ConstantInt::get(CharTy, 0);
871 Value *
Cmp =
B.CreateICmpEQ(CharVal, ZeroChar,
"stpncpy.char0cmp");
873 Value *Off1 =
B.getInt32(1);
874 Value *EndPtr =
B.CreateInBoundsGEP(CharTy, Dst, Off1,
"stpncpy.end");
875 return B.CreateSelect(Cmp, Dst, EndPtr,
"stpncpy.sel");
891 CallInst *NewCI =
B.CreateMemSet(Dst,
B.getInt8(
'\0'),
Size, MemSetAlign);
899 if (
N > SrcLen + 1) {
908 std::string SrcStr = Str.str();
911 SrcStr.resize(
N,
'\0');
912 Src =
B.CreateGlobalString(SrcStr,
"str");
915 Type *PT =
Callee->getFunctionType()->getParamType(0);
927 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
934 Type *CharTy =
B.getIntNTy(CharSize);
944 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
949 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
950 if (BoundCst->isZero())
952 return ConstantInt::get(CI->
getType(), 0);
954 if (BoundCst->isOne()) {
956 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
957 Value *ZeroChar = ConstantInt::get(CharTy, 0);
958 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
959 return B.CreateZExt(Cmp, CI->
getType());
969 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
993 if (Slice.
Array ==
nullptr) {
1012 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
1019 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
1020 NullTermIdx == ArrSize - 1)) {
1022 return B.CreateSub(ConstantInt::get(CI->
getType(), NullTermIdx),
1029 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
1032 if (LenTrue && LenFalse) {
1035 <<
"folded strlen(select) to select of constants";
1037 return B.CreateSelect(
SI->getCondition(),
1038 ConstantInt::get(CI->
getType(), LenTrue - 1),
1039 ConstantInt::get(CI->
getType(), LenFalse - 1));
1047 if (
Value *V = optimizeStringLength(CI,
B, 8))
1055 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1070 return optimizeStringLength(CI,
B, WCharSize);
1080 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1084 if (HasS1 && HasS2) {
1085 size_t I =
S1.find_first_of(S2);
1090 B.getInt64(
I),
"strpbrk");
1094 if (HasS2 && S2.
size() == 1)
1102 if (isa<ConstantPointerNull>(EndPtr)) {
1118 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1122 if (HasS1 && HasS2) {
1123 size_t Pos =
S1.find_first_not_of(S2);
1126 return ConstantInt::get(CI->
getType(), Pos);
1138 if (HasS1 &&
S1.empty())
1142 if (HasS1 && HasS2) {
1143 size_t Pos =
S1.find_first_of(S2);
1146 return ConstantInt::get(CI->
getType(), Pos);
1150 if (HasS2 && S2.
empty())
1167 StrLen,
B, DL, TLI);
1175 replaceAllUsesWith(Old, Cmp);
1186 if (HasStr2 && ToFindStr.
empty())
1190 if (HasStr1 && HasStr2) {
1197 return B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), CI->
getArgOperand(0),
1202 if (HasStr2 && ToFindStr.
size() == 1) {
1223 if (LenC->
isOne()) {
1226 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1228 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1229 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1230 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1238 if (Str.size() == 0)
1247 if (Str.size() < EndOff)
1252 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1262 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1264 if (Str.find(Str[Pos]) == Pos) {
1271 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1272 B.getInt64(Pos),
"memrchr.ptr_plus");
1273 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1278 Str = Str.substr(0, EndOff);
1286 Type *Int8Ty =
B.getInt8Ty();
1287 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1289 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1290 Value *CEqS0 =
B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1291 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1292 Value *SizeM1 =
B.CreateSub(
Size, ConstantInt::get(SizeTy, 1));
1294 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1295 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1309 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1318 if (LenC->
isOne()) {
1321 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1323 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1324 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1325 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1345 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1347 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1350 if (Str.size() == 0)
1359 size_t Pos = Str.find_first_not_of(Str[0]);
1372 Type *Int8Ty =
B.getInt8Ty();
1375 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1377 Value *Sel1 = NullPtr;
1380 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1381 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1382 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1384 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1385 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1386 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1389 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1390 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1391 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1393 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1425 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1426 reinterpret_cast<const unsigned char *
>(Str.end()));
1439 std::string SortedStr = Str.str();
1442 unsigned NonContRanges = 1;
1443 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1444 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1451 if (NonContRanges > 2)
1455 for (
unsigned char C : SortedStr)
1457 B.CreateICmpEQ(CharVal, ConstantInt::get(CharVal->
getType(),
C)));
1459 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1464 unsigned char Width =
NextPowerOf2(std::max((
unsigned char)7, Max));
1474 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1481 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1482 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1486 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1511 if (Pos == MinSize ||
1512 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1520 if (LStr[Pos] != RStr[Pos])
1525 typedef unsigned char UChar;
1526 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1527 Value *MaxSize = ConstantInt::get(
Size->getType(), Pos);
1530 return B.CreateSelect(Cmp, Zero, Res);
1542 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1544 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1546 return B.CreateSub(LHSV, RHSV,
"chardiff");
1554 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1557 Value *LHSV =
nullptr;
1558 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1561 Value *RHSV =
nullptr;
1562 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1570 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1572 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1573 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1581Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1601 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1619 return optimizeMemCmpBCmpCommon(CI,
B);
1625 if (isa<IntrinsicInst>(CI))
1645 if (
N->isNullValue())
1658 if (
N->getZExtValue() <= SrcStr.
size()) {
1667 ConstantInt::get(
N->getType(), std::min(
uint64_t(Pos + 1),
N->getZExtValue()));
1670 return Pos + 1 <=
N->getZExtValue()
1671 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1685 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1691 if (isa<IntrinsicInst>(CI))
1704 if (isa<IntrinsicInst>(CI))
1749 case LibFunc_Znwm12__hot_cold_t:
1752 LibFunc_Znwm12__hot_cold_t, HotCold);
1757 LibFunc_Znwm12__hot_cold_t, HotCold);
1759 case LibFunc_Znam12__hot_cold_t:
1762 LibFunc_Znam12__hot_cold_t, HotCold);
1767 LibFunc_Znam12__hot_cold_t, HotCold);
1769 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1773 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1775 case LibFunc_ZnwmRKSt9nothrow_t:
1779 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1781 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1785 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1787 case LibFunc_ZnamRKSt9nothrow_t:
1791 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1793 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1797 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1799 case LibFunc_ZnwmSt11align_val_t:
1803 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1805 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1809 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1811 case LibFunc_ZnamSt11align_val_t:
1815 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1817 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1821 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1824 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1828 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1831 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1835 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1838 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1842 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1876 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1877 Value *
Op = Cast->getOperand(0);
1878 if (
Op->getType()->isFloatTy())
1881 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1887 return ConstantFP::get(Const->getContext(),
F);
1895 bool isPrecise =
false) {
1926 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1927 CallerName.
size() == (CalleeName.
size() + 1) &&
1942 R =
isBinary ?
B.CreateCall(Fn, V) :
B.CreateCall(Fn, V[0]);
1949 return B.CreateFPExt(R,
B.getDoubleTy());
1955 bool isPrecise =
false) {
1962 bool isPrecise =
false) {
1978 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1979 Real =
B.CreateExtractValue(
Op, 0,
"real");
1980 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
1987 Value *RealReal =
B.CreateFMul(Real, Real);
1988 Value *ImagImag =
B.CreateFMul(Imag, Imag);
1993 *CI,
B.CreateCall(FSqrt,
B.CreateFAdd(RealReal, ImagImag),
"cabs"));
1999 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
2000 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
2003 unsigned BitWidth =
Op->getType()->getPrimitiveSizeInBits();
2005 (
BitWidth == DstWidth && isa<SIToFPInst>(I2F)))
2006 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op,
B.getIntNTy(DstWidth))
2007 :
B.CreateZExt(
Op,
B.getIntNTy(DstWidth));
2048 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2056 ExpName = TLI->
getName(LibFunc_exp);
2057 ID = Intrinsic::exp;
2058 LibFnFloat = LibFunc_expf;
2059 LibFnDouble = LibFunc_exp;
2060 LibFnLongDouble = LibFunc_expl;
2065 ExpName = TLI->
getName(LibFunc_exp2);
2066 ID = Intrinsic::exp2;
2067 LibFnFloat = LibFunc_exp2f;
2068 LibFnDouble = LibFunc_exp2;
2069 LibFnLongDouble = LibFunc_exp2l;
2086 substituteInParent(BaseFn, ExpFn);
2102 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2103 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2107 TLI, LibFunc_ldexp, LibFunc_ldexpf,
2108 LibFunc_ldexpl,
B, NoAttrs));
2112 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2115 BaseR = BaseR / *BaseF;
2117 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2119 if ((IsInteger || IsReciprocal) &&
2122 NI > 1 && NI.isPowerOf2()) {
2123 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2124 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2127 Mod, Intrinsic::exp2, Ty),
2132 LibFunc_exp2l,
B, NoAttrs));
2139 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
2141 LibFunc_exp10f, LibFunc_exp10l,
2150 "pow(1.0, y) should have been simplified earlier!");
2152 Value *Log =
nullptr;
2159 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2162 Mod, Intrinsic::exp2, Ty),
2164 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2168 LibFunc_exp2l,
B, NoAttrs));
2182 return B.CreateCall(SqrtFn, V,
"sqrt");
2186 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2192 LibFunc_sqrtl,
B, Attrs);
2230 Sqrt =
B.CreateCall(FAbsFn, Sqrt,
"abs");
2240 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2241 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2246 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2256 return B.CreateCall(
F, Args);
2278 if (
Value *Exp = replacePowWithExp(Pow,
B))
2285 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2289 return ConstantFP::get(Ty, 1.0);
2297 return B.CreateFMul(
Base,
Base,
"square");
2299 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2310 Value *Sqrt =
nullptr;
2311 if (!ExpoA.isInteger()) {
2325 if (!ExpoI.isInteger())
2348 return B.CreateFMul(PowI, Sqrt);
2355 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2362 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2363 hasFloatVersion(M,
Name)) {
2376 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2377 hasFloatVersion(M,
Name))
2389 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2390 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2392 Constant *One = ConstantFP::get(Ty, 1.0);
2397 return copyFlags(*CI,
B.CreateIntrinsic(Intrinsic::ldexp,
2398 {Ty, Exp->getType()},
2405 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2420 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2434 B.setFastMathFlags(FMF);
2437 : Intrinsic::maxnum;
2440 *CI,
B.CreateCall(
F, {CI->getArgOperand(0), CI->getArgOperand(1)}));
2451 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2459 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2465 LogID = Intrinsic::log;
2466 ExpLb = LibFunc_expf;
2467 Exp2Lb = LibFunc_exp2f;
2468 Exp10Lb = LibFunc_exp10f;
2469 PowLb = LibFunc_powf;
2472 LogID = Intrinsic::log;
2473 ExpLb = LibFunc_exp;
2474 Exp2Lb = LibFunc_exp2;
2475 Exp10Lb = LibFunc_exp10;
2476 PowLb = LibFunc_pow;
2479 LogID = Intrinsic::log;
2480 ExpLb = LibFunc_expl;
2481 Exp2Lb = LibFunc_exp2l;
2482 Exp10Lb = LibFunc_exp10l;
2483 PowLb = LibFunc_powl;
2486 LogID = Intrinsic::log2;
2487 ExpLb = LibFunc_expf;
2488 Exp2Lb = LibFunc_exp2f;
2489 Exp10Lb = LibFunc_exp10f;
2490 PowLb = LibFunc_powf;
2493 LogID = Intrinsic::log2;
2494 ExpLb = LibFunc_exp;
2495 Exp2Lb = LibFunc_exp2;
2496 Exp10Lb = LibFunc_exp10;
2497 PowLb = LibFunc_pow;
2500 LogID = Intrinsic::log2;
2501 ExpLb = LibFunc_expl;
2502 Exp2Lb = LibFunc_exp2l;
2503 Exp10Lb = LibFunc_exp10l;
2504 PowLb = LibFunc_powl;
2506 case LibFunc_log10f:
2507 LogID = Intrinsic::log10;
2508 ExpLb = LibFunc_expf;
2509 Exp2Lb = LibFunc_exp2f;
2510 Exp10Lb = LibFunc_exp10f;
2511 PowLb = LibFunc_powf;
2514 LogID = Intrinsic::log10;
2515 ExpLb = LibFunc_exp;
2516 Exp2Lb = LibFunc_exp2;
2517 Exp10Lb = LibFunc_exp10;
2518 PowLb = LibFunc_pow;
2520 case LibFunc_log10l:
2521 LogID = Intrinsic::log10;
2522 ExpLb = LibFunc_expl;
2523 Exp2Lb = LibFunc_exp2l;
2524 Exp10Lb = LibFunc_exp10l;
2525 PowLb = LibFunc_powl;
2530 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2531 LogID == Intrinsic::log10) {
2533 ExpLb = LibFunc_expf;
2534 Exp2Lb = LibFunc_exp2f;
2535 Exp10Lb = LibFunc_exp10f;
2536 PowLb = LibFunc_powf;
2538 ExpLb = LibFunc_exp;
2539 Exp2Lb = LibFunc_exp2;
2540 Exp10Lb = LibFunc_exp10;
2541 PowLb = LibFunc_pow;
2556 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2564 if (ArgID == Intrinsic::powi)
2565 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2566 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2569 substituteInParent(Arg, MulY);
2575 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2576 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2578 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2581 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2582 Eul = ConstantFP::get(Log->
getType(), 2.0);
2584 Eul = ConstantFP::get(Log->
getType(), 10.0);
2592 substituteInParent(Arg, MulY);
2612 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2617 ExpLb = LibFunc_expf;
2618 Exp2Lb = LibFunc_exp2f;
2619 Exp10Lb = LibFunc_exp10f;
2622 ExpLb = LibFunc_exp;
2623 Exp2Lb = LibFunc_exp2;
2624 Exp10Lb = LibFunc_exp10;
2627 ExpLb = LibFunc_expl;
2628 Exp2Lb = LibFunc_exp2l;
2629 Exp10Lb = LibFunc_exp10l;
2636 ExpLb = LibFunc_expf;
2637 Exp2Lb = LibFunc_exp2f;
2638 Exp10Lb = LibFunc_exp10f;
2640 ExpLb = LibFunc_exp;
2641 Exp2Lb = LibFunc_exp2;
2642 Exp10Lb = LibFunc_exp10;
2648 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2649 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2653 B.SetInsertPoint(Arg);
2656 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2671 (
Callee->getName() ==
"sqrt" ||
2672 Callee->getIntrinsicID() == Intrinsic::sqrt))
2675 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2682 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2688 Value *Op0 =
I->getOperand(0);
2689 Value *Op1 =
I->getOperand(1);
2690 Value *RepeatOp =
nullptr;
2691 Value *OtherOp =
nullptr;
2701 Value *OtherMul0, *OtherMul1;
2704 if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
2706 RepeatOp = OtherMul0;
2717 B.setFastMathFlags(
I->getFastMathFlags());
2721 Type *ArgType =
I->getType();
2723 Value *FabsCall =
B.CreateCall(Fabs, RepeatOp,
"fabs");
2729 Value *SqrtCall =
B.CreateCall(Sqrt, OtherOp,
"sqrt");
2730 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2735Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2741 if (UnsafeFPShrink &&
2744 hasFloatVersion(M,
Name))
2748 auto *OpC = dyn_cast<CallInst>(Op1);
2753 if (!CI->
isFast() || !OpC->isFast())
2766 .
Case(
"tan", LibFunc_atan)
2767 .
Case(
"atanh", LibFunc_tanh)
2768 .
Case(
"sinh", LibFunc_asinh)
2769 .
Case(
"cosh", LibFunc_acosh)
2770 .
Case(
"tanf", LibFunc_atanf)
2771 .
Case(
"atanhf", LibFunc_tanhf)
2772 .
Case(
"sinhf", LibFunc_asinhf)
2773 .
Case(
"coshf", LibFunc_acoshf)
2774 .
Case(
"tanl", LibFunc_atanl)
2775 .
Case(
"atanhl", LibFunc_tanhl)
2776 .
Case(
"sinhl", LibFunc_asinhl)
2777 .
Case(
"coshl", LibFunc_acoshl)
2778 .
Case(
"asinh", LibFunc_sinh)
2779 .
Case(
"asinhf", LibFunc_sinhf)
2780 .
Case(
"asinhl", LibFunc_sinhl)
2782 if (Func == inverseFunc)
2783 Ret = OpC->getArgOperand(0);
2805 Name =
"__sincospif_stret";
2814 Name =
"__sincospi_stret";
2823 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2825 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2828 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2832 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2833 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2836 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2839 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2840 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2842 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2844 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
2926 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2932 Value *Sin, *Cos, *SinCos;
2940 replaceAllUsesWith(
C, Res);
2943 replaceTrigInsts(SinCalls, Sin);
2944 replaceTrigInsts(CosCalls, Cos);
2945 replaceTrigInsts(SinCosCalls, SinCos);
2947 return IsSin ? Sin : Cos;
2950void LibCallSimplifier::classifyArgUse(
2955 auto *CI = dyn_cast<CallInst>(Val);
2966 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
2972 if (Func == LibFunc_sinpif)
2974 else if (Func == LibFunc_cospif)
2976 else if (Func == LibFunc_sincospif_stret)
2979 if (Func == LibFunc_sinpi)
2981 else if (Func == LibFunc_cospi)
2983 else if (Func == LibFunc_sincospi_stret)
2997 Type *ArgType =
Op->getType();
2999 Intrinsic::cttz, ArgType);
3000 Value *
V =
B.CreateCall(
F, {
Op,
B.getTrue()},
"cttz");
3001 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3002 V =
B.CreateIntCast(V, RetType,
false);
3005 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3012 Type *ArgType =
Op->getType();
3014 Intrinsic::ctlz, ArgType);
3015 Value *
V =
B.CreateCall(
F, {
Op,
B.getFalse()},
"ctlz");
3018 return B.CreateIntCast(V, CI->
getType(),
false);
3025 Value *IsNeg =
B.CreateIsNeg(
X);
3026 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3027 return B.CreateSelect(IsNeg, NegX,
X);
3033 Type *ArgType =
Op->getType();
3034 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3035 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3042 Type *ArgType =
Op->getType();
3043 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3050 ConstantInt::get(CI->
getType(), 0x7F));
3068 if (isa<ConstantPointerNull>(EndPtr)) {
3081 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3113 if (!Callee || !Callee->isDeclaration())
3122 if (StreamArg >= (
int)CI->
arg_size())
3130 return GV->
getName() ==
"stderr";
3140 if (FormatStr.
empty())
3151 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3155 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3160 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3165 if (OperandStr.
empty())
3168 if (OperandStr.
size() == 1) {
3172 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3176 if (OperandStr.
back() ==
'\n') {
3178 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3185 if (FormatStr.
back() ==
'\n' &&
3190 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3196 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3205 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3216 if (
Value *V = optimizePrintFString(CI,
B)) {
3227 Callee->getAttributes());
3229 New->setCalledFunction(IPrintFFn);
3239 Callee->getAttributes());
3241 New->setCalledFunction(SmallPrintFFn);
3249Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3268 FormatStr.
size() + 1));
3269 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3274 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3278 if (FormatStr[1] ==
'c') {
3284 B.CreateStore(V,
Ptr);
3285 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3286 B.CreateStore(
B.getInt8(0),
Ptr);
3288 return ConstantInt::get(CI->
getType(), 1);
3291 if (FormatStr[1] ==
's') {
3307 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3310 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3311 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3324 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3328 return B.CreateIntCast(Len, CI->
getType(),
false);
3337 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3348 FT,
Callee->getAttributes());
3350 New->setCalledFunction(SIPrintFFn);
3360 Callee->getAttributes());
3362 New->setCalledFunction(SmallSPrintFFn);
3378 assert(StrArg || (
N < 2 && Str.size() == 1));
3382 if (Str.size() > IntMax)
3388 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3398 NCopy = Str.size() + 1;
3403 if (NCopy && StrArg)
3417 Type *Int8Ty =
B.getInt8Ty();
3418 Value *NulOff =
B.getIntN(IntBits, NCopy);
3419 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3420 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3424Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3453 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3458 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3462 if (FormatStr[1] ==
'c') {
3468 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3476 B.CreateStore(V,
Ptr);
3477 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3478 B.CreateStore(
B.getInt8(0),
Ptr);
3479 return ConstantInt::get(CI->
getType(), 1);
3482 if (FormatStr[1] !=
's')
3491 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3495 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3504Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3506 optimizeErrorReporting(CI,
B, 0);
3529 ConstantInt::get(SizeTTy, FormatStr.
size()),
3535 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3539 if (FormatStr[1] ==
'c') {
3549 if (FormatStr[1] ==
's') {
3563 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3572 FT,
Callee->getAttributes());
3574 New->setCalledFunction(FIPrintFFn);
3583 auto SmallFPrintFFn =
3585 Callee->getAttributes());
3587 New->setCalledFunction(SmallFPrintFFn);
3596 optimizeErrorReporting(CI,
B, 3);
3601 if (SizeC && CountC) {
3606 return ConstantInt::get(CI->
getType(), 0);
3613 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3615 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3623 optimizeErrorReporting(CI,
B, 1);
3648 ConstantInt::get(SizeTTy, Len - 1),
3677bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3679 FloatFuncName +=
'f';
3683Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3694 "Optimizing string/memory libcall would change the calling convention");
3696 case LibFunc_strcat:
3697 return optimizeStrCat(CI, Builder);
3698 case LibFunc_strncat:
3699 return optimizeStrNCat(CI, Builder);
3700 case LibFunc_strchr:
3701 return optimizeStrChr(CI, Builder);
3702 case LibFunc_strrchr:
3703 return optimizeStrRChr(CI, Builder);
3704 case LibFunc_strcmp:
3705 return optimizeStrCmp(CI, Builder);
3706 case LibFunc_strncmp:
3707 return optimizeStrNCmp(CI, Builder);
3708 case LibFunc_strcpy:
3709 return optimizeStrCpy(CI, Builder);
3710 case LibFunc_stpcpy:
3711 return optimizeStpCpy(CI, Builder);
3712 case LibFunc_strlcpy:
3713 return optimizeStrLCpy(CI, Builder);
3714 case LibFunc_stpncpy:
3715 return optimizeStringNCpy(CI,
true, Builder);
3716 case LibFunc_strncpy:
3717 return optimizeStringNCpy(CI,
false, Builder);
3718 case LibFunc_strlen:
3719 return optimizeStrLen(CI, Builder);
3720 case LibFunc_strnlen:
3721 return optimizeStrNLen(CI, Builder);
3722 case LibFunc_strpbrk:
3723 return optimizeStrPBrk(CI, Builder);
3724 case LibFunc_strndup:
3725 return optimizeStrNDup(CI, Builder);
3726 case LibFunc_strtol:
3727 case LibFunc_strtod:
3728 case LibFunc_strtof:
3729 case LibFunc_strtoul:
3730 case LibFunc_strtoll:
3731 case LibFunc_strtold:
3732 case LibFunc_strtoull:
3733 return optimizeStrTo(CI, Builder);
3734 case LibFunc_strspn:
3735 return optimizeStrSpn(CI, Builder);
3736 case LibFunc_strcspn:
3737 return optimizeStrCSpn(CI, Builder);
3738 case LibFunc_strstr:
3739 return optimizeStrStr(CI, Builder);
3740 case LibFunc_memchr:
3741 return optimizeMemChr(CI, Builder);
3742 case LibFunc_memrchr:
3743 return optimizeMemRChr(CI, Builder);
3745 return optimizeBCmp(CI, Builder);
3746 case LibFunc_memcmp:
3747 return optimizeMemCmp(CI, Builder);
3748 case LibFunc_memcpy:
3749 return optimizeMemCpy(CI, Builder);
3750 case LibFunc_memccpy:
3751 return optimizeMemCCpy(CI, Builder);
3752 case LibFunc_mempcpy:
3753 return optimizeMemPCpy(CI, Builder);
3754 case LibFunc_memmove:
3755 return optimizeMemMove(CI, Builder);
3756 case LibFunc_memset:
3757 return optimizeMemSet(CI, Builder);
3758 case LibFunc_realloc:
3759 return optimizeRealloc(CI, Builder);
3760 case LibFunc_wcslen:
3761 return optimizeWcslen(CI, Builder);
3763 return optimizeBCopy(CI, Builder);
3765 case LibFunc_ZnwmRKSt9nothrow_t:
3766 case LibFunc_ZnwmSt11align_val_t:
3767 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3769 case LibFunc_ZnamRKSt9nothrow_t:
3770 case LibFunc_ZnamSt11align_val_t:
3771 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3772 case LibFunc_Znwm12__hot_cold_t:
3773 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3774 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3775 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3776 case LibFunc_Znam12__hot_cold_t:
3777 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3778 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3779 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3780 return optimizeNew(CI, Builder, Func);
3788Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3797 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3801 case LibFunc_sinpif:
3803 return optimizeSinCosPi(CI,
true, Builder);
3804 case LibFunc_cospif:
3806 return optimizeSinCosPi(CI,
false, Builder);
3810 return optimizePow(CI, Builder);
3814 return optimizeExp2(CI, Builder);
3822 return optimizeSqrt(CI, Builder);
3826 case LibFunc_log10f:
3828 case LibFunc_log10l:
3829 case LibFunc_log1pf:
3831 case LibFunc_log1pl:
3838 return optimizeLog(CI, Builder);
3846 case LibFunc_asinhf:
3847 case LibFunc_asinhl:
3852 case LibFunc_atanhf:
3853 case LibFunc_atanhl:
3854 return optimizeTrigInversionPairs(CI, Builder);
3861 case LibFunc_roundeven:
3863 case LibFunc_nearbyint:
3883 case LibFunc_copysign:
3893 return optimizeFMinFMax(CI, Builder);
3897 return optimizeCAbs(CI, Builder);
3928 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3929 UnsafeFPShrink =
true;
3933 if (!IsCallingConvC)
3937 switch (II->getIntrinsicID()) {
3938 case Intrinsic::pow:
3939 return optimizePow(CI, Builder);
3940 case Intrinsic::exp2:
3941 return optimizeExp2(CI, Builder);
3942 case Intrinsic::log:
3943 case Intrinsic::log2:
3944 case Intrinsic::log10:
3945 return optimizeLog(CI, Builder);
3946 case Intrinsic::sqrt:
3947 return optimizeSqrt(CI, Builder);
3948 case Intrinsic::memset:
3949 return optimizeMemSet(CI, Builder);
3950 case Intrinsic::memcpy:
3951 return optimizeMemCpy(CI, Builder);
3952 case Intrinsic::memmove:
3953 return optimizeMemMove(CI, Builder);
3960 if (
Value *SimplifiedFortifiedCI =
3962 return SimplifiedFortifiedCI;
3969 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
3971 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
3977 return optimizeFFS(CI, Builder);
3981 return optimizeFls(CI, Builder);
3985 return optimizeAbs(CI, Builder);
3986 case LibFunc_isdigit:
3987 return optimizeIsDigit(CI, Builder);
3988 case LibFunc_isascii:
3989 return optimizeIsAscii(CI, Builder);
3990 case LibFunc_toascii:
3991 return optimizeToAscii(CI, Builder);
3995 return optimizeAtoi(CI, Builder);
3996 case LibFunc_strtol:
3997 case LibFunc_strtoll:
3998 return optimizeStrToInt(CI, Builder,
true);
3999 case LibFunc_strtoul:
4000 case LibFunc_strtoull:
4001 return optimizeStrToInt(CI, Builder,
false);
4002 case LibFunc_printf:
4003 return optimizePrintF(CI, Builder);
4004 case LibFunc_sprintf:
4005 return optimizeSPrintF(CI, Builder);
4006 case LibFunc_snprintf:
4007 return optimizeSnPrintF(CI, Builder);
4008 case LibFunc_fprintf:
4009 return optimizeFPrintF(CI, Builder);
4010 case LibFunc_fwrite:
4011 return optimizeFWrite(CI, Builder);
4013 return optimizeFPuts(CI, Builder);
4015 return optimizePuts(CI, Builder);
4016 case LibFunc_perror:
4017 return optimizeErrorReporting(CI, Builder);
4018 case LibFunc_vfprintf:
4019 case LibFunc_fiprintf:
4020 return optimizeErrorReporting(CI, Builder, 0);
4034 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
4035 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4042void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4081bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4082 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4083 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4088 if (!Flag || !
Flag->isZero())
4097 if (ObjSizeCI->isMinusOne())
4100 if (OnlyLowerUnknownSize)
4110 return ObjSizeCI->getZExtValue() >=
Len;
4116 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4122Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4124 if (isFortifiedCallFoldable(CI, 3, 2)) {
4134Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4136 if (isFortifiedCallFoldable(CI, 3, 2)) {
4146Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4148 if (isFortifiedCallFoldable(CI, 3, 2)) {
4158Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4161 if (isFortifiedCallFoldable(CI, 3, 2))
4169Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4177 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4179 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4187 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4188 if (Func == LibFunc_strcpy_chk)
4194 if (OnlyLowerUnknownSize)
4206 Value *LenV = ConstantInt::get(SizeTTy, Len);
4210 if (Ret && Func == LibFunc_stpcpy_chk)
4211 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4212 ConstantInt::get(SizeTTy, Len - 1));
4213 return copyFlags(*CI, cast<CallInst>(Ret));
4216Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4218 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4224Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4227 if (isFortifiedCallFoldable(CI, 3, 2)) {
4228 if (Func == LibFunc_strncpy_chk)
4241Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4243 if (isFortifiedCallFoldable(CI, 4, 3))
4251Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4253 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4263Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4265 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4269 VariadicArgs,
B, TLI));
4275Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4277 if (isFortifiedCallFoldable(CI, 2))
4284Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4286 if (isFortifiedCallFoldable(CI, 3))
4294Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4296 if (isFortifiedCallFoldable(CI, 3))
4304Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4306 if (isFortifiedCallFoldable(CI, 3))
4314Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4316 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4324Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4326 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4369 case LibFunc_memcpy_chk:
4370 return optimizeMemCpyChk(CI, Builder);
4371 case LibFunc_mempcpy_chk:
4372 return optimizeMemPCpyChk(CI, Builder);
4373 case LibFunc_memmove_chk:
4374 return optimizeMemMoveChk(CI, Builder);
4375 case LibFunc_memset_chk:
4376 return optimizeMemSetChk(CI, Builder);
4377 case LibFunc_stpcpy_chk:
4378 case LibFunc_strcpy_chk:
4379 return optimizeStrpCpyChk(CI, Builder, Func);
4380 case LibFunc_strlen_chk:
4381 return optimizeStrLenChk(CI, Builder);
4382 case LibFunc_stpncpy_chk:
4383 case LibFunc_strncpy_chk:
4384 return optimizeStrpNCpyChk(CI, Builder, Func);
4385 case LibFunc_memccpy_chk:
4386 return optimizeMemCCpyChk(CI, Builder);
4387 case LibFunc_snprintf_chk:
4388 return optimizeSNPrintfChk(CI, Builder);
4389 case LibFunc_sprintf_chk:
4390 return optimizeSPrintfChk(CI, Builder);
4391 case LibFunc_strcat_chk:
4392 return optimizeStrCatChk(CI, Builder);
4393 case LibFunc_strlcat_chk:
4394 return optimizeStrLCat(CI, Builder);
4395 case LibFunc_strncat_chk:
4396 return optimizeStrNCatChk(CI, Builder);
4397 case LibFunc_strlcpy_chk:
4398 return optimizeStrLCpyChk(CI, Builder);
4399 case LibFunc_vsnprintf_chk:
4400 return optimizeVSNPrintfChk(CI, Builder);
4401 case LibFunc_vsprintf_chk:
4402 return optimizeVSPrintfChk(CI, Builder);
4411 : 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 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 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 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.
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 * 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.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU.
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
void setNoSignedZeros(bool B=true)
static FastMathFlags getFast()
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize=false)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
Take the given call instruction and return a more optimal value to replace the instruction with or 0 ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
void setDefaultOperandBundles(ArrayRef< OperandBundleDef > OpBundles)
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
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.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static bool isCallingConvCCompatible(CallBase *CI)
Returns true if call site / callee has cdecl-compatible calling conventions.
Provides information about what library functions are available for the current target.
unsigned getWCharSize(const Module &M) const
Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
unsigned getSizeTSize(const Module &M) const
Returns the size of the size_t type in bits.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
StringRef getName(LibFunc F) const
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isStructTy() const
True if this is an instance of StructType.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
OneUse_match< T > m_OneUse(const T &SubPattern)
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
Value * emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)
Emit a call to the unary function named 'Name' (e.g.
Value * emitStrChr(Value *Ptr, char C, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strchr function to the builder, for the specified pointer and character.
Value * emitPutChar(Value *Char, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the putchar function. This assumes that Char is an 'int'.
Value * emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the __memcpy_chk function to the builder.
Value * emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncpy function to the builder, for the specified pointer arguments and length.
bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI)
Value * emitHotColdNewAlignedNoThrow(Value *Num, Value *Align, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
bool isKnownNeverInfinity(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
Value * emitSPrintf(Value *Dest, Value *Fmt, ArrayRef< Value * > VariadicArgs, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the sprintf function.
bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice, unsigned ElementSize, uint64_t Offset=0)
Returns true if the value V is a pointer into a ConstantDataArray.
Value * emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memrchr function, analogously to emitMemChr.
Value * emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcat function.
bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty, LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn)
Check whether the overloaded floating point function corresponding to Ty is available.
Value * emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncat function.
bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
Value * emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsnprintf function.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Value * emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strncmp function to the builder.
Value * emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memcmp function.
Value * emitBinaryFloatFnCall(Value *Op1, Value *Op2, const TargetLibraryInfo *TLI, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs)
Emit a call to the binary function named 'Name' (e.g.
Value * emitFPutS(Value *Str, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputs function.
Value * emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strdup function to the builder, for the specified pointer.
void sort(IteratorTy Start, IteratorTy End)
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Value * emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the bcmp function.
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, and add the unsigned integer, A to the product.
uint64_t GetStringLength(const Value *V, unsigned CharSize=8)
If we can compute the length of the string pointed to by the specified pointer, return 'len+1'.
FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, LibFunc TheLibFunc, FunctionType *T, AttributeList AttributeList)
Calls getOrInsertFunction() and then makes sure to add mandatory argument attributes.
Value * emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the strlen function to the builder, for the specified pointer.
Value * emitFPutC(Value *Char, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputc function.
Value * emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the stpncpy function to the builder, for the specified pointer arguments and length.
Value * emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcat function.
Value * emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsprintf function.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
Value * emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the fwrite function.
Value * emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, ArrayRef< Value * > Args, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the snprintf function.
@ Mod
The access may modify the value stored in memory.
Value * emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the stpcpy function to the builder, for the specified pointer arguments.
@ And
Bitwise or logical AND of integers.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
Value * emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the malloc function.
Value * emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memchr function.
Value * emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Value * emitPutS(Value *Str, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the puts function. This assumes that Str is some pointer.
Value * emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the memccpy function.
Value * 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 * emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcpy function to the builder, for the specified pointer arguments.
Value * emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the mempcpy function.
uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmTowardNegative
static constexpr roundingMode rmNearestTiesToEven
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
Holds functions to get, set or test bitfields.
Represents offset+length into a ConstantDataArray.
uint64_t Length
Length of the slice.
uint64_t Offset
Slice starts at this Offset.
const ConstantDataArray * Array
ConstantDataArray pointer.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.