llvm.org GIT mirror llvm / 8964612
[SimplifyLibCalls] Fold more fortified functions into non-fortified variants When the object size argument is -1, no checking can be done, so calling the _chk variant is unnecessary. We already did this for a bunch of these functions. rdar://50797197 Differential revision: https://reviews.llvm.org/D62358 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362272 91177308-0d34-0410-b5e6-96231b3b80d8 Erik Pilkington 2 months ago
8 changed file(s) with 580 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
328328 /// long double __logl_finite(long double x);
329329 TLI_DEFINE_ENUM_INTERNAL(logl_finite)
330330 TLI_DEFINE_STRING_INTERNAL("__logl_finite")
331 /// void *__memccpy_chk(void *dst, const void *src, int c, size_t n,
332 /// size_t dstsize)
333 TLI_DEFINE_ENUM_INTERNAL(memccpy_chk)
334 TLI_DEFINE_STRING_INTERNAL("__memccpy_chk")
331335 /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
332336 TLI_DEFINE_ENUM_INTERNAL(memcpy_chk)
333337 TLI_DEFINE_STRING_INTERNAL("__memcpy_chk")
380384 /// int __small_sprintf(char *str, const char *format, ...);
381385 TLI_DEFINE_ENUM_INTERNAL(small_sprintf)
382386 TLI_DEFINE_STRING_INTERNAL("__small_sprintf")
387 /// int __snprintf_chk(char *s, size_t n, int flags, size_t slen,
388 /// const char *format, ...);
389 TLI_DEFINE_ENUM_INTERNAL(snprintf_chk)
390 TLI_DEFINE_STRING_INTERNAL("__snprintf_chk")
391 /// int __sprintf_chk(char *str, int flags, size_t str_len,
392 /// const char *format, ...);
393 TLI_DEFINE_ENUM_INTERNAL(sprintf_chk)
394 TLI_DEFINE_STRING_INTERNAL("__sprintf_chk")
383395 /// double __sqrt_finite(double x);
384396 TLI_DEFINE_ENUM_INTERNAL(sqrt_finite)
385397 TLI_DEFINE_STRING_INTERNAL("__sqrt_finite")
395407 /// char *__stpncpy_chk(char *s1, const char *s2, size_t n, size_t s1size);
396408 TLI_DEFINE_ENUM_INTERNAL(stpncpy_chk)
397409 TLI_DEFINE_STRING_INTERNAL("__stpncpy_chk")
410 /// char *__strcat_chk(char *s1, const char *s2, size_t s1size);
411 TLI_DEFINE_ENUM_INTERNAL(strcat_chk)
412 TLI_DEFINE_STRING_INTERNAL("__strcat_chk")
398413 /// char *__strcpy_chk(char *s1, const char *s2, size_t s1size);
399414 TLI_DEFINE_ENUM_INTERNAL(strcpy_chk)
400415 TLI_DEFINE_STRING_INTERNAL("__strcpy_chk")
401416 /// char * __strdup(const char *s);
402417 TLI_DEFINE_ENUM_INTERNAL(dunder_strdup)
403418 TLI_DEFINE_STRING_INTERNAL("__strdup")
419 /// size_t __strlcat_chk(char *dst, const char *src, size_t size,
420 /// size_t dstsize);
421 TLI_DEFINE_ENUM_INTERNAL(strlcat_chk)
422 TLI_DEFINE_STRING_INTERNAL("__strlcat_chk")
423 /// size_t __strlcpy_chk(char *dst, const char *src, size_t size,
424 /// size_t dstsize);
425 TLI_DEFINE_ENUM_INTERNAL(strlcpy_chk)
426 TLI_DEFINE_STRING_INTERNAL("__strlcpy_chk")
427 /// char *strncat_chk(char *s1, const char *s2, size_t n, size_t s1size);
428 TLI_DEFINE_ENUM_INTERNAL(strncat_chk)
429 TLI_DEFINE_STRING_INTERNAL("__strncat_chk")
404430 /// char *__strncpy_chk(char *s1, const char *s2, size_t n, size_t s1size);
405431 TLI_DEFINE_ENUM_INTERNAL(strncpy_chk)
406432 TLI_DEFINE_STRING_INTERNAL("__strncpy_chk")
410436 /// char * __strtok_r(char *s, const char *delim, char **save_ptr);
411437 TLI_DEFINE_ENUM_INTERNAL(dunder_strtok_r)
412438 TLI_DEFINE_STRING_INTERNAL("__strtok_r")
439 /// int __vsnprintf_chk(char *s, size_t n, int flags, size_t slen,
440 /// const char *format, va_list ap);
441 TLI_DEFINE_ENUM_INTERNAL(vsnprintf_chk)
442 TLI_DEFINE_STRING_INTERNAL("__vsnprintf_chk")
443 /// int __vsprintf_chk(char *s, int flags, size_t slen, const char *format,
444 /// va_list ap);
445 TLI_DEFINE_ENUM_INTERNAL(vsprintf_chk)
446 TLI_DEFINE_STRING_INTERNAL("__vsprintf_chk")
413447 /// int abs(int j);
414448 TLI_DEFINE_ENUM_INTERNAL(abs)
415449 TLI_DEFINE_STRING_INTERNAL("abs")
11991233 /// char *strdup(const char *s1);
12001234 TLI_DEFINE_ENUM_INTERNAL(strdup)
12011235 TLI_DEFINE_STRING_INTERNAL("strdup")
1236 /// size_t strlcat(char *dst, const char *src, size_t size);
1237 TLI_DEFINE_ENUM_INTERNAL(strlcat)
1238 TLI_DEFINE_STRING_INTERNAL("strlcat")
1239 /// size_t strlcpy(char *dst, const char *src, size_t size);
1240 TLI_DEFINE_ENUM_INTERNAL(strlcpy)
1241 TLI_DEFINE_STRING_INTERNAL("strlcpy")
12021242 /// size_t strlen(const char *s);
12031243 TLI_DEFINE_ENUM_INTERNAL(strlen)
12041244 TLI_DEFINE_STRING_INTERNAL("strlen")
105105 Value *emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
106106 const DataLayout &DL, const TargetLibraryInfo *TLI);
107107
108 /// Emit a call to the memccpy function.
109 Value *emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
110 IRBuilder<> &B, const TargetLibraryInfo *TLI);
111
112 /// Emit a call to the snprintf function.
113 Value *emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
114 ArrayRef Args, IRBuilder<> &B,
115 const TargetLibraryInfo *TLI);
116
117 /// Emit a call to the sprintf function.
118 Value *emitSPrintf(Value *Dest, Value *Fmt, ArrayRef VariadicArgs,
119 IRBuilder<> &B, const TargetLibraryInfo *TLI);
120
121 /// Emit a call to the strcat function.
122 Value *emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
123 const TargetLibraryInfo *TLI);
124
125 /// Emit a call to the strlcpy function.
126 Value *emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
127 const TargetLibraryInfo *TLI);
128
129 /// Emit a call to the strlcat function.
130 Value *emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
131 const TargetLibraryInfo *TLI);
132
133 /// Emit a call to the strncat function.
134 Value *emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
135 const TargetLibraryInfo *TLI);
136
137 /// Emit a call to the vsnprintf function.
138 Value *emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
139 IRBuilder<> &B, const TargetLibraryInfo *TLI);
140
141 /// Emit a call to the vsprintf function.
142 Value *emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilder<> &B,
143 const TargetLibraryInfo *TLI);
144
108145 /// Emit a call to the unary function named 'Name' (e.g. 'floor'). This
109146 /// function is known to take a single of type matching 'Op' and returns one
110147 /// value with the same type. If 'Op' is a long double, 'l' is added as the
5656 Value *optimizeMemMoveChk(CallInst *CI, IRBuilder<> &B);
5757 Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B);
5858
59 // Str/Stp cpy are similar enough to be handled in the same functions.
59 /// Str/Stp cpy are similar enough to be handled in the same functions.
6060 Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func);
6161 Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func);
62 Value *optimizeMemCCpyChk(CallInst *CI, IRBuilder<> &B);
63 Value *optimizeSNPrintfChk(CallInst *CI, IRBuilder<> &B);
64 Value *optimizeSPrintfChk(CallInst *CI,IRBuilder<> &B);
65 Value *optimizeStrCatChk(CallInst *CI, IRBuilder<> &B);
66 Value *optimizeStrLCat(CallInst *CI, IRBuilder<> &B);
67 Value *optimizeStrNCatChk(CallInst *CI, IRBuilder<> &B);
68 Value *optimizeStrLCpyChk(CallInst *CI, IRBuilder<> &B);
69 Value *optimizeVSNPrintfChk(CallInst *CI, IRBuilder<> &B);
70 Value *optimizeVSPrintfChk(CallInst *CI, IRBuilder<> &B);
6271
6372 /// Checks whether the call \p CI to a fortified libcall is foldable
6473 /// to the non-fortified version.
74 ///
75 /// \param CI the call to the fortified libcall.
76 ///
77 /// \param ObjSizeOp the index of the object size parameter of this chk
78 /// function. Not optional since this is mandatory.
79 ///
80 /// \param SizeOp optionally set to the parameter index of an explicit buffer
81 /// size argument. For instance, set to '2' for __strncpy_chk.
82 ///
83 /// \param StrOp optionally set to the parameter index of the source string
84 /// parameter to strcpy-like functions, where only the strlen of the source
85 /// will be writtin into the destination.
86 ///
87 /// \param FlagsOp optionally set to the parameter index of a 'flags'
88 /// parameter. These are used by an implementation to opt-into stricter
89 /// checking.
6590 bool isFortifiedCallFoldable(CallInst *CI, unsigned ObjSizeOp,
66 unsigned SizeOp, bool isString);
91 Optional SizeOp = None,
92 Optional StrOp = None,
93 Optional FlagsOp = None);
6794 };
6895
6996 /// LibCallSimplifier - This class implements a collection of optimizations
690690 return ((NumParams == 2 || NumParams == 3) &&
691691 FTy.getParamType(0)->isPointerTy() &&
692692 FTy.getParamType(1)->isPointerTy());
693 case LibFunc_strcat_chk:
694 --NumParams;
695 if (!IsSizeTTy(FTy.getParamType(NumParams)))
696 return false;
697 LLVM_FALLTHROUGH;
693698 case LibFunc_strcat:
694699 return (NumParams == 2 && FTy.getReturnType()->isPointerTy() &&
695700 FTy.getParamType(0) == FTy.getReturnType() &&
696701 FTy.getParamType(1) == FTy.getReturnType());
697702
703 case LibFunc_strncat_chk:
704 --NumParams;
705 if (!IsSizeTTy(FTy.getParamType(NumParams)))
706 return false;
707 LLVM_FALLTHROUGH;
698708 case LibFunc_strncat:
699709 return (NumParams == 3 && FTy.getReturnType()->isPointerTy() &&
700710 FTy.getParamType(0) == FTy.getReturnType() &&
712722 return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) &&
713723 FTy.getParamType(0) == FTy.getParamType(1) &&
714724 FTy.getParamType(0) == PCharTy);
725
726 case LibFunc_strlcat_chk:
727 case LibFunc_strlcpy_chk:
728 --NumParams;
729 if (!IsSizeTTy(FTy.getParamType(NumParams)))
730 return false;
731 LLVM_FALLTHROUGH;
732 case LibFunc_strlcat:
733 case LibFunc_strlcpy:
734 return NumParams == 3 && IsSizeTTy(FTy.getReturnType()) &&
735 FTy.getParamType(0)->isPointerTy() &&
736 FTy.getParamType(1)->isPointerTy() &&
737 IsSizeTTy(FTy.getParamType(2));
715738
716739 case LibFunc_strncpy_chk:
717740 case LibFunc_stpncpy_chk:
783806 return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() &&
784807 FTy.getParamType(1)->isPointerTy() &&
785808 FTy.getReturnType()->isIntegerTy(32));
809
810 case LibFunc_sprintf_chk:
811 return NumParams == 4 && FTy.getParamType(0)->isPointerTy() &&
812 FTy.getParamType(1)->isIntegerTy(32) &&
813 IsSizeTTy(FTy.getParamType(2)) &&
814 FTy.getParamType(3)->isPointerTy() &&
815 FTy.getReturnType()->isIntegerTy(32);
816
786817 case LibFunc_snprintf:
787818 return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() &&
788819 FTy.getParamType(2)->isPointerTy() &&
789820 FTy.getReturnType()->isIntegerTy(32));
821
822 case LibFunc_snprintf_chk:
823 return NumParams == 5 && FTy.getParamType(0)->isPointerTy() &&
824 IsSizeTTy(FTy.getParamType(1)) &&
825 FTy.getParamType(2)->isIntegerTy(32) &&
826 IsSizeTTy(FTy.getParamType(3)) &&
827 FTy.getParamType(4)->isPointerTy() &&
828 FTy.getReturnType()->isIntegerTy(32);
829
790830 case LibFunc_setitimer:
791831 return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() &&
792832 FTy.getParamType(2)->isPointerTy());
835875 FTy.getParamType(1)->isIntegerTy() &&
836876 IsSizeTTy(FTy.getParamType(2)));
837877
878 case LibFunc_memccpy_chk:
879 --NumParams;
880 if (!IsSizeTTy(FTy.getParamType(NumParams)))
881 return false;
882 LLVM_FALLTHROUGH;
838883 case LibFunc_memccpy:
839884 return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy());
840885 case LibFunc_memalign:
10031048 case LibFunc_vsprintf:
10041049 return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() &&
10051050 FTy.getParamType(1)->isPointerTy());
1051 case LibFunc_vsprintf_chk:
1052 return NumParams == 5 && FTy.getParamType(0)->isPointerTy() &&
1053 FTy.getParamType(1)->isIntegerTy(32) &&
1054 IsSizeTTy(FTy.getParamType(2)) && FTy.getParamType(3)->isPointerTy();
10061055 case LibFunc_vsnprintf:
10071056 return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() &&
10081057 FTy.getParamType(2)->isPointerTy());
1058 case LibFunc_vsnprintf_chk:
1059 return NumParams == 6 && FTy.getParamType(0)->isPointerTy() &&
1060 FTy.getParamType(2)->isIntegerTy(32) &&
1061 IsSizeTTy(FTy.getParamType(3)) && FTy.getParamType(4)->isPointerTy();
10091062 case LibFunc_open:
10101063 return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy());
10111064 case LibFunc_opendir:
911911 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
912912 }
913913
914 Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
915 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
916 return emitLibCall(
917 LibFunc_memccpy, B.getInt8PtrTy(),
918 {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()},
919 {Ptr1, Ptr2, Val, Len}, B, TLI);
920 }
921
922 Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
923 ArrayRef VariadicArgs, IRBuilder<> &B,
924 const TargetLibraryInfo *TLI) {
925 SmallVector Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)};
926 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
927 return emitLibCall(LibFunc_snprintf, B.getInt32Ty(),
928 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()},
929 Args, B, TLI, /*IsVaArgs=*/true);
930 }
931
932 Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
933 ArrayRef VariadicArgs, IRBuilder<> &B,
934 const TargetLibraryInfo *TLI) {
935 SmallVector Args{castToCStr(Dest, B), castToCStr(Fmt, B)};
936 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
937 return emitLibCall(LibFunc_sprintf, B.getInt32Ty(),
938 {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI,
939 /*IsVaArgs=*/true);
940 }
941
942 Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
943 const TargetLibraryInfo *TLI) {
944 return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(),
945 {B.getInt8PtrTy(), B.getInt8PtrTy()},
946 {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI);
947 }
948
949 Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
950 const TargetLibraryInfo *TLI) {
951 return emitLibCall(LibFunc_strlcpy, Size->getType(),
952 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
953 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
954 }
955
956 Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
957 const TargetLibraryInfo *TLI) {
958 return emitLibCall(LibFunc_strlcat, Size->getType(),
959 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
960 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
961 }
962
963 Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
964 const TargetLibraryInfo *TLI) {
965 return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(),
966 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
967 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
968 }
969
970 Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
971 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
972 return emitLibCall(
973 LibFunc_vsnprintf, B.getInt32Ty(),
974 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()},
975 {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI);
976 }
977
978 Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
979 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
980 return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(),
981 {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()},
982 {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI);
983 }
984
914985 /// Append a suffix to the function name according to the type of 'Op'.
915986 static void appendTypeSuffix(Value *Op, StringRef &Name,
916987 SmallString<20> &NameBuffer) {
28242824 // Fortified Library Call Optimizations
28252825 //===----------------------------------------------------------------------===//
28262826
2827 bool FortifiedLibCallSimplifier::isFortifiedCallFoldable(CallInst *CI,
2828 unsigned ObjSizeOp,
2829 unsigned SizeOp,
2830 bool isString) {
2831 if (CI->getArgOperand(ObjSizeOp) == CI->getArgOperand(SizeOp))
2827 bool
2828 FortifiedLibCallSimplifier::isFortifiedCallFoldable(CallInst *CI,
2829 unsigned ObjSizeOp,
2830 Optional SizeOp,
2831 Optional StrOp,
2832 Optional FlagOp) {
2833 // If this function takes a flag argument, the implementation may use it to
2834 // perform extra checks. Don't fold into the non-checking variant.
2835 if (FlagOp) {
2836 ConstantInt *Flag = dyn_cast(CI->getArgOperand(*FlagOp));
2837 if (!Flag || !Flag->isZero())
2838 return false;
2839 }
2840
2841 if (SizeOp && CI->getArgOperand(ObjSizeOp) == CI->getArgOperand(*SizeOp))
28322842 return true;
2843
28332844 if (ConstantInt *ObjSizeCI =
28342845 dyn_cast(CI->getArgOperand(ObjSizeOp))) {
28352846 if (ObjSizeCI->isMinusOne())
28372848 // If the object size wasn't -1 (unknown), bail out if we were asked to.
28382849 if (OnlyLowerUnknownSize)
28392850 return false;
2840 if (isString) {
2841 uint64_t Len = GetStringLength(CI->getArgOperand(SizeOp));
2851 if (StrOp) {
2852 uint64_t Len = GetStringLength(CI->getArgOperand(*StrOp));
28422853 // If the length is 0 we don't know how long it is and so we can't
28432854 // remove the check.
28442855 if (Len == 0)
28452856 return false;
28462857 return ObjSizeCI->getZExtValue() >= Len;
28472858 }
2848 if (ConstantInt *SizeCI = dyn_cast(CI->getArgOperand(SizeOp)))
2849 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
2859
2860 if (SizeOp) {
2861 if (ConstantInt *SizeCI =
2862 dyn_cast(CI->getArgOperand(*SizeOp)))
2863 return ObjSizeCI->getZExtValue() >= SizeCI->getZExtValue();
2864 }
28502865 }
28512866 return false;
28522867 }
28532868
28542869 Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(CallInst *CI,
28552870 IRBuilder<> &B) {
2856 if (isFortifiedCallFoldable(CI, 3, 2, false)) {
2871 if (isFortifiedCallFoldable(CI, 3, 2)) {
28572872 B.CreateMemCpy(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1,
28582873 CI->getArgOperand(2));
28592874 return CI->getArgOperand(0);
28632878
28642879 Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI,
28652880 IRBuilder<> &B) {
2866 if (isFortifiedCallFoldable(CI, 3, 2, false)) {
2881 if (isFortifiedCallFoldable(CI, 3, 2)) {
28672882 B.CreateMemMove(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1,
28682883 CI->getArgOperand(2));
28692884 return CI->getArgOperand(0);
28752890 IRBuilder<> &B) {
28762891 // TODO: Try foldMallocMemset() here.
28772892
2878 if (isFortifiedCallFoldable(CI, 3, 2, false)) {
2893 if (isFortifiedCallFoldable(CI, 3, 2)) {
28792894 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
28802895 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
28812896 return CI->getArgOperand(0);
29012916 // st[rp]cpy_chk call which may fail at runtime if the size is too long.
29022917 // TODO: It might be nice to get a maximum length out of the possible
29032918 // string lengths for varying.
2904 if (isFortifiedCallFoldable(CI, 2, 1, true)) {
2919 if (isFortifiedCallFoldable(CI, 2, None, 1)) {
29052920 if (Func == LibFunc_strcpy_chk)
29062921 return emitStrCpy(Dst, Src, B, TLI);
29072922 else
29292944 Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(CallInst *CI,
29302945 IRBuilder<> &B,
29312946 LibFunc Func) {
2932 if (isFortifiedCallFoldable(CI, 3, 2, false)) {
2947 if (isFortifiedCallFoldable(CI, 3, 2)) {
29332948 if (Func == LibFunc_strncpy_chk)
29342949 return emitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
2935 CI->getArgOperand(2), B, TLI);
2950 CI->getArgOperand(2), B, TLI);
29362951 else
29372952 return emitStpNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
29382953 CI->getArgOperand(2), B, TLI);
29392954 }
2955
2956 return nullptr;
2957 }
2958
2959 Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(CallInst *CI,
2960 IRBuilder<> &B) {
2961 if (isFortifiedCallFoldable(CI, 4, 3))
2962 return emitMemCCpy(CI->getArgOperand(0), CI->getArgOperand(1),
2963 CI->getArgOperand(2), CI->getArgOperand(3), B, TLI);
2964
2965 return nullptr;
2966 }
2967
2968 Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(CallInst *CI,
2969 IRBuilder<> &B) {
2970 if (isFortifiedCallFoldable(CI, 3, 1, None, 2)) {
2971 SmallVector VariadicArgs(CI->arg_begin() + 5, CI->arg_end());
2972 return emitSNPrintf(CI->getArgOperand(0), CI->getArgOperand(1),
2973 CI->getArgOperand(4), VariadicArgs, B, TLI);
2974 }
2975
2976 return nullptr;
2977 }
2978
2979 Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(CallInst *CI,
2980 IRBuilder<> &B) {
2981 if (isFortifiedCallFoldable(CI, 2, None, None, 1)) {
2982 SmallVector VariadicArgs(CI->arg_begin() + 4, CI->arg_end());
2983 return emitSPrintf(CI->getArgOperand(0), CI->getArgOperand(3), VariadicArgs,
2984 B, TLI);
2985 }
2986
2987 return nullptr;
2988 }
2989
2990 Value *FortifiedLibCallSimplifier::optimizeStrCatChk(CallInst *CI,
2991 IRBuilder<> &B) {
2992 if (isFortifiedCallFoldable(CI, 2))
2993 return emitStrCat(CI->getArgOperand(0), CI->getArgOperand(1), B, TLI);
2994
2995 return nullptr;
2996 }
2997
2998 Value *FortifiedLibCallSimplifier::optimizeStrLCat(CallInst *CI,
2999 IRBuilder<> &B) {
3000 if (isFortifiedCallFoldable(CI, 3))
3001 return emitStrLCat(CI->getArgOperand(0), CI->getArgOperand(1),
3002 CI->getArgOperand(2), B, TLI);
3003
3004 return nullptr;
3005 }
3006
3007 Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(CallInst *CI,
3008 IRBuilder<> &B) {
3009 if (isFortifiedCallFoldable(CI, 3))
3010 return emitStrNCat(CI->getArgOperand(0), CI->getArgOperand(1),
3011 CI->getArgOperand(2), B, TLI);
3012
3013 return nullptr;
3014 }
3015
3016 Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(CallInst *CI,
3017 IRBuilder<> &B) {
3018 if (isFortifiedCallFoldable(CI, 3))
3019 return emitStrLCpy(CI->getArgOperand(0), CI->getArgOperand(1),
3020 CI->getArgOperand(2), B, TLI);
3021
3022 return nullptr;
3023 }
3024
3025 Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(CallInst *CI,
3026 IRBuilder<> &B) {
3027 if (isFortifiedCallFoldable(CI, 3, 1, None, 2))
3028 return emitVSNPrintf(CI->getArgOperand(0), CI->getArgOperand(1),
3029 CI->getArgOperand(4), CI->getArgOperand(5), B, TLI);
3030
3031 return nullptr;
3032 }
3033
3034 Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(CallInst *CI,
3035 IRBuilder<> &B) {
3036 if (isFortifiedCallFoldable(CI, 2, None, None, 1))
3037 return emitVSPrintf(CI->getArgOperand(0), CI->getArgOperand(3),
3038 CI->getArgOperand(4), B, TLI);
29403039
29413040 return nullptr;
29423041 }
29853084 case LibFunc_stpncpy_chk:
29863085 case LibFunc_strncpy_chk:
29873086 return optimizeStrpNCpyChk(CI, Builder, Func);
3087 case LibFunc_memccpy_chk:
3088 return optimizeMemCCpyChk(CI, Builder);
3089 case LibFunc_snprintf_chk:
3090 return optimizeSNPrintfChk(CI, Builder);
3091 case LibFunc_sprintf_chk:
3092 return optimizeSPrintfChk(CI, Builder);
3093 case LibFunc_strcat_chk:
3094 return optimizeStrCatChk(CI, Builder);
3095 case LibFunc_strlcat_chk:
3096 return optimizeStrLCat(CI, Builder);
3097 case LibFunc_strncat_chk:
3098 return optimizeStrNCatChk(CI, Builder);
3099 case LibFunc_strlcpy_chk:
3100 return optimizeStrLCpyChk(CI, Builder);
3101 case LibFunc_vsnprintf_chk:
3102 return optimizeVSNPrintfChk(CI, Builder);
3103 case LibFunc_vsprintf_chk:
3104 return optimizeVSPrintfChk(CI, Builder);
29883105 default:
29893106 break;
29903107 }
0 ; RUN: opt < %s -instcombine -S | FileCheck %s --dump-input-on-failure
1
2 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
3
4 @a = common global [60 x i8] zeroinitializer, align 1
5 @b = common global [60 x i8] zeroinitializer, align 1
6 @.str = private constant [12 x i8] c"abcdefghijk\00"
7
8 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
9
10 define i8* @test_memccpy() {
11 ; CHECK-LABEL: define i8* @test_memccpy
12 ; CHECK-NEXT: call i8* @memccpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i32 0, i64 60)
13 ; CHECK-NEXT: ret i8*
14 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
15 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
16 %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 -1)
17 ret i8* %ret
18 }
19
20 define i8* @test_not_memccpy() {
21 ; CHECK-LABEL: define i8* @test_not_memccpy
22 ; CHECK-NEXT: call i8* @__memccpy_chk
23 ; CHECK-NEXT: ret i8*
24 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
25 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
26 %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 59)
27 ret i8* %ret
28 }
29
30 define i32 @test_snprintf() {
31 ; CHECK-LABEL: define i32 @test_snprintf
32 ; CHECK-NEXT: call i32 (i8*, i64, i8*, ...) @snprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
33 ; CHECK-NEXT: ret i32
34 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
35 %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
36 %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 -1, i8* %fmt)
37 ret i32 %ret
38 }
39
40 define i32 @test_not_snprintf() {
41 ; CHECK-LABEL: define i32 @test_not_snprintf
42 ; CHECK-NEXT: call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk
43 ; CHECK-NEXT: call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk
44 ; CHECK-NEXT: ret i32
45 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
46 %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
47 %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 59, i8* %fmt)
48 %ign = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 1, i64 -1, i8* %fmt)
49 ret i32 %ret
50 }
51
52 define i32 @test_sprintf() {
53 ; CHECK-LABEL: define i32 @test_sprintf
54 ; CHECK-NEXT: call i32 (i8*, i8*, ...) @sprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
55 ; CHECK-NEXT: ret i32
56 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
57 %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
58 %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 -1, i8* %fmt)
59 ret i32 %ret
60 }
61
62 define i32 @test_not_sprintf() {
63 ; CHECK-LABEL: define i32 @test_not_sprintf
64 ; CHECK-NEXT: call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk
65 ; CHECK-NEXT: call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk
66 ; CHECK-NEXT: ret i32
67 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
68 %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
69 %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 59, i8* %fmt)
70 %ignored = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 1, i64 -1, i8* %fmt)
71 ret i32 %ret
72 }
73
74 define i8* @test_strcat() {
75 ; CHECK-LABEL: define i8* @test_strcat
76 ; CHECK-NEXT: call i8* @strcat(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
77 ; CHECK-NEXT: ret i8*
78 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
79 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
80 %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 -1)
81 ret i8* %ret
82 }
83
84 define i8* @test_not_strcat() {
85 ; CHECK-LABEL: define i8* @test_not_strcat
86 ; CHECK-NEXT: call i8* @__strcat_chk
87 ; CHECK-NEXT: ret i8*
88 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
89 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
90 %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 0)
91 ret i8* %ret
92 }
93
94 define i64 @test_strlcat() {
95 ; CHECK-LABEL: define i64 @test_strlcat
96 ; CHECK-NEXT: call i64 @strlcat(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
97 ; CHECK-NEXT: ret i64
98 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
99 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
100 %ret = call i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 -1)
101 ret i64 %ret
102 }
103
104 define i64 @test_not_strlcat() {
105 ; CHECK-LABEL: define i64 @test_not_strlcat
106 ; CHECK-NEXT: call i64 @__strlcat_chk
107 ; CHECK-NEXT: ret i64
108 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
109 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
110 %ret = call i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 0)
111 ret i64 %ret
112 }
113
114 define i8* @test_strncat() {
115 ; CHECK-LABEL: define i8* @test_strncat
116 ; CHECK-NEXT: call i8* @strncat(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
117 ; CHECK-NEXT: ret i8*
118 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
119 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
120 %ret = call i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 -1)
121 ret i8* %ret
122 }
123
124 define i8* @test_not_strncat() {
125 ; CHECK-LABEL: define i8* @test_not_strncat
126 ; CHECK-NEXT: call i8* @__strncat_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22, i64 3)
127 ; CHECK-NEXT: ret i8*
128 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
129 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
130 %ret = call i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 3)
131 ret i8* %ret
132 }
133
134 define i64 @test_strlcpy() {
135 ; CHECK-LABEL: define i64 @test_strlcpy
136 ; CHECK-NEXT: call i64 @strlcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
137 ; CHECK-NEXT: ret i64
138 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
139 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
140 %ret = call i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 -1)
141 ret i64 %ret
142 }
143
144 define i64 @test_not_strlcpy() {
145 ; CHECK-LABEL: define i64 @test_not_strlcpy
146 ; CHECK-NEXT: call i64 @__strlcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22, i64 2)
147 ; CHECK-NEXT: ret i64
148 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
149 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
150 %ret = call i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 2)
151 ret i64 %ret
152 }
153
154 define i32 @test_vsnprintf() {
155 ; CHECK-LABEL: define i32 @test_vsnprintf
156 ; CHECK-NEXT: call i32 @vsnprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
157 ; ret i32
158 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
159 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
160 %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null)
161 ret i32 %ret
162 }
163
164 define i32 @test_not_vsnprintf() {
165 ; CHECK-LABEL: define i32 @test_not_vsnprintf
166 ; CHECK-NEXT: call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
167 ; CHECK-NEXT: call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
168 ; ret i32
169 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
170 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
171 %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 3, i8* %src, %struct.__va_list_tag* null)
172 %ign = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 1, i64 -1, i8* %src, %struct.__va_list_tag* null)
173 ret i32 %ret
174 }
175
176 define i32 @test_vsprintf() {
177 ; CHECK-LABEL: define i32 @test_vsprintf
178 ; CHECK-NEXT: call i32 @vsprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
179 ; ret i32
180 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
181 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
182 %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null)
183 ret i32 %ret
184 }
185
186 define i32 @test_not_vsprintf() {
187 ; CHECK-LABEL: define i32 @test_not_vsprintf
188 ; CHECK-NEXT: call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
189 ; CHECK-NEXT: call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
190 ; ret i32
191 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
192 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
193 %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 3, i8* %src, %struct.__va_list_tag* null)
194 %ign = call i32 @__vsprintf_chk(i8* %dst, i32 1, i64 -1, i8* %src, %struct.__va_list_tag* null)
195 ret i32 %ret
196 }
197
198 declare i8* @__memccpy_chk(i8*, i8*, i32, i64, i64)
199 declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)
200 declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)
201 declare i8* @__strcat_chk(i8*, i8*, i64)
202 declare i64 @__strlcat_chk(i8*, i8*, i64, i64)
203 declare i8* @__strncat_chk(i8*, i8*, i64, i64)
204 declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)
205 declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct.__va_list_tag*)
206 declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct.__va_list_tag*)
312312 "declare i8* @strtok(i8*, i8*)\n"
313313 "declare i8* @strtok_r(i8*, i8*, i8**)\n"
314314 "declare i64 @strtol(i8*, i8**, i32)\n"
315 "declare i64 @strlcat(i8*, i8**, i64)\n"
316 "declare i64 @strlcpy(i8*, i8**, i64)\n"
315317 "declare x86_fp80 @strtold(i8*, i8**)\n"
316318 "declare i64 @strtoll(i8*, i8**, i32)\n"
317319 "declare i64 @strtoul(i8*, i8**, i32)\n"
466468 "declare i8* @__stpncpy_chk(i8*, i8*, i64, i64)\n"
467469 "declare i8* @__strcpy_chk(i8*, i8*, i64)\n"
468470 "declare i8* @__strncpy_chk(i8*, i8*, i64, i64)\n"
471 "declare i8* @__memccpy_chk(i8*, i8*, i32, i64)\n"
472 "declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)\n"
473 "declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)\n"
474 "declare i8* @__strcat_chk(i8*, i8*, i64)\n"
475 "declare i64 @__strlcat_chk(i8*, i8*, i64, i64)\n"
476 "declare i8* @__strncat_chk(i8*, i8*, i64, i64)\n"
477 "declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)\n"
478 "declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct*)\n"
479 "declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct*)\n"
469480
470481 "declare i8* @memalign(i64, i64)\n"
471482 "declare i8* @mempcpy(i8*, i8*, i64)\n"