42using namespace PatternMatch;
47 cl::desc(
"Enable unsafe double to float "
48 "shrinking for math lib calls"));
55 cl::desc(
"Enable hot/cold operator new library calls"));
59 "Enable optimization of existing hot/cold operator new library calls"));
66struct HotColdHintParser :
public cl::parser<unsigned> {
71 return O.error(
"'" + Arg +
"' value invalid for uint argument!");
74 return O.error(
"'" + Arg +
"' value must be in the range [0, 255]!");
88 cl::desc(
"Value to pass to hot/cold operator new for cold allocation"));
91 cl::desc(
"Value to pass to hot/cold operator new for "
92 "notcold (warm) allocation"));
95 cl::desc(
"Value to pass to hot/cold operator new for hot allocation"));
102 return Func == LibFunc_abs || Func == LibFunc_labs ||
103 Func == LibFunc_llabs || Func == LibFunc_strlen;
108 for (
User *U : V->users()) {
109 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
110 if (IC->isEquality() && IC->getOperand(1) == With)
120 return OI->getType()->isFloatingPointTy();
126 return OI->getType()->isFP128Ty();
139 if (Base < 2 || Base > 36)
148 if (!isSpace((
unsigned char)Str[
Offset])) {
159 bool Negate = Str[0] ==
'-';
160 if (Str[0] ==
'-' || Str[0] ==
'+') {
161 Str = Str.drop_front();
171 unsigned NBits =
RetTy->getPrimitiveSizeInBits();
172 uint64_t Max = AsSigned && Negate ? 1 : 0;
176 if (Str.size() > 1) {
178 if (toUpper((
unsigned char)Str[1]) ==
'X') {
179 if (Str.size() == 2 || (
Base &&
Base != 16))
184 Str = Str.drop_front(2);
190 }
else if (
Base == 0)
200 for (
unsigned i = 0; i != Str.size(); ++i) {
201 unsigned char DigVal = Str[i];
203 DigVal = DigVal -
'0';
205 DigVal = toUpper(DigVal);
207 DigVal = DigVal -
'A' + 10;
220 if (VFlow || Result > Max)
228 Value *StrEnd =
B.CreateInBoundsGEP(
B.getInt8Ty(), StrBeg, Off,
"endptr");
229 B.CreateStore(StrEnd, EndPtr);
236 return ConstantInt::get(
RetTy, Result);
240 for (
User *U : V->users()) {
241 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
242 if (
Constant *
C = dyn_cast<Constant>(IC->getOperand(1)))
243 if (
C->isNullValue())
271 for (
unsigned ArgNo : ArgNos) {
272 uint64_t DerefBytes = DereferenceableBytes;
277 DereferenceableBytes);
296 for (
unsigned ArgNo : ArgNos) {
322 DerefMin = std::min(
X->getZExtValue(),
Y->getZExtValue());
336 if (
auto *NewCI = dyn_cast_or_null<CallInst>(New))
343 NewCI->
getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
350 return Len >= Str.size() ? Str : Str.substr(0, Len);
375 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
389 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
395 ConstantInt::get(DL.
getIntPtrType(Src->getContext()), Len + 1));
439 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
452 Type *CharTy =
B.getInt8Ty();
453 Value *Char0 =
B.CreateLoad(CharTy, Src);
454 CharVal =
B.CreateTrunc(CharVal, CharTy);
455 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
459 Value *
And =
B.CreateICmpNE(NBytes, Zero);
460 Cmp =
B.CreateLogicalAnd(
And, Cmp);
464 return B.CreateSelect(Cmp, Src, NullPtr);
477 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
488 if (!FT->getParamType(1)->isIntegerTy(IntBits))
495 ConstantInt::get(SizeTTy, Len),
B,
504 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
513 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
526 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
532 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
538 if (CharC && CharC->
isZero())
549 Value *
Size = ConstantInt::get(SizeTTy, NBytes);
556 return ConstantInt::get(CI->
getType(), 0);
563 if (HasStr1 && HasStr2)
564 return ConstantInt::get(CI->
getType(),
565 std::clamp(Str1.
compare(Str2), -1, 1));
567 if (HasStr1 && Str1.
empty())
568 return B.CreateNeg(
B.CreateZExt(
569 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
571 if (HasStr2 && Str2.
empty())
572 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
587 std::min(Len1, Len2)),
592 if (!HasStr1 && HasStr2) {
599 }
else if (HasStr1 && !HasStr2) {
623 return ConstantInt::get(CI->
getType(), 0);
635 return ConstantInt::get(CI->
getType(), 0);
645 if (HasStr1 && HasStr2) {
649 return ConstantInt::get(CI->
getType(),
650 std::clamp(SubStr1.
compare(SubStr2), -1, 1));
653 if (HasStr1 && Str1.
empty())
654 return B.CreateNeg(
B.CreateZExt(
655 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
657 if (HasStr2 && Str2.
empty())
658 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
669 if (!HasStr1 && HasStr2) {
670 Len2 = std::min(Len2,
Length);
677 }
else if (HasStr1 && !HasStr2) {
678 Len1 = std::min(Len1,
Length);
694 if (SrcLen &&
Size) {
696 if (SrcLen <= Size->getZExtValue() + 1)
735 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
745 Type *PT =
Callee->getFunctionType()->getParamType(0);
747 Value *DstEnd =
B.CreateInBoundsGEP(
748 B.getInt8Ty(), Dst, ConstantInt::get(DL.
getIntPtrType(PT), Len - 1));
771 NBytes = SizeC->getZExtValue();
780 B.CreateStore(
B.getInt8(0), Dst);
796 bool NulTerm = SrcLen < NBytes;
805 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
806 NBytes = std::min(NBytes - 1, SrcLen);
811 B.CreateStore(
B.getInt8(0), Dst);
812 return ConstantInt::get(CI->
getType(), 0);
816 Type *PT =
Callee->getFunctionType()->getParamType(0);
825 Value *EndOff = ConstantInt::get(CI->
getType(), NBytes);
826 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
827 B.CreateStore(
B.getInt8(0), EndPtr);
833 return ConstantInt::get(CI->
getType(), SrcLen);
838Value *LibCallSimplifier::optimizeStringNCpy(
CallInst *CI,
bool RetEnd,
856 N = SizeC->getZExtValue();
863 Type *CharTy =
B.getInt8Ty();
864 Value *CharVal =
B.CreateLoad(CharTy, Src,
"stxncpy.char0");
865 B.CreateStore(CharVal, Dst);
871 Value *ZeroChar = ConstantInt::get(CharTy, 0);
872 Value *
Cmp =
B.CreateICmpEQ(CharVal, ZeroChar,
"stpncpy.char0cmp");
874 Value *Off1 =
B.getInt32(1);
875 Value *EndPtr =
B.CreateInBoundsGEP(CharTy, Dst, Off1,
"stpncpy.end");
876 return B.CreateSelect(Cmp, Dst, EndPtr,
"stpncpy.sel");
892 CallInst *NewCI =
B.CreateMemSet(Dst,
B.getInt8(
'\0'),
Size, MemSetAlign);
900 if (
N > SrcLen + 1) {
909 std::string SrcStr = Str.str();
912 SrcStr.resize(
N,
'\0');
913 Src =
B.CreateGlobalString(SrcStr,
"str");
916 Type *PT =
Callee->getFunctionType()->getParamType(0);
928 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
935 Type *CharTy =
B.getIntNTy(CharSize);
945 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
950 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
951 if (BoundCst->isZero())
953 return ConstantInt::get(CI->
getType(), 0);
955 if (BoundCst->isOne()) {
957 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
958 Value *ZeroChar = ConstantInt::get(CharTy, 0);
959 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
960 return B.CreateZExt(Cmp, CI->
getType());
970 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
994 if (Slice.
Array ==
nullptr) {
1013 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
1020 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
1021 NullTermIdx == ArrSize - 1)) {
1023 return B.CreateSub(ConstantInt::get(CI->
getType(), NullTermIdx),
1030 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
1033 if (LenTrue && LenFalse) {
1036 <<
"folded strlen(select) to select of constants";
1038 return B.CreateSelect(
SI->getCondition(),
1039 ConstantInt::get(CI->
getType(), LenTrue - 1),
1040 ConstantInt::get(CI->
getType(), LenFalse - 1));
1048 if (
Value *V = optimizeStringLength(CI,
B, 8))
1056 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1071 return optimizeStringLength(CI,
B, WCharSize);
1081 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1085 if (HasS1 && HasS2) {
1086 size_t I =
S1.find_first_of(S2);
1091 B.getInt64(
I),
"strpbrk");
1095 if (HasS2 && S2.
size() == 1)
1103 if (isa<ConstantPointerNull>(EndPtr)) {
1119 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1123 if (HasS1 && HasS2) {
1124 size_t Pos =
S1.find_first_not_of(S2);
1127 return ConstantInt::get(CI->
getType(), Pos);
1139 if (HasS1 &&
S1.empty())
1143 if (HasS1 && HasS2) {
1144 size_t Pos =
S1.find_first_of(S2);
1147 return ConstantInt::get(CI->
getType(), Pos);
1151 if (HasS2 && S2.
empty())
1168 StrLen,
B, DL, TLI);
1176 replaceAllUsesWith(Old, Cmp);
1187 if (HasStr2 && ToFindStr.
empty())
1191 if (HasStr1 && HasStr2) {
1198 return B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), CI->
getArgOperand(0),
1203 if (HasStr2 && ToFindStr.
size() == 1) {
1224 if (LenC->
isOne()) {
1227 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1229 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1230 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1231 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1239 if (Str.size() == 0)
1248 if (Str.size() < EndOff)
1253 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1263 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1265 if (Str.find(Str[Pos]) == Pos) {
1272 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1273 B.getInt64(Pos),
"memrchr.ptr_plus");
1274 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1279 Str = Str.substr(0, EndOff);
1287 Type *Int8Ty =
B.getInt8Ty();
1288 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1290 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1291 Value *CEqS0 =
B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1292 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1293 Value *SizeM1 =
B.CreateSub(
Size, ConstantInt::get(SizeTy, 1));
1295 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1296 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1310 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1319 if (LenC->
isOne()) {
1322 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1324 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1325 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1326 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1346 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1348 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1351 if (Str.size() == 0)
1360 size_t Pos = Str.find_first_not_of(Str[0]);
1373 Type *Int8Ty =
B.getInt8Ty();
1376 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1378 Value *Sel1 = NullPtr;
1381 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1382 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1383 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1385 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1386 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1387 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1390 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1391 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1392 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1394 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1426 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1427 reinterpret_cast<const unsigned char *
>(Str.end()));
1440 std::string SortedStr = Str.str();
1443 unsigned NonContRanges = 1;
1444 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1445 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1452 if (NonContRanges > 2)
1456 for (
unsigned char C : SortedStr)
1458 B.CreateICmpEQ(CharVal, ConstantInt::get(CharVal->
getType(),
C)));
1460 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1465 unsigned char Width =
NextPowerOf2(std::max((
unsigned char)7, Max));
1475 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1482 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1483 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1487 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1512 if (Pos == MinSize ||
1513 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1521 if (LStr[Pos] != RStr[Pos])
1526 typedef unsigned char UChar;
1527 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1528 Value *MaxSize = ConstantInt::get(
Size->getType(), Pos);
1531 return B.CreateSelect(Cmp, Zero, Res);
1543 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1545 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1547 return B.CreateSub(LHSV, RHSV,
"chardiff");
1555 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1558 Value *LHSV =
nullptr;
1559 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1562 Value *RHSV =
nullptr;
1563 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1571 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1573 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1574 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1582Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1602 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1620 return optimizeMemCmpBCmpCommon(CI,
B);
1626 if (isa<IntrinsicInst>(CI))
1646 if (
N->isNullValue())
1659 if (
N->getZExtValue() <= SrcStr.
size()) {
1668 ConstantInt::get(
N->getType(), std::min(
uint64_t(Pos + 1),
N->getZExtValue()));
1671 return Pos + 1 <=
N->getZExtValue()
1672 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1686 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1692 if (isa<IntrinsicInst>(CI))
1705 if (isa<IntrinsicInst>(CI))
1750 case LibFunc_Znwm12__hot_cold_t:
1753 LibFunc_Znwm12__hot_cold_t, HotCold);
1758 LibFunc_Znwm12__hot_cold_t, HotCold);
1760 case LibFunc_Znam12__hot_cold_t:
1763 LibFunc_Znam12__hot_cold_t, HotCold);
1768 LibFunc_Znam12__hot_cold_t, HotCold);
1770 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1774 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1776 case LibFunc_ZnwmRKSt9nothrow_t:
1780 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1782 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1786 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1788 case LibFunc_ZnamRKSt9nothrow_t:
1792 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1794 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1798 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1800 case LibFunc_ZnwmSt11align_val_t:
1804 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1806 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1810 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1812 case LibFunc_ZnamSt11align_val_t:
1816 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1818 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1822 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1825 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1829 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1832 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1836 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1839 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1843 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1870 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1871 Value *
Op = Cast->getOperand(0);
1872 if (
Op->getType()->isFloatTy())
1875 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1881 return ConstantFP::get(Const->getContext(),
F);
1889 bool isPrecise =
false) {
1920 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1921 CallerName.
size() == (CalleeName.
size() + 1) &&
1936 R =
isBinary ?
B.CreateCall(Fn, V) :
B.CreateCall(Fn, V[0]);
1943 return B.CreateFPExt(R,
B.getDoubleTy());
1949 bool isPrecise =
false) {
1956 bool isPrecise =
false) {
1970 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1972 Real =
B.CreateExtractValue(
Op, 0,
"real");
1973 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
1983 Value *AbsOp =
nullptr;
1984 if (
ConstantFP *ConstReal = dyn_cast<ConstantFP>(Real)) {
1985 if (ConstReal->isZero())
1988 }
else if (
ConstantFP *ConstImag = dyn_cast<ConstantFP>(Imag)) {
1989 if (ConstImag->isZero())
1998 *CI,
B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp,
nullptr,
"cabs"));
2009 Value *RealReal =
B.CreateFMul(Real, Real);
2010 Value *ImagImag =
B.CreateFMul(Imag, Imag);
2012 return copyFlags(*CI,
B.CreateUnaryIntrinsic(Intrinsic::sqrt,
2013 B.CreateFAdd(RealReal, ImagImag),
2020 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
2021 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
2024 unsigned BitWidth =
Op->getType()->getScalarSizeInBits();
2025 if (
BitWidth < DstWidth || (
BitWidth == DstWidth && isa<SIToFPInst>(I2F))) {
2026 Type *IntTy =
Op->getType()->getWithNewBitWidth(DstWidth);
2027 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op, IntTy)
2028 :
B.CreateZExt(
Op, IntTy);
2069 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2077 ExpName = TLI->
getName(LibFunc_exp);
2078 ID = Intrinsic::exp;
2079 LibFnFloat = LibFunc_expf;
2080 LibFnDouble = LibFunc_exp;
2081 LibFnLongDouble = LibFunc_expl;
2086 ExpName = TLI->
getName(LibFunc_exp2);
2087 ID = Intrinsic::exp2;
2088 LibFnFloat = LibFunc_exp2f;
2089 LibFnDouble = LibFunc_exp2;
2090 LibFnLongDouble = LibFunc_exp2l;
2097 ?
B.CreateUnaryIntrinsic(
ID,
FMul,
nullptr, ExpName)
2106 substituteInParent(BaseFn, ExpFn);
2123 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2125 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2130 Constant *One = ConstantFP::get(Ty, 1.0);
2133 return copyFlags(*Pow,
B.CreateIntrinsic(Intrinsic::ldexp,
2134 {Ty, ExpoI->getType()},
2135 {One, ExpoI}, Pow,
"exp2"));
2139 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2140 LibFunc_ldexpl,
B, NoAttrs));
2145 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2148 BaseR = BaseR / *BaseF;
2150 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2152 if ((IsInteger || IsReciprocal) &&
2155 NI > 1 && NI.isPowerOf2()) {
2156 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2157 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2159 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2164 LibFunc_exp2l,
B, NoAttrs));
2170 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l)) {
2174 B.CreateIntrinsic(Intrinsic::exp10, {Ty}, {Expo}, Pow,
"exp10");
2179 LibFunc_exp10f, LibFunc_exp10l,
2189 "pow(1.0, y) should have been simplified earlier!");
2191 Value *Log =
nullptr;
2198 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2200 return copyFlags(*Pow,
B.CreateUnaryIntrinsic(Intrinsic::exp2,
FMul,
2202 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2206 LibFunc_exp2l,
B, NoAttrs));
2218 return B.CreateUnaryIntrinsic(Intrinsic::sqrt, V,
nullptr,
"sqrt");
2221 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2227 LibFunc_sqrtl,
B, Attrs);
2264 Sqrt =
B.CreateUnaryIntrinsic(Intrinsic::fabs, Sqrt,
nullptr,
"abs");
2273 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2274 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2279 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2288 return B.CreateIntrinsic(Intrinsic::powi, Types, Args);
2310 if (
Value *Exp = replacePowWithExp(Pow,
B))
2317 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2321 return ConstantFP::get(Ty, 1.0);
2329 return B.CreateFMul(
Base,
Base,
"square");
2331 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2342 Value *Sqrt =
nullptr;
2343 if (!ExpoA.isInteger()) {
2357 if (!ExpoI.isInteger())
2380 return B.CreateFMul(PowI, Sqrt);
2387 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2394 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2395 hasFloatVersion(M,
Name)) {
2408 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2409 hasFloatVersion(M,
Name))
2418 const bool UseIntrinsic =
Callee->isIntrinsic();
2427 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2429 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2431 Constant *One = ConstantFP::get(Ty, 1.0);
2434 return copyFlags(*CI,
B.CreateIntrinsic(Intrinsic::ldexp,
2435 {Ty, Exp->getType()},
2442 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2457 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2471 B.setFastMathFlags(FMF);
2474 : Intrinsic::maxnum;
2487 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2495 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2501 LogID = Intrinsic::log;
2502 ExpLb = LibFunc_expf;
2503 Exp2Lb = LibFunc_exp2f;
2504 Exp10Lb = LibFunc_exp10f;
2505 PowLb = LibFunc_powf;
2508 LogID = Intrinsic::log;
2509 ExpLb = LibFunc_exp;
2510 Exp2Lb = LibFunc_exp2;
2511 Exp10Lb = LibFunc_exp10;
2512 PowLb = LibFunc_pow;
2515 LogID = Intrinsic::log;
2516 ExpLb = LibFunc_expl;
2517 Exp2Lb = LibFunc_exp2l;
2518 Exp10Lb = LibFunc_exp10l;
2519 PowLb = LibFunc_powl;
2522 LogID = Intrinsic::log2;
2523 ExpLb = LibFunc_expf;
2524 Exp2Lb = LibFunc_exp2f;
2525 Exp10Lb = LibFunc_exp10f;
2526 PowLb = LibFunc_powf;
2529 LogID = Intrinsic::log2;
2530 ExpLb = LibFunc_exp;
2531 Exp2Lb = LibFunc_exp2;
2532 Exp10Lb = LibFunc_exp10;
2533 PowLb = LibFunc_pow;
2536 LogID = Intrinsic::log2;
2537 ExpLb = LibFunc_expl;
2538 Exp2Lb = LibFunc_exp2l;
2539 Exp10Lb = LibFunc_exp10l;
2540 PowLb = LibFunc_powl;
2542 case LibFunc_log10f:
2543 LogID = Intrinsic::log10;
2544 ExpLb = LibFunc_expf;
2545 Exp2Lb = LibFunc_exp2f;
2546 Exp10Lb = LibFunc_exp10f;
2547 PowLb = LibFunc_powf;
2550 LogID = Intrinsic::log10;
2551 ExpLb = LibFunc_exp;
2552 Exp2Lb = LibFunc_exp2;
2553 Exp10Lb = LibFunc_exp10;
2554 PowLb = LibFunc_pow;
2556 case LibFunc_log10l:
2557 LogID = Intrinsic::log10;
2558 ExpLb = LibFunc_expl;
2559 Exp2Lb = LibFunc_exp2l;
2560 Exp10Lb = LibFunc_exp10l;
2561 PowLb = LibFunc_powl;
2566 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2567 LogID == Intrinsic::log10) {
2569 ExpLb = LibFunc_expf;
2570 Exp2Lb = LibFunc_exp2f;
2571 Exp10Lb = LibFunc_exp10f;
2572 PowLb = LibFunc_powf;
2574 ExpLb = LibFunc_exp;
2575 Exp2Lb = LibFunc_exp2;
2576 Exp10Lb = LibFunc_exp10;
2577 PowLb = LibFunc_pow;
2592 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2595 ?
B.CreateUnaryIntrinsic(LogID, Arg->
getOperand(0),
nullptr,
"log")
2599 if (ArgID == Intrinsic::powi)
2600 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2601 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2604 substituteInParent(Arg, MulY);
2610 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2611 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2613 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2616 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2617 Eul = ConstantFP::get(Log->
getType(), 2.0);
2619 Eul = ConstantFP::get(Log->
getType(), 10.0);
2621 ?
B.CreateUnaryIntrinsic(LogID, Eul,
nullptr,
"log")
2626 substituteInParent(Arg, MulY);
2646 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2651 ExpLb = LibFunc_expf;
2652 Exp2Lb = LibFunc_exp2f;
2653 Exp10Lb = LibFunc_exp10f;
2656 ExpLb = LibFunc_exp;
2657 Exp2Lb = LibFunc_exp2;
2658 Exp10Lb = LibFunc_exp10;
2661 ExpLb = LibFunc_expl;
2662 Exp2Lb = LibFunc_exp2l;
2663 Exp10Lb = LibFunc_exp10l;
2670 ExpLb = LibFunc_expf;
2671 Exp2Lb = LibFunc_exp2f;
2672 Exp10Lb = LibFunc_exp10f;
2674 ExpLb = LibFunc_exp;
2675 Exp2Lb = LibFunc_exp2;
2676 Exp10Lb = LibFunc_exp10;
2682 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2683 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2687 B.SetInsertPoint(Arg);
2690 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2705 (
Callee->getName() ==
"sqrt" ||
2706 Callee->getIntrinsicID() == Intrinsic::sqrt))
2709 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2716 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2722 Value *Op0 =
I->getOperand(0);
2723 Value *Op1 =
I->getOperand(1);
2724 Value *RepeatOp =
nullptr;
2725 Value *OtherOp =
nullptr;
2735 Value *OtherMul0, *OtherMul1;
2738 if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
2740 RepeatOp = OtherMul0;
2751 B.setFastMathFlags(
I->getFastMathFlags());
2756 B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp,
nullptr,
"fabs");
2762 B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp,
nullptr,
"sqrt");
2763 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2768Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2774 if (UnsafeFPShrink &&
2777 hasFloatVersion(M,
Name))
2781 auto *OpC = dyn_cast<CallInst>(Op1);
2786 if (!CI->
isFast() || !OpC->isFast())
2799 .
Case(
"tan", LibFunc_atan)
2800 .
Case(
"atanh", LibFunc_tanh)
2801 .
Case(
"sinh", LibFunc_asinh)
2802 .
Case(
"cosh", LibFunc_acosh)
2803 .
Case(
"tanf", LibFunc_atanf)
2804 .
Case(
"atanhf", LibFunc_tanhf)
2805 .
Case(
"sinhf", LibFunc_asinhf)
2806 .
Case(
"coshf", LibFunc_acoshf)
2807 .
Case(
"tanl", LibFunc_atanl)
2808 .
Case(
"atanhl", LibFunc_tanhl)
2809 .
Case(
"sinhl", LibFunc_asinhl)
2810 .
Case(
"coshl", LibFunc_acoshl)
2811 .
Case(
"asinh", LibFunc_sinh)
2812 .
Case(
"asinhf", LibFunc_sinhf)
2813 .
Case(
"asinhl", LibFunc_sinhl)
2815 if (Func == inverseFunc)
2816 Ret = OpC->getArgOperand(0);
2838 Name =
"__sincospif_stret";
2847 Name =
"__sincospi_stret";
2856 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2858 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2861 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2865 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2866 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2869 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2872 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2873 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2875 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2877 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
2959 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2965 Value *Sin, *Cos, *SinCos;
2973 replaceAllUsesWith(
C, Res);
2976 replaceTrigInsts(SinCalls, Sin);
2977 replaceTrigInsts(CosCalls, Cos);
2978 replaceTrigInsts(SinCosCalls, SinCos);
2980 return IsSin ? Sin : Cos;
2983void LibCallSimplifier::classifyArgUse(
2988 auto *CI = dyn_cast<CallInst>(Val);
2999 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
3005 if (Func == LibFunc_sinpif)
3007 else if (Func == LibFunc_cospif)
3009 else if (Func == LibFunc_sincospif_stret)
3012 if (Func == LibFunc_sinpi)
3014 else if (Func == LibFunc_cospi)
3016 else if (Func == LibFunc_sincospi_stret)
3030 Type *ArgType =
Op->getType();
3031 Value *
V =
B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {
Op,
B.getTrue()},
3033 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3034 V =
B.CreateIntCast(V, RetType,
false);
3037 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3044 Type *ArgType =
Op->getType();
3045 Value *
V =
B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {
Op,
B.getFalse()},
3049 return B.CreateIntCast(V, CI->
getType(),
false);
3056 Value *IsNeg =
B.CreateIsNeg(
X);
3057 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3058 return B.CreateSelect(IsNeg, NegX,
X);
3064 Type *ArgType =
Op->getType();
3065 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3066 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3073 Type *ArgType =
Op->getType();
3074 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3081 ConstantInt::get(CI->
getType(), 0x7F));
3099 if (isa<ConstantPointerNull>(EndPtr)) {
3112 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3144 if (!Callee || !Callee->isDeclaration())
3153 if (StreamArg >= (
int)CI->
arg_size())
3161 return GV->
getName() ==
"stderr";
3171 if (FormatStr.
empty())
3182 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3186 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3191 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3196 if (OperandStr.
empty())
3199 if (OperandStr.
size() == 1) {
3203 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3207 if (OperandStr.
back() ==
'\n') {
3209 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3216 if (FormatStr.
back() ==
'\n' &&
3221 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3227 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3236 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3247 if (
Value *V = optimizePrintFString(CI,
B)) {
3258 Callee->getAttributes());
3260 New->setCalledFunction(IPrintFFn);
3270 Callee->getAttributes());
3272 New->setCalledFunction(SmallPrintFFn);
3280Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3299 FormatStr.
size() + 1));
3300 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3305 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3309 if (FormatStr[1] ==
'c') {
3315 B.CreateStore(V,
Ptr);
3316 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3317 B.CreateStore(
B.getInt8(0),
Ptr);
3319 return ConstantInt::get(CI->
getType(), 1);
3322 if (FormatStr[1] ==
's') {
3338 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3341 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3342 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3355 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3359 return B.CreateIntCast(Len, CI->
getType(),
false);
3368 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3379 FT,
Callee->getAttributes());
3381 New->setCalledFunction(SIPrintFFn);
3391 Callee->getAttributes());
3393 New->setCalledFunction(SmallSPrintFFn);
3409 assert(StrArg || (
N < 2 && Str.size() == 1));
3413 if (Str.size() > IntMax)
3419 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3429 NCopy = Str.size() + 1;
3434 if (NCopy && StrArg)
3448 Type *Int8Ty =
B.getInt8Ty();
3449 Value *NulOff =
B.getIntN(IntBits, NCopy);
3450 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3451 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3455Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3484 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3489 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3493 if (FormatStr[1] ==
'c') {
3499 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3507 B.CreateStore(V,
Ptr);
3508 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3509 B.CreateStore(
B.getInt8(0),
Ptr);
3510 return ConstantInt::get(CI->
getType(), 1);
3513 if (FormatStr[1] !=
's')
3522 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3526 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3535Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3537 optimizeErrorReporting(CI,
B, 0);
3560 ConstantInt::get(SizeTTy, FormatStr.
size()),
3566 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3570 if (FormatStr[1] ==
'c') {
3580 if (FormatStr[1] ==
's') {
3594 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3603 FT,
Callee->getAttributes());
3605 New->setCalledFunction(FIPrintFFn);
3614 auto SmallFPrintFFn =
3616 Callee->getAttributes());
3618 New->setCalledFunction(SmallFPrintFFn);
3627 optimizeErrorReporting(CI,
B, 3);
3632 if (SizeC && CountC) {
3637 return ConstantInt::get(CI->
getType(), 0);
3644 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3646 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3654 optimizeErrorReporting(CI,
B, 1);
3679 ConstantInt::get(SizeTTy, Len - 1),
3708bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3710 FloatFuncName +=
'f';
3714Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3725 "Optimizing string/memory libcall would change the calling convention");
3727 case LibFunc_strcat:
3728 return optimizeStrCat(CI, Builder);
3729 case LibFunc_strncat:
3730 return optimizeStrNCat(CI, Builder);
3731 case LibFunc_strchr:
3732 return optimizeStrChr(CI, Builder);
3733 case LibFunc_strrchr:
3734 return optimizeStrRChr(CI, Builder);
3735 case LibFunc_strcmp:
3736 return optimizeStrCmp(CI, Builder);
3737 case LibFunc_strncmp:
3738 return optimizeStrNCmp(CI, Builder);
3739 case LibFunc_strcpy:
3740 return optimizeStrCpy(CI, Builder);
3741 case LibFunc_stpcpy:
3742 return optimizeStpCpy(CI, Builder);
3743 case LibFunc_strlcpy:
3744 return optimizeStrLCpy(CI, Builder);
3745 case LibFunc_stpncpy:
3746 return optimizeStringNCpy(CI,
true, Builder);
3747 case LibFunc_strncpy:
3748 return optimizeStringNCpy(CI,
false, Builder);
3749 case LibFunc_strlen:
3750 return optimizeStrLen(CI, Builder);
3751 case LibFunc_strnlen:
3752 return optimizeStrNLen(CI, Builder);
3753 case LibFunc_strpbrk:
3754 return optimizeStrPBrk(CI, Builder);
3755 case LibFunc_strndup:
3756 return optimizeStrNDup(CI, Builder);
3757 case LibFunc_strtol:
3758 case LibFunc_strtod:
3759 case LibFunc_strtof:
3760 case LibFunc_strtoul:
3761 case LibFunc_strtoll:
3762 case LibFunc_strtold:
3763 case LibFunc_strtoull:
3764 return optimizeStrTo(CI, Builder);
3765 case LibFunc_strspn:
3766 return optimizeStrSpn(CI, Builder);
3767 case LibFunc_strcspn:
3768 return optimizeStrCSpn(CI, Builder);
3769 case LibFunc_strstr:
3770 return optimizeStrStr(CI, Builder);
3771 case LibFunc_memchr:
3772 return optimizeMemChr(CI, Builder);
3773 case LibFunc_memrchr:
3774 return optimizeMemRChr(CI, Builder);
3776 return optimizeBCmp(CI, Builder);
3777 case LibFunc_memcmp:
3778 return optimizeMemCmp(CI, Builder);
3779 case LibFunc_memcpy:
3780 return optimizeMemCpy(CI, Builder);
3781 case LibFunc_memccpy:
3782 return optimizeMemCCpy(CI, Builder);
3783 case LibFunc_mempcpy:
3784 return optimizeMemPCpy(CI, Builder);
3785 case LibFunc_memmove:
3786 return optimizeMemMove(CI, Builder);
3787 case LibFunc_memset:
3788 return optimizeMemSet(CI, Builder);
3789 case LibFunc_realloc:
3790 return optimizeRealloc(CI, Builder);
3791 case LibFunc_wcslen:
3792 return optimizeWcslen(CI, Builder);
3794 return optimizeBCopy(CI, Builder);
3796 case LibFunc_ZnwmRKSt9nothrow_t:
3797 case LibFunc_ZnwmSt11align_val_t:
3798 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3800 case LibFunc_ZnamRKSt9nothrow_t:
3801 case LibFunc_ZnamSt11align_val_t:
3802 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3803 case LibFunc_Znwm12__hot_cold_t:
3804 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3805 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3806 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3807 case LibFunc_Znam12__hot_cold_t:
3808 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3809 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3810 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3811 return optimizeNew(CI, Builder, Func);
3819Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3828 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3832 case LibFunc_sinpif:
3834 return optimizeSinCosPi(CI,
true, Builder);
3835 case LibFunc_cospif:
3837 return optimizeSinCosPi(CI,
false, Builder);
3841 return optimizePow(CI, Builder);
3845 return optimizeExp2(CI, Builder);
3853 return optimizeSqrt(CI, Builder);
3857 case LibFunc_log10f:
3859 case LibFunc_log10l:
3860 case LibFunc_log1pf:
3862 case LibFunc_log1pl:
3869 return optimizeLog(CI, Builder);
3877 case LibFunc_asinhf:
3878 case LibFunc_asinhl:
3883 case LibFunc_atanhf:
3884 case LibFunc_atanhl:
3885 return optimizeTrigInversionPairs(CI, Builder);
3892 case LibFunc_roundeven:
3894 case LibFunc_nearbyint:
3914 case LibFunc_copysign:
3924 return optimizeFMinFMax(CI, Builder);
3928 return optimizeCAbs(CI, Builder);
3959 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3960 UnsafeFPShrink =
true;
3964 if (!IsCallingConvC)
3968 switch (
II->getIntrinsicID()) {
3969 case Intrinsic::pow:
3970 return optimizePow(CI, Builder);
3971 case Intrinsic::exp2:
3972 return optimizeExp2(CI, Builder);
3973 case Intrinsic::log:
3974 case Intrinsic::log2:
3975 case Intrinsic::log10:
3976 return optimizeLog(CI, Builder);
3977 case Intrinsic::sqrt:
3978 return optimizeSqrt(CI, Builder);
3979 case Intrinsic::memset:
3980 return optimizeMemSet(CI, Builder);
3981 case Intrinsic::memcpy:
3982 return optimizeMemCpy(CI, Builder);
3983 case Intrinsic::memmove:
3984 return optimizeMemMove(CI, Builder);
3991 if (
Value *SimplifiedFortifiedCI =
3993 return SimplifiedFortifiedCI;
4000 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
4002 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4008 return optimizeFFS(CI, Builder);
4012 return optimizeFls(CI, Builder);
4016 return optimizeAbs(CI, Builder);
4017 case LibFunc_isdigit:
4018 return optimizeIsDigit(CI, Builder);
4019 case LibFunc_isascii:
4020 return optimizeIsAscii(CI, Builder);
4021 case LibFunc_toascii:
4022 return optimizeToAscii(CI, Builder);
4026 return optimizeAtoi(CI, Builder);
4027 case LibFunc_strtol:
4028 case LibFunc_strtoll:
4029 return optimizeStrToInt(CI, Builder,
true);
4030 case LibFunc_strtoul:
4031 case LibFunc_strtoull:
4032 return optimizeStrToInt(CI, Builder,
false);
4033 case LibFunc_printf:
4034 return optimizePrintF(CI, Builder);
4035 case LibFunc_sprintf:
4036 return optimizeSPrintF(CI, Builder);
4037 case LibFunc_snprintf:
4038 return optimizeSnPrintF(CI, Builder);
4039 case LibFunc_fprintf:
4040 return optimizeFPrintF(CI, Builder);
4041 case LibFunc_fwrite:
4042 return optimizeFWrite(CI, Builder);
4044 return optimizeFPuts(CI, Builder);
4046 return optimizePuts(CI, Builder);
4047 case LibFunc_perror:
4048 return optimizeErrorReporting(CI, Builder);
4049 case LibFunc_vfprintf:
4050 case LibFunc_fiprintf:
4051 return optimizeErrorReporting(CI, Builder, 0);
4065 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
4066 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4073void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4112bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4113 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4114 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4119 if (!Flag || !
Flag->isZero())
4128 if (ObjSizeCI->isMinusOne())
4131 if (OnlyLowerUnknownSize)
4141 return ObjSizeCI->getZExtValue() >=
Len;
4147 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4153Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4155 if (isFortifiedCallFoldable(CI, 3, 2)) {
4165Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4167 if (isFortifiedCallFoldable(CI, 3, 2)) {
4177Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4179 if (isFortifiedCallFoldable(CI, 3, 2)) {
4189Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4192 if (isFortifiedCallFoldable(CI, 3, 2))
4200Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4208 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4210 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4218 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4219 if (Func == LibFunc_strcpy_chk)
4225 if (OnlyLowerUnknownSize)
4237 Value *LenV = ConstantInt::get(SizeTTy, Len);
4241 if (Ret && Func == LibFunc_stpcpy_chk)
4242 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4243 ConstantInt::get(SizeTTy, Len - 1));
4244 return copyFlags(*CI, cast<CallInst>(Ret));
4247Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4249 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4255Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4258 if (isFortifiedCallFoldable(CI, 3, 2)) {
4259 if (Func == LibFunc_strncpy_chk)
4272Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4274 if (isFortifiedCallFoldable(CI, 4, 3))
4282Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4284 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4294Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4296 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4300 VariadicArgs,
B, TLI));
4306Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4308 if (isFortifiedCallFoldable(CI, 2))
4315Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4317 if (isFortifiedCallFoldable(CI, 3))
4325Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4327 if (isFortifiedCallFoldable(CI, 3))
4335Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4337 if (isFortifiedCallFoldable(CI, 3))
4345Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4347 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4355Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4357 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4400 case LibFunc_memcpy_chk:
4401 return optimizeMemCpyChk(CI, Builder);
4402 case LibFunc_mempcpy_chk:
4403 return optimizeMemPCpyChk(CI, Builder);
4404 case LibFunc_memmove_chk:
4405 return optimizeMemMoveChk(CI, Builder);
4406 case LibFunc_memset_chk:
4407 return optimizeMemSetChk(CI, Builder);
4408 case LibFunc_stpcpy_chk:
4409 case LibFunc_strcpy_chk:
4410 return optimizeStrpCpyChk(CI, Builder, Func);
4411 case LibFunc_strlen_chk:
4412 return optimizeStrLenChk(CI, Builder);
4413 case LibFunc_stpncpy_chk:
4414 case LibFunc_strncpy_chk:
4415 return optimizeStrpNCpyChk(CI, Builder, Func);
4416 case LibFunc_memccpy_chk:
4417 return optimizeMemCCpyChk(CI, Builder);
4418 case LibFunc_snprintf_chk:
4419 return optimizeSNPrintfChk(CI, Builder);
4420 case LibFunc_sprintf_chk:
4421 return optimizeSPrintfChk(CI, Builder);
4422 case LibFunc_strcat_chk:
4423 return optimizeStrCatChk(CI, Builder);
4424 case LibFunc_strlcat_chk:
4425 return optimizeStrLCat(CI, Builder);
4426 case LibFunc_strncat_chk:
4427 return optimizeStrNCatChk(CI, Builder);
4428 case LibFunc_strlcpy_chk:
4429 return optimizeStrLCpyChk(CI, Builder);
4430 case LibFunc_vsnprintf_chk:
4431 return optimizeVSNPrintfChk(CI, Builder);
4432 case LibFunc_vsprintf_chk:
4433 return optimizeVSPrintfChk(CI, Builder);
4442 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static bool isBinary(MachineInstr &MI)
const SmallVectorImpl< MachineOperand > & Cond
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With)
Return true if it is only used in equality comparisons with With.
static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef< unsigned > ArgNos, Value *Size, const DataLayout &DL)
static cl::opt< unsigned, false, HotColdHintParser > ColdNewHintValue("cold-new-hint-value", cl::Hidden, cl::init(1), cl::desc("Value to pass to hot/cold operator new for cold allocation"))
static bool insertSinCosCall(IRBuilderBase &B, Function *OrigCallee, Value *Arg, bool UseFloat, Value *&Sin, Value *&Cos, Value *&SinCos, const TargetLibraryInfo *TLI)
static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len, const DataLayout &DL)
static Value * mergeAttributesAndFlags(CallInst *NewCI, const CallInst &Old)
static cl::opt< bool > OptimizeHotColdNew("optimize-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable hot/cold operator new library calls"))
static Value * optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for binary functions.
static bool ignoreCallingConv(LibFunc Func)
static cl::opt< bool > OptimizeExistingHotColdNew("optimize-existing-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable optimization of existing hot/cold operator new library calls"))
static void annotateDereferenceableBytes(CallInst *CI, ArrayRef< unsigned > ArgNos, uint64_t DereferenceableBytes)
static bool isReportingError(Function *Callee, CallInst *CI, int StreamArg)
static Value * optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, bool isBinary, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float functions.
static Value * optimizeSymmetricCall(CallInst *CI, bool IsEven, IRBuilderBase &B)
static Value * getSqrtCall(Value *V, AttributeList Attrs, bool NoErrno, Module *M, IRBuilderBase &B, const TargetLibraryInfo *TLI)
static Value * valueHasFloatPrecision(Value *Val)
Return a variant of Val with float type.
static Value * optimizeMemCmpConstantSize(CallInst *CI, Value *LHS, Value *RHS, uint64_t Len, IRBuilderBase &B, const DataLayout &DL)
static Value * createPowWithIntegerExponent(Value *Base, Value *Expo, Module *M, IRBuilderBase &B)
static Value * convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, uint64_t Base, bool AsSigned, IRBuilderBase &B)
static Value * memChrToCharCompare(CallInst *CI, Value *NBytes, IRBuilderBase &B, const DataLayout &DL)
static Value * copyFlags(const CallInst &Old, Value *New)
static StringRef substr(StringRef Str, uint64_t Len)
static cl::opt< unsigned, false, HotColdHintParser > HotNewHintValue("hot-new-hint-value", cl::Hidden, cl::init(254), cl::desc("Value to pass to hot/cold operator new for hot allocation"))
static bool isTrigLibCall(CallInst *CI)
static 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...
bool isFast() const LLVM_READONLY
Determine whether all fast-math-flags are set.
const Function * getFunction() const
Return the function this instruction belongs to.
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
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.
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.
const ParentTy * getParent() const
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.