BuildLibCalls.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements some functions that will create standard C libcalls.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/Transforms/Utils/BuildLibCalls.h"
  14. #include "llvm/Constants.h"
  15. #include "llvm/Function.h"
  16. #include "llvm/IRBuilder.h"
  17. #include "llvm/Intrinsics.h"
  18. #include "llvm/Intrinsics.h"
  19. #include "llvm/LLVMContext.h"
  20. #include "llvm/LLVMContext.h"
  21. #include "llvm/Module.h"
  22. #include "llvm/Type.h"
  23. #include "llvm/ADT/SmallString.h"
  24. #include "llvm/Target/TargetData.h"
  25. #include "llvm/Target/TargetLibraryInfo.h"
  26. using namespace llvm;
  27. /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
  28. Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
  29. return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
  30. }
  31. /// EmitStrLen - Emit a call to the strlen function to the builder, for the
  32. /// specified pointer. This always returns an integer value of size intptr_t.
  33. Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD) {
  34. Module *M = B.GetInsertBlock()->getParent()->getParent();
  35. AttributeWithIndex AWI[2];
  36. AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
  37. AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
  38. Attribute::NoUnwind);
  39. LLVMContext &Context = B.GetInsertBlock()->getContext();
  40. Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI),
  41. TD->getIntPtrType(Context),
  42. B.getInt8PtrTy(),
  43. NULL);
  44. CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
  45. if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
  46. CI->setCallingConv(F->getCallingConv());
  47. return CI;
  48. }
  49. /// EmitStrChr - Emit a call to the strchr function to the builder, for the
  50. /// specified pointer and character. Ptr is required to be some pointer type,
  51. /// and the return value has 'i8*' type.
  52. Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
  53. const TargetData *TD) {
  54. Module *M = B.GetInsertBlock()->getParent()->getParent();
  55. AttributeWithIndex AWI =
  56. AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
  57. Type *I8Ptr = B.getInt8PtrTy();
  58. Type *I32Ty = B.getInt32Ty();
  59. Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI),
  60. I8Ptr, I8Ptr, I32Ty, NULL);
  61. CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
  62. ConstantInt::get(I32Ty, C), "strchr");
  63. if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
  64. CI->setCallingConv(F->getCallingConv());
  65. return CI;
  66. }
  67. /// EmitStrNCmp - Emit a call to the strncmp function to the builder.
  68. Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
  69. IRBuilder<> &B, const TargetData *TD) {
  70. Module *M = B.GetInsertBlock()->getParent()->getParent();
  71. AttributeWithIndex AWI[3];
  72. AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
  73. AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
  74. AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
  75. Attribute::NoUnwind);
  76. LLVMContext &Context = B.GetInsertBlock()->getContext();
  77. Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI),
  78. B.getInt32Ty(),
  79. B.getInt8PtrTy(),
  80. B.getInt8PtrTy(),
  81. TD->getIntPtrType(Context), NULL);
  82. CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
  83. CastToCStr(Ptr2, B), Len, "strncmp");
  84. if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
  85. CI->setCallingConv(F->getCallingConv());
  86. return CI;
  87. }
  88. /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
  89. /// specified pointer arguments.
  90. Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
  91. const TargetData *TD, StringRef Name) {
  92. Module *M = B.GetInsertBlock()->getParent()->getParent();
  93. AttributeWithIndex AWI[2];
  94. AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
  95. AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  96. Type *I8Ptr = B.getInt8PtrTy();
  97. Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
  98. I8Ptr, I8Ptr, I8Ptr, NULL);
  99. CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
  100. Name);
  101. if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
  102. CI->setCallingConv(F->getCallingConv());
  103. return CI;
  104. }
  105. /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
  106. /// specified pointer arguments.
  107. Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
  108. IRBuilder<> &B, const TargetData *TD, StringRef Name) {
  109. Module *M = B.GetInsertBlock()->getParent()->getParent();
  110. AttributeWithIndex AWI[2];
  111. AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
  112. AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  113. Type *I8Ptr = B.getInt8PtrTy();
  114. Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
  115. I8Ptr, I8Ptr, I8Ptr,
  116. Len->getType(), NULL);
  117. CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
  118. Len, "strncpy");
  119. if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
  120. CI->setCallingConv(F->getCallingConv());
  121. return CI;
  122. }
  123. /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
  124. /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
  125. /// are pointers.
  126. Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
  127. IRBuilder<> &B, const TargetData *TD) {
  128. Module *M = B.GetInsertBlock()->getParent()->getParent();
  129. AttributeWithIndex AWI;
  130. AWI = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  131. LLVMContext &Context = B.GetInsertBlock()->getContext();
  132. Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
  133. AttrListPtr::get(AWI),
  134. B.getInt8PtrTy(),
  135. B.getInt8PtrTy(),
  136. B.getInt8PtrTy(),
  137. TD->getIntPtrType(Context),
  138. TD->getIntPtrType(Context), NULL);
  139. Dst = CastToCStr(Dst, B);
  140. Src = CastToCStr(Src, B);
  141. CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
  142. if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
  143. CI->setCallingConv(F->getCallingConv());
  144. return CI;
  145. }
  146. /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
  147. /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
  148. Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
  149. Value *Len, IRBuilder<> &B, const TargetData *TD) {
  150. Module *M = B.GetInsertBlock()->getParent()->getParent();
  151. AttributeWithIndex AWI;
  152. AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
  153. LLVMContext &Context = B.GetInsertBlock()->getContext();
  154. Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI),
  155. B.getInt8PtrTy(),
  156. B.getInt8PtrTy(),
  157. B.getInt32Ty(),
  158. TD->getIntPtrType(Context),
  159. NULL);
  160. CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
  161. if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
  162. CI->setCallingConv(F->getCallingConv());
  163. return CI;
  164. }
  165. /// EmitMemCmp - Emit a call to the memcmp function.
  166. Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
  167. Value *Len, IRBuilder<> &B, const TargetData *TD) {
  168. Module *M = B.GetInsertBlock()->getParent()->getParent();
  169. AttributeWithIndex AWI[3];
  170. AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
  171. AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
  172. AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
  173. Attribute::NoUnwind);
  174. LLVMContext &Context = B.GetInsertBlock()->getContext();
  175. Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI),
  176. B.getInt32Ty(),
  177. B.getInt8PtrTy(),
  178. B.getInt8PtrTy(),
  179. TD->getIntPtrType(Context), NULL);
  180. CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
  181. Len, "memcmp");
  182. if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
  183. CI->setCallingConv(F->getCallingConv());
  184. return CI;
  185. }
  186. /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
  187. /// 'floor'). This function is known to take a single of type matching 'Op' and
  188. /// returns one value with the same type. If 'Op' is a long double, 'l' is
  189. /// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
  190. Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
  191. const AttrListPtr &Attrs) {
  192. SmallString<20> NameBuffer;
  193. if (!Op->getType()->isDoubleTy()) {
  194. // If we need to add a suffix, copy into NameBuffer.
  195. NameBuffer += Name;
  196. if (Op->getType()->isFloatTy())
  197. NameBuffer += 'f'; // floorf
  198. else
  199. NameBuffer += 'l'; // floorl
  200. Name = NameBuffer;
  201. }
  202. Module *M = B.GetInsertBlock()->getParent()->getParent();
  203. Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
  204. Op->getType(), NULL);
  205. CallInst *CI = B.CreateCall(Callee, Op, Name);
  206. CI->setAttributes(Attrs);
  207. if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
  208. CI->setCallingConv(F->getCallingConv());
  209. return CI;
  210. }
  211. /// EmitPutChar - Emit a call to the putchar function. This assumes that Char
  212. /// is an integer.
  213. Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD) {
  214. Module *M = B.GetInsertBlock()->getParent()->getParent();
  215. Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
  216. B.getInt32Ty(), NULL);
  217. CallInst *CI = B.CreateCall(PutChar,
  218. B.CreateIntCast(Char,
  219. B.getInt32Ty(),
  220. /*isSigned*/true,
  221. "chari"),
  222. "putchar");
  223. if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
  224. CI->setCallingConv(F->getCallingConv());
  225. return CI;
  226. }
  227. /// EmitPutS - Emit a call to the puts function. This assumes that Str is
  228. /// some pointer.
  229. void llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD) {
  230. Module *M = B.GetInsertBlock()->getParent()->getParent();
  231. AttributeWithIndex AWI[2];
  232. AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
  233. AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  234. Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI),
  235. B.getInt32Ty(),
  236. B.getInt8PtrTy(),
  237. NULL);
  238. CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
  239. if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
  240. CI->setCallingConv(F->getCallingConv());
  241. }
  242. /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
  243. /// an integer and File is a pointer to FILE.
  244. void llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
  245. const TargetData *TD) {
  246. Module *M = B.GetInsertBlock()->getParent()->getParent();
  247. AttributeWithIndex AWI[2];
  248. AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
  249. AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  250. Constant *F;
  251. if (File->getType()->isPointerTy())
  252. F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI),
  253. B.getInt32Ty(),
  254. B.getInt32Ty(), File->getType(),
  255. NULL);
  256. else
  257. F = M->getOrInsertFunction("fputc",
  258. B.getInt32Ty(),
  259. B.getInt32Ty(),
  260. File->getType(), NULL);
  261. Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
  262. "chari");
  263. CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
  264. if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
  265. CI->setCallingConv(Fn->getCallingConv());
  266. }
  267. /// EmitFPutS - Emit a call to the puts function. Str is required to be a
  268. /// pointer and File is a pointer to FILE.
  269. void llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
  270. const TargetData *TD, const TargetLibraryInfo *TLI) {
  271. Module *M = B.GetInsertBlock()->getParent()->getParent();
  272. AttributeWithIndex AWI[3];
  273. AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
  274. AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
  275. AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  276. StringRef FPutsName = TLI->getName(LibFunc::fputs);
  277. Constant *F;
  278. if (File->getType()->isPointerTy())
  279. F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI),
  280. B.getInt32Ty(),
  281. B.getInt8PtrTy(),
  282. File->getType(), NULL);
  283. else
  284. F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
  285. B.getInt8PtrTy(),
  286. File->getType(), NULL);
  287. CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
  288. if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
  289. CI->setCallingConv(Fn->getCallingConv());
  290. }
  291. /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
  292. /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
  293. void llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
  294. IRBuilder<> &B, const TargetData *TD,
  295. const TargetLibraryInfo *TLI) {
  296. Module *M = B.GetInsertBlock()->getParent()->getParent();
  297. AttributeWithIndex AWI[3];
  298. AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
  299. AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
  300. AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
  301. LLVMContext &Context = B.GetInsertBlock()->getContext();
  302. StringRef FWriteName = TLI->getName(LibFunc::fwrite);
  303. Constant *F;
  304. if (File->getType()->isPointerTy())
  305. F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI),
  306. TD->getIntPtrType(Context),
  307. B.getInt8PtrTy(),
  308. TD->getIntPtrType(Context),
  309. TD->getIntPtrType(Context),
  310. File->getType(), NULL);
  311. else
  312. F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
  313. B.getInt8PtrTy(),
  314. TD->getIntPtrType(Context),
  315. TD->getIntPtrType(Context),
  316. File->getType(), NULL);
  317. CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
  318. ConstantInt::get(TD->getIntPtrType(Context), 1), File);
  319. if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
  320. CI->setCallingConv(Fn->getCallingConv());
  321. }
  322. SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
  323. bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD) {
  324. // We really need TargetData for later.
  325. if (!TD) return false;
  326. this->CI = CI;
  327. Function *Callee = CI->getCalledFunction();
  328. StringRef Name = Callee->getName();
  329. FunctionType *FT = Callee->getFunctionType();
  330. LLVMContext &Context = CI->getParent()->getContext();
  331. IRBuilder<> B(CI);
  332. if (Name == "__memcpy_chk") {
  333. // Check if this has the right signature.
  334. if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
  335. !FT->getParamType(0)->isPointerTy() ||
  336. !FT->getParamType(1)->isPointerTy() ||
  337. FT->getParamType(2) != TD->getIntPtrType(Context) ||
  338. FT->getParamType(3) != TD->getIntPtrType(Context))
  339. return false;
  340. if (isFoldable(3, 2, false)) {
  341. B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
  342. CI->getArgOperand(2), 1);
  343. replaceCall(CI->getArgOperand(0));
  344. return true;
  345. }
  346. return false;
  347. }
  348. // Should be similar to memcpy.
  349. if (Name == "__mempcpy_chk") {
  350. return false;
  351. }
  352. if (Name == "__memmove_chk") {
  353. // Check if this has the right signature.
  354. if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
  355. !FT->getParamType(0)->isPointerTy() ||
  356. !FT->getParamType(1)->isPointerTy() ||
  357. FT->getParamType(2) != TD->getIntPtrType(Context) ||
  358. FT->getParamType(3) != TD->getIntPtrType(Context))
  359. return false;
  360. if (isFoldable(3, 2, false)) {
  361. B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
  362. CI->getArgOperand(2), 1);
  363. replaceCall(CI->getArgOperand(0));
  364. return true;
  365. }
  366. return false;
  367. }
  368. if (Name == "__memset_chk") {
  369. // Check if this has the right signature.
  370. if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
  371. !FT->getParamType(0)->isPointerTy() ||
  372. !FT->getParamType(1)->isIntegerTy() ||
  373. FT->getParamType(2) != TD->getIntPtrType(Context) ||
  374. FT->getParamType(3) != TD->getIntPtrType(Context))
  375. return false;
  376. if (isFoldable(3, 2, false)) {
  377. Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
  378. false);
  379. B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
  380. replaceCall(CI->getArgOperand(0));
  381. return true;
  382. }
  383. return false;
  384. }
  385. if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
  386. // Check if this has the right signature.
  387. if (FT->getNumParams() != 3 ||
  388. FT->getReturnType() != FT->getParamType(0) ||
  389. FT->getParamType(0) != FT->getParamType(1) ||
  390. FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
  391. FT->getParamType(2) != TD->getIntPtrType(Context))
  392. return 0;
  393. // If a) we don't have any length information, or b) we know this will
  394. // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
  395. // st[rp]cpy_chk call which may fail at runtime if the size is too long.
  396. // TODO: It might be nice to get a maximum length out of the possible
  397. // string lengths for varying.
  398. if (isFoldable(2, 1, true)) {
  399. Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
  400. Name.substr(2, 6));
  401. replaceCall(Ret);
  402. return true;
  403. }
  404. return false;
  405. }
  406. if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
  407. // Check if this has the right signature.
  408. if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
  409. FT->getParamType(0) != FT->getParamType(1) ||
  410. FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
  411. !FT->getParamType(2)->isIntegerTy() ||
  412. FT->getParamType(3) != TD->getIntPtrType(Context))
  413. return false;
  414. if (isFoldable(3, 2, false)) {
  415. Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
  416. CI->getArgOperand(2), B, TD, Name.substr(2, 7));
  417. replaceCall(Ret);
  418. return true;
  419. }
  420. return false;
  421. }
  422. if (Name == "__strcat_chk") {
  423. return false;
  424. }
  425. if (Name == "__strncat_chk") {
  426. return false;
  427. }
  428. return false;
  429. }