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)
3039 APSInt QuotInt(IntBW,
false);
3046 B.CreateAlignedStore(
3047 ConstantInt::get(
B.getIntNTy(IntBW), QuotInt.getExtValue()),
3049 return ConstantFP::get(CI->
getType(), Rem);
3061 Type *ArgType =
Op->getType();
3062 Value *
V =
B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {
Op,
B.getTrue()},
3064 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
3065 V =
B.CreateIntCast(V, RetType,
false);
3068 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
3075 Type *ArgType =
Op->getType();
3076 Value *
V =
B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {
Op,
B.getFalse()},
3080 return B.CreateIntCast(V, CI->
getType(),
false);
3087 Value *IsNeg =
B.CreateIsNeg(
X);
3088 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
3089 return B.CreateSelect(IsNeg, NegX,
X);
3095 Type *ArgType =
Op->getType();
3096 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
3097 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
3104 Type *ArgType =
Op->getType();
3105 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
3112 ConstantInt::get(CI->
getType(), 0x7F));
3130 if (isa<ConstantPointerNull>(EndPtr)) {
3143 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3175 if (!Callee || !Callee->isDeclaration())
3184 if (StreamArg >= (
int)CI->
arg_size())
3192 return GV->
getName() ==
"stderr";
3202 if (FormatStr.
empty())
3213 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3217 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3222 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3227 if (OperandStr.
empty())
3230 if (OperandStr.
size() == 1) {
3234 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3238 if (OperandStr.
back() ==
'\n') {
3240 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3247 if (FormatStr.
back() ==
'\n' &&
3252 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3258 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3267 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3278 if (
Value *V = optimizePrintFString(CI,
B)) {
3289 Callee->getAttributes());
3291 New->setCalledFunction(IPrintFFn);
3301 Callee->getAttributes());
3303 New->setCalledFunction(SmallPrintFFn);
3311Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3330 FormatStr.
size() + 1));
3331 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3336 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3340 if (FormatStr[1] ==
'c') {
3346 B.CreateStore(V,
Ptr);
3347 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3348 B.CreateStore(
B.getInt8(0),
Ptr);
3350 return ConstantInt::get(CI->
getType(), 1);
3353 if (FormatStr[1] ==
's') {
3369 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3372 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3373 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3386 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3390 return B.CreateIntCast(Len, CI->
getType(),
false);
3399 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3410 FT,
Callee->getAttributes());
3412 New->setCalledFunction(SIPrintFFn);
3422 Callee->getAttributes());
3424 New->setCalledFunction(SmallSPrintFFn);
3440 assert(StrArg || (
N < 2 && Str.size() == 1));
3444 if (Str.size() > IntMax)
3450 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3460 NCopy = Str.size() + 1;
3465 if (NCopy && StrArg)
3479 Type *Int8Ty =
B.getInt8Ty();
3480 Value *NulOff =
B.getIntN(IntBits, NCopy);
3481 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3482 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3486Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3515 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3520 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3524 if (FormatStr[1] ==
'c') {
3530 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3538 B.CreateStore(V,
Ptr);
3539 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3540 B.CreateStore(
B.getInt8(0),
Ptr);
3541 return ConstantInt::get(CI->
getType(), 1);
3544 if (FormatStr[1] !=
's')
3553 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3557 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3566Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3568 optimizeErrorReporting(CI,
B, 0);
3591 ConstantInt::get(SizeTTy, FormatStr.
size()),
3597 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3601 if (FormatStr[1] ==
'c') {
3611 if (FormatStr[1] ==
's') {
3625 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3634 FT,
Callee->getAttributes());
3636 New->setCalledFunction(FIPrintFFn);
3645 auto SmallFPrintFFn =
3647 Callee->getAttributes());
3649 New->setCalledFunction(SmallFPrintFFn);
3658 optimizeErrorReporting(CI,
B, 3);
3663 if (SizeC && CountC) {
3668 return ConstantInt::get(CI->
getType(), 0);
3675 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3677 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3685 optimizeErrorReporting(CI,
B, 1);
3710 ConstantInt::get(SizeTTy, Len - 1),
3739bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3741 FloatFuncName +=
'f';
3745Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3756 "Optimizing string/memory libcall would change the calling convention");
3758 case LibFunc_strcat:
3759 return optimizeStrCat(CI, Builder);
3760 case LibFunc_strncat:
3761 return optimizeStrNCat(CI, Builder);
3762 case LibFunc_strchr:
3763 return optimizeStrChr(CI, Builder);
3764 case LibFunc_strrchr:
3765 return optimizeStrRChr(CI, Builder);
3766 case LibFunc_strcmp:
3767 return optimizeStrCmp(CI, Builder);
3768 case LibFunc_strncmp:
3769 return optimizeStrNCmp(CI, Builder);
3770 case LibFunc_strcpy:
3771 return optimizeStrCpy(CI, Builder);
3772 case LibFunc_stpcpy:
3773 return optimizeStpCpy(CI, Builder);
3774 case LibFunc_strlcpy:
3775 return optimizeStrLCpy(CI, Builder);
3776 case LibFunc_stpncpy:
3777 return optimizeStringNCpy(CI,
true, Builder);
3778 case LibFunc_strncpy:
3779 return optimizeStringNCpy(CI,
false, Builder);
3780 case LibFunc_strlen:
3781 return optimizeStrLen(CI, Builder);
3782 case LibFunc_strnlen:
3783 return optimizeStrNLen(CI, Builder);
3784 case LibFunc_strpbrk:
3785 return optimizeStrPBrk(CI, Builder);
3786 case LibFunc_strndup:
3787 return optimizeStrNDup(CI, Builder);
3788 case LibFunc_strtol:
3789 case LibFunc_strtod:
3790 case LibFunc_strtof:
3791 case LibFunc_strtoul:
3792 case LibFunc_strtoll:
3793 case LibFunc_strtold:
3794 case LibFunc_strtoull:
3795 return optimizeStrTo(CI, Builder);
3796 case LibFunc_strspn:
3797 return optimizeStrSpn(CI, Builder);
3798 case LibFunc_strcspn:
3799 return optimizeStrCSpn(CI, Builder);
3800 case LibFunc_strstr:
3801 return optimizeStrStr(CI, Builder);
3802 case LibFunc_memchr:
3803 return optimizeMemChr(CI, Builder);
3804 case LibFunc_memrchr:
3805 return optimizeMemRChr(CI, Builder);
3807 return optimizeBCmp(CI, Builder);
3808 case LibFunc_memcmp:
3809 return optimizeMemCmp(CI, Builder);
3810 case LibFunc_memcpy:
3811 return optimizeMemCpy(CI, Builder);
3812 case LibFunc_memccpy:
3813 return optimizeMemCCpy(CI, Builder);
3814 case LibFunc_mempcpy:
3815 return optimizeMemPCpy(CI, Builder);
3816 case LibFunc_memmove:
3817 return optimizeMemMove(CI, Builder);
3818 case LibFunc_memset:
3819 return optimizeMemSet(CI, Builder);
3820 case LibFunc_realloc:
3821 return optimizeRealloc(CI, Builder);
3822 case LibFunc_wcslen:
3823 return optimizeWcslen(CI, Builder);
3825 return optimizeBCopy(CI, Builder);
3827 case LibFunc_ZnwmRKSt9nothrow_t:
3828 case LibFunc_ZnwmSt11align_val_t:
3829 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3831 case LibFunc_ZnamRKSt9nothrow_t:
3832 case LibFunc_ZnamSt11align_val_t:
3833 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3834 case LibFunc_Znwm12__hot_cold_t:
3835 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
3836 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
3837 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3838 case LibFunc_Znam12__hot_cold_t:
3839 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
3840 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
3841 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
3842 return optimizeNew(CI, Builder, Func);
3850Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3859 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3863 case LibFunc_sinpif:
3865 return optimizeSinCosPi(CI,
true, Builder);
3866 case LibFunc_cospif:
3868 return optimizeSinCosPi(CI,
false, Builder);
3872 return optimizePow(CI, Builder);
3876 return optimizeExp2(CI, Builder);
3884 return optimizeSqrt(CI, Builder);
3888 case LibFunc_log10f:
3890 case LibFunc_log10l:
3891 case LibFunc_log1pf:
3893 case LibFunc_log1pl:
3900 return optimizeLog(CI, Builder);
3908 case LibFunc_asinhf:
3909 case LibFunc_asinhl:
3914 case LibFunc_atanhf:
3915 case LibFunc_atanhl:
3916 return optimizeTrigInversionPairs(CI, Builder);
3923 case LibFunc_roundeven:
3925 case LibFunc_nearbyint:
3945 case LibFunc_copysign:
3955 return optimizeFMinFMax(CI, Builder);
3959 return optimizeCAbs(CI, Builder);
3960 case LibFunc_remquo:
3961 case LibFunc_remquof:
3962 case LibFunc_remquol:
3963 return optimizeRemquo(CI, Builder);
3994 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3995 UnsafeFPShrink =
true;
3999 if (!IsCallingConvC)
4003 switch (
II->getIntrinsicID()) {
4004 case Intrinsic::pow:
4005 return optimizePow(CI, Builder);
4006 case Intrinsic::exp2:
4007 return optimizeExp2(CI, Builder);
4008 case Intrinsic::log:
4009 case Intrinsic::log2:
4010 case Intrinsic::log10:
4011 return optimizeLog(CI, Builder);
4012 case Intrinsic::sqrt:
4013 return optimizeSqrt(CI, Builder);
4014 case Intrinsic::memset:
4015 return optimizeMemSet(CI, Builder);
4016 case Intrinsic::memcpy:
4017 return optimizeMemCpy(CI, Builder);
4018 case Intrinsic::memmove:
4019 return optimizeMemMove(CI, Builder);
4026 if (
Value *SimplifiedFortifiedCI =
4028 return SimplifiedFortifiedCI;
4035 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
4037 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4043 return optimizeFFS(CI, Builder);
4047 return optimizeFls(CI, Builder);
4051 return optimizeAbs(CI, Builder);
4052 case LibFunc_isdigit:
4053 return optimizeIsDigit(CI, Builder);
4054 case LibFunc_isascii:
4055 return optimizeIsAscii(CI, Builder);
4056 case LibFunc_toascii:
4057 return optimizeToAscii(CI, Builder);
4061 return optimizeAtoi(CI, Builder);
4062 case LibFunc_strtol:
4063 case LibFunc_strtoll:
4064 return optimizeStrToInt(CI, Builder,
true);
4065 case LibFunc_strtoul:
4066 case LibFunc_strtoull:
4067 return optimizeStrToInt(CI, Builder,
false);
4068 case LibFunc_printf:
4069 return optimizePrintF(CI, Builder);
4070 case LibFunc_sprintf:
4071 return optimizeSPrintF(CI, Builder);
4072 case LibFunc_snprintf:
4073 return optimizeSnPrintF(CI, Builder);
4074 case LibFunc_fprintf:
4075 return optimizeFPrintF(CI, Builder);
4076 case LibFunc_fwrite:
4077 return optimizeFWrite(CI, Builder);
4079 return optimizeFPuts(CI, Builder);
4081 return optimizePuts(CI, Builder);
4082 case LibFunc_perror:
4083 return optimizeErrorReporting(CI, Builder);
4084 case LibFunc_vfprintf:
4085 case LibFunc_fiprintf:
4086 return optimizeErrorReporting(CI, Builder, 0);
4100 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
4101 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4108void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
4147bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4148 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
4149 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
4154 if (!Flag || !
Flag->isZero())
4163 if (ObjSizeCI->isMinusOne())
4166 if (OnlyLowerUnknownSize)
4176 return ObjSizeCI->getZExtValue() >=
Len;
4182 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4188Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4190 if (isFortifiedCallFoldable(CI, 3, 2)) {
4200Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4202 if (isFortifiedCallFoldable(CI, 3, 2)) {
4212Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4214 if (isFortifiedCallFoldable(CI, 3, 2)) {
4224Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4227 if (isFortifiedCallFoldable(CI, 3, 2))
4235Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4243 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4245 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4253 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4254 if (Func == LibFunc_strcpy_chk)
4260 if (OnlyLowerUnknownSize)
4272 Value *LenV = ConstantInt::get(SizeTTy, Len);
4276 if (Ret && Func == LibFunc_stpcpy_chk)
4277 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4278 ConstantInt::get(SizeTTy, Len - 1));
4279 return copyFlags(*CI, cast<CallInst>(Ret));
4282Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4284 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4290Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4293 if (isFortifiedCallFoldable(CI, 3, 2)) {
4294 if (Func == LibFunc_strncpy_chk)
4307Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4309 if (isFortifiedCallFoldable(CI, 4, 3))
4317Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4319 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4329Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4331 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4335 VariadicArgs,
B, TLI));
4341Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4343 if (isFortifiedCallFoldable(CI, 2))
4350Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4352 if (isFortifiedCallFoldable(CI, 3))
4360Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4362 if (isFortifiedCallFoldable(CI, 3))
4370Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4372 if (isFortifiedCallFoldable(CI, 3))
4380Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4382 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4390Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4392 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4435 case LibFunc_memcpy_chk:
4436 return optimizeMemCpyChk(CI, Builder);
4437 case LibFunc_mempcpy_chk:
4438 return optimizeMemPCpyChk(CI, Builder);
4439 case LibFunc_memmove_chk:
4440 return optimizeMemMoveChk(CI, Builder);
4441 case LibFunc_memset_chk:
4442 return optimizeMemSetChk(CI, Builder);
4443 case LibFunc_stpcpy_chk:
4444 case LibFunc_strcpy_chk:
4445 return optimizeStrpCpyChk(CI, Builder, Func);
4446 case LibFunc_strlen_chk:
4447 return optimizeStrLenChk(CI, Builder);
4448 case LibFunc_stpncpy_chk:
4449 case LibFunc_strncpy_chk:
4450 return optimizeStrpNCpyChk(CI, Builder, Func);
4451 case LibFunc_memccpy_chk:
4452 return optimizeMemCCpyChk(CI, Builder);
4453 case LibFunc_snprintf_chk:
4454 return optimizeSNPrintfChk(CI, Builder);
4455 case LibFunc_sprintf_chk:
4456 return optimizeSPrintfChk(CI, Builder);
4457 case LibFunc_strcat_chk:
4458 return optimizeStrCatChk(CI, Builder);
4459 case LibFunc_strlcat_chk:
4460 return optimizeStrLCat(CI, Builder);
4461 case LibFunc_strncat_chk:
4462 return optimizeStrNCatChk(CI, Builder);
4463 case LibFunc_strlcpy_chk:
4464 return optimizeStrLCpyChk(CI, Builder);
4465 case LibFunc_vsnprintf_chk:
4466 return optimizeVSNPrintfChk(CI, Builder);
4467 case LibFunc_vsprintf_chk:
4468 return optimizeVSPrintfChk(CI, Builder);
4477 : 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.
opStatus divide(const APFloat &RHS, roundingMode RM)
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 remainder(const APFloat &RHS)
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.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
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
opStatus
IEEE-754R 7: Default exception handling.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Holds functions to get, set or test bitfields.
Represents offset+length into a ConstantDataArray.
uint64_t Length
Length of the slice.
uint64_t Offset
Slice starts at this Offset.
const ConstantDataArray * Array
ConstantDataArray pointer.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.