41using namespace PatternMatch;
46 cl::desc(
"Enable unsafe double to float "
47 "shrinking for math lib calls"));
54 cl::desc(
"Enable hot/cold operator new library calls"));
61struct HotColdHintParser :
public cl::parser<unsigned> {
66 return O.error(
"'" + Arg +
"' value invalid for uint argument!");
69 return O.error(
"'" + Arg +
"' value must be in the range [0, 255]!");
83 cl::desc(
"Value to pass to hot/cold operator new for cold allocation"));
86 cl::desc(
"Value to pass to hot/cold operator new for hot allocation"));
93 return Func == LibFunc_abs || Func == LibFunc_labs ||
94 Func == LibFunc_llabs || Func == LibFunc_strlen;
99 for (
User *U : V->users()) {
100 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
101 if (IC->isEquality() && IC->getOperand(1) == With)
111 return OI->getType()->isFloatingPointTy();
117 return OI->getType()->isFP128Ty();
130 if (Base < 2 || Base > 36)
139 if (!isSpace((
unsigned char)Str[
Offset])) {
150 bool Negate = Str[0] ==
'-';
151 if (Str[0] ==
'-' || Str[0] ==
'+') {
152 Str = Str.drop_front();
162 unsigned NBits =
RetTy->getPrimitiveSizeInBits();
163 uint64_t Max = AsSigned && Negate ? 1 : 0;
167 if (Str.size() > 1) {
169 if (toUpper((
unsigned char)Str[1]) ==
'X') {
170 if (Str.size() == 2 || (
Base &&
Base != 16))
175 Str = Str.drop_front(2);
181 }
else if (
Base == 0)
191 for (
unsigned i = 0; i != Str.size(); ++i) {
192 unsigned char DigVal = Str[i];
194 DigVal = DigVal -
'0';
196 DigVal = toUpper(DigVal);
198 DigVal = DigVal -
'A' + 10;
211 if (VFlow || Result > Max)
219 Value *StrEnd =
B.CreateInBoundsGEP(
B.getInt8Ty(), StrBeg, Off,
"endptr");
220 B.CreateStore(StrEnd, EndPtr);
227 return ConstantInt::get(
RetTy, Result);
231 for (
User *U : V->users()) {
232 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
233 if (
Constant *
C = dyn_cast<Constant>(IC->getOperand(1)))
234 if (
C->isNullValue())
262 for (
unsigned ArgNo : ArgNos) {
263 uint64_t DerefBytes = DereferenceableBytes;
268 DereferenceableBytes);
287 for (
unsigned ArgNo : ArgNos) {
313 DerefMin = std::min(
X->getZExtValue(),
Y->getZExtValue());
327 if (
auto *NewCI = dyn_cast_or_null<CallInst>(New))
334 NewCI->
getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
341 return Len >= Str.size() ? Str : Str.substr(0, Len);
366 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
380 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
386 ConstantInt::get(DL.
getIntPtrType(Src->getContext()), Len + 1));
430 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
443 Type *CharTy =
B.getInt8Ty();
444 Value *Char0 =
B.CreateLoad(CharTy, Src);
445 CharVal =
B.CreateTrunc(CharVal, CharTy);
446 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
450 Value *
And =
B.CreateICmpNE(NBytes, Zero);
451 Cmp =
B.CreateLogicalAnd(
And, Cmp);
455 return B.CreateSelect(Cmp, Src, NullPtr);
468 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
479 if (!FT->getParamType(1)->isIntegerTy(IntBits))
486 ConstantInt::get(SizeTTy, Len),
B,
495 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
504 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
517 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
523 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
529 if (CharC && CharC->
isZero())
540 Value *
Size = ConstantInt::get(SizeTTy, NBytes);
547 return ConstantInt::get(CI->
getType(), 0);
554 if (HasStr1 && HasStr2)
555 return ConstantInt::get(CI->
getType(),
556 std::clamp(Str1.
compare(Str2), -1, 1));
558 if (HasStr1 && Str1.
empty())
559 return B.CreateNeg(
B.CreateZExt(
560 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
562 if (HasStr2 && Str2.
empty())
563 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
578 std::min(Len1, Len2)),
583 if (!HasStr1 && HasStr2) {
590 }
else if (HasStr1 && !HasStr2) {
614 return ConstantInt::get(CI->
getType(), 0);
626 return ConstantInt::get(CI->
getType(), 0);
636 if (HasStr1 && HasStr2) {
640 return ConstantInt::get(CI->
getType(),
641 std::clamp(SubStr1.
compare(SubStr2), -1, 1));
644 if (HasStr1 && Str1.
empty())
645 return B.CreateNeg(
B.CreateZExt(
646 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
648 if (HasStr2 && Str2.
empty())
649 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
660 if (!HasStr1 && HasStr2) {
661 Len2 = std::min(Len2,
Length);
668 }
else if (HasStr1 && !HasStr2) {
669 Len1 = std::min(Len1,
Length);
685 if (SrcLen &&
Size) {
687 if (SrcLen <= Size->getZExtValue() + 1)
726 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
736 Type *PT =
Callee->getFunctionType()->getParamType(0);
738 Value *DstEnd =
B.CreateInBoundsGEP(
739 B.getInt8Ty(), Dst, ConstantInt::get(DL.
getIntPtrType(PT), Len - 1));
762 NBytes = SizeC->getZExtValue();
771 B.CreateStore(
B.getInt8(0), Dst);
787 bool NulTerm = SrcLen < NBytes;
796 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
797 NBytes = std::min(NBytes - 1, SrcLen);
802 B.CreateStore(
B.getInt8(0), Dst);
803 return ConstantInt::get(CI->
getType(), 0);
807 Type *PT =
Callee->getFunctionType()->getParamType(0);
816 Value *EndOff = ConstantInt::get(CI->
getType(), NBytes);
817 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
818 B.CreateStore(
B.getInt8(0), EndPtr);
824 return ConstantInt::get(CI->
getType(), SrcLen);
829Value *LibCallSimplifier::optimizeStringNCpy(
CallInst *CI,
bool RetEnd,
847 N = SizeC->getZExtValue();
854 Type *CharTy =
B.getInt8Ty();
855 Value *CharVal =
B.CreateLoad(CharTy, Src,
"stxncpy.char0");
856 B.CreateStore(CharVal, Dst);
862 Value *ZeroChar = ConstantInt::get(CharTy, 0);
863 Value *
Cmp =
B.CreateICmpEQ(CharVal, ZeroChar,
"stpncpy.char0cmp");
865 Value *Off1 =
B.getInt32(1);
866 Value *EndPtr =
B.CreateInBoundsGEP(CharTy, Dst, Off1,
"stpncpy.end");
867 return B.CreateSelect(Cmp, Dst, EndPtr,
"stpncpy.sel");
883 CallInst *NewCI =
B.CreateMemSet(Dst,
B.getInt8(
'\0'),
Size, MemSetAlign);
891 if (
N > SrcLen + 1) {
900 std::string SrcStr = Str.str();
903 SrcStr.resize(
N,
'\0');
904 Src =
B.CreateGlobalString(SrcStr,
"str");
907 Type *PT =
Callee->getFunctionType()->getParamType(0);
919 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
926 Type *CharTy =
B.getIntNTy(CharSize);
936 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
941 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
942 if (BoundCst->isZero())
944 return ConstantInt::get(CI->
getType(), 0);
946 if (BoundCst->isOne()) {
948 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
949 Value *ZeroChar = ConstantInt::get(CharTy, 0);
950 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
951 return B.CreateZExt(Cmp, CI->
getType());
961 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
985 if (Slice.
Array ==
nullptr) {
1004 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
1011 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
1012 NullTermIdx == ArrSize - 1)) {
1014 return B.CreateSub(ConstantInt::get(CI->
getType(), NullTermIdx),
1021 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
1024 if (LenTrue && LenFalse) {
1027 <<
"folded strlen(select) to select of constants";
1029 return B.CreateSelect(
SI->getCondition(),
1030 ConstantInt::get(CI->
getType(), LenTrue - 1),
1031 ConstantInt::get(CI->
getType(), LenFalse - 1));
1039 if (
Value *V = optimizeStringLength(CI,
B, 8))
1047 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1062 return optimizeStringLength(CI,
B, WCharSize);
1072 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1076 if (HasS1 && HasS2) {
1077 size_t I =
S1.find_first_of(S2);
1082 B.getInt64(
I),
"strpbrk");
1086 if (HasS2 && S2.
size() == 1)
1094 if (isa<ConstantPointerNull>(EndPtr)) {
1110 if ((HasS1 &&
S1.empty()) || (HasS2 && S2.
empty()))
1114 if (HasS1 && HasS2) {
1115 size_t Pos =
S1.find_first_not_of(S2);
1118 return ConstantInt::get(CI->
getType(), Pos);
1130 if (HasS1 &&
S1.empty())
1134 if (HasS1 && HasS2) {
1135 size_t Pos =
S1.find_first_of(S2);
1138 return ConstantInt::get(CI->
getType(), Pos);
1142 if (HasS2 && S2.
empty())
1159 StrLen,
B, DL, TLI);
1167 replaceAllUsesWith(Old, Cmp);
1178 if (HasStr2 && ToFindStr.
empty())
1182 if (HasStr1 && HasStr2) {
1189 return B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), CI->
getArgOperand(0),
1194 if (HasStr2 && ToFindStr.
size() == 1) {
1215 if (LenC->
isOne()) {
1218 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1220 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1221 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1222 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1230 if (Str.size() == 0)
1239 if (Str.size() < EndOff)
1244 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1254 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1256 if (Str.find(Str[Pos]) == Pos) {
1263 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1264 B.getInt64(Pos),
"memrchr.ptr_plus");
1265 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1270 Str = Str.substr(0, EndOff);
1278 Type *Int8Ty =
B.getInt8Ty();
1279 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1281 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1282 Value *CEqS0 =
B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1283 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1284 Value *SizeM1 =
B.CreateSub(
Size, ConstantInt::get(SizeTy, 1));
1286 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1287 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1301 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1310 if (LenC->
isOne()) {
1313 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1315 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1316 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1317 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1337 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1339 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1342 if (Str.size() == 0)
1351 size_t Pos = Str.find_first_not_of(Str[0]);
1364 Type *Int8Ty =
B.getInt8Ty();
1367 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1369 Value *Sel1 = NullPtr;
1372 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1373 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1374 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1376 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1377 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1378 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1381 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1382 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1383 Value *NNeZ =
B.CreateICmpNE(
Size, ConstantInt::get(SizeTy, 0));
1385 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1417 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1418 reinterpret_cast<const unsigned char *
>(Str.end()));
1431 std::string SortedStr = Str.str();
1434 unsigned NonContRanges = 1;
1435 for (
size_t i = 1; i < SortedStr.size(); ++i) {
1436 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1443 if (NonContRanges > 2)
1447 for (
unsigned char C : SortedStr)
1449 B.CreateICmpEQ(CharVal, ConstantInt::get(CharVal->
getType(),
C)));
1451 return B.CreateIntToPtr(
B.CreateOr(CharCompares), CI->
getType());
1456 unsigned char Width =
NextPowerOf2(std::max((
unsigned char)7, Max));
1466 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1473 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1474 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1478 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1503 if (Pos == MinSize ||
1504 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1512 if (LStr[Pos] != RStr[Pos])
1517 typedef unsigned char UChar;
1518 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1519 Value *MaxSize = ConstantInt::get(
Size->getType(), Pos);
1522 return B.CreateSelect(Cmp, Zero, Res);
1534 Value *LHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
LHS,
"lhsc"),
1536 Value *RHSV =
B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
RHS,
"rhsc"),
1538 return B.CreateSub(LHSV, RHSV,
"chardiff");
1546 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1549 Value *LHSV =
nullptr;
1550 if (
auto *LHSC = dyn_cast<Constant>(
LHS))
1553 Value *RHSV =
nullptr;
1554 if (
auto *RHSC = dyn_cast<Constant>(
RHS))
1562 LHSV =
B.CreateLoad(IntType,
LHS,
"lhsv");
1564 RHSV =
B.CreateLoad(IntType,
RHS,
"rhsv");
1565 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1573Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1593 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1611 return optimizeMemCmpBCmpCommon(CI,
B);
1617 if (isa<IntrinsicInst>(CI))
1637 if (
N->isNullValue())
1650 if (
N->getZExtValue() <= SrcStr.
size()) {
1659 ConstantInt::get(
N->getType(), std::min(
uint64_t(Pos + 1),
N->getZExtValue()));
1662 return Pos + 1 <=
N->getZExtValue()
1663 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1677 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1683 if (isa<IntrinsicInst>(CI))
1696 if (isa<IntrinsicInst>(CI))
1733 LibFunc_Znwm12__hot_cold_t, HotCold);
1736 LibFunc_Znam12__hot_cold_t, HotCold);
1737 case LibFunc_ZnwmRKSt9nothrow_t:
1739 TLI, LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t,
1741 case LibFunc_ZnamRKSt9nothrow_t:
1743 TLI, LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t,
1745 case LibFunc_ZnwmSt11align_val_t:
1747 TLI, LibFunc_ZnwmSt11align_val_t12__hot_cold_t,
1749 case LibFunc_ZnamSt11align_val_t:
1751 TLI, LibFunc_ZnamSt11align_val_t12__hot_cold_t,
1753 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1756 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1757 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1760 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1791 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1792 Value *
Op = Cast->getOperand(0);
1793 if (
Op->getType()->isFloatTy())
1796 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1802 return ConstantFP::get(Const->getContext(),
F);
1810 bool isPrecise =
false) {
1841 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1842 CallerName.
size() == (CalleeName.
size() + 1) &&
1857 R =
isBinary ?
B.CreateCall(Fn, V) :
B.CreateCall(Fn, V[0]);
1864 return B.CreateFPExt(R,
B.getDoubleTy());
1870 bool isPrecise =
false) {
1877 bool isPrecise =
false) {
1893 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1894 Real =
B.CreateExtractValue(
Op, 0,
"real");
1895 Imag =
B.CreateExtractValue(
Op, 1,
"imag");
1902 Value *RealReal =
B.CreateFMul(Real, Real);
1903 Value *ImagImag =
B.CreateFMul(Imag, Imag);
1908 *CI,
B.CreateCall(FSqrt,
B.CreateFAdd(RealReal, ImagImag),
"cabs"));
1914 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
1915 Value *
Op = cast<Instruction>(I2F)->getOperand(0);
1918 unsigned BitWidth =
Op->getType()->getPrimitiveSizeInBits();
1920 (
BitWidth == DstWidth && isa<SIToFPInst>(I2F)))
1921 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(
Op,
B.getIntNTy(DstWidth))
1922 :
B.CreateZExt(
Op,
B.getIntNTy(DstWidth));
1963 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
1971 ExpName = TLI->
getName(LibFunc_exp);
1972 ID = Intrinsic::exp;
1973 LibFnFloat = LibFunc_expf;
1974 LibFnDouble = LibFunc_exp;
1975 LibFnLongDouble = LibFunc_expl;
1980 ExpName = TLI->
getName(LibFunc_exp2);
1981 ID = Intrinsic::exp2;
1982 LibFnFloat = LibFunc_exp2f;
1983 LibFnDouble = LibFunc_exp2;
1984 LibFnLongDouble = LibFunc_exp2l;
2001 substituteInParent(BaseFn, ExpFn);
2017 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
2018 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2022 TLI, LibFunc_ldexp, LibFunc_ldexpf,
2023 LibFunc_ldexpl,
B, NoAttrs));
2027 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2030 BaseR = BaseR / *BaseF;
2032 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2034 if ((IsInteger || IsReciprocal) &&
2037 NI > 1 && NI.isPowerOf2()) {
2038 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2039 Value *
FMul =
B.CreateFMul(Expo, ConstantFP::get(Ty,
N),
"mul");
2042 Mod, Intrinsic::exp2, Ty),
2047 LibFunc_exp2l,
B, NoAttrs));
2054 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
2056 LibFunc_exp10f, LibFunc_exp10l,
2065 "pow(1.0, y) should have been simplified earlier!");
2067 Value *Log =
nullptr;
2074 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2077 Mod, Intrinsic::exp2, Ty),
2079 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2083 LibFunc_exp2l,
B, NoAttrs));
2097 return B.CreateCall(SqrtFn, V,
"sqrt");
2101 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2107 LibFunc_sqrtl,
B, Attrs);
2145 Sqrt =
B.CreateCall(FAbsFn, Sqrt,
"abs");
2155 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2156 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2161 Sqrt =
B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt,
"reciprocal");
2171 return B.CreateCall(
F, Args);
2193 if (
Value *Exp = replacePowWithExp(Pow,
B))
2200 return B.CreateFDiv(ConstantFP::get(Ty, 1.0),
Base,
"reciprocal");
2204 return ConstantFP::get(Ty, 1.0);
2212 return B.CreateFMul(
Base,
Base,
"square");
2214 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2225 Value *Sqrt =
nullptr;
2226 if (!ExpoA.isInteger()) {
2240 if (!ExpoI.isInteger())
2263 return B.CreateFMul(PowI, Sqrt);
2270 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2277 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2278 hasFloatVersion(M,
Name)) {
2291 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2292 hasFloatVersion(M,
Name))
2304 if ((isa<SIToFPInst>(
Op) || isa<UIToFPInst>(
Op)) &&
2305 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2311 LibFunc_ldexp, LibFunc_ldexpf,
2326 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2340 B.setFastMathFlags(FMF);
2343 : Intrinsic::maxnum;
2346 *CI,
B.CreateCall(
F, {CI->getArgOperand(0), CI->getArgOperand(1)}));
2357 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2365 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2371 LogID = Intrinsic::log;
2372 ExpLb = LibFunc_expf;
2373 Exp2Lb = LibFunc_exp2f;
2374 Exp10Lb = LibFunc_exp10f;
2375 PowLb = LibFunc_powf;
2378 LogID = Intrinsic::log;
2379 ExpLb = LibFunc_exp;
2380 Exp2Lb = LibFunc_exp2;
2381 Exp10Lb = LibFunc_exp10;
2382 PowLb = LibFunc_pow;
2385 LogID = Intrinsic::log;
2386 ExpLb = LibFunc_expl;
2387 Exp2Lb = LibFunc_exp2l;
2388 Exp10Lb = LibFunc_exp10l;
2389 PowLb = LibFunc_powl;
2392 LogID = Intrinsic::log2;
2393 ExpLb = LibFunc_expf;
2394 Exp2Lb = LibFunc_exp2f;
2395 Exp10Lb = LibFunc_exp10f;
2396 PowLb = LibFunc_powf;
2399 LogID = Intrinsic::log2;
2400 ExpLb = LibFunc_exp;
2401 Exp2Lb = LibFunc_exp2;
2402 Exp10Lb = LibFunc_exp10;
2403 PowLb = LibFunc_pow;
2406 LogID = Intrinsic::log2;
2407 ExpLb = LibFunc_expl;
2408 Exp2Lb = LibFunc_exp2l;
2409 Exp10Lb = LibFunc_exp10l;
2410 PowLb = LibFunc_powl;
2412 case LibFunc_log10f:
2413 LogID = Intrinsic::log10;
2414 ExpLb = LibFunc_expf;
2415 Exp2Lb = LibFunc_exp2f;
2416 Exp10Lb = LibFunc_exp10f;
2417 PowLb = LibFunc_powf;
2420 LogID = Intrinsic::log10;
2421 ExpLb = LibFunc_exp;
2422 Exp2Lb = LibFunc_exp2;
2423 Exp10Lb = LibFunc_exp10;
2424 PowLb = LibFunc_pow;
2426 case LibFunc_log10l:
2427 LogID = Intrinsic::log10;
2428 ExpLb = LibFunc_expl;
2429 Exp2Lb = LibFunc_exp2l;
2430 Exp10Lb = LibFunc_exp10l;
2431 PowLb = LibFunc_powl;
2436 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2437 LogID == Intrinsic::log10) {
2439 ExpLb = LibFunc_expf;
2440 Exp2Lb = LibFunc_exp2f;
2441 Exp10Lb = LibFunc_exp10f;
2442 PowLb = LibFunc_powf;
2444 ExpLb = LibFunc_exp;
2445 Exp2Lb = LibFunc_exp2;
2446 Exp10Lb = LibFunc_exp10;
2447 PowLb = LibFunc_pow;
2462 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2470 if (ArgID == Intrinsic::powi)
2471 Y =
B.CreateSIToFP(
Y, Ty,
"cast");
2472 Value *MulY =
B.CreateFMul(
Y, LogX,
"mul");
2475 substituteInParent(Arg, MulY);
2481 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2482 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2484 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2487 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2488 Eul = ConstantFP::get(Log->
getType(), 2.0);
2490 Eul = ConstantFP::get(Log->
getType(), 10.0);
2498 substituteInParent(Arg, MulY);
2518 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2523 ExpLb = LibFunc_expf;
2524 Exp2Lb = LibFunc_exp2f;
2525 Exp10Lb = LibFunc_exp10f;
2528 ExpLb = LibFunc_exp;
2529 Exp2Lb = LibFunc_exp2;
2530 Exp10Lb = LibFunc_exp10;
2533 ExpLb = LibFunc_expl;
2534 Exp2Lb = LibFunc_exp2l;
2535 Exp10Lb = LibFunc_exp10l;
2542 ExpLb = LibFunc_expf;
2543 Exp2Lb = LibFunc_exp2f;
2544 Exp10Lb = LibFunc_exp10f;
2546 ExpLb = LibFunc_exp;
2547 Exp2Lb = LibFunc_exp2;
2548 Exp10Lb = LibFunc_exp10;
2554 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2555 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2559 B.SetInsertPoint(Arg);
2562 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2577 (
Callee->getName() ==
"sqrt" ||
2578 Callee->getIntrinsicID() == Intrinsic::sqrt))
2581 if (
Value *Opt = mergeSqrtToExp(CI,
B))
2588 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2594 Value *Op0 =
I->getOperand(0);
2595 Value *Op1 =
I->getOperand(1);
2596 Value *RepeatOp =
nullptr;
2597 Value *OtherOp =
nullptr;
2607 Value *OtherMul0, *OtherMul1;
2610 if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
2612 RepeatOp = OtherMul0;
2623 B.setFastMathFlags(
I->getFastMathFlags());
2627 Type *ArgType =
I->getType();
2629 Value *FabsCall =
B.CreateCall(Fabs, RepeatOp,
"fabs");
2635 Value *SqrtCall =
B.CreateCall(Sqrt, OtherOp,
"sqrt");
2636 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2641Value *LibCallSimplifier::optimizeTrigInversionPairs(
CallInst *CI,
2647 if (UnsafeFPShrink &&
2650 hasFloatVersion(M,
Name))
2654 auto *OpC = dyn_cast<CallInst>(Op1);
2659 if (!CI->
isFast() || !OpC->isFast())
2672 .
Case(
"tan", LibFunc_atan)
2673 .
Case(
"atanh", LibFunc_tanh)
2674 .
Case(
"sinh", LibFunc_asinh)
2675 .
Case(
"cosh", LibFunc_acosh)
2676 .
Case(
"tanf", LibFunc_atanf)
2677 .
Case(
"atanhf", LibFunc_tanhf)
2678 .
Case(
"sinhf", LibFunc_asinhf)
2679 .
Case(
"coshf", LibFunc_acoshf)
2680 .
Case(
"tanl", LibFunc_atanl)
2681 .
Case(
"atanhl", LibFunc_tanhl)
2682 .
Case(
"sinhl", LibFunc_asinhl)
2683 .
Case(
"coshl", LibFunc_acoshl)
2684 .
Case(
"asinh", LibFunc_sinh)
2685 .
Case(
"asinhf", LibFunc_sinhf)
2686 .
Case(
"asinhl", LibFunc_sinhl)
2688 if (Func == inverseFunc)
2689 Ret = OpC->getArgOperand(0);
2711 Name =
"__sincospif_stret";
2720 Name =
"__sincospi_stret";
2729 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2731 if (
Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
2734 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2738 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2739 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2742 SinCos =
B.CreateCall(Callee, Arg,
"sincospi");
2745 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2746 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2748 Sin =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 0),
2750 Cos =
B.CreateExtractElement(SinCos, ConstantInt::get(
B.getInt32Ty(), 1),
2832 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2838 Value *Sin, *Cos, *SinCos;
2846 replaceAllUsesWith(
C, Res);
2849 replaceTrigInsts(SinCalls, Sin);
2850 replaceTrigInsts(CosCalls, Cos);
2851 replaceTrigInsts(SinCosCalls, SinCos);
2853 return IsSin ? Sin : Cos;
2856void LibCallSimplifier::classifyArgUse(
2861 auto *CI = dyn_cast<CallInst>(Val);
2872 if (!Callee || !TLI->
getLibFunc(*Callee, Func) ||
2878 if (Func == LibFunc_sinpif)
2880 else if (Func == LibFunc_cospif)
2882 else if (Func == LibFunc_sincospif_stret)
2885 if (Func == LibFunc_sinpi)
2887 else if (Func == LibFunc_cospi)
2889 else if (Func == LibFunc_sincospi_stret)
2903 Type *ArgType =
Op->getType();
2905 Intrinsic::cttz, ArgType);
2906 Value *
V =
B.CreateCall(
F, {
Op,
B.getTrue()},
"cttz");
2907 V =
B.CreateAdd(V, ConstantInt::get(
V->getType(), 1));
2908 V =
B.CreateIntCast(V, RetType,
false);
2911 return B.CreateSelect(
Cond, V, ConstantInt::get(RetType, 0));
2918 Type *ArgType =
Op->getType();
2920 Intrinsic::ctlz, ArgType);
2921 Value *
V =
B.CreateCall(
F, {
Op,
B.getFalse()},
"ctlz");
2924 return B.CreateIntCast(V, CI->
getType(),
false);
2931 Value *IsNeg =
B.CreateIsNeg(
X);
2932 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
2933 return B.CreateSelect(IsNeg, NegX,
X);
2939 Type *ArgType =
Op->getType();
2940 Op =
B.CreateSub(
Op, ConstantInt::get(ArgType,
'0'),
"isdigittmp");
2941 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 10),
"isdigit");
2948 Type *ArgType =
Op->getType();
2949 Op =
B.CreateICmpULT(
Op, ConstantInt::get(ArgType, 128),
"isascii");
2956 ConstantInt::get(CI->
getType(), 0x7F));
2974 if (isa<ConstantPointerNull>(EndPtr)) {
2987 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
3019 if (!Callee || !Callee->isDeclaration())
3028 if (StreamArg >= (
int)CI->
arg_size())
3036 return GV->
getName() ==
"stderr";
3046 if (FormatStr.
empty())
3057 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
3061 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)FormatStr[0]);
3066 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
3071 if (OperandStr.
empty())
3074 if (OperandStr.
size() == 1) {
3078 Value *IntChar = ConstantInt::get(IntTy, (
unsigned char)OperandStr[0]);
3082 if (OperandStr.
back() ==
'\n') {
3084 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
3091 if (FormatStr.
back() ==
'\n' &&
3096 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
3102 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
3111 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
3122 if (
Value *V = optimizePrintFString(CI,
B)) {
3133 Callee->getAttributes());
3135 New->setCalledFunction(IPrintFFn);
3145 Callee->getAttributes());
3147 New->setCalledFunction(SmallPrintFFn);
3155Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
3174 FormatStr.
size() + 1));
3175 return ConstantInt::get(CI->
getType(), FormatStr.
size());
3180 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3184 if (FormatStr[1] ==
'c') {
3190 B.CreateStore(V,
Ptr);
3191 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3192 B.CreateStore(
B.getInt8(0),
Ptr);
3194 return ConstantInt::get(CI->
getType(), 1);
3197 if (FormatStr[1] ==
's') {
3213 return ConstantInt::get(CI->
getType(), SrcLen - 1);
3216 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
3217 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3230 B.CreateAdd(Len, ConstantInt::get(
Len->getType(), 1),
"leninc");
3234 return B.CreateIntCast(Len, CI->
getType(),
false);
3243 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3254 FT,
Callee->getAttributes());
3256 New->setCalledFunction(SIPrintFFn);
3266 Callee->getAttributes());
3268 New->setCalledFunction(SmallSPrintFFn);
3284 assert(StrArg || (
N < 2 && Str.size() == 1));
3288 if (Str.size() > IntMax)
3294 Value *StrLen = ConstantInt::get(CI->
getType(), Str.size());
3304 NCopy = Str.size() + 1;
3309 if (NCopy && StrArg)
3323 Type *Int8Ty =
B.getInt8Ty();
3324 Value *NulOff =
B.getIntN(IntBits, NCopy);
3325 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3326 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3330Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3359 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3364 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3368 if (FormatStr[1] ==
'c') {
3374 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3382 B.CreateStore(V,
Ptr);
3383 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3384 B.CreateStore(
B.getInt8(0),
Ptr);
3385 return ConstantInt::get(CI->
getType(), 1);
3388 if (FormatStr[1] !=
's')
3397 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3401 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3410Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3412 optimizeErrorReporting(CI,
B, 0);
3435 ConstantInt::get(SizeTTy, FormatStr.
size()),
3441 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3445 if (FormatStr[1] ==
'c') {
3455 if (FormatStr[1] ==
's') {
3469 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3478 FT,
Callee->getAttributes());
3480 New->setCalledFunction(FIPrintFFn);
3489 auto SmallFPrintFFn =
3491 Callee->getAttributes());
3493 New->setCalledFunction(SmallFPrintFFn);
3502 optimizeErrorReporting(CI,
B, 3);
3507 if (SizeC && CountC) {
3512 return ConstantInt::get(CI->
getType(), 0);
3519 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3521 return NewCI ? ConstantInt::get(CI->
getType(), 1) : nullptr;
3529 optimizeErrorReporting(CI,
B, 1);
3554 ConstantInt::get(SizeTTy, Len - 1),
3583bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3585 FloatFuncName +=
'f';
3589Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3600 "Optimizing string/memory libcall would change the calling convention");
3602 case LibFunc_strcat:
3603 return optimizeStrCat(CI, Builder);
3604 case LibFunc_strncat:
3605 return optimizeStrNCat(CI, Builder);
3606 case LibFunc_strchr:
3607 return optimizeStrChr(CI, Builder);
3608 case LibFunc_strrchr:
3609 return optimizeStrRChr(CI, Builder);
3610 case LibFunc_strcmp:
3611 return optimizeStrCmp(CI, Builder);
3612 case LibFunc_strncmp:
3613 return optimizeStrNCmp(CI, Builder);
3614 case LibFunc_strcpy:
3615 return optimizeStrCpy(CI, Builder);
3616 case LibFunc_stpcpy:
3617 return optimizeStpCpy(CI, Builder);
3618 case LibFunc_strlcpy:
3619 return optimizeStrLCpy(CI, Builder);
3620 case LibFunc_stpncpy:
3621 return optimizeStringNCpy(CI,
true, Builder);
3622 case LibFunc_strncpy:
3623 return optimizeStringNCpy(CI,
false, Builder);
3624 case LibFunc_strlen:
3625 return optimizeStrLen(CI, Builder);
3626 case LibFunc_strnlen:
3627 return optimizeStrNLen(CI, Builder);
3628 case LibFunc_strpbrk:
3629 return optimizeStrPBrk(CI, Builder);
3630 case LibFunc_strndup:
3631 return optimizeStrNDup(CI, Builder);
3632 case LibFunc_strtol:
3633 case LibFunc_strtod:
3634 case LibFunc_strtof:
3635 case LibFunc_strtoul:
3636 case LibFunc_strtoll:
3637 case LibFunc_strtold:
3638 case LibFunc_strtoull:
3639 return optimizeStrTo(CI, Builder);
3640 case LibFunc_strspn:
3641 return optimizeStrSpn(CI, Builder);
3642 case LibFunc_strcspn:
3643 return optimizeStrCSpn(CI, Builder);
3644 case LibFunc_strstr:
3645 return optimizeStrStr(CI, Builder);
3646 case LibFunc_memchr:
3647 return optimizeMemChr(CI, Builder);
3648 case LibFunc_memrchr:
3649 return optimizeMemRChr(CI, Builder);
3651 return optimizeBCmp(CI, Builder);
3652 case LibFunc_memcmp:
3653 return optimizeMemCmp(CI, Builder);
3654 case LibFunc_memcpy:
3655 return optimizeMemCpy(CI, Builder);
3656 case LibFunc_memccpy:
3657 return optimizeMemCCpy(CI, Builder);
3658 case LibFunc_mempcpy:
3659 return optimizeMemPCpy(CI, Builder);
3660 case LibFunc_memmove:
3661 return optimizeMemMove(CI, Builder);
3662 case LibFunc_memset:
3663 return optimizeMemSet(CI, Builder);
3664 case LibFunc_realloc:
3665 return optimizeRealloc(CI, Builder);
3666 case LibFunc_wcslen:
3667 return optimizeWcslen(CI, Builder);
3669 return optimizeBCopy(CI, Builder);
3671 case LibFunc_ZnwmRKSt9nothrow_t:
3672 case LibFunc_ZnwmSt11align_val_t:
3673 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3675 case LibFunc_ZnamRKSt9nothrow_t:
3676 case LibFunc_ZnamSt11align_val_t:
3677 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
3678 return optimizeNew(CI, Builder, Func);
3686Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3695 if (
Value *V = optimizeSymmetric(CI, Func, Builder))
3699 case LibFunc_sinpif:
3701 return optimizeSinCosPi(CI,
true, Builder);
3702 case LibFunc_cospif:
3704 return optimizeSinCosPi(CI,
false, Builder);
3708 return optimizePow(CI, Builder);
3712 return optimizeExp2(CI, Builder);
3720 return optimizeSqrt(CI, Builder);
3724 case LibFunc_log10f:
3726 case LibFunc_log10l:
3727 case LibFunc_log1pf:
3729 case LibFunc_log1pl:
3736 return optimizeLog(CI, Builder);
3744 case LibFunc_asinhf:
3745 case LibFunc_asinhl:
3750 case LibFunc_atanhf:
3751 case LibFunc_atanhl:
3752 return optimizeTrigInversionPairs(CI, Builder);
3759 case LibFunc_roundeven:
3761 case LibFunc_nearbyint:
3781 case LibFunc_copysign:
3791 return optimizeFMinFMax(CI, Builder);
3795 return optimizeCAbs(CI, Builder);
3826 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3827 UnsafeFPShrink =
true;
3831 if (!IsCallingConvC)
3835 switch (II->getIntrinsicID()) {
3836 case Intrinsic::pow:
3837 return optimizePow(CI, Builder);
3838 case Intrinsic::exp2:
3839 return optimizeExp2(CI, Builder);
3840 case Intrinsic::log:
3841 case Intrinsic::log2:
3842 case Intrinsic::log10:
3843 return optimizeLog(CI, Builder);
3844 case Intrinsic::sqrt:
3845 return optimizeSqrt(CI, Builder);
3846 case Intrinsic::memset:
3847 return optimizeMemSet(CI, Builder);
3848 case Intrinsic::memcpy:
3849 return optimizeMemCpy(CI, Builder);
3850 case Intrinsic::memmove:
3851 return optimizeMemMove(CI, Builder);
3858 if (
Value *SimplifiedFortifiedCI =
3860 return SimplifiedFortifiedCI;
3867 if (
Value *V = optimizeStringMemoryLibCall(CI, Builder))
3869 if (
Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
3875 return optimizeFFS(CI, Builder);
3879 return optimizeFls(CI, Builder);
3883 return optimizeAbs(CI, Builder);
3884 case LibFunc_isdigit:
3885 return optimizeIsDigit(CI, Builder);
3886 case LibFunc_isascii:
3887 return optimizeIsAscii(CI, Builder);
3888 case LibFunc_toascii:
3889 return optimizeToAscii(CI, Builder);
3893 return optimizeAtoi(CI, Builder);
3894 case LibFunc_strtol:
3895 case LibFunc_strtoll:
3896 return optimizeStrToInt(CI, Builder,
true);
3897 case LibFunc_strtoul:
3898 case LibFunc_strtoull:
3899 return optimizeStrToInt(CI, Builder,
false);
3900 case LibFunc_printf:
3901 return optimizePrintF(CI, Builder);
3902 case LibFunc_sprintf:
3903 return optimizeSPrintF(CI, Builder);
3904 case LibFunc_snprintf:
3905 return optimizeSnPrintF(CI, Builder);
3906 case LibFunc_fprintf:
3907 return optimizeFPrintF(CI, Builder);
3908 case LibFunc_fwrite:
3909 return optimizeFWrite(CI, Builder);
3911 return optimizeFPuts(CI, Builder);
3913 return optimizePuts(CI, Builder);
3914 case LibFunc_perror:
3915 return optimizeErrorReporting(CI, Builder);
3916 case LibFunc_vfprintf:
3917 case LibFunc_fiprintf:
3918 return optimizeErrorReporting(CI, Builder, 0);
3932 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), AC(AC), ORE(ORE), BFI(BFI),
3933 PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
3940void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
3979bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
3980 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
3981 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
3986 if (!Flag || !
Flag->isZero())
3995 if (ObjSizeCI->isMinusOne())
3998 if (OnlyLowerUnknownSize)
4008 return ObjSizeCI->getZExtValue() >=
Len;
4014 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4020Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
4022 if (isFortifiedCallFoldable(CI, 3, 2)) {
4032Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
4034 if (isFortifiedCallFoldable(CI, 3, 2)) {
4044Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
4046 if (isFortifiedCallFoldable(CI, 3, 2)) {
4056Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
4059 if (isFortifiedCallFoldable(CI, 3, 2))
4067Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
4075 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4077 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
4085 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4086 if (Func == LibFunc_strcpy_chk)
4092 if (OnlyLowerUnknownSize)
4104 Value *LenV = ConstantInt::get(SizeTTy, Len);
4108 if (Ret && Func == LibFunc_stpcpy_chk)
4109 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
4110 ConstantInt::get(SizeTTy, Len - 1));
4111 return copyFlags(*CI, cast<CallInst>(Ret));
4114Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
4116 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4122Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
4125 if (isFortifiedCallFoldable(CI, 3, 2)) {
4126 if (Func == LibFunc_strncpy_chk)
4139Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
4141 if (isFortifiedCallFoldable(CI, 4, 3))
4149Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
4151 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4161Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
4163 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4167 VariadicArgs,
B, TLI));
4173Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
4175 if (isFortifiedCallFoldable(CI, 2))
4182Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
4184 if (isFortifiedCallFoldable(CI, 3))
4192Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
4194 if (isFortifiedCallFoldable(CI, 3))
4202Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
4204 if (isFortifiedCallFoldable(CI, 3))
4212Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
4214 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4222Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4224 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4267 case LibFunc_memcpy_chk:
4268 return optimizeMemCpyChk(CI, Builder);
4269 case LibFunc_mempcpy_chk:
4270 return optimizeMemPCpyChk(CI, Builder);
4271 case LibFunc_memmove_chk:
4272 return optimizeMemMoveChk(CI, Builder);
4273 case LibFunc_memset_chk:
4274 return optimizeMemSetChk(CI, Builder);
4275 case LibFunc_stpcpy_chk:
4276 case LibFunc_strcpy_chk:
4277 return optimizeStrpCpyChk(CI, Builder, Func);
4278 case LibFunc_strlen_chk:
4279 return optimizeStrLenChk(CI, Builder);
4280 case LibFunc_stpncpy_chk:
4281 case LibFunc_strncpy_chk:
4282 return optimizeStrpNCpyChk(CI, Builder, Func);
4283 case LibFunc_memccpy_chk:
4284 return optimizeMemCCpyChk(CI, Builder);
4285 case LibFunc_snprintf_chk:
4286 return optimizeSNPrintfChk(CI, Builder);
4287 case LibFunc_sprintf_chk:
4288 return optimizeSPrintfChk(CI, Builder);
4289 case LibFunc_strcat_chk:
4290 return optimizeStrCatChk(CI, Builder);
4291 case LibFunc_strlcat_chk:
4292 return optimizeStrLCat(CI, Builder);
4293 case LibFunc_strncat_chk:
4294 return optimizeStrNCatChk(CI, Builder);
4295 case LibFunc_strlcpy_chk:
4296 return optimizeStrLCpyChk(CI, Builder);
4297 case LibFunc_vsnprintf_chk:
4298 return optimizeVSNPrintfChk(CI, Builder);
4299 case LibFunc_vsprintf_chk:
4300 return optimizeVSPrintfChk(CI, Builder);
4309 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static bool isBinary(MachineInstr &MI)
const SmallVectorImpl< MachineOperand > & Cond
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With)
Return true if it is only used in equality comparisons with With.
static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef< unsigned > ArgNos, Value *Size, const DataLayout &DL)
static cl::opt< unsigned, false, HotColdHintParser > ColdNewHintValue("cold-new-hint-value", cl::Hidden, cl::init(1), cl::desc("Value to pass to hot/cold operator new for cold allocation"))
static bool insertSinCosCall(IRBuilderBase &B, Function *OrigCallee, Value *Arg, bool UseFloat, Value *&Sin, Value *&Cos, Value *&SinCos, const TargetLibraryInfo *TLI)
static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len, const DataLayout &DL)
static Value * mergeAttributesAndFlags(CallInst *NewCI, const CallInst &Old)
static cl::opt< bool > OptimizeHotColdNew("optimize-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable hot/cold operator new library calls"))
static Value * optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for binary functions.
static bool ignoreCallingConv(LibFunc Func)
static 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"))
This file defines the SmallString class.
bool isFiniteNonZero() const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
double convertToDouble() const
Converts this APFloat to host double value.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
opStatus add(const APFloat &RHS, roundingMode RM)
const fltSemantics & getSemantics() const
float convertToFloat() const
Converts this APFloat to host float value.
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Class for arbitrary precision integers.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
Attribute getFnAttr(Attribute::AttrKind Kind) const
Return the attribute object that exists for the function.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &B) const
Add an argument attribute to the list.
MaybeAlign getAlignment() const
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool doesNotAccessMemory(unsigned OpNo) const
void removeRetAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the return value.
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
uint64_t getParamDereferenceableBytes(unsigned i) const
Extract the number of dereferenceable bytes for a call or parameter (0=unknown).
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
bool doesNotThrow() const
Determine if the call cannot unwind.
Value * getArgOperand(unsigned i) const
uint64_t getParamDereferenceableOrNullBytes(unsigned i) const
Extract the number of dereferenceable_or_null bytes for a parameter (0=unknown).
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the parameter attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
bool isNoTailCall() const
TailCallKind getTailCallKind() const
bool isMustTailCall() const
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
uint64_t getElementAsInteger(unsigned i) const
If this is a sequential container of integers (of any size), return the specified element in the low ...
ConstantFP - Floating Point Values [float, double].
static Constant * getInfinity(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
bool fitsInLegalInteger(unsigned Width) const
Returns true if the specified type fits in a native integer type supported by the CPU.
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
void setNoSignedZeros(bool B=true)
static FastMathFlags getFast()
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize=false)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
Take the given call instruction and return a more optimal value to replace the instruction with or 0 ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
void setDefaultOperandBundles(ArrayRef< OperandBundleDef > OpBundles)
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
bool isFast() const LLVM_READONLY
Determine whether all fast-math-flags are set.
const Function * getFunction() const
Return the function this instruction belongs to.
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, AssumptionCache *AC, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
An instruction for reading from memory.
Value * getPointerOperand()
A Module instance is used to store all the information related to an LLVM module.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Analysis providing profile information.
This class represents the LLVM 'select' instruction.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static bool isCallingConvCCompatible(CallBase *CI)
Returns true if call site / callee has cdecl-compatible calling conventions.
Provides information about what library functions are available for the current target.
unsigned getWCharSize(const Module &M) const
Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
unsigned getSizeTSize(const Module &M) const
Returns the size of the size_t type in bits.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
StringRef getName(LibFunc F) const
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isStructTy() const
True if this is an instance of StructType.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
specific_fpval m_SpecificFP(double V)
Match a specific floating point value or vector with all elements equal to the value.
OneUse_match< T > m_OneUse(const T &SubPattern)
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to be non-zero when defined.
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.
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.