diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 144 |
1 files changed, 43 insertions, 101 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index b8e0f63c481d..e190a1294eb3 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -142,12 +142,10 @@ static void annotateDereferenceableBytes(CallInst *CI, unsigned AS = CI->getArgOperand(ArgNo)->getType()->getPointerAddressSpace(); if (!llvm::NullPointerIsDefined(F, AS) || CI->paramHasAttr(ArgNo, Attribute::NonNull)) - DerefBytes = std::max(CI->getDereferenceableOrNullBytes( - ArgNo + AttributeList::FirstArgIndex), + DerefBytes = std::max(CI->getParamDereferenceableOrNullBytes(ArgNo), DereferenceableBytes); - - if (CI->getDereferenceableBytes(ArgNo + AttributeList::FirstArgIndex) < - DerefBytes) { + + if (CI->getParamDereferenceableBytes(ArgNo) < DerefBytes) { CI->removeParamAttr(ArgNo, Attribute::Dereferenceable); if (!llvm::NullPointerIsDefined(F, AS) || CI->paramHasAttr(ArgNo, Attribute::NonNull)) @@ -512,14 +510,18 @@ Value *LibCallSimplifier::optimizeStrCpy(CallInst *CI, IRBuilderBase &B) { B.CreateMemCpy(Dst, Align(1), Src, Align(1), ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len)); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return Dst; } Value *LibCallSimplifier::optimizeStpCpy(CallInst *CI, IRBuilderBase &B) { Function *Callee = CI->getCalledFunction(); Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); + + // stpcpy(d,s) -> strcpy(d,s) if the result is not used. + if (CI->use_empty()) + return emitStrCpy(Dst, Src, B, TLI); + if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) Value *StrLen = emitStrLen(Src, B, DL, TLI); return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr; @@ -541,8 +543,7 @@ Value *LibCallSimplifier::optimizeStpCpy(CallInst *CI, IRBuilderBase &B) { // copy for us. Make a memcpy to copy the nul byte with align = 1. CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), LenV); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return DstEnd; } @@ -577,9 +578,9 @@ Value *LibCallSimplifier::optimizeStrNCpy(CallInst *CI, IRBuilderBase &B) { if (SrcLen == 0) { // strncpy(x, "", y) -> memset(x, '\0', y) Align MemSetAlign = - CI->getAttributes().getParamAttributes(0).getAlignment().valueOrOne(); + CI->getAttributes().getParamAttrs(0).getAlignment().valueOrOne(); CallInst *NewCI = B.CreateMemSet(Dst, B.getInt8('\0'), Size, MemSetAlign); - AttrBuilder ArgAttrs(CI->getAttributes().getParamAttributes(0)); + AttrBuilder ArgAttrs(CI->getAttributes().getParamAttrs(0)); NewCI->setAttributes(NewCI->getAttributes().addParamAttributes( CI->getContext(), 0, ArgAttrs)); return Dst; @@ -604,8 +605,7 @@ Value *LibCallSimplifier::optimizeStrNCpy(CallInst *CI, IRBuilderBase &B) { CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), ConstantInt::get(DL.getIntPtrType(PT), Len)); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return Dst; } @@ -1082,8 +1082,7 @@ Value *LibCallSimplifier::optimizeMemCpy(CallInst *CI, IRBuilderBase &B) { CallInst *NewCI = B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), Size); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return CI->getArgOperand(0); } @@ -1136,8 +1135,7 @@ Value *LibCallSimplifier::optimizeMemPCpy(CallInst *CI, IRBuilderBase &B) { // any return attributes are compliant. // TODO: Attach return value attributes to the 1st operand to preserve them? NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, N); } @@ -1151,70 +1149,21 @@ Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilderBase &B) { CallInst *NewCI = B.CreateMemMove(CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), Size); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return CI->getArgOperand(0); } -/// Fold memset[_chk](malloc(n), 0, n) --> calloc(1, n). -Value *LibCallSimplifier::foldMallocMemset(CallInst *Memset, IRBuilderBase &B) { - // This has to be a memset of zeros (bzero). - auto *FillValue = dyn_cast<ConstantInt>(Memset->getArgOperand(1)); - if (!FillValue || FillValue->getZExtValue() != 0) - return nullptr; - - // TODO: We should handle the case where the malloc has more than one use. - // This is necessary to optimize common patterns such as when the result of - // the malloc is checked against null or when a memset intrinsic is used in - // place of a memset library call. - auto *Malloc = dyn_cast<CallInst>(Memset->getArgOperand(0)); - if (!Malloc || !Malloc->hasOneUse()) - return nullptr; - - // Is the inner call really malloc()? - Function *InnerCallee = Malloc->getCalledFunction(); - if (!InnerCallee) - return nullptr; - - LibFunc Func; - if (!TLI->getLibFunc(*InnerCallee, Func) || !TLI->has(Func) || - Func != LibFunc_malloc) - return nullptr; - - // The memset must cover the same number of bytes that are malloc'd. - if (Memset->getArgOperand(2) != Malloc->getArgOperand(0)) - return nullptr; - - // Replace the malloc with a calloc. We need the data layout to know what the - // actual size of a 'size_t' parameter is. - B.SetInsertPoint(Malloc->getParent(), ++Malloc->getIterator()); - const DataLayout &DL = Malloc->getModule()->getDataLayout(); - IntegerType *SizeType = DL.getIntPtrType(B.GetInsertBlock()->getContext()); - if (Value *Calloc = emitCalloc(ConstantInt::get(SizeType, 1), - Malloc->getArgOperand(0), - Malloc->getAttributes(), B, *TLI)) { - substituteInParent(Malloc, Calloc); - return Calloc; - } - - return nullptr; -} - Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilderBase &B) { Value *Size = CI->getArgOperand(2); annotateNonNullAndDereferenceable(CI, 0, Size, DL); if (isa<IntrinsicInst>(CI)) return nullptr; - if (auto *Calloc = foldMallocMemset(CI, B)) - return Calloc; - // memset(p, v, n) -> llvm.memset(align 1 p, v, n) Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, Size, Align(1)); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return CI->getArgOperand(0); } @@ -1346,13 +1295,13 @@ Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilderBase &B) { B.setFastMathFlags(CI->getFastMathFlags()); Value *Real, *Imag; - if (CI->getNumArgOperands() == 1) { + if (CI->arg_size() == 1) { Value *Op = CI->getArgOperand(0); assert(Op->getType()->isArrayTy() && "Unexpected signature for cabs!"); Real = B.CreateExtractValue(Op, 0, "real"); Imag = B.CreateExtractValue(Op, 1, "imag"); } else { - assert(CI->getNumArgOperands() == 2 && "Unexpected signature for cabs!"); + assert(CI->arg_size() == 2 && "Unexpected signature for cabs!"); Real = CI->getArgOperand(0); Imag = CI->getArgOperand(1); } @@ -2333,7 +2282,7 @@ Value *LibCallSimplifier::optimizeErrorReporting(CallInst *CI, IRBuilderBase &B, // Proceedings of PACT'98, Oct. 1998, IEEE if (!CI->hasFnAttr(Attribute::Cold) && isReportingError(Callee, CI, StreamArg)) { - CI->addAttribute(AttributeList::FunctionIndex, Attribute::Cold); + CI->addFnAttr(Attribute::Cold); } return nullptr; @@ -2349,7 +2298,7 @@ static bool isReportingError(Function *Callee, CallInst *CI, int StreamArg) { // These functions might be considered cold, but only if their stream // argument is stderr. - if (StreamArg >= (int)CI->getNumArgOperands()) + if (StreamArg >= (int)CI->arg_size()) return false; LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(StreamArg)); if (!LI) @@ -2381,7 +2330,7 @@ Value *LibCallSimplifier::optimizePrintFString(CallInst *CI, IRBuilderBase &B) { return emitPutChar(B.getInt32(FormatStr[0]), B, TLI); // Try to remove call or emit putchar/puts. - if (FormatStr == "%s" && CI->getNumArgOperands() > 1) { + if (FormatStr == "%s" && CI->arg_size() > 1) { StringRef OperandStr; if (!getConstantStringInfo(CI->getOperand(1), OperandStr)) return nullptr; @@ -2402,7 +2351,7 @@ Value *LibCallSimplifier::optimizePrintFString(CallInst *CI, IRBuilderBase &B) { // printf("foo\n") --> puts("foo") if (FormatStr.back() == '\n' && - FormatStr.find('%') == StringRef::npos) { // No format characters. + !FormatStr.contains('%')) { // No format characters. // Create a string literal with no \n on it. We expect the constant merge // pass to be run after this pass, to merge duplicate strings. FormatStr = FormatStr.drop_back(); @@ -2412,12 +2361,12 @@ Value *LibCallSimplifier::optimizePrintFString(CallInst *CI, IRBuilderBase &B) { // Optimize specific format strings. // printf("%c", chr) --> putchar(chr) - if (FormatStr == "%c" && CI->getNumArgOperands() > 1 && + if (FormatStr == "%c" && CI->arg_size() > 1 && CI->getArgOperand(1)->getType()->isIntegerTy()) return emitPutChar(CI->getArgOperand(1), B, TLI); // printf("%s\n", str) --> puts(str) - if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && + if (FormatStr == "%s\n" && CI->arg_size() > 1 && CI->getArgOperand(1)->getType()->isPointerTy()) return emitPutS(CI->getArgOperand(1), B, TLI); return nullptr; @@ -2469,10 +2418,10 @@ Value *LibCallSimplifier::optimizeSPrintFString(CallInst *CI, // If we just have a format string (nothing else crazy) transform it. Value *Dest = CI->getArgOperand(0); - if (CI->getNumArgOperands() == 2) { + if (CI->arg_size() == 2) { // Make sure there's no % in the constant array. We could try to handle // %% -> % in the future if we cared. - if (FormatStr.find('%') != StringRef::npos) + if (FormatStr.contains('%')) return nullptr; // we found a format specifier, bail out. // sprintf(str, fmt) -> llvm.memcpy(align 1 str, align 1 fmt, strlen(fmt)+1) @@ -2485,8 +2434,7 @@ Value *LibCallSimplifier::optimizeSPrintFString(CallInst *CI, // The remaining optimizations require the format string to be "%s" or "%c" // and have an extra operand. - if (FormatStr.size() != 2 || FormatStr[0] != '%' || - CI->getNumArgOperands() < 3) + if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->arg_size() < 3) return nullptr; // Decode the second character of the format string. @@ -2597,10 +2545,10 @@ Value *LibCallSimplifier::optimizeSnPrintFString(CallInst *CI, return nullptr; // If we just have a format string (nothing else crazy) transform it. - if (CI->getNumArgOperands() == 3) { + if (CI->arg_size() == 3) { // Make sure there's no % in the constant array. We could try to handle // %% -> % in the future if we cared. - if (FormatStr.find('%') != StringRef::npos) + if (FormatStr.contains('%')) return nullptr; // we found a format specifier, bail out. if (N == 0) @@ -2619,8 +2567,7 @@ Value *LibCallSimplifier::optimizeSnPrintFString(CallInst *CI, // The remaining optimizations require the format string to be "%s" or "%c" // and have an extra operand. - if (FormatStr.size() == 2 && FormatStr[0] == '%' && - CI->getNumArgOperands() == 4) { + if (FormatStr.size() == 2 && FormatStr[0] == '%' && CI->arg_size() == 4) { // Decode the second character of the format string. if (FormatStr[1] == 'c') { @@ -2688,9 +2635,9 @@ Value *LibCallSimplifier::optimizeFPrintFString(CallInst *CI, return nullptr; // fprintf(F, "foo") --> fwrite("foo", 3, 1, F) - if (CI->getNumArgOperands() == 2) { + if (CI->arg_size() == 2) { // Could handle %% -> % if we cared. - if (FormatStr.find('%') != StringRef::npos) + if (FormatStr.contains('%')) return nullptr; // We found a format specifier. return emitFWrite( @@ -2701,8 +2648,7 @@ Value *LibCallSimplifier::optimizeFPrintFString(CallInst *CI, // The remaining optimizations require the format string to be "%s" or "%c" // and have an extra operand. - if (FormatStr.size() != 2 || FormatStr[0] != '%' || - CI->getNumArgOperands() < 3) + if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->arg_size() < 3) return nullptr; // Decode the second character of the format string. @@ -3066,7 +3012,6 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) { return optimizeLog(CI, Builder); case Intrinsic::sqrt: return optimizeSqrt(CI, Builder); - // TODO: Use foldMallocMemset() with memset intrinsic. case Intrinsic::memset: return optimizeMemSet(CI, Builder); case Intrinsic::memcpy: @@ -3266,8 +3211,7 @@ Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(CallInst *CI, B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), CI->getArgOperand(2)); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return CI->getArgOperand(0); } return nullptr; @@ -3280,8 +3224,7 @@ Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI, B.CreateMemMove(CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), CI->getArgOperand(2)); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return CI->getArgOperand(0); } return nullptr; @@ -3289,15 +3232,12 @@ Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI, Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI, IRBuilderBase &B) { - // TODO: Try foldMallocMemset() here. - if (isFortifiedCallFoldable(CI, 3, 2)) { Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), Align(1)); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes(AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return CI->getArgOperand(0); } return nullptr; @@ -3311,9 +3251,7 @@ Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(CallInst *CI, CI->getArgOperand(2), B, DL, TLI)) { CallInst *NewCI = cast<CallInst>(Call); NewCI->setAttributes(CI->getAttributes()); - NewCI->removeAttributes( - AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCI->getType())); + NewCI->removeRetAttrs(AttributeFuncs::typeIncompatible(NewCI->getType())); return NewCI; } return nullptr; @@ -3354,7 +3292,11 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, else return nullptr; - Type *SizeTTy = DL.getIntPtrType(CI->getContext()); + // FIXME: There is really no guarantee that sizeof(size_t) is equal to + // sizeof(int*) for every target. So the assumption used here to derive the + // SizeTBits based on the size of an integer pointer in address space zero + // isn't always valid. + Type *SizeTTy = DL.getIntPtrType(CI->getContext(), /*AddressSpace=*/0); Value *LenV = ConstantInt::get(SizeTTy, Len); Value *Ret = emitMemCpyChk(Dst, Src, LenV, ObjSize, B, DL, TLI); // If the function was an __stpcpy_chk, and we were able to fold it into |
