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)) {
2396 LibFunc_ldexp, LibFunc_ldexpf,
2411 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2425 B.setFastMathFlags(FMF);
2428 : Intrinsic::maxnum;
2431 *CI,
B.CreateCall(
F, {CI->getArgOperand(0), CI->getArgOperand(1)}));
2442 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2450 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2456 LogID = Intrinsic::log;
2457 ExpLb = LibFunc_expf;
2458 Exp2Lb = LibFunc_exp2f;
2459 Exp10Lb = LibFunc_exp10f;
2460 PowLb = LibFunc_powf;
2463 LogID = Intrinsic::log;
2464 ExpLb = LibFunc_exp;
2465 Exp2Lb = LibFunc_exp2;
2466 Exp10Lb = LibFunc_exp10;
2467 PowLb = LibFunc_pow;
2470 LogID = Intrinsic::log;
2471 ExpLb = LibFunc_expl;
2472 Exp2Lb = LibFunc_exp2l;
2473 Exp10Lb = LibFunc_exp10l;
2474 PowLb = LibFunc_powl;
2477 LogID = Intrinsic::log2;
2478 ExpLb = LibFunc_expf;
2479 Exp2Lb = LibFunc_exp2f;
2480 Exp10Lb = LibFunc_exp10f;
2481 PowLb = LibFunc_powf;
2484 LogID = Intrinsic::log2;
2485 ExpLb = LibFunc_exp;
2486 Exp2Lb = LibFunc_exp2;
2487 Exp10Lb = LibFunc_exp10;
2488 PowLb = LibFunc_pow;
2491 LogID = Intrinsic::log2;
2492 ExpLb = LibFunc_expl;
2493 Exp2Lb = LibFunc_exp2l;
2494 Exp10Lb = LibFunc_exp10l;
2495 PowLb = LibFunc_powl;
2497 case LibFunc_log10f:
2498 LogID = Intrinsic::log10;
2499 ExpLb = LibFunc_expf;
2500 Exp2Lb = LibFunc_exp2f;
2501 Exp10Lb = LibFunc_exp10f;
2502 PowLb = LibFunc_powf;
2505 LogID = Intrinsic::log10;
2506 ExpLb = LibFunc_exp;
2507 Exp2Lb = LibFunc_exp2;
2508 Exp10Lb = LibFunc_exp10;
2509 PowLb = LibFunc_pow;
2511 case LibFunc_log10l:
2512 LogID = Intrinsic::log10;
2513 ExpLb = LibFunc_expl;
2514 Exp2Lb = LibFunc_exp2l;
2515 Exp10Lb = LibFunc_exp10l;
2516 PowLb = LibFunc_powl;
2521 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2522 LogID == Intrinsic::log10) {
2524 ExpLb = LibFunc_expf;
2525 Exp2Lb = LibFunc_exp2f;
2526 Exp10Lb = LibFunc_exp10f;
2527 PowLb = LibFunc_powf;
2529 ExpLb = LibFunc_exp;
2530 Exp2Lb = LibFunc_exp2;
2531 Exp10Lb = LibFunc_exp10;
2532 PowLb = LibFunc_pow;
2547 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2555 if (ArgID == Intrinsic::powi)
2556 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2557 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2560 substituteInParent(Arg, MulY);
2566 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2567 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2569 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2572 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2573 Eul = ConstantFP::get(Log->
getType(), 2.0);
2575 Eul = ConstantFP::get(Log->
getType(), 10.0);
2583 substituteInParent(Arg, MulY);
2603 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2608 ExpLb = LibFunc_expf;
2609 Exp2Lb = LibFunc_exp2f;
2610 Exp10Lb = LibFunc_exp10f;
2613 ExpLb = LibFunc_exp;
2614 Exp2Lb = LibFunc_exp2;
2615 Exp10Lb = LibFunc_exp10;
2618 ExpLb = LibFunc_expl;
2619 Exp2Lb = LibFunc_exp2l;
2620 Exp10Lb = LibFunc_exp10l;
2627 ExpLb = LibFunc_expf;
2628 Exp2Lb = LibFunc_exp2f;
2629 Exp10Lb = LibFunc_exp10f;
2631 ExpLb = LibFunc_exp;
2632 Exp2Lb = LibFunc_exp2;
2633 Exp10Lb = LibFunc_exp10;
2639 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2640 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2644 B.SetInsertPoint(Arg);
2647 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2662 (
Callee->getName() ==
"sqrt" ||
2663 Callee->getIntrinsicID() == Intrinsic::sqrt))
2666 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2673 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2679 Value *Op0 =
I->getOperand(0);
2680 Value *Op1 =
I->getOperand(1);
2681 Value *RepeatOp =
nullptr;
2682 Value *OtherOp =
nullptr;
2692 Value *OtherMul0, *OtherMul1;
2695 if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
2697 RepeatOp = OtherMul0;
2708 B.setFastMathFlags(
I->getFastMathFlags());
2712 Type *ArgType =
I->getType();
2714 Value *FabsCall =
B.CreateCall(Fabs, RepeatOp,
"fabs");
2720 Value *SqrtCall =
B.CreateCall(Sqrt, OtherOp,
"sqrt");
2721 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2726Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2732 if (UnsafeFPShrink &&
2735 hasFloatVersion(M,
Name))
2739 auto *OpC = dyn_cast<CallInst>(Op1);
2744 if (!CI->
isFast() || !OpC->isFast())
2757 .
Case(
"tan", LibFunc_atan)
2758 .
Case(
"atanh", LibFunc_tanh)
2759 .
Case(
"sinh", LibFunc_asinh)
2760 .
Case(
"cosh", LibFunc_acosh)
2761 .
Case(
"tanf", LibFunc_atanf)
2762 .
Case(
"atanhf", LibFunc_tanhf)
2763 .
Case(
"sinhf", LibFunc_asinhf)
2764 .
Case(
"coshf", LibFunc_acoshf)
2765 .
Case(
"tanl", LibFunc_atanl)
2766 .
Case(
"atanhl", LibFunc_tanhl)
2767 .
Case(
"sinhl", LibFunc_asinhl)
2768 .
Case(
"coshl", LibFunc_acoshl)
2769 .
Case(
"asinh", LibFunc_sinh)
2770 .
Case(
"asinhf", LibFunc_sinhf)
2771 .
Case(
"asinhl", LibFunc_sinhl)
2773 if (Func == inverseFunc)
2774 Ret = OpC->getArgOperand(0);
2796 Name =
"__sincospif_stret";
2805 Name =
"__sincospi_stret";
2814 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2816 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2819 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2823 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2824 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2827 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2830 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2831 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2833 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2835 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
2917 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2923 Value *Sin, *Cos, *SinCos;
2931 replaceAllUsesWith(
C, Res);
2934 replaceTrigInsts(SinCalls, Sin);
2935 replaceTrigInsts(CosCalls, Cos);
2936 replaceTrigInsts(SinCosCalls, SinCos);
2938 return IsSin ? Sin : Cos;
2941void LibCallSimplifier::classifyArgUse(
2946 auto *CI = dyn_cast<CallInst>(Val);
2957 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
2963 if (Func == LibFunc_sinpif)
2965 else if (Func == LibFunc_cospif)
2967 else if (Func == LibFunc_sincospif_stret)
2970 if (Func == LibFunc_sinpi)
2972 else if (Func == LibFunc_cospi)
2974 else if (Func == LibFunc_sincospi_stret)
2988 Type *ArgType =
Op->getType();
2990 Intrinsic::cttz, ArgType);
2991 Value *
V =
B.CreateCall(
F, {
Op,
B.getTrue()},
"cttz");
2992 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
2993 V =
B.CreateIntCast(V, RetType,
false);
2996 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3003 Type *ArgType =
Op->getType();
3005 Intrinsic::ctlz, ArgType);
3006 Value *
V =
B.CreateCall(
F, {
Op,
B.getFalse()},
"ctlz");
3009 return B.CreateIntCast(V, CI->
getType(),
false);
3016 Value *IsNeg =
B.CreateIsNeg(
X);
3017 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3018 return B.CreateSelect(IsNeg, NegX,
X);
3024 Type *ArgType =
Op->getType();
3025 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3026 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3033 Type *ArgType =
Op->getType();
3034 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3041 ConstantInt::get(CI->
getType(), 0x7F));
3059 if (isa<ConstantPointerNull>(EndPtr)) {
3072 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3104 if (!Callee || !Callee->isDeclaration())
3113 if (StreamArg >= (
int)CI->
arg_size())
3121 return GV->
getName() ==
"stderr";
3131 if (FormatStr.
empty())
3142 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3146 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3151 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3156 if (OperandStr.
empty())
3159 if (OperandStr.
size() == 1) {
3163 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3167 if (OperandStr.
back() ==
'\n') {
3169 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3176 if (FormatStr.
back() ==
'\n' &&
3181 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3187 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3196 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3207 if (
Value *V = optimizePrintFString(CI,
B)) {
3218 Callee->getAttributes());
3220 New->setCalledFunction(IPrintFFn);
3230 Callee->getAttributes());
3232 New->setCalledFunction(SmallPrintFFn);
3240Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3259 FormatStr.
size() + 1));
3260 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3265 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3269 if (FormatStr[1] ==
'c') {
3275 B.CreateStore(V,
Ptr);
3276 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3277 B.CreateStore(
B.getInt8(0),
Ptr);
3279 return ConstantInt::get(CI->
getType(), 1);
3282 if (FormatStr[1] ==
's') {
3298 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3301 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3302 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3315 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3319 return B.CreateIntCast(Len, CI->
getType(),
false);
3328 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3339 FT,
Callee->getAttributes());
3341 New->setCalledFunction(SIPrintFFn);
3351 Callee->getAttributes());
3353 New->setCalledFunction(SmallSPrintFFn);
3369 assert(StrArg || (
N < 2 && Str.size() == 1));
3373 if (Str.size() > IntMax)
3379 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3389 NCopy = Str.size() + 1;
3394 if (NCopy && StrArg)
3408 Type *Int8Ty =
B.getInt8Ty();
3409 Value *NulOff =
B.getIntN(IntBits, NCopy);
3410 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3411 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3415Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3444 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3449 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3453 if (FormatStr[1] ==
'c') {
3459 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3467 B.CreateStore(V,
Ptr);
3468 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3469 B.CreateStore(
B.getInt8(0),
Ptr);
3470 return ConstantInt::get(CI->
getType(), 1);
3473 if (FormatStr[1] !=
's')
3482 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3486 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3495Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3497 optimizeErrorReporting(CI,
B, 0);
3520 ConstantInt::get(SizeTTy, FormatStr.
size()),
3526 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3530 if (FormatStr[1] ==
'c') {
3540 if (FormatStr[1] ==
's') {
3554 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3563 FT,
Callee->getAttributes());
3565 New->setCalledFunction(FIPrintFFn);
3574 auto SmallFPrintFFn =
3576 Callee->getAttributes());
3578 New->setCalledFunction(SmallFPrintFFn);
3587 optimizeErrorReporting(CI,
B, 3);
3592 if (SizeC && CountC) {
3597 return ConstantInt::get(CI->
getType(), 0);
3604 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3606 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3614 optimizeErrorReporting(CI,
B, 1);
3639 ConstantInt::get(SizeTTy, Len - 1),
3668bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3670 FloatFuncName +=
'f';
3674Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3685 "Optimizing string/memory libcall would change the calling convention");
3687 case LibFunc_strcat:
3688 return optimizeStrCat(CI, Builder);
3689 case LibFunc_strncat:
3690 return optimizeStrNCat(CI, Builder);
3691 case LibFunc_strchr:
3692 return optimizeStrChr(CI, Builder);
3693 case LibFunc_strrchr:
3694 return optimizeStrRChr(CI, Builder);
3695 case LibFunc_strcmp:
3696 return optimizeStrCmp(CI, Builder);
3697 case LibFunc_strncmp:
3698 return optimizeStrNCmp(CI, Builder);
3699 case LibFunc_strcpy:
3700 return optimizeStrCpy(CI, Builder);
3701 case LibFunc_stpcpy:
3702 return optimizeStpCpy(CI, Builder);
3703 case LibFunc_strlcpy:
3704 return optimizeStrLCpy(CI, Builder);
3705 case LibFunc_stpncpy:
3706 return optimizeStringNCpy(CI,
true, Builder);
3707 case LibFunc_strncpy:
3708 return optimizeStringNCpy(CI,
false, Builder);
3709 case LibFunc_strlen:
3710 return optimizeStrLen(CI, Builder);
3711 case LibFunc_strnlen:
3712 return optimizeStrNLen(CI, Builder);
3713 case LibFunc_strpbrk:
3714 return optimizeStrPBrk(CI, Builder);
3715 case LibFunc_strndup:
3716 return optimizeStrNDup(CI, Builder);
3717 case LibFunc_strtol:
3718 case LibFunc_strtod:
3719 case LibFunc_strtof:
3720 case LibFunc_strtoul:
3721 case LibFunc_strtoll:
3722 case LibFunc_strtold:
3723 case LibFunc_strtoull:
3724 return optimizeStrTo(CI, Builder);
3725 case LibFunc_strspn:
3726 return optimizeStrSpn(CI, Builder);
3727 case LibFunc_strcspn:
3728 return optimizeStrCSpn(CI, Builder);
3729 case LibFunc_strstr:
3730 return optimizeStrStr(CI, Builder);
3731 case LibFunc_memchr:
3732 return optimizeMemChr(CI, Builder);
3733 case LibFunc_memrchr:
3734 return optimizeMemRChr(CI, Builder);
3736 return optimizeBCmp(CI, Builder);
3737 case LibFunc_memcmp:
3738 return optimizeMemCmp(CI, Builder);
3739 case LibFunc_memcpy:
3740 return optimizeMemCpy(CI, Builder);
3741 case LibFunc_memccpy:
3742 return optimizeMemCCpy(CI, Builder);
3743 case LibFunc_mempcpy:
3744 return optimizeMemPCpy(CI, Builder);
3745 case LibFunc_memmove:
3746 return optimizeMemMove(CI, Builder);
3747 case LibFunc_memset:
3748 return optimizeMemSet(CI, Builder);
3749 case LibFunc_realloc:
3750 return optimizeRealloc(CI, Builder);
3751 case LibFunc_wcslen:
3752 return optimizeWcslen(CI, Builder);
3754 return optimizeBCopy(CI, Builder);
3756 case LibFunc_ZnwmRKSt9nothrow_t:
3757 case LibFunc_ZnwmSt11align_val_t:
3758 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3760 case LibFunc_ZnamRKSt9nothrow_t:
3761 case LibFunc_ZnamSt11align_val_t:
3762 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3763 case LibFunc_Znwm12__hot_cold_t:
3764 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3765 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3766 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3767 case LibFunc_Znam12__hot_cold_t:
3768 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3769 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3770 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3771 return optimizeNew(CI, Builder, Func);
3779Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3788 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3792 case LibFunc_sinpif:
3794 return optimizeSinCosPi(CI,
true, Builder);
3795 case LibFunc_cospif:
3797 return optimizeSinCosPi(CI,
false, Builder);
3801 return optimizePow(CI, Builder);
3805 return optimizeExp2(CI, Builder);
3813 return optimizeSqrt(CI, Builder);
3817 case LibFunc_log10f:
3819 case LibFunc_log10l:
3820 case LibFunc_log1pf:
3822 case LibFunc_log1pl:
3829 return optimizeLog(CI, Builder);
3837 case LibFunc_asinhf:
3838 case LibFunc_asinhl:
3843 case LibFunc_atanhf:
3844 case LibFunc_atanhl:
3845 return optimizeTrigInversionPairs(CI, Builder);
3852 case LibFunc_roundeven:
3854 case LibFunc_nearbyint:
3874 case LibFunc_copysign:
3884 return optimizeFMinFMax(CI, Builder);
3888 return optimizeCAbs(CI, Builder);
3919 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3920 UnsafeFPShrink =
true;
3924 if (!IsCallingConvC)
3928 switch (II->getIntrinsicID()) {
3929 case Intrinsic::pow:
3930 return optimizePow(CI, Builder);
3931 case Intrinsic::exp2:
3932 return optimizeExp2(CI, Builder);
3933 case Intrinsic::log:
3934 case Intrinsic::log2:
3935 case Intrinsic::log10:
3936 return optimizeLog(CI, Builder);
3937 case Intrinsic::sqrt:
3938 return optimizeSqrt(CI, Builder);
3939 case Intrinsic::memset:
3940 return optimizeMemSet(CI, Builder);
3941 case Intrinsic::memcpy:
3942 return optimizeMemCpy(CI, Builder);
3943 case Intrinsic::memmove:
3944 return optimizeMemMove(CI, Builder);
3951 if (
Value *SimplifiedFortifiedCI =
3953 return SimplifiedFortifiedCI;
3960 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
3962 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
3968 return optimizeFFS(CI, Builder);
3972 return optimizeFls(CI, Builder);
3976 return optimizeAbs(CI, Builder);
3977 case LibFunc_isdigit:
3978 return optimizeIsDigit(CI, Builder);
3979 case LibFunc_isascii:
3980 return optimizeIsAscii(CI, Builder);
3981 case LibFunc_toascii:
3982 return optimizeToAscii(CI, Builder);
3986 return optimizeAtoi(CI, Builder);
3987 case LibFunc_strtol:
3988 case LibFunc_strtoll:
3989 return optimizeStrToInt(CI, Builder,
true);
3990 case LibFunc_strtoul:
3991 case LibFunc_strtoull:
3992 return optimizeStrToInt(CI, Builder,
false);
3993 case LibFunc_printf:
3994 return optimizePrintF(CI, Builder);
3995 case LibFunc_sprintf:
3996 return optimizeSPrintF(CI, Builder);
3997 case LibFunc_snprintf:
3998 return optimizeSnPrintF(CI, Builder);
3999 case LibFunc_fprintf:
4000 return optimizeFPrintF(CI, Builder);
4001 case LibFunc_fwrite:
4002 return optimizeFWrite(CI, Builder);
4004 return optimizeFPuts(CI, Builder);
4006 return optimizePuts(CI, Builder);
4007 case LibFunc_perror:
4008 return optimizeErrorReporting(CI, Builder);
4009 case LibFunc_vfprintf:
4010 case LibFunc_fiprintf:
4011 return optimizeErrorReporting(CI, Builder, 0);
4025 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
4026 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4033void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4072bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4073 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4074 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4079 if (!Flag || !
Flag->isZero())
4088 if (ObjSizeCI->isMinusOne())
4091 if (OnlyLowerUnknownSize)
4101 return ObjSizeCI->getZExtValue() >=
Len;
4107 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4113Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4115 if (isFortifiedCallFoldable(CI, 3, 2)) {
4125Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4127 if (isFortifiedCallFoldable(CI, 3, 2)) {
4137Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4139 if (isFortifiedCallFoldable(CI, 3, 2)) {
4149Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4152 if (isFortifiedCallFoldable(CI, 3, 2))
4160Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4168 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4170 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4178 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4179 if (Func == LibFunc_strcpy_chk)
4185 if (OnlyLowerUnknownSize)
4197 Value *LenV = ConstantInt::get(SizeTTy, Len);
4201 if (Ret && Func == LibFunc_stpcpy_chk)
4202 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4203 ConstantInt::get(SizeTTy, Len - 1));
4204 return copyFlags(*CI, cast<CallInst>(Ret));
4207Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4209 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4215Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4218 if (isFortifiedCallFoldable(CI, 3, 2)) {
4219 if (Func == LibFunc_strncpy_chk)
4232Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4234 if (isFortifiedCallFoldable(CI, 4, 3))
4242Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4244 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4254Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4256 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4260 VariadicArgs,
B, TLI));
4266Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4268 if (isFortifiedCallFoldable(CI, 2))
4275Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4277 if (isFortifiedCallFoldable(CI, 3))
4285Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4287 if (isFortifiedCallFoldable(CI, 3))
4295Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4297 if (isFortifiedCallFoldable(CI, 3))
4305Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4307 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4315Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4317 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4360 case LibFunc_memcpy_chk:
4361 return optimizeMemCpyChk(CI, Builder);
4362 case LibFunc_mempcpy_chk:
4363 return optimizeMemPCpyChk(CI, Builder);
4364 case LibFunc_memmove_chk:
4365 return optimizeMemMoveChk(CI, Builder);
4366 case LibFunc_memset_chk:
4367 return optimizeMemSetChk(CI, Builder);
4368 case LibFunc_stpcpy_chk:
4369 case LibFunc_strcpy_chk:
4370 return optimizeStrpCpyChk(CI, Builder, Func);
4371 case LibFunc_strlen_chk:
4372 return optimizeStrLenChk(CI, Builder);
4373 case LibFunc_stpncpy_chk:
4374 case LibFunc_strncpy_chk:
4375 return optimizeStrpNCpyChk(CI, Builder, Func);
4376 case LibFunc_memccpy_chk:
4377 return optimizeMemCCpyChk(CI, Builder);
4378 case LibFunc_snprintf_chk:
4379 return optimizeSNPrintfChk(CI, Builder);
4380 case LibFunc_sprintf_chk:
4381 return optimizeSPrintfChk(CI, Builder);
4382 case LibFunc_strcat_chk:
4383 return optimizeStrCatChk(CI, Builder);
4384 case LibFunc_strlcat_chk:
4385 return optimizeStrLCat(CI, Builder);
4386 case LibFunc_strncat_chk:
4387 return optimizeStrNCatChk(CI, Builder);
4388 case LibFunc_strlcpy_chk:
4389 return optimizeStrLCpyChk(CI, Builder);
4390 case LibFunc_vsnprintf_chk:
4391 return optimizeVSNPrintfChk(CI, Builder);
4392 case LibFunc_vsprintf_chk:
4393 return optimizeVSPrintfChk(CI, Builder);
4402 : 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.