39using namespace PatternMatch;
44 cl::desc(
"Enable unsafe double to float "
45 "shrinking for math lib calls"));
52 return Func == LibFunc_abs || Func == LibFunc_labs ||
53 Func == LibFunc_llabs || Func == LibFunc_strlen;
58 for (
User *U : V->users()) {
59 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
60 if (IC->isEquality() && IC->getOperand(1) == With)
70 return OI->getType()->isFloatingPointTy();
76 return OI->getType()->isFP128Ty();
89 if (Base < 2 || Base > 36)
98 if (!isSpace((
unsigned char)Str[
Offset])) {
109 bool Negate = Str[0] ==
'-';
110 if (Str[0] ==
'-' || Str[0] ==
'+') {
111 Str = Str.drop_front();
121 unsigned NBits =
RetTy->getPrimitiveSizeInBits();
122 uint64_t Max = AsSigned && Negate ? 1 : 0;
126 if (Str.size() > 1) {
128 if (toUpper((
unsigned char)Str[1]) ==
'X') {
129 if (Str.size() == 2 || (
Base &&
Base != 16))
134 Str = Str.drop_front(2);
140 }
else if (
Base == 0)
150 for (
unsigned i = 0; i != Str.size(); ++i) {
151 unsigned char DigVal = Str[i];
153 DigVal = DigVal -
'0';
155 DigVal = toUpper(DigVal);
157 DigVal = DigVal -
'A' + 10;
170 if (VFlow || Result > Max)
178 Value *StrEnd =
B.CreateInBoundsGEP(
B.getInt8Ty(), StrBeg, Off,
"endptr");
179 B.CreateStore(StrEnd, EndPtr);
190 for (
User *U : V->users()) {
191 if (
ICmpInst *IC = dyn_cast<ICmpInst>(U))
192 if (
Constant *
C = dyn_cast<Constant>(IC->getOperand(1)))
193 if (
C->isNullValue())
221 for (
unsigned ArgNo : ArgNos) {
222 uint64_t DerefBytes = DereferenceableBytes;
227 DereferenceableBytes);
246 for (
unsigned ArgNo : ArgNos) {
272 DerefMin = std::min(
X->getZExtValue(),
Y->getZExtValue());
286 if (
auto *NewCI = dyn_cast_or_null<CallInst>(New))
293 NewCI->
getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
300 return Len >= Str.size() ? Str : Str.substr(0, Len);
325 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len,
B));
339 Value *CpyDst =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, DstLen,
"endptr");
389 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen,
B));
402 Type *CharTy =
B.getInt8Ty();
403 Value *Char0 =
B.CreateLoad(CharTy, Src);
404 CharVal =
B.CreateTrunc(CharVal, CharTy);
405 Value *Cmp =
B.CreateICmpEQ(Char0, CharVal,
"char0cmp");
409 Value *
And =
B.CreateICmpNE(NBytes, Zero);
410 Cmp =
B.CreateLogicalAnd(
And, Cmp);
414 return B.CreateSelect(Cmp, Src, NullPtr);
427 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
438 if (!FT->getParamType(1)->isIntegerTy(IntBits))
454 return B.CreateIntToPtr(
B.getTrue(), CI->
getType());
463 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, StrLen,
"strchr");
476 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(
I),
"strchr");
482 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
488 if (CharC && CharC->
isZero())
513 if (HasStr1 && HasStr2)
515 std::clamp(Str1.
compare(Str2), -1, 1));
517 if (HasStr1 && Str1.
empty())
518 return B.CreateNeg(
B.CreateZExt(
519 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
521 if (HasStr2 && Str2.
empty())
522 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
537 std::min(Len1, Len2)),
542 if (!HasStr1 && HasStr2) {
549 }
else if (HasStr1 && !HasStr2) {
595 if (HasStr1 && HasStr2) {
600 std::clamp(SubStr1.
compare(SubStr2), -1, 1));
603 if (HasStr1 && Str1.
empty())
604 return B.CreateNeg(
B.CreateZExt(
605 B.CreateLoad(
B.getInt8Ty(), Str2P,
"strcmpload"), CI->
getType()));
607 if (HasStr2 && Str2.
empty())
608 return B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(), Str1P,
"strcmpload"),
619 if (!HasStr1 && HasStr2) {
620 Len2 = std::min(Len2,
Length);
627 }
else if (HasStr1 && !HasStr2) {
628 Len1 = std::min(Len1,
Length);
644 if (SrcLen &&
Size) {
646 if (SrcLen <= Size->getZExtValue() + 1)
685 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
697 Value *DstEnd =
B.CreateInBoundsGEP(
721 NBytes = SizeC->getZExtValue();
730 B.CreateStore(
B.getInt8(0), Dst);
746 bool NulTerm = SrcLen < NBytes;
755 SrcLen = std::min(SrcLen,
uint64_t(Str.size()));
756 NBytes = std::min(NBytes - 1, SrcLen);
761 B.CreateStore(
B.getInt8(0), Dst);
776 Value *EndPtr =
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, EndOff);
777 B.CreateStore(
B.getInt8(0), EndPtr);
788Value *LibCallSimplifier::optimizeStringNCpy(
CallInst *CI,
bool RetEnd,
806 N = SizeC->getZExtValue();
813 Type *CharTy =
B.getInt8Ty();
814 Value *CharVal =
B.CreateLoad(CharTy, Src,
"stxncpy.char0");
815 B.CreateStore(CharVal, Dst);
822 Value *
Cmp =
B.CreateICmpEQ(CharVal, ZeroChar,
"stpncpy.char0cmp");
824 Value *Off1 =
B.getInt32(1);
825 Value *EndPtr =
B.CreateInBoundsGEP(CharTy, Dst, Off1,
"stpncpy.end");
826 return B.CreateSelect(Cmp, Dst, EndPtr,
"stpncpy.sel");
842 CallInst *NewCI =
B.CreateMemSet(Dst,
B.getInt8(
'\0'),
Size, MemSetAlign);
850 if (
N > SrcLen + 1) {
859 std::string SrcStr = Str.str();
862 SrcStr.resize(
N,
'\0');
863 Src =
B.CreateGlobalString(SrcStr,
"str");
878 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, Off,
"endptr");
885 Type *CharTy =
B.getIntNTy(CharSize);
895 return B.CreateZExt(
B.CreateLoad(CharTy, Src,
"char0"),
900 if (
ConstantInt *BoundCst = dyn_cast<ConstantInt>(Bound)) {
901 if (BoundCst->isZero())
905 if (BoundCst->isOne()) {
907 Value *CharVal =
B.CreateLoad(CharTy, Src,
"strnlen.char0");
909 Value *
Cmp =
B.CreateICmpNE(CharVal, ZeroChar,
"strnlen.char0cmp");
910 return B.CreateZExt(Cmp, CI->
getType());
920 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
944 if (Slice.
Array ==
nullptr) {
963 cast<ArrayType>(
GEP->getSourceElementType())->getNumElements();
970 (isa<GlobalVariable>(
GEP->getOperand(0)) &&
971 NullTermIdx == ArrSize - 1)) {
980 if (
SelectInst *SI = dyn_cast<SelectInst>(Src)) {
983 if (LenTrue && LenFalse) {
986 <<
"folded strlen(select) to select of constants";
988 return B.CreateSelect(
SI->getCondition(),
998 if (
Value *V = optimizeStringLength(CI,
B, 8))
1006 if (
Value *V = optimizeStringLength(CI,
B, 8, Bound))
1021 return optimizeStringLength(CI,
B, WCharSize);
1031 if ((HasS1 && S1.
empty()) || (HasS2 && S2.
empty()))
1035 if (HasS1 && HasS2) {
1041 B.getInt64(
I),
"strpbrk");
1045 if (HasS2 && S2.
size() == 1)
1053 if (isa<ConstantPointerNull>(EndPtr)) {
1069 if ((HasS1 && S1.
empty()) || (HasS2 && S2.
empty()))
1073 if (HasS1 && HasS2) {
1089 if (HasS1 && S1.
empty())
1093 if (HasS1 && HasS2) {
1101 if (HasS2 && S2.
empty())
1118 StrLen,
B, DL, TLI);
1126 replaceAllUsesWith(Old, Cmp);
1137 if (HasStr2 && ToFindStr.
empty())
1141 if (HasStr1 && HasStr2) {
1150 B.CreateConstInBoundsGEP1_64(
B.getInt8Ty(), Result,
Offset,
"strstr");
1151 return B.CreateBitCast(Result, CI->
getType());
1155 if (HasStr2 && ToFindStr.
size() == 1) {
1157 return StrChr ?
B.CreateBitCast(StrChr, CI->
getType()) :
nullptr;
1177 if (LenC->
isOne()) {
1180 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memrchr.char0");
1182 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1183 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memrchr.char0cmp");
1184 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memrchr.sel");
1192 if (Str.size() == 0)
1201 if (Str.size() < EndOff)
1206 if (
ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal)) {
1216 return B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos));
1218 if (Str.find(Str[Pos]) == Pos) {
1225 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
1226 B.getInt64(Pos),
"memrchr.ptr_plus");
1227 return B.CreateSelect(Cmp, NullPtr, SrcPlus,
"memrchr.sel");
1232 Str = Str.substr(0, EndOff);
1240 Type *Int8Ty =
B.getInt8Ty();
1243 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1245 Value *
And =
B.CreateLogicalAnd(NNeZ, CEqS0);
1248 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1,
"memrchr.ptr_plus");
1249 return B.CreateSelect(
And, SrcPlus, NullPtr,
"memrchr.sel");
1263 ConstantInt *CharC = dyn_cast<ConstantInt>(CharVal);
1272 if (LenC->
isOne()) {
1275 Value *Val =
B.CreateLoad(
B.getInt8Ty(), SrcStr,
"memchr.char0");
1277 CharVal =
B.CreateTrunc(CharVal,
B.getInt8Ty());
1278 Value *
Cmp =
B.CreateICmpEQ(Val, CharVal,
"memchr.char0cmp");
1279 return B.CreateSelect(Cmp, SrcStr, NullPtr,
"memchr.sel");
1299 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr,
B.getInt64(Pos),
1301 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1304 if (Str.size() == 0)
1313 size_t Pos = Str.find_first_not_of(Str[0]);
1326 Type *Int8Ty =
B.getInt8Ty();
1329 CharVal =
B.CreateTrunc(CharVal, Int8Ty);
1331 Value *Sel1 = NullPtr;
1336 Value *CEqSPos =
B.CreateICmpEQ(CharVal, StrPos);
1338 Value *
And =
B.CreateAnd(CEqSPos, NGtPos);
1339 Value *SrcPlus =
B.CreateInBoundsGEP(
B.getInt8Ty(), SrcStr, PosVal);
1340 Sel1 =
B.CreateSelect(
And, SrcPlus, NullPtr,
"memchr.sel1");
1344 Value *CEqS0 =
B.CreateICmpEQ(Str0, CharVal);
1347 return B.CreateSelect(
And, SrcStr, Sel1,
"memchr.sel2");
1375 *std::max_element(
reinterpret_cast<const unsigned char *
>(Str.begin()),
1376 reinterpret_cast<const unsigned char *
>(Str.end()));
1398 C =
B.CreateAnd(
C,
B.getIntN(Width, 0xFF));
1405 Value *Shl =
B.CreateShl(
B.getIntN(Width, 1ULL),
C);
1406 Value *
Bits =
B.CreateIsNotNull(
B.CreateAnd(Shl, BitfieldC),
"memchr.bits");
1410 return B.CreateIntToPtr(
B.CreateLogicalAnd(Bounds, Bits,
"memchr"),
1435 if (Pos == MinSize ||
1436 (StrNCmp && (LStr[Pos] ==
'\0' && RStr[Pos] ==
'\0'))) {
1444 if (LStr[Pos] != RStr[Pos])
1449 typedef unsigned char UChar;
1450 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1454 return B.CreateSelect(Cmp, Zero, Res);
1472 return B.CreateSub(LHSV, RHSV,
"chardiff");
1480 Align PrefAlignment =
DL.getPrefTypeAlign(IntType);
1483 Value *LHSV =
nullptr;
1484 if (
auto *LHSC = dyn_cast<Constant>(
LHS)) {
1488 Value *RHSV =
nullptr;
1489 if (
auto *RHSC = dyn_cast<Constant>(
RHS)) {
1501 LHSV =
B.CreateLoad(IntType,
B.CreateBitCast(
LHS, LHSPtrTy),
"lhsv");
1506 RHSV =
B.CreateLoad(IntType,
B.CreateBitCast(
RHS, RHSPtrTy),
"rhsv");
1508 return B.CreateZExt(
B.CreateICmpNE(LHSV, RHSV), CI->
getType(),
"memcmp");
1516Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(
CallInst *CI,
1536 if (
Value *V = optimizeMemCmpBCmpCommon(CI,
B))
1554 return optimizeMemCmpBCmpCommon(CI,
B);
1560 if (isa<IntrinsicInst>(CI))
1580 if (
N->isNullValue())
1593 if (
N->getZExtValue() <= SrcStr.
size()) {
1605 return Pos + 1 <=
N->getZExtValue()
1606 ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, NewN)
1620 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
N);
1626 if (isa<IntrinsicInst>(CI))
1639 if (isa<IntrinsicInst>(CI))
1681 if (
FPExtInst *Cast = dyn_cast<FPExtInst>(Val)) {
1682 Value *Op = Cast->getOperand(0);
1683 if (Op->getType()->isFloatTy())
1686 if (
ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
1700 bool isPrecise =
false) {
1731 if (!CallerName.
empty() && CallerName.
back() ==
'f' &&
1732 CallerName.
size() == (CalleeName.
size() + 1) &&
1747 R =
isBinary ?
B.CreateCall(Fn, V) :
B.CreateCall(Fn, V[0]);
1754 return B.CreateFPExt(R,
B.getDoubleTy());
1760 bool isPrecise =
false) {
1767 bool isPrecise =
false) {
1783 assert(
Op->getType()->isArrayTy() &&
"Unexpected signature for cabs!");
1784 Real =
B.CreateExtractValue(Op, 0,
"real");
1785 Imag =
B.CreateExtractValue(Op, 1,
"imag");
1792 Value *RealReal =
B.CreateFMul(Real, Real);
1793 Value *ImagImag =
B.CreateFMul(Imag, Imag);
1798 *CI,
B.CreateCall(FSqrt,
B.CreateFAdd(RealReal, ImagImag),
"cabs"));
1803 if (!isa<FPMathOperator>(Call))
1807 B.setFastMathFlags(Call->getFastMathFlags());
1821 return B.CreateFNeg(
1822 copyFlags(*Call,
B.CreateCall(Call->getCalledFunction(),
X)));
1830 B.CreateCall(Call->getCalledFunction(),
X,
"cos"));
1841 if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
1842 Value *Op = cast<Instruction>(I2F)->getOperand(0);
1845 unsigned BitWidth = Op->getType()->getPrimitiveSizeInBits();
1847 (
BitWidth == DstWidth && isa<SIToFPInst>(I2F)))
1848 return isa<SIToFPInst>(I2F) ?
B.CreateSExt(Op,
B.getIntNTy(DstWidth))
1849 :
B.CreateZExt(Op,
B.getIntNTy(DstWidth));
1890 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
1898 ExpName = TLI->
getName(LibFunc_exp);
1899 ID = Intrinsic::exp;
1900 LibFnFloat = LibFunc_expf;
1901 LibFnDouble = LibFunc_exp;
1902 LibFnLongDouble = LibFunc_expl;
1907 ExpName = TLI->
getName(LibFunc_exp2);
1908 ID = Intrinsic::exp2;
1909 LibFnFloat = LibFunc_exp2f;
1910 LibFnDouble = LibFunc_exp2;
1911 LibFnLongDouble = LibFunc_exp2l;
1928 substituteInParent(BaseFn, ExpFn);
1944 (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
1945 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
1949 TLI, LibFunc_ldexp, LibFunc_ldexpf,
1950 LibFunc_ldexpl,
B, NoAttrs));
1954 if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
1957 BaseR = BaseR / *BaseF;
1959 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
1961 if ((IsInteger || IsReciprocal) &&
1964 NI > 1 && NI.isPowerOf2()) {
1965 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
1969 Mod, Intrinsic::exp2, Ty),
1974 LibFunc_exp2l,
B, NoAttrs));
1981 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
1983 LibFunc_exp10f, LibFunc_exp10l,
1992 "pow(1.0, y) should have been simplified earlier!");
1994 Value *Log =
nullptr;
2001 Value *
FMul =
B.CreateFMul(Log, Expo,
"mul");
2004 Mod, Intrinsic::exp2, Ty),
2006 else if (
hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2010 LibFunc_exp2l,
B, NoAttrs));
2024 return B.CreateCall(SqrtFn, V,
"sqrt");
2028 if (
hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2034 LibFunc_sqrtl,
B, Attrs);
2071 Sqrt =
B.CreateCall(FAbsFn, Sqrt,
"abs");
2081 Value *FCmp =
B.CreateFCmpOEQ(
Base, NegInf,
"isinf");
2082 Sqrt =
B.CreateSelect(FCmp, PosInf, Sqrt);
2097 return B.CreateCall(
F, Args);
2119 if (
Value *Exp = replacePowWithExp(Pow,
B))
2138 return B.CreateFMul(
Base,
Base,
"square");
2140 if (
Value *Sqrt = replacePowWithSqrt(Pow,
B))
2151 Value *Sqrt =
nullptr;
2152 if (!ExpoA.isInteger()) {
2166 if (!ExpoI.isInteger())
2189 return B.CreateFMul(PowI, Sqrt);
2196 if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
2203 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_pow) &&
2204 hasFloatVersion(M,
Name)) {
2217 if (UnsafeFPShrink &&
Name == TLI->
getName(LibFunc_exp2) &&
2218 hasFloatVersion(M,
Name))
2230 if ((isa<SIToFPInst>(Op) || isa<UIToFPInst>(Op)) &&
2231 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2237 LibFunc_ldexp, LibFunc_ldexpf,
2252 if ((
Name ==
"fmin" ||
Name ==
"fmax") && hasFloatVersion(M,
Name))
2266 B.setFastMathFlags(FMF);
2269 : Intrinsic::maxnum;
2272 *CI,
B.CreateCall(
F, {CI->getArgOperand(0), CI->getArgOperand(1)}));
2283 if (UnsafeFPShrink && hasFloatVersion(
Mod, LogNm))
2291 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2297 LogID = Intrinsic::log;
2298 ExpLb = LibFunc_expf;
2299 Exp2Lb = LibFunc_exp2f;
2300 Exp10Lb = LibFunc_exp10f;
2301 PowLb = LibFunc_powf;
2304 LogID = Intrinsic::log;
2305 ExpLb = LibFunc_exp;
2306 Exp2Lb = LibFunc_exp2;
2307 Exp10Lb = LibFunc_exp10;
2308 PowLb = LibFunc_pow;
2311 LogID = Intrinsic::log;
2312 ExpLb = LibFunc_expl;
2313 Exp2Lb = LibFunc_exp2l;
2314 Exp10Lb = LibFunc_exp10l;
2315 PowLb = LibFunc_powl;
2318 LogID = Intrinsic::log2;
2319 ExpLb = LibFunc_expf;
2320 Exp2Lb = LibFunc_exp2f;
2321 Exp10Lb = LibFunc_exp10f;
2322 PowLb = LibFunc_powf;
2325 LogID = Intrinsic::log2;
2326 ExpLb = LibFunc_exp;
2327 Exp2Lb = LibFunc_exp2;
2328 Exp10Lb = LibFunc_exp10;
2329 PowLb = LibFunc_pow;
2332 LogID = Intrinsic::log2;
2333 ExpLb = LibFunc_expl;
2334 Exp2Lb = LibFunc_exp2l;
2335 Exp10Lb = LibFunc_exp10l;
2336 PowLb = LibFunc_powl;
2338 case LibFunc_log10f:
2339 LogID = Intrinsic::log10;
2340 ExpLb = LibFunc_expf;
2341 Exp2Lb = LibFunc_exp2f;
2342 Exp10Lb = LibFunc_exp10f;
2343 PowLb = LibFunc_powf;
2346 LogID = Intrinsic::log10;
2347 ExpLb = LibFunc_exp;
2348 Exp2Lb = LibFunc_exp2;
2349 Exp10Lb = LibFunc_exp10;
2350 PowLb = LibFunc_pow;
2352 case LibFunc_log10l:
2353 LogID = Intrinsic::log10;
2354 ExpLb = LibFunc_expl;
2355 Exp2Lb = LibFunc_exp2l;
2356 Exp10Lb = LibFunc_exp10l;
2357 PowLb = LibFunc_powl;
2362 else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2363 LogID == Intrinsic::log10) {
2365 ExpLb = LibFunc_expf;
2366 Exp2Lb = LibFunc_exp2f;
2367 Exp10Lb = LibFunc_exp10f;
2368 PowLb = LibFunc_powf;
2370 ExpLb = LibFunc_exp;
2371 Exp2Lb = LibFunc_exp2;
2372 Exp10Lb = LibFunc_exp10;
2373 PowLb = LibFunc_pow;
2388 if (ArgLb == PowLb || ArgID == Intrinsic::pow) {
2392 Arg->getOperand(0),
"log")
2394 Value *MulY =
B.CreateFMul(
Arg->getArgOperand(1), LogX,
"mul");
2397 substituteInParent(
Arg, MulY);
2403 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2404 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2406 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2409 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2417 Value *MulY =
B.CreateFMul(
Arg->getArgOperand(0), LogE,
"mul");
2420 substituteInParent(
Arg, MulY);
2435 (
Callee->getName() ==
"sqrt" ||
2436 Callee->getIntrinsicID() == Intrinsic::sqrt))
2443 if (!
I ||
I->getOpcode() != Instruction::FMul || !
I->isFast())
2449 Value *Op0 =
I->getOperand(0);
2450 Value *Op1 =
I->getOperand(1);
2451 Value *RepeatOp =
nullptr;
2452 Value *OtherOp =
nullptr;
2462 Value *OtherMul0, *OtherMul1;
2465 if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
2467 RepeatOp = OtherMul0;
2478 B.setFastMathFlags(
I->getFastMathFlags());
2482 Type *ArgType =
I->getType();
2484 Value *FabsCall =
B.CreateCall(Fabs, RepeatOp,
"fabs");
2490 Value *SqrtCall =
B.CreateCall(Sqrt, OtherOp,
"sqrt");
2491 return copyFlags(*CI,
B.CreateFMul(FabsCall, SqrtCall));
2502 if (UnsafeFPShrink &&
Name ==
"tan" && hasFloatVersion(M,
Name))
2506 auto *OpC = dyn_cast<CallInst>(Op1);
2511 if (!CI->
isFast() || !OpC->isFast())
2521 ((Func == LibFunc_atan &&
Callee->getName() ==
"tan") ||
2522 (Func == LibFunc_atanf &&
Callee->getName() ==
"tanf") ||
2523 (Func == LibFunc_atanl &&
Callee->getName() ==
"tanl")))
2524 Ret = OpC->getArgOperand(0);
2545 Name =
"__sincospif_stret";
2554 Name =
"__sincospi_stret";
2563 M, *TLI, TheLibFunc, OrigCallee->
getAttributes(), ResTy, ArgTy);
2568 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
2572 BasicBlock &EntryBB =
B.GetInsertBlock()->getParent()->getEntryBlock();
2573 B.SetInsertPoint(&EntryBB, EntryBB.
begin());
2576 SinCos =
B.CreateCall(
Callee,
Arg,
"sincospi");
2579 Sin =
B.CreateExtractValue(SinCos, 0,
"sinpi");
2580 Cos =
B.CreateExtractValue(SinCos, 1,
"cospi");
2602 bool IsFloat =
Arg->getType()->isFloatTy();
2609 classifyArgUse(U,
F, IsFloat, SinCalls, CosCalls, SinCosCalls);
2615 Value *Sin, *Cos, *SinCos;
2623 replaceAllUsesWith(
C, Res);
2626 replaceTrigInsts(SinCalls, Sin);
2627 replaceTrigInsts(CosCalls, Cos);
2628 replaceTrigInsts(SinCosCalls, SinCos);
2630 return IsSin ? Sin : Cos;
2633void LibCallSimplifier::classifyArgUse(
2638 auto *CI = dyn_cast<CallInst>(Val);
2655 if (Func == LibFunc_sinpif)
2657 else if (Func == LibFunc_cospif)
2659 else if (Func == LibFunc_sincospif_stret)
2662 if (Func == LibFunc_sinpi)
2664 else if (Func == LibFunc_cospi)
2666 else if (Func == LibFunc_sincospi_stret)
2680 Type *ArgType =
Op->getType();
2682 Intrinsic::cttz, ArgType);
2683 Value *
V =
B.CreateCall(
F, {
Op,
B.getTrue()},
"cttz");
2685 V =
B.CreateIntCast(V, RetType,
false);
2695 Type *ArgType =
Op->getType();
2697 Intrinsic::ctlz, ArgType);
2698 Value *
V =
B.CreateCall(
F, {
Op,
B.getFalse()},
"ctlz");
2701 return B.CreateIntCast(V, CI->
getType(),
false);
2708 Value *IsNeg =
B.CreateIsNeg(
X);
2709 Value *NegX =
B.CreateNSWNeg(
X,
"neg");
2710 return B.CreateSelect(IsNeg, NegX,
X);
2716 Type *ArgType =
Op->getType();
2719 return B.CreateZExt(Op, CI->
getType());
2725 Type *ArgType =
Op->getType();
2727 return B.CreateZExt(Op, CI->
getType());
2751 if (isa<ConstantPointerNull>(EndPtr)) {
2764 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned,
B);
2805 if (StreamArg >= (
int)CI->
arg_size())
2813 return GV->
getName() ==
"stderr";
2823 if (FormatStr.
empty())
2834 if (FormatStr.
size() == 1 || FormatStr ==
"%%") {
2843 if (FormatStr ==
"%s" && CI->
arg_size() > 1) {
2848 if (OperandStr.
empty())
2851 if (OperandStr.
size() == 1) {
2859 if (OperandStr.
back() ==
'\n') {
2861 Value *GV =
B.CreateGlobalString(OperandStr,
"str");
2868 if (FormatStr.
back() ==
'\n' &&
2873 Value *GV =
B.CreateGlobalString(FormatStr,
"str");
2879 if (FormatStr ==
"%c" && CI->
arg_size() > 1 &&
2888 if (FormatStr ==
"%s\n" && CI->
arg_size() > 1 &&
2899 if (
Value *V = optimizePrintFString(CI,
B)) {
2910 Callee->getAttributes());
2912 New->setCalledFunction(IPrintFFn);
2922 Callee->getAttributes());
2924 New->setCalledFunction(SmallPrintFFn);
2932Value *LibCallSimplifier::optimizeSPrintFString(
CallInst *CI,
2951 FormatStr.
size() + 1));
2957 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
2961 if (FormatStr[1] ==
'c') {
2967 B.CreateStore(V,
Ptr);
2968 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
2969 B.CreateStore(
B.getInt8(0),
Ptr);
2974 if (FormatStr[1] ==
's') {
2994 V =
B.CreatePointerCast(V,
B.getInt8PtrTy());
2995 Dest =
B.CreatePointerCast(Dest,
B.getInt8PtrTy());
2996 Value *PtrDiff =
B.CreatePtrDiff(
B.getInt8Ty(), V, Dest);
2997 return B.CreateIntCast(PtrDiff, CI->
getType(),
false);
3014 return B.CreateIntCast(Len, CI->
getType(),
false);
3023 if (
Value *V = optimizeSPrintFString(CI,
B)) {
3034 FT,
Callee->getAttributes());
3036 New->setCalledFunction(SIPrintFFn);
3046 Callee->getAttributes());
3048 New->setCalledFunction(SmallSPrintFFn);
3064 assert(StrArg || (
N < 2 && Str.size() == 1));
3068 if (Str.size() > IntMax)
3084 NCopy = Str.size() + 1;
3089 if (NCopy && StrArg)
3103 Type *Int8Ty =
B.getInt8Ty();
3104 Value *NulOff =
B.getIntN(IntBits, NCopy);
3105 Value *DstEnd =
B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff,
"endptr");
3110Value *LibCallSimplifier::optimizeSnPrintFString(
CallInst *CI,
3139 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr,
N,
B);
3144 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() != 4)
3148 if (FormatStr[1] ==
'c') {
3154 return emitSnPrintfMemCpy(CI,
nullptr, CharStr,
N,
B);
3162 B.CreateStore(V,
Ptr);
3163 Ptr =
B.CreateInBoundsGEP(
B.getInt8Ty(),
Ptr,
B.getInt32(1),
"nul");
3164 B.CreateStore(
B.getInt8(0),
Ptr);
3168 if (FormatStr[1] !=
's')
3177 return emitSnPrintfMemCpy(CI, StrArg, Str,
N,
B);
3181 if (
Value *V = optimizeSnPrintFString(CI,
B)) {
3190Value *LibCallSimplifier::optimizeFPrintFString(
CallInst *CI,
3192 optimizeErrorReporting(CI,
B, 0);
3221 if (FormatStr.
size() != 2 || FormatStr[0] !=
'%' || CI->
arg_size() < 3)
3225 if (FormatStr[1] ==
'c') {
3235 if (FormatStr[1] ==
's') {
3249 if (
Value *V = optimizeFPrintFString(CI,
B)) {
3258 FT,
Callee->getAttributes());
3260 New->setCalledFunction(FIPrintFFn);
3269 auto SmallFPrintFFn =
3271 Callee->getAttributes());
3273 New->setCalledFunction(SmallFPrintFFn);
3282 optimizeErrorReporting(CI,
B, 3);
3287 if (SizeC && CountC) {
3300 Value *Cast =
B.CreateIntCast(Char, IntTy,
true,
"chari");
3310 optimizeErrorReporting(CI,
B, 1);
3364bool LibCallSimplifier::hasFloatVersion(
const Module *M,
StringRef FuncName) {
3366 FloatFuncName +=
'f';
3370Value *LibCallSimplifier::optimizeStringMemoryLibCall(
CallInst *CI,
3381 "Optimizing string/memory libcall would change the calling convention");
3383 case LibFunc_strcat:
3384 return optimizeStrCat(CI, Builder);
3385 case LibFunc_strncat:
3386 return optimizeStrNCat(CI, Builder);
3387 case LibFunc_strchr:
3388 return optimizeStrChr(CI, Builder);
3389 case LibFunc_strrchr:
3390 return optimizeStrRChr(CI, Builder);
3391 case LibFunc_strcmp:
3392 return optimizeStrCmp(CI, Builder);
3393 case LibFunc_strncmp:
3394 return optimizeStrNCmp(CI, Builder);
3395 case LibFunc_strcpy:
3396 return optimizeStrCpy(CI, Builder);
3397 case LibFunc_stpcpy:
3398 return optimizeStpCpy(CI, Builder);
3399 case LibFunc_strlcpy:
3400 return optimizeStrLCpy(CI, Builder);
3401 case LibFunc_stpncpy:
3402 return optimizeStringNCpy(CI,
true, Builder);
3403 case LibFunc_strncpy:
3404 return optimizeStringNCpy(CI,
false, Builder);
3405 case LibFunc_strlen:
3406 return optimizeStrLen(CI, Builder);
3407 case LibFunc_strnlen:
3408 return optimizeStrNLen(CI, Builder);
3409 case LibFunc_strpbrk:
3410 return optimizeStrPBrk(CI, Builder);
3411 case LibFunc_strndup:
3412 return optimizeStrNDup(CI, Builder);
3413 case LibFunc_strtol:
3414 case LibFunc_strtod:
3415 case LibFunc_strtof:
3416 case LibFunc_strtoul:
3417 case LibFunc_strtoll:
3418 case LibFunc_strtold:
3419 case LibFunc_strtoull:
3420 return optimizeStrTo(CI, Builder);
3421 case LibFunc_strspn:
3422 return optimizeStrSpn(CI, Builder);
3423 case LibFunc_strcspn:
3424 return optimizeStrCSpn(CI, Builder);
3425 case LibFunc_strstr:
3426 return optimizeStrStr(CI, Builder);
3427 case LibFunc_memchr:
3428 return optimizeMemChr(CI, Builder);
3429 case LibFunc_memrchr:
3430 return optimizeMemRChr(CI, Builder);
3432 return optimizeBCmp(CI, Builder);
3433 case LibFunc_memcmp:
3434 return optimizeMemCmp(CI, Builder);
3435 case LibFunc_memcpy:
3436 return optimizeMemCpy(CI, Builder);
3437 case LibFunc_memccpy:
3438 return optimizeMemCCpy(CI, Builder);
3439 case LibFunc_mempcpy:
3440 return optimizeMemPCpy(CI, Builder);
3441 case LibFunc_memmove:
3442 return optimizeMemMove(CI, Builder);
3443 case LibFunc_memset:
3444 return optimizeMemSet(CI, Builder);
3445 case LibFunc_realloc:
3446 return optimizeRealloc(CI, Builder);
3447 case LibFunc_wcslen:
3448 return optimizeWcslen(CI, Builder);
3450 return optimizeBCopy(CI, Builder);
3458Value *LibCallSimplifier::optimizeFloatingPointLibCall(
CallInst *CI,
3471 case LibFunc_sinpif:
3473 return optimizeSinCosPi(CI,
true, Builder);
3474 case LibFunc_cospif:
3476 return optimizeSinCosPi(CI,
false, Builder);
3480 return optimizePow(CI, Builder);
3484 return optimizeExp2(CI, Builder);
3492 return optimizeSqrt(CI, Builder);
3496 case LibFunc_log10f:
3498 case LibFunc_log10l:
3499 case LibFunc_log1pf:
3501 case LibFunc_log1pl:
3508 return optimizeLog(CI, Builder);
3512 return optimizeTan(CI, Builder);
3519 case LibFunc_roundeven:
3521 case LibFunc_nearbyint:
3545 case LibFunc_copysign:
3555 return optimizeFMinFMax(CI, Builder);
3559 return optimizeCAbs(CI, Builder);
3583 Builder.setDefaultOperandBundles(OpBundles);
3590 else if (isa<FPMathOperator>(CI) && CI->
isFast())
3591 UnsafeFPShrink =
true;
3595 if (!IsCallingConvC)
3599 switch (II->getIntrinsicID()) {
3600 case Intrinsic::pow:
3601 return optimizePow(CI,
Builder);
3602 case Intrinsic::exp2:
3603 return optimizeExp2(CI,
Builder);
3604 case Intrinsic::log:
3605 case Intrinsic::log2:
3606 case Intrinsic::log10:
3607 return optimizeLog(CI,
Builder);
3608 case Intrinsic::sqrt:
3609 return optimizeSqrt(CI,
Builder);
3610 case Intrinsic::memset:
3611 return optimizeMemSet(CI,
Builder);
3612 case Intrinsic::memcpy:
3613 return optimizeMemCpy(CI,
Builder);
3614 case Intrinsic::memmove:
3615 return optimizeMemMove(CI,
Builder);
3622 if (
Value *SimplifiedFortifiedCI =
3625 CallInst *SimplifiedCI = dyn_cast<CallInst>(SimplifiedFortifiedCI);
3629 replaceAllUsesWith(CI, SimplifiedCI);
3634 Builder.SetInsertPoint(SimplifiedCI);
3635 if (
Value *V = optimizeStringMemoryLibCall(SimplifiedCI,
Builder)) {
3637 substituteInParent(SimplifiedCI, V);
3641 return SimplifiedFortifiedCI;
3649 if (
Value *V = optimizeStringMemoryLibCall(CI,
Builder))
3651 if (
Value *V = optimizeFloatingPointLibCall(CI, Func,
Builder))
3657 return optimizeFFS(CI,
Builder);
3661 return optimizeFls(CI,
Builder);
3665 return optimizeAbs(CI,
Builder);
3666 case LibFunc_isdigit:
3667 return optimizeIsDigit(CI,
Builder);
3668 case LibFunc_isascii:
3669 return optimizeIsAscii(CI,
Builder);
3670 case LibFunc_toascii:
3671 return optimizeToAscii(CI,
Builder);
3675 return optimizeAtoi(CI,
Builder);
3676 case LibFunc_strtol:
3677 case LibFunc_strtoll:
3678 return optimizeStrToInt(CI,
Builder,
true);
3679 case LibFunc_strtoul:
3680 case LibFunc_strtoull:
3681 return optimizeStrToInt(CI,
Builder,
false);
3682 case LibFunc_printf:
3683 return optimizePrintF(CI,
Builder);
3684 case LibFunc_sprintf:
3685 return optimizeSPrintF(CI,
Builder);
3686 case LibFunc_snprintf:
3687 return optimizeSnPrintF(CI,
Builder);
3688 case LibFunc_fprintf:
3689 return optimizeFPrintF(CI,
Builder);
3690 case LibFunc_fwrite:
3691 return optimizeFWrite(CI,
Builder);
3693 return optimizeFPuts(CI,
Builder);
3695 return optimizePuts(CI,
Builder);
3696 case LibFunc_perror:
3697 return optimizeErrorReporting(CI,
Builder);
3698 case LibFunc_vfprintf:
3699 case LibFunc_fiprintf:
3700 return optimizeErrorReporting(CI,
Builder, 0);
3714 : FortifiedSimplifier(TLI),
DL(
DL), TLI(TLI), ORE(ORE), BFI(BFI), PSI(PSI),
3715 Replacer(Replacer), Eraser(Eraser) {}
3722void LibCallSimplifier::eraseFromParent(
Instruction *
I) {
3761bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
3762 CallInst *CI,
unsigned ObjSizeOp, std::optional<unsigned> SizeOp,
3763 std::optional<unsigned> StrOp, std::optional<unsigned> FlagOp) {
3768 if (!Flag || !
Flag->isZero())
3777 if (ObjSizeCI->isMinusOne())
3780 if (OnlyLowerUnknownSize)
3790 return ObjSizeCI->getZExtValue() >=
Len;
3796 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
3802Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(
CallInst *CI,
3804 if (isFortifiedCallFoldable(CI, 3, 2)) {
3814Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(
CallInst *CI,
3816 if (isFortifiedCallFoldable(CI, 3, 2)) {
3826Value *FortifiedLibCallSimplifier::optimizeMemSetChk(
CallInst *CI,
3828 if (isFortifiedCallFoldable(CI, 3, 2)) {
3838Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(
CallInst *CI,
3841 if (isFortifiedCallFoldable(CI, 3, 2))
3849Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(
CallInst *CI,
3857 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
3859 return StrLen ?
B.CreateInBoundsGEP(
B.getInt8Ty(), Dst, StrLen) :
nullptr;
3867 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
3868 if (Func == LibFunc_strcpy_chk)
3874 if (OnlyLowerUnknownSize)
3890 if (Ret && Func == LibFunc_stpcpy_chk)
3891 return B.CreateInBoundsGEP(
B.getInt8Ty(), Dst,
3893 return copyFlags(*CI, cast<CallInst>(Ret));
3896Value *FortifiedLibCallSimplifier::optimizeStrLenChk(
CallInst *CI,
3898 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
3904Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(
CallInst *CI,
3907 if (isFortifiedCallFoldable(CI, 3, 2)) {
3908 if (Func == LibFunc_strncpy_chk)
3921Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(
CallInst *CI,
3923 if (isFortifiedCallFoldable(CI, 4, 3))
3931Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(
CallInst *CI,
3933 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
3943Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(
CallInst *CI,
3945 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
3949 VariadicArgs,
B, TLI));
3955Value *FortifiedLibCallSimplifier::optimizeStrCatChk(
CallInst *CI,
3957 if (isFortifiedCallFoldable(CI, 2))
3964Value *FortifiedLibCallSimplifier::optimizeStrLCat(
CallInst *CI,
3966 if (isFortifiedCallFoldable(CI, 3))
3974Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(
CallInst *CI,
3976 if (isFortifiedCallFoldable(CI, 3))
3984Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(
CallInst *CI,
3986 if (isFortifiedCallFoldable(CI, 3))
3994Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(
CallInst *CI,
3996 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4004Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(
CallInst *CI,
4006 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4037 Builder.setDefaultOperandBundles(OpBundles);
4049 case LibFunc_memcpy_chk:
4050 return optimizeMemCpyChk(CI,
Builder);
4051 case LibFunc_mempcpy_chk:
4052 return optimizeMemPCpyChk(CI,
Builder);
4053 case LibFunc_memmove_chk:
4054 return optimizeMemMoveChk(CI,
Builder);
4055 case LibFunc_memset_chk:
4056 return optimizeMemSetChk(CI,
Builder);
4057 case LibFunc_stpcpy_chk:
4058 case LibFunc_strcpy_chk:
4059 return optimizeStrpCpyChk(CI,
Builder, Func);
4060 case LibFunc_strlen_chk:
4061 return optimizeStrLenChk(CI,
Builder);
4062 case LibFunc_stpncpy_chk:
4063 case LibFunc_strncpy_chk:
4064 return optimizeStrpNCpyChk(CI,
Builder, Func);
4065 case LibFunc_memccpy_chk:
4066 return optimizeMemCCpyChk(CI,
Builder);
4067 case LibFunc_snprintf_chk:
4068 return optimizeSNPrintfChk(CI,
Builder);
4069 case LibFunc_sprintf_chk:
4070 return optimizeSPrintfChk(CI,
Builder);
4071 case LibFunc_strcat_chk:
4072 return optimizeStrCatChk(CI,
Builder);
4073 case LibFunc_strlcat_chk:
4074 return optimizeStrLCat(CI,
Builder);
4075 case LibFunc_strncat_chk:
4076 return optimizeStrNCatChk(CI,
Builder);
4077 case LibFunc_strlcpy_chk:
4078 return optimizeStrLCpyChk(CI,
Builder);
4079 case LibFunc_vsnprintf_chk:
4080 return optimizeVSNPrintfChk(CI,
Builder);
4081 case LibFunc_vsprintf_chk:
4082 return optimizeVSPrintfChk(CI,
Builder);
4091 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-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)
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 Value * optimizeTrigReflections(CallInst *Call, LibFunc Func, IRBuilderBase &B)
static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef< unsigned > ArgNos, Value *Size, const DataLayout &DL)
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 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 * 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 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),...
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
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)
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).
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 ...
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ConstantFP - Floating Point Values [float, double].
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
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.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
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...
FunctionType * getFunctionType()
Type * getParamType(unsigned i) const
Parameter type accessors.
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.
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.
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
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.
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.
bool startswith(StringRef Prefix) const
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
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.
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
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.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
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.
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...
initializer< Ty > init(const Ty &Val)
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 * castToCStr(Value *V, IRBuilderBase &B)
Ret