LLVM: lib/Transforms/Utils/SimplifyLibCalls.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
42
43#include
44
45using namespace llvm;
47
51 cl::desc("Enable unsafe double to float "
52 "shrinking for math lib calls"));
53
54
55
56
59 cl::desc("Enable hot/cold operator new library calls"));
63 "Enable optimization of existing hot/cold operator new library calls"));
66 cl::desc("Enable transformation of nobuiltin operator new library calls"));
67
68namespace {
69
70
71
72
73struct HotColdHintParser : public cl::parser {
75
76 bool parse(cl::Option &O, StringRef ArgName, StringRef Arg, unsigned &Value) {
78 return O.error("'" + Arg + "' value invalid for uint argument!");
79
81 return O.error("'" + Arg + "' value must be in the range [0, 255]!");
82
83 return false;
84 }
85};
86
87}
88
89
90
91
92
95 cl::desc("Value to pass to hot/cold operator new for cold allocation"));
98 cl::desc("Value to pass to hot/cold operator new for "
99 "notcold (warm) allocation"));
102 cl::desc("Value to pass to hot/cold operator new for hot allocation"));
106 "Value to pass to hot/cold operator new for ambiguous allocation"));
107
108
109
110
111
113 return Func == LibFunc_abs || Func == LibFunc_labs ||
114 Func == LibFunc_llabs || Func == LibFunc_strlen;
115}
116
117
121 if (IC->isEquality() && IC->getOperand(1) == With)
122 continue;
123
124 return false;
125 }
126 return true;
127}
128
131 return OI->getType()->isFloatingPointTy();
132 });
133}
134
137 return OI->getType()->isFP128Ty();
138 });
139}
140
141
142
143
144
145
146
147
151 if (Base != 0)
152
153 return nullptr;
154
155
157
160 Str = Str.substr(Offset);
161 break;
162 }
163
164 if (Str.empty())
165
166
167 return nullptr;
168
169
170 bool Negate = Str[0] == '-';
171 if (Str[0] == '-' || Str[0] == '+') {
172 Str = Str.drop_front();
173 if (Str.empty())
174
175 return nullptr;
177 }
178
179
180
183 uint64_t Max = AsSigned && Negate ? 1 : 0;
185
186
187 if (Str.size() > 1) {
188 if (Str[0] == '0') {
189 if (toUpper((unsigned char)Str[1]) == 'X') {
190 if (Str.size() == 2 || (Base && Base != 16))
191
192
193 return nullptr;
194
195 Str = Str.drop_front(2);
198 }
199 else if (Base == 0)
201 } else if (Base == 0)
203 }
204 else if (Base == 0)
206
207
208
209
211 for (unsigned i = 0; i != Str.size(); ++i) {
212 unsigned char DigVal = Str[i];
214 DigVal = DigVal - '0';
215 else {
216 DigVal = toUpper(DigVal);
218 DigVal = DigVal - 'A' + 10;
219 else
220 return nullptr;
221 }
222
223 if (DigVal >= Base)
224
225 return nullptr;
226
227
228
229 bool VFlow;
231 if (VFlow || Result > Max)
232 return nullptr;
233 }
234
235 if (EndPtr) {
236
237 Value *Off = B.getInt64(Offset + Str.size());
239 Value *StrEnd = B.CreateInBoundsGEP(B.getInt8Ty(), StrBeg, Off, "endptr");
240 B.CreateStore(StrEnd, EndPtr);
241 }
242
243 if (Negate)
244
245 Result = -Result;
246
247 return ConstantInt::get(RetTy, Result);
248}
249
254 if (C->isNullValue())
255 continue;
256
257 return false;
258 }
259 return true;
260}
261
265 return false;
266
268 return false;
269
271 return false;
272
273 return true;
274}
275
278 uint64_t DereferenceableBytes) {
280 if ()
281 return;
282 for (unsigned ArgNo : ArgNos) {
283 uint64_t DerefBytes = DereferenceableBytes;
288 DereferenceableBytes);
289
294 CI->removeParamAttr(ArgNo, Attribute::DereferenceableOrNull);
297 }
298 }
299}
300
304 if ()
305 return;
306
307 for (unsigned ArgNo : ArgNos) {
308 if (!CI->paramHasAttr(ArgNo, Attribute::NoUndef))
310
311 if (!CI->paramHasAttr(ArgNo, Attribute::NonNull)) {
312 unsigned AS =
315 continue;
317 }
318
320 }
321}
322
333 DerefMin = std::min(X, Y);
335 }
336 }
337}
338
339
340
341
342
343
351
354 NewCI->getContext(), {NewCI->getAttributes(), Old.getAttributes()}));
355 NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(
357 for (unsigned I = 0; I < NewCI->arg_size(); ++I)
361
363}
364
365
367 return Len >= Str.size() ? Str : Str.substr(0, Len);
368}
369
370
371
372
373
375
379
380
382 if (Len)
384 else
385 return nullptr;
386 --Len;
387
388
389 if (Len == 0)
390 return Dst;
391
392 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, Len, B));
393}
394
395Value *LibCallSimplifier::emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
397
398
400 if (!DstLen)
401 return nullptr;
402
403
404
405
406 Value *CpyDst = B.CreateInBoundsGEP(B.getInt8Ty(), Dst, DstLen, "endptr");
407
408
409
410 B.CreateMemCpy(CpyDst, Align(1), Src, Align(1),
411 TLI->getAsSizeT(Len + 1, *B.GetInsertBlock()->getModule()));
412 return Dst;
413}
414
416
420 uint64_t Len;
424
425
427 if (LengthArg) {
429
430 if (!Len)
431 return Dst;
432 } else {
433 return nullptr;
434 }
435
436
438 if (SrcLen) {
440 --SrcLen;
441 } else {
442 return nullptr;
443 }
444
445
446 if (SrcLen == 0)
447 return Dst;
448
449
450 if (Len < SrcLen)
451 return nullptr;
452
453
454
455 return copyFlags(*CI, emitStrLenMemCpy(Src, Dst, SrcLen, B));
456}
457
458
459
460
463{
466
467
468 Type *CharTy = B.getInt8Ty();
469 Value *Char0 = B.CreateLoad(CharTy, Src);
470 CharVal = B.CreateTrunc(CharVal, CharTy);
471 Value *Cmp = B.CreateICmpEQ(Char0, CharVal, "char0cmp");
472
473 if (NBytes) {
474 Value *Zero = ConstantInt::get(NBytes->getType(), 0);
475 Value *And = B.CreateICmpNE(NBytes, Zero);
476 Cmp = B.CreateLogicalAnd(And, Cmp);
477 }
478
480 return B.CreateSelect(Cmp, Src, NullPtr);
481}
482
487
490
491
492
494 if (!CharC) {
496 if (Len)
498 else
499 return nullptr;
500
502 FunctionType *FT = Callee->getFunctionType();
503 unsigned IntBits = TLI->getIntSize();
504 if (!FT->getParamType(1)->isIntegerTy(IntBits))
505 return nullptr;
506
507 unsigned SizeTBits = TLI->getSizeTSize(*CI->getModule());
510 emitMemChr(SrcStr, CharVal,
511 ConstantInt::get(SizeTTy, Len), B,
512 DL, TLI));
513 }
514
515 if (CharC->isZero()) {
518
519
520 return B.CreateIntToPtr(B.getTrue(), CI->getType());
521 }
522
523
524
525 StringRef Str;
527 if (CharC->isZero())
529 return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, StrLen, "strchr");
530 return nullptr;
531 }
532
533
534
536 ? Str.size()
538 if (I == StringRef::npos)
540
541
542 return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(I), "strchr");
543}
544
550
551 StringRef Str;
553
554 if (CharC && CharC->isZero())
556 return nullptr;
557 }
558
559 unsigned SizeTBits = TLI->getSizeTSize(*CI->getModule());
561
562
563
564 uint64_t NBytes = Str.size() + 1;
565 Value *Size = ConstantInt::get(SizeTTy, NBytes);
567}
568
571 if (Str1P == Str2P)
572 return ConstantInt::get(CI->getType(), 0);
573
574 StringRef Str1, Str2;
577
578
579 if (HasStr1 && HasStr2)
581 std::clamp(Str1.compare(Str2), -1, 1));
582
583 if (HasStr1 && Str1.empty())
584 return B.CreateNeg(B.CreateZExt(
585 B.CreateLoad(B.getInt8Ty(), Str2P, "strcmpload"), CI->getType()));
586
587 if (HasStr2 && Str2.empty())
588 return B.CreateZExt(B.CreateLoad(B.getInt8Ty(), Str1P, "strcmpload"),
590
591
593 if (Len1)
596 if (Len2)
598
599 if (Len1 && Len2) {
602 TLI->getAsSizeT(std::min(Len1, Len2), *CI->getModule()),
603 B, DL, TLI));
604 }
605
606
607 if (!HasStr1 && HasStr2) {
610 TLI->getAsSizeT(Len2, *CI->getModule()),
611 B, DL, TLI));
612 } else if (HasStr1 && !HasStr2) {
615 TLI->getAsSizeT(Len1, *CI->getModule()),
616 B, DL, TLI));
617 }
618
620 return nullptr;
621}
622
623
624
628
633 if (Str1P == Str2P)
634 return ConstantInt::get(CI->getType(), 0);
635
638
642 else
644
645 if (Length == 0)
646 return ConstantInt::get(CI->getType(), 0);
647
648 if (Length == 1)
650
651 StringRef Str1, Str2;
654
655
656 if (HasStr1 && HasStr2) {
657
661 std::clamp(SubStr1.compare(SubStr2), -1, 1));
662 }
663
664 if (HasStr1 && Str1.empty())
665 return B.CreateNeg(B.CreateZExt(
666 B.CreateLoad(B.getInt8Ty(), Str2P, "strcmpload"), CI->getType()));
667
668 if (HasStr2 && Str2.empty())
669 return B.CreateZExt(B.CreateLoad(B.getInt8Ty(), Str1P, "strcmpload"),
671
673 if (Len1)
676 if (Len2)
678
679
680 if (!HasStr1 && HasStr2) {
681 Len2 = std::min(Len2, Length);
684 TLI->getAsSizeT(Len2, *CI->getModule()),
685 B, DL, TLI));
686 } else if (HasStr1 && !HasStr2) {
687 Len1 = std::min(Len1, Length);
690 TLI->getAsSizeT(Len1, *CI->getModule()),
691 B, DL, TLI));
692 }
693
694 return nullptr;
695}
696
701 if (SrcLen && Size) {
703 if (SrcLen <= Size->getZExtValue() + 1)
705 }
706
707 return nullptr;
708}
709
712 if (Dst == Src)
713 return Src;
714
716
718 if (Len)
720 else
721 return nullptr;
722
723
724
725 CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1),
726 TLI->getAsSizeT(Len, *CI->getModule()));
728 return Dst;
729}
730
733
734
737
738 if (Dst == Src) {
740 return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr;
741 }
742
743
745 if (Len)
747 else
748 return nullptr;
749
750 Value *LenV = TLI->getAsSizeT(Len, *CI->getModule());
751 Value *DstEnd = B.CreateInBoundsGEP(
752 B.getInt8Ty(), Dst, TLI->getAsSizeT(Len - 1, *CI->getModule()));
753
754
755
756 CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), LenV);
758 return DstEnd;
759}
760
761
762
766
767
769
770
772
773 uint64_t NBytes;
775 NBytes = SizeC->getZExtValue();
776 else
777 return nullptr;
778
781 if (NBytes <= 1) {
782 if (NBytes == 1)
783
784 B.CreateStore(B.getInt8(0), Dst);
785
786
788 }
789
790
791
792
793 StringRef Str;
795 return nullptr;
796
797 uint64_t SrcLen = Str.find('\0');
798
799
800 bool NulTerm = SrcLen < NBytes;
801
802 if (NulTerm)
803
804
805 NBytes = SrcLen + 1;
806 else {
807
808
809 SrcLen = std::min(SrcLen, uint64_t(Str.size()));
810 NBytes = std::min(NBytes - 1, SrcLen);
811 }
812
813 if (SrcLen == 0) {
814
815 B.CreateStore(B.getInt8(0), Dst);
816 return ConstantInt::get(CI->getType(), 0);
817 }
818
819
820
821
822 CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1),
823 TLI->getAsSizeT(NBytes, *CI->getModule()));
825
826 if (!NulTerm) {
827 Value *EndOff = ConstantInt::get(CI->getType(), NBytes);
828 Value *EndPtr = B.CreateInBoundsGEP(B.getInt8Ty(), Dst, EndOff);
829 B.CreateStore(B.getInt8(0), EndPtr);
830 }
831
832
833
834
835 return ConstantInt::get(CI->getType(), SrcLen);
836}
837
838
839
840Value *LibCallSimplifier::optimizeStringNCpy(CallInst *CI, bool RetEnd,
845
847
848
851 }
852
853
854
857 N = SizeC->getZExtValue();
858
859 if (N == 0)
860
861 return Dst;
862
863 if (N == 1) {
864 Type *CharTy = B.getInt8Ty();
865 Value *CharVal = B.CreateLoad(CharTy, Src, "stxncpy.char0");
866 B.CreateStore(CharVal, Dst);
867 if (!RetEnd)
868
869 return Dst;
870
871
872 Value *ZeroChar = ConstantInt::get(CharTy, 0);
873 Value *Cmp = B.CreateICmpEQ(CharVal, ZeroChar, "stpncpy.char0cmp");
874
875 Value *Off1 = B.getInt32(1);
876 Value *EndPtr = B.CreateInBoundsGEP(CharTy, Dst, Off1, "stpncpy.end");
877 return B.CreateSelect(Cmp, Dst, EndPtr, "stpncpy.sel");
878 }
879
880
882 if (SrcLen)
884 else
885 return nullptr;
886
887 --SrcLen;
888
889 if (SrcLen == 0) {
890
891 Align MemSetAlign =
892 CI->getAttributes().getParamAttrs(0).getAlignment().valueOrOne();
893 CallInst *NewCI = B.CreateMemSet(Dst, B.getInt8('\0'), Size, MemSetAlign);
898 return Dst;
899 }
900
901 if (N > SrcLen + 1) {
902 if (N > 128)
903
904 return nullptr;
905
906
907 StringRef Str;
909 return nullptr;
910 std::string SrcStr = Str.str();
911
912
913 SrcStr.resize(N, '\0');
914 Src = B.CreateGlobalString(SrcStr, "str", 0,
915 nullptr, false);
916 }
917
918
919
920 CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1),
921 TLI->getAsSizeT(N, *CI->getModule()));
923 if (!RetEnd)
924 return Dst;
925
926
927
928 Value *Off = B.getInt64(std::min(SrcLen, N));
929 return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, Off, "endptr");
930}
931
933 unsigned CharSize,
937
940
941
942
943
944
945
946 return B.CreateZExt(B.CreateLoad(CharTy, Src, "char0"),
948 }
949
950 if (Bound) {
952 if (BoundCst->isZero())
953
954 return ConstantInt::get(CI->getType(), 0);
955
956 if (BoundCst->isOne()) {
957
958 Value *CharVal = B.CreateLoad(CharTy, Src, "strnlen.char0");
959 Value *ZeroChar = ConstantInt::get(CharTy, 0);
960 Value *Cmp = B.CreateICmpNE(CharVal, ZeroChar, "strnlen.char0cmp");
961 return B.CreateZExt(Cmp, CI->getType());
962 }
963 }
964 }
965
967 Value *LenC = ConstantInt::get(CI->getType(), Len - 1);
968
969
970 if (Bound)
971 return B.CreateBinaryIntrinsic(Intrinsic::umin, LenC, Bound);
972 return LenC;
973 }
974
975 if (Bound)
976
977 return nullptr;
978
979
980
981
982
983
984
985
986
988 unsigned BW = DL.getIndexTypeSizeInBits(GEP->getType());
989 SmallMapVector<Value *, APInt, 4> VarOffsets;
990 APInt ConstOffset(BW, 0);
991 assert(CharSize % 8 == 0 && "Expected a multiple of 8 sized CharSize");
992
993 if (->collectOffset(DL, BW, VarOffsets, ConstOffset) ||
994 VarOffsets.size() != 1 || ConstOffset != 0 ||
995 VarOffsets.begin()->second != CharSize / 8)
996 return nullptr;
997
998 ConstantDataArraySlice Slice;
1000 uint64_t NullTermIdx;
1001 if (Slice.Array == nullptr) {
1002 NullTermIdx = 0;
1003 } else {
1004 NullTermIdx = ~((uint64_t)0);
1005 for (uint64_t I = 0, E = Slice.Length; I < E; ++I) {
1007 NullTermIdx = I;
1008 break;
1009 }
1010 }
1011
1012
1013 if (NullTermIdx == ~((uint64_t)0))
1014 return nullptr;
1015 }
1016
1019
1020
1021
1022
1023
1026 NullTermIdx == Slice.Length - 1)) {
1028 return B.CreateSub(ConstantInt::get(CI->getType(), NullTermIdx),
1030 }
1031 }
1032 }
1033
1034
1036 uint64_t LenTrue = GetStringLength(SI->getTrueValue(), CharSize);
1037 uint64_t LenFalse = GetStringLength(SI->getFalseValue(), CharSize);
1038 if (LenTrue && LenFalse) {
1039 ORE.emit([&]() {
1040 return OptimizationRemark("instcombine", "simplify-libcalls", CI)
1041 << "folded strlen(select) to select of constants";
1042 });
1043 return B.CreateSelect(SI->getCondition(),
1044 ConstantInt::get(CI->getType(), LenTrue - 1),
1045 ConstantInt::get(CI->getType(), LenFalse - 1));
1046 }
1047 }
1048
1049 return nullptr;
1050}
1051
1053 if (Value *V = optimizeStringLength(CI, B, 8))
1054 return V;
1056 return nullptr;
1057}
1058
1061 if (Value *V = optimizeStringLength(CI, B, 8, Bound))
1062 return V;
1063
1066 return nullptr;
1067}
1068
1071 unsigned WCharSize = TLI->getWCharSize(M) * 8;
1072
1073 if (WCharSize == 0)
1074 return nullptr;
1075
1076 return optimizeStringLength(CI, B, WCharSize);
1077}
1078
1080 StringRef S1, S2;
1083
1084
1085
1086 if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
1088
1089
1090 if (HasS1 && HasS2) {
1091 size_t I = S1.find_first_of(S2);
1094
1095 return B.CreateInBoundsGEP(B.getInt8Ty(), CI->getArgOperand(0),
1096 B.getInt64(I), "strpbrk");
1097 }
1098
1099
1100 if (HasS2 && S2.size() == 1)
1102
1103 return nullptr;
1104}
1105
1109
1110
1113 }
1114
1115 return nullptr;
1116}
1117
1119 StringRef S1, S2;
1122
1123
1124
1125 if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
1127
1128
1129 if (HasS1 && HasS2) {
1130 size_t Pos = S1.find_first_not_of(S2);
1132 Pos = S1.size();
1133 return ConstantInt::get(CI->getType(), Pos);
1134 }
1135
1136 return nullptr;
1137}
1138
1140 StringRef S1, S2;
1143
1144
1145 if (HasS1 && S1.empty())
1147
1148
1149 if (HasS1 && HasS2) {
1150 size_t Pos = S1.find_first_of(S2);
1152 Pos = S1.size();
1153 return ConstantInt::get(CI->getType(), Pos);
1154 }
1155
1156
1157 if (HasS2 && S2.empty())
1159
1160 return nullptr;
1161}
1162
1164
1167
1168
1171 if (!StrLen)
1172 return nullptr;
1174 StrLen, B, DL, TLI);
1175 if (!StrNCmp)
1176 return nullptr;
1182 replaceAllUsesWith(Old, Cmp);
1183 }
1184 return CI;
1185 }
1186
1187
1188 StringRef SearchStr, ToFindStr;
1191
1192
1193 if (HasStr2 && ToFindStr.empty())
1195
1196
1197 if (HasStr1 && HasStr2) {
1198 size_t Offset = SearchStr.find(ToFindStr);
1199
1202
1203
1204 return B.CreateConstInBoundsGEP1_64(B.getInt8Ty(), CI->getArgOperand(0),
1206 }
1207
1208
1209 if (HasStr2 && ToFindStr.size() == 1) {
1211 }
1212
1214 return nullptr;
1215}
1216
1224
1225 if (LenC) {
1227
1228 return NullPtr;
1229
1230 if (LenC->isOne()) {
1231
1232
1233 Value *Val = B.CreateLoad(B.getInt8Ty(), SrcStr, "memrchr.char0");
1234
1235 CharVal = B.CreateTrunc(CharVal, B.getInt8Ty());
1236 Value *Cmp = B.CreateICmpEQ(Val, CharVal, "memrchr.char0cmp");
1237 return B.CreateSelect(Cmp, SrcStr, NullPtr, "memrchr.sel");
1238 }
1239 }
1240
1241 StringRef Str;
1243 return nullptr;
1244
1245 if (Str.size() == 0)
1246
1247
1248
1249 return NullPtr;
1250
1252 if (LenC) {
1254 if (Str.size() < EndOff)
1255
1256 return nullptr;
1257 }
1258
1260
1261 size_t Pos = Str.rfind(CharC->getZExtValue(), EndOff);
1263
1264
1265 return NullPtr;
1266
1267 if (LenC)
1268
1269 return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos));
1270
1271 if (Str.find(Str[Pos]) == Pos) {
1272
1273
1274
1275
1276 Value *Cmp = B.CreateICmpULE(Size, ConstantInt::get(Size->getType(), Pos),
1277 "memrchr.cmp");
1278 Value *SrcPlus = B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr,
1279 B.getInt64(Pos), "memrchr.ptr_plus");
1280 return B.CreateSelect(Cmp, NullPtr, SrcPlus, "memrchr.sel");
1281 }
1282 }
1283
1284
1285 Str = Str.substr(0, EndOff);
1287 return nullptr;
1288
1289
1290
1291
1292 Type *SizeTy = Size->getType();
1293 Type *Int8Ty = B.getInt8Ty();
1294 Value *NNeZ = B.CreateICmpNE(Size, ConstantInt::get(SizeTy, 0));
1295
1296 CharVal = B.CreateTrunc(CharVal, Int8Ty);
1297 Value *CEqS0 = B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
1298 Value *And = B.CreateLogicalAnd(NNeZ, CEqS0);
1299 Value *SizeM1 = B.CreateSub(Size, ConstantInt::get(SizeTy, 1));
1300 Value *SrcPlus =
1301 B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1, "memrchr.ptr_plus");
1302 return B.CreateSelect(And, SrcPlus, NullPtr, "memrchr.sel");
1303}
1304
1308
1313 }
1314
1319
1320
1321 if (LenC) {
1323 return NullPtr;
1324
1325 if (LenC->isOne()) {
1326
1327
1328 Value *Val = B.CreateLoad(B.getInt8Ty(), SrcStr, "memchr.char0");
1329
1330 CharVal = B.CreateTrunc(CharVal, B.getInt8Ty());
1331 Value *Cmp = B.CreateICmpEQ(Val, CharVal, "memchr.char0cmp");
1332 return B.CreateSelect(Cmp, SrcStr, NullPtr, "memchr.sel");
1333 }
1334 }
1335
1336 StringRef Str;
1338 return nullptr;
1339
1340 if (CharC) {
1341 size_t Pos = Str.find(CharC->getZExtValue());
1343
1344
1345 return NullPtr;
1346
1347
1348
1349
1350 Value *Cmp = B.CreateICmpULE(Size, ConstantInt::get(Size->getType(), Pos),
1351 "memchr.cmp");
1352 Value *SrcPlus = B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos),
1353 "memchr.ptr");
1354 return B.CreateSelect(Cmp, NullPtr, SrcPlus);
1355 }
1356
1357 if (Str.size() == 0)
1358
1359
1360
1361 return NullPtr;
1362
1363 if (LenC)
1365
1366 size_t Pos = Str.find_first_not_of(Str[0]);
1368 || Str.find_first_not_of(Str[Pos], Pos) == StringRef::npos) {
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 Type *SizeTy = Size->getType();
1380
1381
1382 CharVal = B.CreateTrunc(CharVal, Int8Ty);
1383
1384 Value *Sel1 = NullPtr;
1386
1387 Value *PosVal = ConstantInt::get(SizeTy, Pos);
1388 Value *StrPos = ConstantInt::get(Int8Ty, Str[Pos]);
1389 Value *CEqSPos = B.CreateICmpEQ(CharVal, StrPos);
1391 Value *And = B.CreateAnd(CEqSPos, NGtPos);
1392 Value *SrcPlus = B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, PosVal);
1393 Sel1 = B.CreateSelect(And, SrcPlus, NullPtr, "memchr.sel1");
1394 }
1395
1396 Value *Str0 = ConstantInt::get(Int8Ty, Str[0]);
1397 Value *CEqS0 = B.CreateICmpEQ(Str0, CharVal);
1398 Value *NNeZ = B.CreateICmpNE(Size, ConstantInt::get(SizeTy, 0));
1399 Value *And = B.CreateAnd(NNeZ, CEqS0);
1400 return B.CreateSelect(And, SrcStr, Sel1, "memchr.sel2");
1401 }
1402
1403 if (!LenC) {
1405
1406
1407
1409
1410
1411 return nullptr;
1412 }
1413
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1428 return nullptr;
1429
1430 unsigned char Max =
1431 *std::max_element(reinterpret_cast<const unsigned char *>(Str.begin()),
1432 reinterpret_cast<const unsigned char *>(Str.end()));
1433
1434
1435
1436
1437
1438
1439 if (!DL.fitsInLegalInteger(Max + 1)) {
1440
1441
1442
1443
1444
1445 std::string SortedStr = Str.str();
1447
1448 unsigned NonContRanges = 1;
1449 for (size_t i = 1; i < SortedStr.size(); ++i) {
1450 if (SortedStr[i] > SortedStr[i - 1] + 1) {
1451 NonContRanges++;
1452 }
1453 }
1454
1455
1456
1457 if (NonContRanges > 2)
1458 return nullptr;
1459
1460
1461 CharVal = B.CreateTrunc(CharVal, B.getInt8Ty());
1462
1464 for (unsigned char C : SortedStr)
1465 CharCompares.push_back(B.CreateICmpEQ(CharVal, B.getInt8(C)));
1466
1467 return B.CreateIntToPtr(B.CreateOr(CharCompares), CI->getType());
1468 }
1469
1470
1471
1472 unsigned char Width = NextPowerOf2(std::max((unsigned char)7, Max));
1473
1474
1476 for (char C : Str)
1477 Bitfield.setBit((unsigned char)C);
1478 Value *BitfieldC = B.getInt(Bitfield);
1479
1480
1481 Value *C = B.CreateZExtOrTrunc(CharVal, BitfieldC->getType());
1482 C = B.CreateAnd(C, B.getIntN(Width, 0xFF));
1483
1484
1486 "memchr.bounds");
1487
1488
1489 Value *Shl = B.CreateShl(B.getIntN(Width, 1ULL), C);
1490 Value *Bits = B.CreateIsNotNull(B.CreateAnd(Shl, BitfieldC), "memchr.bits");
1491
1492
1493
1494 return B.CreateIntToPtr(B.CreateLogicalAnd(Bounds, Bits, "memchr"),
1496}
1497
1498
1499
1505
1509 return nullptr;
1510
1511
1512
1513
1514
1515
1517 Value *Zero = ConstantInt::get(CI->getType(), 0);
1518 for (uint64_t MinSize = std::min(LStr.size(), RStr.size()); ; ++Pos) {
1519 if (Pos == MinSize ||
1520 (StrNCmp && (LStr[Pos] == '\0' && RStr[Pos] == '\0'))) {
1521
1522
1523
1524
1525 return Zero;
1526 }
1527
1528 if (LStr[Pos] != RStr[Pos])
1529 break;
1530 }
1531
1532
1533 typedef unsigned char UChar;
1534 int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
1535 Value *MaxSize = ConstantInt::get(Size->getType(), Pos);
1538 return B.CreateSelect(Cmp, Zero, Res);
1539}
1540
1541
1545 if (Len == 0)
1547
1548
1549 if (Len == 1) {
1550 Value *LHSV = B.CreateZExt(B.CreateLoad(B.getInt8Ty(), LHS, "lhsc"),
1552 Value *RHSV = B.CreateZExt(B.CreateLoad(B.getInt8Ty(), RHS, "rhsc"),
1554 return B.CreateSub(LHSV, RHSV, "chardiff");
1555 }
1556
1557
1558
1559
1562 Align PrefAlignment = DL.getPrefTypeAlign(IntType);
1563
1564
1565 Value *LHSV = nullptr;
1568
1569 Value *RHSV = nullptr;
1572
1573
1574
1577 if (!LHSV)
1578 LHSV = B.CreateLoad(IntType, LHS, "lhsv");
1579 if (!RHSV)
1580 RHSV = B.CreateLoad(IntType, RHS, "rhsv");
1581 return B.CreateZExt(B.CreateICmpNE(LHSV, RHSV), CI->getType(), "memcmp");
1582 }
1583 }
1584
1585 return nullptr;
1586}
1587
1588
1589Value *LibCallSimplifier::optimizeMemCmpBCmpCommon(CallInst *CI,
1593
1595
1597 return Res;
1598
1599
1601 if (!LenC)
1602 return nullptr;
1603
1605}
1606
1609 if (Value *V = optimizeMemCmpBCmpCommon(CI, B))
1610 return V;
1611
1612
1613
1614
1621 }
1622
1623 return nullptr;
1624}
1625
1627 return optimizeMemCmpBCmpCommon(CI, B);
1628}
1629
1634 return nullptr;
1635
1636
1641}
1642
1648 StringRef SrcStr;
1649 if (CI->use_empty() && Dst == Src)
1650 return Dst;
1651
1652 if (N) {
1653 if (N->isNullValue())
1656
1657 !StopChar)
1658 return nullptr;
1659 } else {
1660 return nullptr;
1661 }
1662
1663
1666 if (N->getZExtValue() <= SrcStr.size()) {
1670 }
1671 return nullptr;
1672 }
1673
1675 ConstantInt::get(N->getType(), std::min(uint64_t(Pos + 1), N->getZExtValue()));
1676
1678 return Pos + 1 <= N->getZExtValue()
1679 ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, NewN)
1681}
1682
1686
1687 CallInst *NewCI =
1689
1690
1691
1693 return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, N);
1694}
1695
1700 return nullptr;
1701
1702
1707}
1708
1713 return nullptr;
1714
1715
1720}
1721
1725
1726 return nullptr;
1727}
1728
1729
1730
1731Value *LibCallSimplifier::maybeOptimizeNoBuiltinOperatorNew(CallInst *CI,
1734 return nullptr;
1736 if (!Callee)
1737 return nullptr;
1738 LibFunc Func;
1739 if (!TLI->getLibFunc(*Callee, Func))
1740 return nullptr;
1741 switch (Func) {
1742 case LibFunc_Znwm:
1743 case LibFunc_ZnwmRKSt9nothrow_t:
1744 case LibFunc_ZnwmSt11align_val_t:
1745 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1746 case LibFunc_Znam:
1747 case LibFunc_ZnamRKSt9nothrow_t:
1748 case LibFunc_ZnamSt11align_val_t:
1749 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1750 case LibFunc_size_returning_new:
1751 case LibFunc_size_returning_new_aligned:
1752
1753
1754
1756 return nullptr;
1757 break;
1758 case LibFunc_Znwm12__hot_cold_t:
1759 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1760 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1761 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1762 case LibFunc_Znam12__hot_cold_t:
1763 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1764 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1765 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1766 case LibFunc_size_returning_new_hot_cold:
1767 case LibFunc_size_returning_new_aligned_hot_cold:
1768
1769
1771 return nullptr;
1772 break;
1773 default:
1774 return nullptr;
1775 }
1776 return optimizeNew(CI, B, Func);
1777}
1778
1779
1780
1781
1782
1784 LibFunc &Func) {
1786 return nullptr;
1787
1788 uint8_t HotCold;
1789 if (CI->getAttributes().getFnAttr("memprof").getValueAsString() == "cold")
1791 else if (CI->getAttributes().getFnAttr("memprof").getValueAsString() ==
1792 "notcold")
1794 else if (CI->getAttributes().getFnAttr("memprof").getValueAsString() == "hot")
1796 else if (CI->getAttributes().getFnAttr("memprof").getValueAsString() ==
1797 "ambiguous")
1799 else
1800 return nullptr;
1801
1802
1803
1804
1805
1806
1807
1808
1809 Value *NewCall = nullptr;
1810 switch (Func) {
1811 case LibFunc_Znwm12__hot_cold_t:
1814 LibFunc_Znwm12__hot_cold_t, HotCold);
1815 break;
1816 case LibFunc_Znwm:
1818 LibFunc_Znwm12__hot_cold_t, HotCold);
1819 break;
1820 case LibFunc_Znam12__hot_cold_t:
1823 LibFunc_Znam12__hot_cold_t, HotCold);
1824 break;
1825 case LibFunc_Znam:
1827 LibFunc_Znam12__hot_cold_t, HotCold);
1828 break;
1829 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
1833 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1834 break;
1835 case LibFunc_ZnwmRKSt9nothrow_t:
1838 LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
1839 break;
1840 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
1844 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1845 break;
1846 case LibFunc_ZnamRKSt9nothrow_t:
1849 LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
1850 break;
1851 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
1855 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1856 break;
1857 case LibFunc_ZnwmSt11align_val_t:
1860 LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
1861 break;
1862 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
1866 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1867 break;
1868 case LibFunc_ZnamSt11align_val_t:
1871 LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
1872 break;
1873 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1877 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1878 HotCold);
1879 break;
1880 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1883 TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1884 break;
1885 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
1889 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
1890 HotCold);
1891 break;
1892 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1895 TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
1896 break;
1897 case LibFunc_size_returning_new:
1899 LibFunc_size_returning_new_hot_cold,
1900 HotCold);
1901 break;
1902 case LibFunc_size_returning_new_hot_cold:
1905 LibFunc_size_returning_new_hot_cold,
1906 HotCold);
1907 break;
1908 case LibFunc_size_returning_new_aligned:
1911 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1912 break;
1913 case LibFunc_size_returning_new_aligned_hot_cold:
1917 LibFunc_size_returning_new_aligned_hot_cold, HotCold);
1918 break;
1919 default:
1920 return nullptr;
1921 }
1922
1925
1926 return NewCall;
1927}
1928
1929
1930
1931
1932
1933
1940
1941
1942
1943
1944
1945
1948 Value *Op = Cast->getOperand(0);
1949 if (Op->getType()->isFloatTy())
1950 return Op;
1951 }
1953 APFloat F = Const->getValueAPF();
1954 bool losesInfo;
1956 &losesInfo);
1957 if (!losesInfo)
1958 return ConstantFP::get(Const->getContext(), F);
1959 }
1960 return nullptr;
1961}
1962
1963
1966 bool isPrecise = false) {
1969 return nullptr;
1970
1971
1972
1973
1974 if (isPrecise)
1978 return nullptr;
1979 }
1980
1981
1985 if (!V[0] || (isBinary && !V[1]))
1986 return nullptr;
1987
1988
1989
1990
1991
1992
1994 bool IsIntrinsic = CalleeFn->isIntrinsic();
1995 if (!IsIntrinsic) {
1997 if (CallerName.ends_with('f') &&
1998 CallerName.size() == (CalleeName.size() + 1) &&
2000 return nullptr;
2001 }
2002
2003
2006
2007
2009 if (IsIntrinsic) {
2011 R = isBinary ? B.CreateIntrinsic(IID, B.getFloatTy(), V)
2012 : B.CreateIntrinsic(IID, B.getFloatTy(), V[0]);
2013 } else {
2014 AttributeList CalleeAttrs = CalleeFn->getAttributes();
2016 CalleeAttrs)
2018 }
2019 return B.CreateFPExt(R, B.getDoubleTy());
2020}
2021
2022
2025 bool isPrecise = false) {
2027}
2028
2029
2032 bool isPrecise = false) {
2034}
2035
2036
2038 Value *Real, *Imag;
2039
2041
2043 return nullptr;
2044
2046 assert(Op->getType()->isArrayTy() && "Unexpected signature for cabs!");
2047
2048 Real = B.CreateExtractValue(Op, 0, "real");
2049 Imag = B.CreateExtractValue(Op, 1, "imag");
2050
2051 } else {
2052 assert(CI->arg_size() == 2 && "Unexpected signature for cabs!");
2053
2056
2057
2058
2059 Value *AbsOp = nullptr;
2061 if (ConstReal->isZero())
2062 AbsOp = Imag;
2063
2065 if (ConstImag->isZero())
2066 AbsOp = Real;
2067 }
2068
2069 if (AbsOp)
2071 *CI, B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp, CI, "cabs"));
2072
2074 return nullptr;
2075 }
2076
2077
2078 Value *RealReal = B.CreateFMulFMF(Real, Real, CI);
2079 Value *ImagImag = B.CreateFMulFMF(Imag, Imag, CI);
2081 *CI, B.CreateUnaryIntrinsic(Intrinsic::sqrt,
2082 B.CreateFAddFMF(RealReal, ImagImag, CI), CI,
2083 "cabs"));
2084}
2085
2086
2087
2091
2092
2093 unsigned BitWidth = Op->getType()->getScalarSizeInBits();
2095 Type *IntTy = Op->getType()->getWithNewBitWidth(DstWidth);
2097 : B.CreateZExt(Op, IntTy);
2098 }
2099 }
2100
2101 return nullptr;
2102}
2103
2104
2105
2106
2111 bool Ignored;
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2130 LibFunc LibFn;
2131
2133 if (CalleeFn && TLI->getLibFunc(CalleeFn->getName(), LibFn) &&
2135 StringRef ExpName;
2138 LibFunc LibFnFloat, LibFnDouble, LibFnLongDouble;
2139
2140 switch (LibFn) {
2141 default:
2142 return nullptr;
2143 case LibFunc_expf:
2144 case LibFunc_exp:
2145 case LibFunc_expl:
2146 ExpName = TLI->getName(LibFunc_exp);
2147 ID = Intrinsic::exp;
2148 LibFnFloat = LibFunc_expf;
2149 LibFnDouble = LibFunc_exp;
2150 LibFnLongDouble = LibFunc_expl;
2151 break;
2152 case LibFunc_exp2f:
2153 case LibFunc_exp2:
2154 case LibFunc_exp2l:
2155 ExpName = TLI->getName(LibFunc_exp2);
2156 ID = Intrinsic::exp2;
2157 LibFnFloat = LibFunc_exp2f;
2158 LibFnDouble = LibFunc_exp2;
2159 LibFnLongDouble = LibFunc_exp2l;
2160 break;
2161 }
2162
2163
2166 ? B.CreateUnaryIntrinsic(ID, FMul, nullptr, ExpName)
2168 LibFnLongDouble, B,
2170
2171
2172
2173
2174
2175 substituteInParent(BaseFn, ExpFn);
2176 return ExpFn;
2177 }
2178 }
2179
2180
2181
2184 return nullptr;
2185
2186 AttributeList NoAttrs;
2187
2189
2190
2193 (UseIntrinsic ||
2194 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2195
2196
2197
2199 Constant *One = ConstantFP::get(Ty, 1.0);
2200
2201 if (UseIntrinsic) {
2202 return copyFlags(*Pow, B.CreateIntrinsic(Intrinsic::ldexp,
2203 {Ty, ExpoI->getType()},
2204 {One, ExpoI}, Pow, "exp2"));
2205 }
2206
2208 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2209 LibFunc_ldexpl, B, NoAttrs));
2210 }
2211 }
2212
2213
2214 if (hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) {
2217 BaseR = BaseR / *BaseF;
2218 bool IsInteger = BaseF->isInteger(), IsReciprocal = BaseR.isInteger();
2219 const APFloat *NF = IsReciprocal ? &BaseR : BaseF;
2220 APSInt NI(64, false);
2221 if ((IsInteger || IsReciprocal) &&
2224 NI > 1 && NI.isPowerOf2()) {
2225 double N = NI.logBase2() * (IsReciprocal ? -1.0 : 1.0);
2226 Value *FMul = B.CreateFMul(Expo, ConstantFP::get(Ty, N), "mul");
2228 return copyFlags(*Pow, B.CreateUnaryIntrinsic(Intrinsic::exp2, FMul,
2229 nullptr, "exp2"));
2230 else
2232 LibFunc_exp2f,
2233 LibFunc_exp2l, B, NoAttrs));
2234 }
2235 }
2236
2237
2239 hasFloatFn(M, TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l)) {
2240
2242 CallInst *NewExp10 =
2243 B.CreateIntrinsic(Intrinsic::exp10, {Ty}, {Expo}, Pow, "exp10");
2244 return copyFlags(*Pow, NewExp10);
2245 }
2246
2248 LibFunc_exp10f, LibFunc_exp10l,
2249 B, NoAttrs));
2250 }
2251
2252
2255
2256
2258 "pow(1.0, y) should have been simplified earlier!");
2259
2265
2266 if (Log) {
2267 Value *FMul = B.CreateFMul(Log, Expo, "mul");
2269 return copyFlags(*Pow, B.CreateUnaryIntrinsic(Intrinsic::exp2, FMul,
2270 nullptr, "exp2"));
2271 else if (hasFloatFn(M, TLI, Ty, LibFunc_exp2, LibFunc_exp2f,
2272 LibFunc_exp2l))
2274 LibFunc_exp2f,
2275 LibFunc_exp2l, B, NoAttrs));
2276 }
2277 }
2278
2279 return nullptr;
2280}
2281
2285
2286 if (NoErrno)
2287 return B.CreateUnaryIntrinsic(Intrinsic::sqrt, V, nullptr, "sqrt");
2288
2289
2290 if (hasFloatFn(M, TLI, V->getType(), LibFunc_sqrt, LibFunc_sqrtf,
2291 LibFunc_sqrtl))
2292
2293
2294
2296 LibFunc_sqrtl, B, Attrs);
2297
2298 return nullptr;
2299}
2300
2301
2306
2310 return nullptr;
2311
2312
2313
2315 return nullptr;
2316
2317
2318
2319
2320
2323 Base, SimplifyQuery(DL, TLI, DT, AC, Pow, true, true, DC)))
2324 return nullptr;
2325
2327 TLI);
2328 if (!Sqrt)
2329 return nullptr;
2330
2331
2333 Sqrt = B.CreateUnaryIntrinsic(Intrinsic::fabs, Sqrt, nullptr, "abs");
2334
2336
2337
2338
2342 Value *FCmp = B.CreateFCmpOEQ(Base, NegInf, "isinf");
2343 Sqrt = B.CreateSelect(FCmp, PosInf, Sqrt);
2344 }
2345
2346
2348 Sqrt = B.CreateFDiv(ConstantFP::get(Ty, 1.0), Sqrt, "reciprocal");
2349
2350 return Sqrt;
2351}
2352
2357 return B.CreateIntrinsic(Intrinsic::powi, Types, Args);
2358}
2359
2368 bool Ignored;
2369
2370
2371 IRBuilderBase::FastMathFlagGuard Guard(B);
2373
2374
2375
2377 return Base;
2378
2379 if (Value *Exp = replacePowWithExp(Pow, B))
2380 return Exp;
2381
2382
2383
2384
2386 return B.CreateFDiv(ConstantFP::get(Ty, 1.0), Base, "reciprocal");
2387
2388
2390 return ConstantFP::get(Ty, 1.0);
2391
2392
2394 return Base;
2395
2396
2398 return B.CreateFMul(Base, Base, "square");
2399
2400 if (Value *Sqrt = replacePowWithSqrt(Pow, B))
2401 return Sqrt;
2402
2403
2404
2405
2411 Value *Sqrt = nullptr;
2412 if (!ExpoA.isInteger()) {
2414
2415
2416
2418 return nullptr;
2419
2421 return nullptr;
2422
2425 return nullptr;
2426 if (!ExpoI.isInteger())
2427 return nullptr;
2428 ExpoF = &ExpoI;
2429
2431 B, TLI);
2432 if (!Sqrt)
2433 return nullptr;
2434 }
2435
2436
2437
2438 APSInt IntExpo(TLI->getIntSize(), false);
2443 *Pow,
2445 Base, ConstantInt::get(B.getIntNTy(TLI->getIntSize()), IntExpo),
2446 M, B));
2447
2448 if (PowI && Sqrt)
2449 return B.CreateFMul(PowI, Sqrt);
2450
2451 return PowI;
2452 }
2453 }
2454
2455
2459 }
2460
2461
2462
2463 if (UnsafeFPShrink && Name == TLI->getName(LibFunc_pow) &&
2464 hasFloatVersion(M, Name)) {
2466 return Shrunk;
2467 }
2468
2469 return nullptr;
2470}
2471
2476 Value *Ret = nullptr;
2477 if (UnsafeFPShrink && Name == TLI->getName(LibFunc_exp2) &&
2478 hasFloatVersion(M, Name))
2480
2481
2482
2483
2484
2485
2486
2487 const bool UseIntrinsic = Callee->isIntrinsic();
2488
2490 if (!UseIntrinsic && Ty->isVectorTy())
2491 return Ret;
2492
2493
2494
2497 (UseIntrinsic ||
2498 hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
2500 Constant *One = ConstantFP::get(Ty, 1.0);
2501
2502 if (UseIntrinsic) {
2503 return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp,
2504 {Ty, Exp->getType()},
2505 {One, Exp}, CI));
2506 }
2507
2508 IRBuilderBase::FastMathFlagGuard Guard(B);
2511 One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
2512 LibFunc_ldexpl, B, AttributeList()));
2513 }
2514 }
2515
2516 return Ret;
2517}
2518
2521
2522
2523
2526 if ((Name == "fmin" || Name == "fmax") && hasFloatVersion(M, Name))
2528 return Ret;
2529
2530
2531
2532
2533
2534
2535
2536
2539
2540 Intrinsic::ID IID = Callee->getName().starts_with("fmin") ? Intrinsic::minnum
2541 : Intrinsic::maxnum;
2544}
2545
2546Value *LibCallSimplifier::optimizeFMinimumnumFMaximumnum(CallInst *CI,
2549
2550
2551
2554 if ((Name == "fminimum_num" || Name == "fmaximum_num") &&
2555 hasFloatVersion(M, Name))
2557 return Ret;
2558
2559
2560
2561
2562
2564 ? Intrinsic::minimumnum
2565 : Intrinsic::maximumnum;
2568}
2569
2571 Function *LogFn = Log->getCalledFunction();
2572 StringRef LogNm = LogFn->getName();
2575 Type *Ty = Log->getType();
2576
2577 if (UnsafeFPShrink && hasFloatVersion(Mod, LogNm))
2579 return Ret;
2580
2581 LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
2582
2583
2584 if (TLI->getLibFunc(LogNm, LogLb)) {
2585 switch (LogLb) {
2586 case LibFunc_logf:
2587 LogID = Intrinsic::log;
2588 ExpLb = LibFunc_expf;
2589 Exp2Lb = LibFunc_exp2f;
2590 Exp10Lb = LibFunc_exp10f;
2591 PowLb = LibFunc_powf;
2592 break;
2593 case LibFunc_log:
2594 LogID = Intrinsic::log;
2595 ExpLb = LibFunc_exp;
2596 Exp2Lb = LibFunc_exp2;
2597 Exp10Lb = LibFunc_exp10;
2598 PowLb = LibFunc_pow;
2599 break;
2600 case LibFunc_logl:
2601 LogID = Intrinsic::log;
2602 ExpLb = LibFunc_expl;
2603 Exp2Lb = LibFunc_exp2l;
2604 Exp10Lb = LibFunc_exp10l;
2605 PowLb = LibFunc_powl;
2606 break;
2607 case LibFunc_log2f:
2608 LogID = Intrinsic::log2;
2609 ExpLb = LibFunc_expf;
2610 Exp2Lb = LibFunc_exp2f;
2611 Exp10Lb = LibFunc_exp10f;
2612 PowLb = LibFunc_powf;
2613 break;
2614 case LibFunc_log2:
2615 LogID = Intrinsic::log2;
2616 ExpLb = LibFunc_exp;
2617 Exp2Lb = LibFunc_exp2;
2618 Exp10Lb = LibFunc_exp10;
2619 PowLb = LibFunc_pow;
2620 break;
2621 case LibFunc_log2l:
2622 LogID = Intrinsic::log2;
2623 ExpLb = LibFunc_expl;
2624 Exp2Lb = LibFunc_exp2l;
2625 Exp10Lb = LibFunc_exp10l;
2626 PowLb = LibFunc_powl;
2627 break;
2628 case LibFunc_log10f:
2629 LogID = Intrinsic::log10;
2630 ExpLb = LibFunc_expf;
2631 Exp2Lb = LibFunc_exp2f;
2632 Exp10Lb = LibFunc_exp10f;
2633 PowLb = LibFunc_powf;
2634 break;
2635 case LibFunc_log10:
2636 LogID = Intrinsic::log10;
2637 ExpLb = LibFunc_exp;
2638 Exp2Lb = LibFunc_exp2;
2639 Exp10Lb = LibFunc_exp10;
2640 PowLb = LibFunc_pow;
2641 break;
2642 case LibFunc_log10l:
2643 LogID = Intrinsic::log10;
2644 ExpLb = LibFunc_expl;
2645 Exp2Lb = LibFunc_exp2l;
2646 Exp10Lb = LibFunc_exp10l;
2647 PowLb = LibFunc_powl;
2648 break;
2649 default:
2650 return nullptr;
2651 }
2652
2653
2654 bool IsKnownNoErrno = Log->hasNoNaNs() && Log->hasNoInfs();
2655 if (!IsKnownNoErrno) {
2656 SimplifyQuery SQ(DL, TLI, DT, AC, Log, true, true, DC);
2658 Log->getOperand(0),
2660 Function *F = Log->getParent()->getParent();
2662 IsKnownNoErrno =
2665 }
2666 if (IsKnownNoErrno) {
2667 auto *NewLog = B.CreateUnaryIntrinsic(LogID, Log->getArgOperand(0), Log);
2668 NewLog->copyMetadata(*Log);
2670 }
2671 } else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2672 LogID == Intrinsic::log10) {
2674 ExpLb = LibFunc_expf;
2675 Exp2Lb = LibFunc_exp2f;
2676 Exp10Lb = LibFunc_exp10f;
2677 PowLb = LibFunc_powf;
2679 ExpLb = LibFunc_exp;
2680 Exp2Lb = LibFunc_exp2;
2681 Exp10Lb = LibFunc_exp10;
2682 PowLb = LibFunc_pow;
2683 } else
2684 return nullptr;
2685 } else
2686 return nullptr;
2687
2688
2691 return nullptr;
2692
2693 IRBuilderBase::FastMathFlagGuard Guard(B);
2695
2697 LibFunc ArgLb = NotLibFunc;
2698 TLI->getLibFunc(*Arg, ArgLb);
2699
2700
2701 AttributeList NoAttrs;
2702 if (ArgLb == PowLb || ArgID == Intrinsic::pow || ArgID == Intrinsic::powi) {
2704 Log->doesNotAccessMemory()
2705 ? B.CreateUnaryIntrinsic(LogID, Arg->getOperand(0), nullptr, "log")
2708
2709 if (ArgID == Intrinsic::powi)
2710 Y = B.CreateSIToFP(Y, Ty, "cast");
2711 Value *MulY = B.CreateFMul(Y, LogX, "mul");
2712
2713
2714 substituteInParent(Arg, MulY);
2715 return MulY;
2716 }
2717
2718
2719
2720 if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb ||
2721 ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) {
2723 if (ArgLb == ExpLb || ArgID == Intrinsic::exp)
2724
2725 Eul = ConstantFP::get(Log->getType(), numbers::e);
2726 else if (ArgLb == Exp2Lb || ArgID == Intrinsic::exp2)
2727 Eul = ConstantFP::get(Log->getType(), 2.0);
2728 else
2729 Eul = ConstantFP::get(Log->getType(), 10.0);
2730 Value *LogE = Log->doesNotAccessMemory()
2731 ? B.CreateUnaryIntrinsic(LogID, Eul, nullptr, "log")
2734
2735
2736 substituteInParent(Arg, MulY);
2737 return MulY;
2738 }
2739
2740 return nullptr;
2741}
2742
2743
2746 return nullptr;
2747
2751 return nullptr;
2753 LibFunc ArgLb = NotLibFunc;
2754 TLI->getLibFunc(*Arg, ArgLb);
2755
2756 LibFunc SqrtLb, ExpLb, Exp2Lb, Exp10Lb;
2757
2758 if (TLI->getLibFunc(SqrtFn->getName(), SqrtLb))
2759 switch (SqrtLb) {
2760 case LibFunc_sqrtf:
2761 ExpLb = LibFunc_expf;
2762 Exp2Lb = LibFunc_exp2f;
2763 Exp10Lb = LibFunc_exp10f;
2764 break;
2765 case LibFunc_sqrt:
2766 ExpLb = LibFunc_exp;
2767 Exp2Lb = LibFunc_exp2;
2768 Exp10Lb = LibFunc_exp10;
2769 break;
2770 case LibFunc_sqrtl:
2771 ExpLb = LibFunc_expl;
2772 Exp2Lb = LibFunc_exp2l;
2773 Exp10Lb = LibFunc_exp10l;
2774 break;
2775 default:
2776 return nullptr;
2777 }
2778 else if (SqrtFn->getIntrinsicID() == Intrinsic::sqrt) {
2780 ExpLb = LibFunc_expf;
2781 Exp2Lb = LibFunc_exp2f;
2782 Exp10Lb = LibFunc_exp10f;
2784 ExpLb = LibFunc_exp;
2785 Exp2Lb = LibFunc_exp2;
2786 Exp10Lb = LibFunc_exp10;
2787 } else
2788 return nullptr;
2789 } else
2790 return nullptr;
2791
2792 if (ArgLb != ExpLb && ArgLb != Exp2Lb && ArgLb != Exp10Lb &&
2793 ArgID != Intrinsic::exp && ArgID != Intrinsic::exp2)
2794 return nullptr;
2795
2796 IRBuilderBase::InsertPointGuard Guard(B);
2797 B.SetInsertPoint(Arg);
2798 auto *ExpOperand = Arg->getOperand(0);
2799 auto *FMul =
2800 B.CreateFMulFMF(ExpOperand, ConstantFP::get(ExpOperand->getType(), 0.5),
2801 CI, "merged.sqrt");
2802
2804 return Arg;
2805}
2806
2810 Value *Ret = nullptr;
2811
2812
2813
2815 (Callee->getName() == "sqrt" ||
2816 Callee->getIntrinsicID() == Intrinsic::sqrt))
2818
2819 if (Value *Opt = mergeSqrtToExp(CI, B))
2820 return Opt;
2821
2823 return Ret;
2824
2826 if ( || I->getOpcode() != Instruction::FMul ||
->isFast())
2827 return Ret;
2828
2829
2830
2831
2832 Value *Op0 = I->getOperand(0);
2833 Value *Op1 = I->getOperand(1);
2834 Value *RepeatOp = nullptr;
2835 Value *OtherOp = nullptr;
2836 if (Op0 == Op1) {
2837
2838 RepeatOp = Op0;
2839 } else {
2840
2841
2842
2843
2844
2848
2849 RepeatOp = MulOp;
2850 OtherOp = Op1;
2853
2854 RepeatOp = MulOp;
2855 OtherOp = Op0;
2856 }
2857 }
2858 if (!RepeatOp)
2859 return Ret;
2860
2861
2862
2863
2864
2865
2866 Value *FabsCall =
2867 B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp, I, "fabs");
2868 if (OtherOp) {
2869
2870
2871
2872 Value *SqrtCall =
2873 B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp, I, "sqrt");
2874 return copyFlags(*CI, B.CreateFMulFMF(FabsCall, SqrtCall, I));
2875 }
2876 return copyFlags(*CI, FabsCall);
2877}
2878
2880
2881
2882
2883
2885 if (!IsNoNan) {
2886 SimplifyQuery SQ(DL, TLI, DT, AC, CI, true, true, DC);
2889 KnownFPClass Known1 =
2892 const fltSemantics &FltSem =
2895 }
2896 }
2897
2898 if (IsNoNan) {
2901 FRemI->setHasNoNaNs(true);
2902 return FRem;
2903 }
2904 return nullptr;
2905}
2906
2907Value *LibCallSimplifier::optimizeTrigInversionPairs(CallInst *CI,
2911 Value *Ret = nullptr;
2913 if (UnsafeFPShrink &&
2914 (Name == "tan" || Name == "atanh" || Name == "sinh" || Name == "cosh" ||
2915 Name == "asinh") &&
2916 hasFloatVersion(M, Name))
2918
2921 if (!OpC)
2922 return Ret;
2923
2924
2925 if (!CI->isFast() || !OpC->isFast())
2926 return Ret;
2927
2928
2929
2930
2931
2932
2933 LibFunc Func;
2934 Function *F = OpC->getCalledFunction();
2935 if (F && TLI->getLibFunc(F->getName(), Func) &&
2937 LibFunc inverseFunc = llvm::StringSwitch(Callee->getName())
2938 .Case("tan", LibFunc_atan)
2939 .Case("atanh", LibFunc_tanh)
2940 .Case("sinh", LibFunc_asinh)
2941 .Case("cosh", LibFunc_acosh)
2942 .Case("tanf", LibFunc_atanf)
2943 .Case("atanhf", LibFunc_tanhf)
2944 .Case("sinhf", LibFunc_asinhf)
2945 .Case("coshf", LibFunc_acoshf)
2946 .Case("tanl", LibFunc_atanl)
2947 .Case("atanhl", LibFunc_tanhl)
2948 .Case("sinhl", LibFunc_asinhl)
2949 .Case("coshl", LibFunc_acoshl)
2950 .Case("asinh", LibFunc_sinh)
2951 .Case("asinhf", LibFunc_sinhf)
2952 .Case("asinhl", LibFunc_sinhl)
2953 .Default(NotLibFunc);
2954 if (Func == inverseFunc)
2955 Ret = OpC->getArgOperand(0);
2956 }
2957 return Ret;
2958}
2959
2966
2968 bool UseFloat, Value *&Sin, Value *&Cos,
2972 Type *ResTy;
2974
2976 if (UseFloat) {
2977 Name = "__sincospif_stret";
2978
2979 assert(T.getArch() != Triple::x86 && "x86 messy and unsupported for now");
2980
2981
2985 } else {
2986 Name = "__sincospi_stret";
2988 }
2989
2991 return false;
2992 LibFunc TheLibFunc;
2995 M, *TLI, TheLibFunc, OrigCallee->getAttributes(), ResTy, ArgTy);
2996
2998
2999
3000 B.SetInsertPoint(ArgInst->getParent(), ++ArgInst->getIterator());
3001 } else {
3002
3003
3004 BasicBlock &EntryBB = B.GetInsertBlock()->getParent()->getEntryBlock();
3005 B.SetInsertPoint(&EntryBB, EntryBB.begin());
3006 }
3007
3008 SinCos = B.CreateCall(Callee, Arg, "sincospi");
3009
3011 Sin = B.CreateExtractValue(SinCos, 0, "sinpi");
3012 Cos = B.CreateExtractValue(SinCos, 1, "cospi");
3013 } else {
3014 Sin = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 0),
3015 "sinpi");
3016 Cos = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 1),
3017 "cospi");
3018 }
3019
3020 return true;
3021}
3022
3027
3030 Call->copyFastMathFlags(CI);
3032 if (IsEven) {
3033
3035 }
3036
3037 return B.CreateFNegFMF(CallInst, CI);
3038 }
3039
3040
3044 Call->copyFastMathFlags(CI);
3046 }
3047
3048 return nullptr;
3049}
3050
3051Value *LibCallSimplifier::optimizeSymmetric(CallInst *CI, LibFunc Func,
3053 switch (Func) {
3054 case LibFunc_cos:
3055 case LibFunc_cosf:
3056 case LibFunc_cosl:
3058
3059 case LibFunc_sin:
3060 case LibFunc_sinf:
3061 case LibFunc_sinl:
3062
3063 case LibFunc_tan:
3064 case LibFunc_tanf:
3065 case LibFunc_tanl:
3066
3067 case LibFunc_erf:
3068 case LibFunc_erff:
3069 case LibFunc_erfl:
3071
3072 default:
3073 return nullptr;
3074 }
3075}
3076
3078
3079
3081 return nullptr;
3082
3085 return nullptr;
3086
3090
3092
3093
3094
3095
3097 for (User *U : Arg->users())
3098 classifyArgUse(U, F, IsFloat, SinCalls, CosCalls, SinCosCalls);
3099
3100
3101 if (SinCalls.empty() || CosCalls.empty())
3102 return nullptr;
3103
3104 Value *Sin, *Cos, *SinCos;
3106 SinCos, TLI))
3107 return nullptr;
3108
3109 auto replaceTrigInsts = [this](SmallVectorImpl<CallInst *> &Calls,
3111 for (CallInst *C : Calls)
3112 replaceAllUsesWith(C, Res);
3113 };
3114
3115 replaceTrigInsts(SinCalls, Sin);
3116 replaceTrigInsts(CosCalls, Cos);
3117 replaceTrigInsts(SinCosCalls, SinCos);
3118
3119 return IsSin ? Sin : Cos;
3120}
3121
3122void LibCallSimplifier::classifyArgUse(
3129 return;
3130
3131
3133 return;
3134
3137 LibFunc Func;
3138 if (!Callee || !TLI->getLibFunc(*Callee, Func) ||
3141 return;
3142
3143 if (IsFloat) {
3144 if (Func == LibFunc_sinpif)
3146 else if (Func == LibFunc_cospif)
3148 else if (Func == LibFunc_sincospif_stret)
3150 } else {
3151 if (Func == LibFunc_sinpi)
3153 else if (Func == LibFunc_cospi)
3155 else if (Func == LibFunc_sincospi_stret)
3157 }
3158}
3159
3160
3165 return nullptr;
3166
3171 return nullptr;
3174 return nullptr;
3175
3176
3177 unsigned IntBW = TLI->getIntSize();
3178 APSInt QuotInt(IntBW, false);
3179 bool IsExact;
3180 Status =
3183 return nullptr;
3184
3185 B.CreateAlignedStore(
3188 return ConstantFP::get(CI->getType(), Rem);
3189}
3190
3191
3193
3195 return nullptr;
3196
3197
3198
3203
3205
3208 return nullptr;
3209
3212
3215 return ConstantFP::get(CI->getType(), MaxVal);
3216}
3217
3218
3219
3220
3221
3223
3224
3227 Type *ArgType = Op->getType();
3228 Value *V = B.CreateIntrinsic(Intrinsic::cttz, {ArgType}, {Op, B.getTrue()},
3229 nullptr, "cttz");
3230 V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1));
3231 V = B.CreateIntCast(V, RetType, false);
3232
3234 return B.CreateSelect(Cond, V, ConstantInt::get(RetType, 0));
3235}
3236
3238
3239
3241 Type *ArgType = Op->getType();
3242 Value *V = B.CreateIntrinsic(Intrinsic::ctlz, {ArgType}, {Op, B.getFalse()},
3243 nullptr, "ctlz");
3245 V);
3246 return B.CreateIntCast(V, CI->getType(), false);
3247}
3248
3250
3251
3253 Value *IsNeg = B.CreateIsNeg(X);
3254 Value *NegX = B.CreateNSWNeg(X, "neg");
3255 return B.CreateSelect(IsNeg, NegX, X);
3256}
3257
3259
3261 Type *ArgType = Op->getType();
3262 Op = B.CreateSub(Op, ConstantInt::get(ArgType, '0'), "isdigittmp");
3263 Op = B.CreateICmpULT(Op, ConstantInt::get(ArgType, 10), "isdigit");
3264 return B.CreateZExt(Op, CI->getType());
3265}
3266
3268
3270 Type *ArgType = Op->getType();
3271 Op = B.CreateICmpULT(Op, ConstantInt::get(ArgType, 128), "isascii");
3272 return B.CreateZExt(Op, CI->getType());
3273}
3274
3276
3278 ConstantInt::get(CI->getType(), 0x7F));
3279}
3280
3281
3283 StringRef Str;
3285 return nullptr;
3286
3287 return convertStrToInt(CI, Str, nullptr, 10, true, B);
3288}
3289
3290
3292 bool AsSigned) {
3295
3296
3299 EndPtr = nullptr;
3301 return nullptr;
3302
3303 StringRef Str;
3305 return nullptr;
3306
3308 return convertStrToInt(CI, Str, EndPtr, CInt->getSExtValue(), AsSigned, B);
3309 }
3310
3311 return nullptr;
3312}
3313
3314
3315
3316
3317
3319
3321 int StreamArg) {
3323
3324
3325
3326
3327
3328
3329
3330
3331 if (!CI->hasFnAttr(Attribute::Cold) &&
3334 }
3335
3336 return nullptr;
3337}
3338
3340 if (!Callee || !Callee->isDeclaration())
3341 return false;
3342
3343 if (StreamArg < 0)
3344 return true;
3345
3346
3347
3348
3349 if (StreamArg >= (int)CI->arg_size())
3350 return false;
3352 if (!LI)
3353 return false;
3356 return false;
3357 return GV->getName() == "stderr";
3358}
3359
3361
3362 StringRef FormatStr;
3364 return nullptr;
3365
3366
3367 if (FormatStr.empty())
3369
3370
3371
3372
3374 return nullptr;
3375
3377
3378 if (FormatStr.size() == 1 || FormatStr == "%%") {
3379
3380
3381
3382 Value *IntChar = ConstantInt::get(IntTy, (unsigned char)FormatStr[0]);
3383 return copyFlags(*CI, emitPutChar(IntChar, B, TLI));
3384 }
3385
3386
3387 if (FormatStr == "%s" && CI->arg_size() > 1) {
3388 StringRef OperandStr;
3389 if (!getConstantStringInfo(CI->getOperand(1), OperandStr))
3390 return nullptr;
3391
3392 if (OperandStr.empty())
3393 return (Value *)CI;
3394
3395 if (OperandStr.size() == 1) {
3396
3397
3398
3399 Value *IntChar = ConstantInt::get(IntTy, (unsigned char)OperandStr[0]);
3400 return copyFlags(*CI, emitPutChar(IntChar, B, TLI));
3401 }
3402
3403 if (OperandStr.back() == '\n') {
3404 OperandStr = OperandStr.drop_back();
3405 Value *GV = B.CreateGlobalString(OperandStr, "str");
3406 return copyFlags(*CI, emitPutS(GV, B, TLI));
3407 }
3408 return nullptr;
3409 }
3410
3411
3412 if (FormatStr.back() == '\n' &&
3413 !FormatStr.contains('%')) {
3414
3415
3416 FormatStr = FormatStr.drop_back();
3417 Value *GV = B.CreateGlobalString(FormatStr, "str");
3418 return copyFlags(*CI, emitPutS(GV, B, TLI));
3419 }
3420
3421
3422
3423 if (FormatStr == "%c" && CI->arg_size() > 1 &&
3425
3426
3427 Value *IntChar = B.CreateIntCast(CI->getArgOperand(1), IntTy, false);
3428 return copyFlags(*CI, emitPutChar(IntChar, B, TLI));
3429 }
3430
3431
3432 if (FormatStr == "%s\n" && CI->arg_size() > 1 &&
3435 return nullptr;
3436}
3437
3439
3442 FunctionType *FT = Callee->getFunctionType();
3443 if (Value *V = optimizePrintFString(CI, B)) {
3444 return V;
3445 }
3446
3448
3449
3450
3453 FunctionCallee IPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_iprintf, FT,
3454 Callee->getAttributes());
3456 New->setCalledFunction(IPrintFFn);
3457 B.Insert(New);
3458 return New;
3459 }
3460
3461
3462
3465 auto SmallPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_small_printf, FT,
3466 Callee->getAttributes());
3468 New->setCalledFunction(SmallPrintFFn);
3469 B.Insert(New);
3470 return New;
3471 }
3472
3473 return nullptr;
3474}
3475
3476Value *LibCallSimplifier::optimizeSPrintFString(CallInst *CI,
3478
3479 StringRef FormatStr;
3481 return nullptr;
3482
3483
3486
3487
3488 if (FormatStr.contains('%'))
3489 return nullptr;
3490
3491
3493
3494 TLI->getAsSizeT(FormatStr.size() + 1, *CI->getModule()));
3495 return ConstantInt::get(CI->getType(), FormatStr.size());
3496 }
3497
3498
3499
3500 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->arg_size() < 3)
3501 return nullptr;
3502
3503
3504 if (FormatStr[1] == 'c') {
3505
3507 return nullptr;
3509 Value *Ptr = Dest;
3510 B.CreateStore(V, Ptr);
3511 Ptr = B.CreateInBoundsGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul");
3512 B.CreateStore(B.getInt8(0), Ptr);
3513
3514 return ConstantInt::get(CI->getType(), 1);
3515 }
3516
3517 if (FormatStr[1] == 's') {
3518
3519
3521 return nullptr;
3522
3524
3526
3528 if (SrcLen) {
3530 TLI->getAsSizeT(SrcLen, *CI->getModule()));
3531
3532 return ConstantInt::get(CI->getType(), SrcLen - 1);
3534
3535 Value *PtrDiff = B.CreatePtrDiff(B.getInt8Ty(), V, Dest);
3536 return B.CreateIntCast(PtrDiff, CI->getType(), false);
3537 }
3538
3541 return nullptr;
3542
3544 if (!Len)
3545 return nullptr;
3547 B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1), "leninc");
3549
3550
3551 return B.CreateIntCast(Len, CI->getType(), false);
3552 }
3553 return nullptr;
3554}
3555
3559 FunctionType *FT = Callee->getFunctionType();
3560 if (Value *V = optimizeSPrintFString(CI, B)) {
3561 return V;
3562 }
3563
3565
3566
3567
3570 FunctionCallee SIPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_siprintf,
3571 FT, Callee->getAttributes());
3573 New->setCalledFunction(SIPrintFFn);
3574 B.Insert(New);
3575 return New;
3576 }
3577
3578
3579
3582 auto SmallSPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_small_sprintf, FT,
3583 Callee->getAttributes());
3585 New->setCalledFunction(SmallSPrintFFn);
3586 B.Insert(New);
3587 return New;
3588 }
3589
3590 return nullptr;
3591}
3592
3593
3594
3595
3596
3597
3598Value *LibCallSimplifier::emitSnPrintfMemCpy(CallInst *CI, Value *StrArg,
3601 assert(StrArg || (N < 2 && Str.size() == 1));
3602
3603 unsigned IntBits = TLI->getIntSize();
3604 uint64_t IntMax = maxIntN(IntBits);
3605 if (Str.size() > IntMax)
3606
3607
3608
3609 return nullptr;
3610
3611 Value *StrLen = ConstantInt::get(CI->getType(), Str.size());
3612 if (N == 0)
3613 return StrLen;
3614
3615
3616
3617 uint64_t NCopy;
3618 if (N > Str.size())
3619
3620
3621 NCopy = Str.size() + 1;
3622 else
3623 NCopy = N - 1;
3624
3626 if (NCopy && StrArg)
3627
3629 TLI->getAsSizeT(NCopy, *CI->getModule())));
3630
3631 if (N > Str.size())
3632
3633
3634 return StrLen;
3635
3636
3638 Value *NulOff = B.getIntN(IntBits, NCopy);
3639 Value *DstEnd = B.CreateInBoundsGEP(Int8Ty, DstArg, NulOff, "endptr");
3640 B.CreateStore(ConstantInt::get(Int8Ty, 0), DstEnd);
3641 return StrLen;
3642}
3643
3644Value *LibCallSimplifier::optimizeSnPrintFString(CallInst *CI,
3646
3649 return nullptr;
3650
3651 uint64_t N = Size->getZExtValue();
3652 uint64_t IntMax = maxIntN(TLI->getIntSize());
3653 if (N > IntMax)
3654
3655
3656 return nullptr;
3657
3660
3661
3662 StringRef FormatStr;
3664 return nullptr;
3665
3666
3668 if (FormatStr.contains('%'))
3669
3670
3671 return nullptr;
3672
3673 return emitSnPrintfMemCpy(CI, FmtArg, FormatStr, N, B);
3674 }
3675
3676
3677
3678 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->arg_size() != 4)
3679 return nullptr;
3680
3681
3682 if (FormatStr[1] == 'c') {
3683 if (N <= 1) {
3684
3685
3686
3687 StringRef CharStr("*");
3688 return emitSnPrintfMemCpy(CI, nullptr, CharStr, N, B);
3689 }
3690
3691
3693 return nullptr;
3695 Value *Ptr = DstArg;
3696 B.CreateStore(V, Ptr);
3697 Ptr = B.CreateInBoundsGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul");
3698 B.CreateStore(B.getInt8(0), Ptr);
3699 return ConstantInt::get(CI->getType(), 1);
3700 }
3701
3702 if (FormatStr[1] != 's')
3703 return nullptr;
3704
3706
3707 StringRef Str;
3709 return nullptr;
3710
3711 return emitSnPrintfMemCpy(CI, StrArg, Str, N, B);
3712}
3713
3715 if (Value *V = optimizeSnPrintFString(CI, B)) {
3716 return V;
3717 }
3718
3721 return nullptr;
3722}
3723
3724Value *LibCallSimplifier::optimizeFPrintFString(CallInst *CI,
3726 optimizeErrorReporting(CI, B, 0);
3727
3728
3729 StringRef FormatStr;
3731 return nullptr;
3732
3733
3734
3735
3737 return nullptr;
3738
3739
3741
3742 if (FormatStr.contains('%'))
3743 return nullptr;
3744
3747 TLI->getAsSizeT(FormatStr.size(), *CI->getModule()),
3749 }
3750
3751
3752
3753 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->arg_size() < 3)
3754 return nullptr;
3755
3756
3757 if (FormatStr[1] == 'c') {
3758
3760 return nullptr;
3761 Type *IntTy = B.getIntNTy(TLI->getIntSize());
3763 "chari");
3765 }
3766
3767 if (FormatStr[1] == 's') {
3768
3770 return nullptr;
3773 }
3774 return nullptr;
3775}
3776
3780 FunctionType *FT = Callee->getFunctionType();
3781 if (Value *V = optimizeFPrintFString(CI, B)) {
3782 return V;
3783 }
3784
3785
3786
3789 FunctionCallee FIPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_fiprintf,
3790 FT, Callee->getAttributes());
3792 New->setCalledFunction(FIPrintFFn);
3793 B.Insert(New);
3794 return New;
3795 }
3796
3797
3798
3801 auto SmallFPrintFFn =
3803 Callee->getAttributes());
3805 New->setCalledFunction(SmallFPrintFFn);
3806 B.Insert(New);
3807 return New;
3808 }
3809
3810 return nullptr;
3811}
3812
3814 optimizeErrorReporting(CI, B, 3);
3815
3816
3819 if (SizeC && CountC) {
3821
3822
3823 if (Bytes == 0)
3824 return ConstantInt::get(CI->getType(), 0);
3825
3826
3827
3828 if (Bytes == 1 && CI->use_empty()) {
3831 Value *Cast = B.CreateIntCast(Char, IntTy, true, "chari");
3833 return NewCI ? ConstantInt::get(CI->getType(), 1) : nullptr;
3834 }
3835 }
3836
3837 return nullptr;
3838}
3839
3841 optimizeErrorReporting(CI, B, 1);
3842
3843
3844
3847 return nullptr;
3848
3849
3851 return nullptr;
3852
3853
3855 if (!Len)
3856 return nullptr;
3857
3858
3859 unsigned SizeTBits = TLI->getSizeTSize(*CI->getModule());
3862 *CI,
3864 ConstantInt::get(SizeTTy, Len - 1),
3866}
3867
3871 return nullptr;
3872
3873
3874
3875 StringRef Str;
3877
3878
3881 }
3882
3883 return nullptr;
3884}
3885
3886Value *LibCallSimplifier::optimizeExit(CallInst *CI) {
3887
3888
3889 const APInt *C;
3890 if (!CI->hasFnAttr(Attribute::Cold) &&
3893 }
3894 return nullptr;
3895}
3896
3898
3902}
3903
3904bool LibCallSimplifier::hasFloatVersion(const Module *M, StringRef FuncName) {
3905 SmallString<20> FloatFuncName = FuncName;
3906 FloatFuncName += 'f';
3908}
3909
3910Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
3913 LibFunc Func;
3915
3916
3917 if (TLI->getLibFunc(*Callee, Func) && isLibFuncEmittable(M, TLI, Func)) {
3918
3922 "Optimizing string/memory libcall would change the calling convention");
3923 switch (Func) {
3924 case LibFunc_strcat:
3925 return optimizeStrCat(CI, Builder);
3926 case LibFunc_strncat:
3927 return optimizeStrNCat(CI, Builder);
3928 case LibFunc_strchr:
3929 return optimizeStrChr(CI, Builder);
3930 case LibFunc_strrchr:
3931 return optimizeStrRChr(CI, Builder);
3932 case LibFunc_strcmp:
3933 return optimizeStrCmp(CI, Builder);
3934 case LibFunc_strncmp:
3935 return optimizeStrNCmp(CI, Builder);
3936 case LibFunc_strcpy:
3937 return optimizeStrCpy(CI, Builder);
3938 case LibFunc_stpcpy:
3939 return optimizeStpCpy(CI, Builder);
3940 case LibFunc_strlcpy:
3941 return optimizeStrLCpy(CI, Builder);
3942 case LibFunc_stpncpy:
3943 return optimizeStringNCpy(CI, true, Builder);
3944 case LibFunc_strncpy:
3945 return optimizeStringNCpy(CI, false, Builder);
3946 case LibFunc_strlen:
3947 return optimizeStrLen(CI, Builder);
3948 case LibFunc_strnlen:
3949 return optimizeStrNLen(CI, Builder);
3950 case LibFunc_strpbrk:
3951 return optimizeStrPBrk(CI, Builder);
3952 case LibFunc_strndup:
3953 return optimizeStrNDup(CI, Builder);
3954 case LibFunc_strtol:
3955 case LibFunc_strtod:
3956 case LibFunc_strtof:
3957 case LibFunc_strtoul:
3958 case LibFunc_strtoll:
3959 case LibFunc_strtold:
3960 case LibFunc_strtoull:
3961 return optimizeStrTo(CI, Builder);
3962 case LibFunc_strspn:
3963 return optimizeStrSpn(CI, Builder);
3964 case LibFunc_strcspn:
3965 return optimizeStrCSpn(CI, Builder);
3966 case LibFunc_strstr:
3967 return optimizeStrStr(CI, Builder);
3968 case LibFunc_memchr:
3969 return optimizeMemChr(CI, Builder);
3970 case LibFunc_memrchr:
3971 return optimizeMemRChr(CI, Builder);
3972 case LibFunc_bcmp:
3973 return optimizeBCmp(CI, Builder);
3974 case LibFunc_memcmp:
3975 return optimizeMemCmp(CI, Builder);
3976 case LibFunc_memcpy:
3977 return optimizeMemCpy(CI, Builder);
3978 case LibFunc_memccpy:
3979 return optimizeMemCCpy(CI, Builder);
3980 case LibFunc_mempcpy:
3981 return optimizeMemPCpy(CI, Builder);
3982 case LibFunc_memmove:
3983 return optimizeMemMove(CI, Builder);
3984 case LibFunc_memset:
3985 return optimizeMemSet(CI, Builder);
3986 case LibFunc_realloc:
3987 return optimizeRealloc(CI, Builder);
3988 case LibFunc_wcslen:
3989 return optimizeWcslen(CI, Builder);
3990 case LibFunc_bcopy:
3991 return optimizeBCopy(CI, Builder);
3992 case LibFunc_Znwm:
3993 case LibFunc_ZnwmRKSt9nothrow_t:
3994 case LibFunc_ZnwmSt11align_val_t:
3995 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
3996 case LibFunc_Znam:
3997 case LibFunc_ZnamRKSt9nothrow_t:
3998 case LibFunc_ZnamSt11align_val_t:
3999 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
4000 case LibFunc_Znwm12__hot_cold_t:
4001 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
4002 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
4003 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
4004 case LibFunc_Znam12__hot_cold_t:
4005 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
4006 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
4007 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
4008 case LibFunc_size_returning_new:
4009 case LibFunc_size_returning_new_hot_cold:
4010 case LibFunc_size_returning_new_aligned:
4011 case LibFunc_size_returning_new_aligned_hot_cold:
4012 return optimizeNew(CI, Builder, Func);
4013 default:
4014 break;
4015 }
4016 }
4017 return nullptr;
4018}
4019
4020
4024 return nullptr;
4025
4027
4028 if (CharSeq.empty())
4029 Fill = APInt(32, 0);
4031 return nullptr;
4032
4034}
4035
4036Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
4037 LibFunc Func,
4040
4041
4043 return nullptr;
4044
4045 if (Value *V = optimizeSymmetric(CI, Func, Builder))
4046 return V;
4047
4048 switch (Func) {
4049 case LibFunc_sinpif:
4050 case LibFunc_sinpi:
4051 return optimizeSinCosPi(CI, true, Builder);
4052 case LibFunc_cospif:
4053 case LibFunc_cospi:
4054 return optimizeSinCosPi(CI, false, Builder);
4055 case LibFunc_powf:
4056 case LibFunc_pow:
4057 case LibFunc_powl:
4058 return optimizePow(CI, Builder);
4059 case LibFunc_exp2l:
4060 case LibFunc_exp2:
4061 case LibFunc_exp2f:
4062 return optimizeExp2(CI, Builder);
4063 case LibFunc_fabsf:
4064 case LibFunc_fabs:
4065 case LibFunc_fabsl:
4067 case LibFunc_sqrtf:
4068 case LibFunc_sqrt:
4069 case LibFunc_sqrtl:
4070 return optimizeSqrt(CI, Builder);
4071 case LibFunc_fmod:
4072 case LibFunc_fmodf:
4073 case LibFunc_fmodl:
4074 return optimizeFMod(CI, Builder);
4075 case LibFunc_logf:
4076 case LibFunc_log:
4077 case LibFunc_logl:
4078 case LibFunc_log10f:
4079 case LibFunc_log10:
4080 case LibFunc_log10l:
4081 case LibFunc_log1pf:
4082 case LibFunc_log1p:
4083 case LibFunc_log1pl:
4084 case LibFunc_log2f:
4085 case LibFunc_log2:
4086 case LibFunc_log2l:
4087 case LibFunc_logbf:
4088 case LibFunc_logb:
4089 case LibFunc_logbl:
4090 return optimizeLog(CI, Builder);
4091 case LibFunc_tan:
4092 case LibFunc_tanf:
4093 case LibFunc_tanl:
4094 case LibFunc_sinh:
4095 case LibFunc_sinhf:
4096 case LibFunc_sinhl:
4097 case LibFunc_asinh:
4098 case LibFunc_asinhf:
4099 case LibFunc_asinhl:
4100 case LibFunc_cosh:
4101 case LibFunc_coshf:
4102 case LibFunc_coshl:
4103 case LibFunc_atanh:
4104 case LibFunc_atanhf:
4105 case LibFunc_atanhl:
4106 return optimizeTrigInversionPairs(CI, Builder);
4107 case LibFunc_ceil:
4109 case LibFunc_floor:
4111 case LibFunc_round:
4113 case LibFunc_roundeven:
4115 case LibFunc_nearbyint:
4117 case LibFunc_rint:
4119 case LibFunc_trunc:
4121 case LibFunc_acos:
4122 case LibFunc_acosh:
4123 case LibFunc_asin:
4124 case LibFunc_atan:
4125 case LibFunc_cbrt:
4126 case LibFunc_exp:
4127 case LibFunc_exp10:
4128 case LibFunc_expm1:
4129 case LibFunc_cos:
4130 case LibFunc_sin:
4131 case LibFunc_tanh:
4134 return nullptr;
4135 case LibFunc_copysign:
4138 return nullptr;
4139 case LibFunc_fdim:
4140 case LibFunc_fdimf:
4141 case LibFunc_fdiml:
4142 return optimizeFdim(CI, Builder);
4143 case LibFunc_fminf:
4144 case LibFunc_fmin:
4145 case LibFunc_fminl:
4146 case LibFunc_fmaxf:
4147 case LibFunc_fmax:
4148 case LibFunc_fmaxl:
4149 return optimizeFMinFMax(CI, Builder);
4150 case LibFunc_fminimum_numf:
4151 case LibFunc_fminimum_num:
4152 case LibFunc_fminimum_numl:
4153 case LibFunc_fmaximum_numf:
4154 case LibFunc_fmaximum_num:
4155 case LibFunc_fmaximum_numl:
4156 return optimizeFMinimumnumFMaximumnum(CI, Builder);
4157 case LibFunc_cabs:
4158 case LibFunc_cabsf:
4159 case LibFunc_cabsl:
4160 return optimizeCAbs(CI, Builder);
4161 case LibFunc_remquo:
4162 case LibFunc_remquof:
4163 case LibFunc_remquol:
4164 return optimizeRemquo(CI, Builder);
4165 case LibFunc_nan:
4166 case LibFunc_nanf:
4167 case LibFunc_nanl:
4169 default:
4170 return nullptr;
4171 }
4172}
4173
4177
4178
4179
4180
4182
4183 return maybeOptimizeNoBuiltinOperatorNew(CI, Builder);
4184 }
4185
4186 LibFunc Func;
4189
4192
4194 Builder.setDefaultOperandBundles(OpBundles);
4195
4196
4197
4198
4202 UnsafeFPShrink = true;
4203
4204
4206 if (!IsCallingConvC)
4207 return nullptr;
4208
4209
4210 switch (II->getIntrinsicID()) {
4211 case Intrinsic::pow:
4212 return optimizePow(CI, Builder);
4213 case Intrinsic::exp2:
4214 return optimizeExp2(CI, Builder);
4215 case Intrinsic:🪵
4216 case Intrinsic::log2:
4217 case Intrinsic::log10:
4218 return optimizeLog(CI, Builder);
4219 case Intrinsic::sqrt:
4220 return optimizeSqrt(CI, Builder);
4221 case Intrinsic::memset:
4222 return optimizeMemSet(CI, Builder);
4223 case Intrinsic::memcpy:
4224 return optimizeMemCpy(CI, Builder);
4225 case Intrinsic::memmove:
4226 return optimizeMemMove(CI, Builder);
4227 case Intrinsic::sin:
4228 case Intrinsic::cos:
4229 if (UnsafeFPShrink)
4231 return nullptr;
4232 default:
4233 return nullptr;
4234 }
4235 }
4236
4237
4238 if (Value *SimplifiedFortifiedCI =
4239 FortifiedSimplifier.optimizeCall(CI, Builder))
4240 return SimplifiedFortifiedCI;
4241
4242
4243 if (TLI->getLibFunc(*Callee, Func) && isLibFuncEmittable(M, TLI, Func)) {
4244
4246 return nullptr;
4247 if (Value *V = optimizeStringMemoryLibCall(CI, Builder))
4248 return V;
4249 if (Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
4250 return V;
4251 switch (Func) {
4252 case LibFunc_ffs:
4253 case LibFunc_ffsl:
4254 case LibFunc_ffsll:
4255 return optimizeFFS(CI, Builder);
4256 case LibFunc_fls:
4257 case LibFunc_flsl:
4258 case LibFunc_flsll:
4259 return optimizeFls(CI, Builder);
4260 case LibFunc_abs:
4261 case LibFunc_labs:
4262 case LibFunc_llabs:
4263 return optimizeAbs(CI, Builder);
4264 case LibFunc_isdigit:
4265 return optimizeIsDigit(CI, Builder);
4266 case LibFunc_isascii:
4267 return optimizeIsAscii(CI, Builder);
4268 case LibFunc_toascii:
4269 return optimizeToAscii(CI, Builder);
4270 case LibFunc_atoi:
4271 case LibFunc_atol:
4272 case LibFunc_atoll:
4273 return optimizeAtoi(CI, Builder);
4274 case LibFunc_strtol:
4275 case LibFunc_strtoll:
4276 return optimizeStrToInt(CI, Builder, true);
4277 case LibFunc_strtoul:
4278 case LibFunc_strtoull:
4279 return optimizeStrToInt(CI, Builder, false);
4280 case LibFunc_printf:
4281 return optimizePrintF(CI, Builder);
4282 case LibFunc_sprintf:
4283 return optimizeSPrintF(CI, Builder);
4284 case LibFunc_snprintf:
4285 return optimizeSnPrintF(CI, Builder);
4286 case LibFunc_fprintf:
4287 return optimizeFPrintF(CI, Builder);
4288 case LibFunc_fwrite:
4289 return optimizeFWrite(CI, Builder);
4290 case LibFunc_fputs:
4291 return optimizeFPuts(CI, Builder);
4292 case LibFunc_puts:
4293 return optimizePuts(CI, Builder);
4294 case LibFunc_perror:
4295 return optimizeErrorReporting(CI, Builder);
4296 case LibFunc_vfprintf:
4297 case LibFunc_fiprintf:
4298 return optimizeErrorReporting(CI, Builder, 0);
4299 case LibFunc_exit:
4300 case LibFunc_Exit:
4301 return optimizeExit(CI);
4302 default:
4303 return nullptr;
4304 }
4305 }
4306 return nullptr;
4307}
4308
4315 : FortifiedSimplifier(TLI), DL(DL), TLI(TLI), DT(DT), DC(DC), AC(AC),
4316 ORE(ORE), BFI(BFI), PSI(PSI), Replacer(Replacer), Eraser(Eraser) {}
4317
4318void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) {
4319
4320 Replacer(I, With);
4321}
4322
4323void LibCallSimplifier::eraseFromParent(Instruction *I) {
4324 Eraser(I);
4325}
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(
4363 CallInst *CI, unsigned ObjSizeOp, std::optional SizeOp,
4364 std::optional StrOp, std::optional FlagOp) {
4365
4366
4367 if (FlagOp) {
4369 if (!Flag || ->isZero())
4370 return false;
4371 }
4372
4374 return true;
4375
4376 if (ConstantInt *ObjSizeCI =
4378 if (ObjSizeCI->isMinusOne())
4379 return true;
4380
4381 if (OnlyLowerUnknownSize)
4382 return false;
4383 if (StrOp) {
4385
4386
4387 if (Len)
4389 else
4390 return false;
4391 return ObjSizeCI->getZExtValue() >= Len;
4392 }
4393
4394 if (SizeOp) {
4395 if (ConstantInt *SizeCI =
4397 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
4398 }
4399 }
4400 return false;
4401}
4402
4403Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(CallInst *CI,
4405 if (isFortifiedCallFoldable(CI, 3, 2)) {
4406 CallInst *NewCI =
4411 }
4412 return nullptr;
4413}
4414
4415Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI,
4417 if (isFortifiedCallFoldable(CI, 3, 2)) {
4418 CallInst *NewCI =
4423 }
4424 return nullptr;
4425}
4426
4427Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI,
4429 if (isFortifiedCallFoldable(CI, 3, 2)) {
4431 CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val,
4435 }
4436 return nullptr;
4437}
4438
4439Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(CallInst *CI,
4442 if (isFortifiedCallFoldable(CI, 3, 2))
4446 }
4447 return nullptr;
4448}
4449
4450Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI,
4452 LibFunc Func) {
4456
4457
4458 if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) {
4460 return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr;
4461 }
4462
4463
4464
4465
4466
4467
4468 if (isFortifiedCallFoldable(CI, 2, std::nullopt, 1)) {
4469 if (Func == LibFunc_strcpy_chk)
4471 else
4473 }
4474
4475 if (OnlyLowerUnknownSize)
4476 return nullptr;
4477
4478
4480 if (Len)
4482 else
4483 return nullptr;
4484
4485 unsigned SizeTBits = TLI->getSizeTSize(*CI->getModule());
4487 Value *LenV = ConstantInt::get(SizeTTy, Len);
4489
4490
4491 if (Ret && Func == LibFunc_stpcpy_chk)
4492 return B.CreateInBoundsGEP(B.getInt8Ty(), Dst,
4493 ConstantInt::get(SizeTTy, Len - 1));
4495}
4496
4497Value *FortifiedLibCallSimplifier::optimizeStrLenChk(CallInst *CI,
4499 if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0))
4502 return nullptr;
4503}
4504
4505Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(CallInst *CI,
4507 LibFunc Func) {
4508 if (isFortifiedCallFoldable(CI, 3, 2)) {
4509 if (Func == LibFunc_strncpy_chk)
4513 else
4517 }
4518
4519 return nullptr;
4520}
4521
4522Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(CallInst *CI,
4524 if (isFortifiedCallFoldable(CI, 4, 3))
4528
4529 return nullptr;
4530}
4531
4532Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(CallInst *CI,
4534 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2)) {
4535 SmallVector<Value *, 8> VariadicArgs(drop_begin(CI->args(), 5));
4539 }
4540
4541 return nullptr;
4542}
4543
4544Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(CallInst *CI,
4546 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1)) {
4547 SmallVector<Value *, 8> VariadicArgs(drop_begin(CI->args(), 4));
4550 VariadicArgs, B, TLI));
4551 }
4552
4553 return nullptr;
4554}
4555
4556Value *FortifiedLibCallSimplifier::optimizeStrCatChk(CallInst *CI,
4558 if (isFortifiedCallFoldable(CI, 2))
4561
4562 return nullptr;
4563}
4564
4565Value *FortifiedLibCallSimplifier::optimizeStrLCat(CallInst *CI,
4567 if (isFortifiedCallFoldable(CI, 3))
4571
4572 return nullptr;
4573}
4574
4575Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(CallInst *CI,
4577 if (isFortifiedCallFoldable(CI, 3))
4581
4582 return nullptr;
4583}
4584
4585Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(CallInst *CI,
4587 if (isFortifiedCallFoldable(CI, 3))
4591
4592 return nullptr;
4593}
4594
4595Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(CallInst *CI,
4597 if (isFortifiedCallFoldable(CI, 3, 1, std::nullopt, 2))
4601
4602 return nullptr;
4603}
4604
4605Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(CallInst *CI,
4607 if (isFortifiedCallFoldable(CI, 2, std::nullopt, std::nullopt, 1))
4611
4612 return nullptr;
4613}
4614
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630 LibFunc Func;
4633
4636
4638 Builder.setDefaultOperandBundles(OpBundles);
4639
4640
4641
4642 if (!TLI->getLibFunc(*Callee, Func))
4643 return nullptr;
4644
4645
4647 return nullptr;
4648
4649 switch (Func) {
4650 case LibFunc_memcpy_chk:
4651 return optimizeMemCpyChk(CI, Builder);
4652 case LibFunc_mempcpy_chk:
4653 return optimizeMemPCpyChk(CI, Builder);
4654 case LibFunc_memmove_chk:
4655 return optimizeMemMoveChk(CI, Builder);
4656 case LibFunc_memset_chk:
4657 return optimizeMemSetChk(CI, Builder);
4658 case LibFunc_stpcpy_chk:
4659 case LibFunc_strcpy_chk:
4660 return optimizeStrpCpyChk(CI, Builder, Func);
4661 case LibFunc_strlen_chk:
4662 return optimizeStrLenChk(CI, Builder);
4663 case LibFunc_stpncpy_chk:
4664 case LibFunc_strncpy_chk:
4665 return optimizeStrpNCpyChk(CI, Builder, Func);
4666 case LibFunc_memccpy_chk:
4667 return optimizeMemCCpyChk(CI, Builder);
4668 case LibFunc_snprintf_chk:
4669 return optimizeSNPrintfChk(CI, Builder);
4670 case LibFunc_sprintf_chk:
4671 return optimizeSPrintfChk(CI, Builder);
4672 case LibFunc_strcat_chk:
4673 return optimizeStrCatChk(CI, Builder);
4674 case LibFunc_strlcat_chk:
4675 return optimizeStrLCat(CI, Builder);
4676 case LibFunc_strncat_chk:
4677 return optimizeStrNCatChk(CI, Builder);
4678 case LibFunc_strlcpy_chk:
4679 return optimizeStrLCpyChk(CI, Builder);
4680 case LibFunc_vsnprintf_chk:
4681 return optimizeVSNPrintfChk(CI, Builder);
4682 case LibFunc_vsprintf_chk:
4683 return optimizeVSPrintfChk(CI, Builder);
4684 default:
4685 break;
4686 }
4687 return nullptr;
4688}
4689
4692 : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
static llvm::Error parse(DataExtractor &Data, uint64_t BaseAddr, LineEntryCallback const &Callback)
Machine Check Debug Module
uint64_t IntrinsicInst * II
static bool isBinary(MachineInstr &MI)
const SmallVectorImpl< MachineOperand > & Cond
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With)
Return true if it is only used in equality comparisons with With.
Definition SimplifyLibCalls.cpp:118
static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef< unsigned > ArgNos, Value *Size, const DataLayout &DL)
Definition SimplifyLibCalls.cpp:323
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)
Definition SimplifyLibCalls.cpp:2967
static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len, const DataLayout &DL)
Definition SimplifyLibCalls.cpp:262
static Value * mergeAttributesAndFlags(CallInst *NewCI, const CallInst &Old)
Definition SimplifyLibCalls.cpp:352
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.
Definition SimplifyLibCalls.cpp:2030
static bool ignoreCallingConv(LibFunc Func)
Definition SimplifyLibCalls.cpp:112
static cl::opt< bool > OptimizeExistingHotColdNew("optimize-existing-hot-cold-new", cl::Hidden, cl::init(false), cl::desc("Enable optimization of existing hot/cold operator new library calls"))
static void annotateDereferenceableBytes(CallInst *CI, ArrayRef< unsigned > ArgNos, uint64_t DereferenceableBytes)
Definition SimplifyLibCalls.cpp:276
static bool isReportingError(Function *Callee, CallInst *CI, int StreamArg)
Definition SimplifyLibCalls.cpp:3339
static Value * optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, bool isBinary, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float functions.
Definition SimplifyLibCalls.cpp:1964
static Value * optimizeSymmetricCall(CallInst *CI, bool IsEven, IRBuilderBase &B)
Definition SimplifyLibCalls.cpp:3023
static Value * getSqrtCall(Value *V, AttributeList Attrs, bool NoErrno, Module *M, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Definition SimplifyLibCalls.cpp:2282
static Value * valueHasFloatPrecision(Value *Val)
Return a variant of Val with float type.
Definition SimplifyLibCalls.cpp:1946
static Value * optimizeMemCmpConstantSize(CallInst *CI, Value *LHS, Value *RHS, uint64_t Len, IRBuilderBase &B, const DataLayout &DL)
Definition SimplifyLibCalls.cpp:1542
static Value * createPowWithIntegerExponent(Value *Base, Value *Expo, Module *M, IRBuilderBase &B)
Definition SimplifyLibCalls.cpp:2353
static Value * convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, uint64_t Base, bool AsSigned, IRBuilderBase &B)
Definition SimplifyLibCalls.cpp:148
static Value * memChrToCharCompare(CallInst *CI, Value *NBytes, IRBuilderBase &B, const DataLayout &DL)
Definition SimplifyLibCalls.cpp:461
static Value * copyFlags(const CallInst &Old, Value *New)
Definition SimplifyLibCalls.cpp:344
static StringRef substr(StringRef Str, uint64_t Len)
Definition SimplifyLibCalls.cpp:366
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)
Definition SimplifyLibCalls.cpp:2960
static Value * optimizeNaN(CallInst *CI)
Constant folding nan/nanf/nanl.
Definition SimplifyLibCalls.cpp:4021
static bool isOnlyUsedInComparisonWithZero(Value *V)
Definition SimplifyLibCalls.cpp:250
static Value * replaceUnaryCall(CallInst *CI, IRBuilderBase &B, Intrinsic::ID IID)
Definition SimplifyLibCalls.cpp:1934
static bool callHasFloatingPointArgument(const CallInst *CI)
Definition SimplifyLibCalls.cpp:129
static Value * optimizeUnaryDoubleFP(CallInst *CI, IRBuilderBase &B, const TargetLibraryInfo *TLI, bool isPrecise=false)
Shrink double -> float for unary functions.
Definition SimplifyLibCalls.cpp:2023
static bool callHasFP128Argument(const CallInst *CI)
Definition SimplifyLibCalls.cpp:135
static cl::opt< bool > OptimizeNoBuiltinHotColdNew("optimize-nobuiltin-hot-cold-new-new", cl::Hidden, cl::init(false), cl::desc("Enable transformation of nobuiltin operator new library calls"))
static cl::opt< unsigned, false, HotColdHintParser > AmbiguousNewHintValue("ambiguous-new-hint-value", cl::Hidden, cl::init(222), cl::desc("Value to pass to hot/cold operator new for ambiguous allocation"))
static void annotateNonNullNoUndefBasedOnAccess(CallInst *CI, ArrayRef< unsigned > ArgNos)
Definition SimplifyLibCalls.cpp:301
static Value * optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, Value *Size, bool StrNCmp, IRBuilderBase &B, const DataLayout &DL)
Definition SimplifyLibCalls.cpp:1500
static Value * getIntToFPVal(Value *I2F, IRBuilderBase &B, unsigned DstWidth)
Definition SimplifyLibCalls.cpp:2088
static cl::opt< bool > EnableUnsafeFPShrink("enable-double-float-shrink", cl::Hidden, cl::init(false), cl::desc("Enable unsafe double to float " "shrinking for math lib calls"))
static cl::opt< unsigned, false, HotColdHintParser > NotColdNewHintValue("notcold-new-hint-value", cl::Hidden, cl::init(128), cl::desc("Value to pass to hot/cold operator new for " "notcold (warm) allocation"))
This file defines the SmallString class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmTowardNegative
static constexpr roundingMode rmNearestTiesToEven
opStatus
IEEE-754R 7: Default exception handling.
opStatus divide(const APFloat &RHS, roundingMode RM)
bool isFiniteNonZero() const
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
opStatus subtract(const APFloat &RHS, roundingMode RM)
LLVM_ABI 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
LLVM_ABI float convertToFloat() const
Converts this APFloat to host float value.
opStatus remainder(const APFloat &RHS)
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
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 LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
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 removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove)
Removes the attributes from the given argument.
LLVM_ABI 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.
AttributeSet getParamAttributes(unsigned ArgNo) const
Return the param attributes for this call.
uint64_t getParamDereferenceableBytes(unsigned i) const
Extract the number of dereferenceable bytes for a call or parameter (0=unknown).
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
AttributeSet getRetAttributes() const
Return the return attributes for this call.
void setAttributes(AttributeList A)
Set the 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).
LLVM_ABI 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 attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
LLVM_ABI 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
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
@ 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.
LLVM_ABI uint64_t getElementAsInteger(uint64_t 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 LLVM_ABI Constant * getInfinity(Type *Ty, bool Negative=false)
static LLVM_ABI Constant * getQNaN(Type *Ty, bool Negative=false, APInt *Payload=nullptr)
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 ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
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 LLVM_ABI 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.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
void setNoSignedZeros(bool B=true)
static FastMathFlags getFast()
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize=false)
Definition SimplifyLibCalls.cpp:4690
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
Take the given call instruction and return a more optimal value to replace the instruction with or 0 ...
Definition SimplifyLibCalls.cpp:4615
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
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.
LLVM_ABI 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.
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI bool isFast() const LLVM_READONLY
Determine whether all fast-math-flags are set.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
LLVM_ABI bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Class to represent integer types.
static LLVM_ABI 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, DominatorTree *DT, DomConditionCache *DC, AssumptionCache *AC, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, function_ref< void(Instruction *, Value *)> Replacer=&replaceAllUsesWithDefault, function_ref< void(Instruction *)> Eraser=&eraseFromParentDefault)
Definition SimplifyLibCalls.cpp:4309
Value * optimizeCall(CallInst *CI, IRBuilderBase &B)
optimizeCall - Take the given call instruction and return a more optimal value to replace the instruc...
Definition SimplifyLibCalls.cpp:4174
An instruction for reading from memory.
Value * getPointerOperand()
A Module instance is used to store all the information related to an LLVM module.
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
Analysis providing profile information.
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.
static constexpr size_t npos
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.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static LLVM_ABI 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.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
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.
LLVM_ABI 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.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isStructTy() const
True if this is an instance of StructType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
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.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM_ABI const fltSemantics & getFltSemantics() const
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()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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.
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
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.
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
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'.
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
This namespace contains all of the command line option processing machinery.
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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.
FunctionAddr VTableAddr Value
LLVM_ABI 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.
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
LLVM_ABI 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.
constexpr uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
LLVM_ABI Value * emitPutChar(Value *Char, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the putchar function. This assumes that Char is an 'int'.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
LLVM_ABI bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI)
LLVM_ABI Value * emitHotColdNewAlignedNoThrow(Value *Num, Value *Align, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI Value * emitSPrintf(Value *Dest, Value *Fmt, ArrayRef< Value * > VariadicArgs, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the sprintf function.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
LLVM_ABI Value * emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcat function.
LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI Value * emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strncat function.
LLVM_ABI 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...
LLVM_ABI Value * emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsnprintf function.
auto dyn_cast_or_null(const Y &Val)
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.
LLVM_ABI 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.
LLVM_ABI Value * emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memcmp function.
LLVM_ABI 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.
bool isAlpha(char C)
Checks if character C is a valid letter as classified by "C" locale.
LLVM_ABI Value * emitFPutS(Value *Str, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputs function.
LLVM_ABI Value * emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strdup function to the builder, for the specified pointer.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI Value * emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the bcmp function.
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
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.
LLVM_ABI 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'.
LLVM_ABI FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, LibFunc TheLibFunc, FunctionType *T, AttributeList AttributeList)
Calls getOrInsertFunction() and then makes sure to add mandatory argument attributes.
LLVM_ABI 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.
LLVM_ABI Value * emitFPutC(Value *Char, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the fputc function.
LLVM_ABI 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.
LLVM_ABI Value * emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strcat function.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Value * emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the vsprintf function.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI Value * emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the fwrite function.
LLVM_ABI 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.
LLVM_ABI 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.
char toUpper(char x)
Returns the corresponding uppercase character if x is lowercase.
DWARFExpression::Operation Op
@ NearestTiesToEven
roundTiesToEven.
constexpr int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI Value * emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
LLVM_ABI Value * emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the malloc function.
LLVM_ABI Value * emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memchr function.
LLVM_ABI Value * emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
bool isSpace(char C)
Checks whether character C is whitespace in the "C" locale.
LLVM_ABI Value * emitPutS(Value *Str, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the puts function. This assumes that Str is some pointer.
LLVM_ABI Value * emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the memccpy function.
LLVM_ABI Value * emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
LLVM_ABI Value * emitHotColdNew(Value *Num, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
Emit a call to the hot/cold operator new function.
LLVM_ABI 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...
LLVM_ABI Value * emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, const TargetLibraryInfo *TLI)
Emit a call to the strlcpy function.
LLVM_ABI Value * emitHotColdSizeReturningNewAligned(Value *Num, Value *Align, IRBuilderBase &B, const TargetLibraryInfo *TLI, LibFunc NewFunc, uint8_t HotCold)
LLVM_ABI 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.
LLVM_ABI Value * emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the mempcpy function.
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
static constexpr FPClassTest OrderedLessThanZeroMask
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a zero.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...