From 14d93907213302dcd57b6dd2baeb9adccc59ab61 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 19 Apr 2022 22:26:09 -0700 Subject: [PATCH] Revert D123198 "[BuildLibCalls] Introduce getOrInsertLibFunc() for use when building libcalls." test/Transforms/InstCombine/pr39177.ll failed in a -DLLVM_USE_SANITIZER=Undefined build. ``` lib/Transforms/Utils/BuildLibCalls.cpp:1217:17: runtime error: reference binding to null pointer of type 'llvm::Function' ``` `Function &F = *M->getFunction(Name);` This reverts commit 0f8c626723d2bbd547e78dcab5ab260dfbc437e1. --- llvm/include/llvm/IR/Module.h | 2 - llvm/include/llvm/Transforms/Utils/BuildLibCalls.h | 56 +----- llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp | 2 +- llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 6 +- llvm/lib/Transforms/Utils/BuildLibCalls.cpp | 213 +++++++-------------- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 34 ++-- .../test/Transforms/InferFunctionAttrs/annotate.ll | 5 + .../InstCombine/SystemZ/libcall-arg-exts.ll | 98 ---------- .../InstCombine/double-float-shrink-1.ll | 2 +- 9 files changed, 102 insertions(+), 316 deletions(-) delete mode 100644 llvm/test/Transforms/InstCombine/SystemZ/libcall-arg-exts.ll diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index ddf8161..6cad37f 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -363,8 +363,6 @@ public: /// In all cases, the returned value is a FunctionCallee wrapper around the /// 'FunctionType *T' passed in, as well as a 'Value*' either of the Function or /// the bitcast to the function. - /// - /// Note: For library calls getOrInsertLibFunc() should be used instead. FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList); diff --git a/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h index 9b6899f..87d33b9 100644 --- a/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -22,45 +22,12 @@ namespace llvm { class IRBuilderBase; /// Analyze the name and prototype of the given function and set any - /// applicable attributes. Note that this merely helps optimizations on an - /// already existing function but does not consider mandatory attributes. - /// + /// applicable attributes. /// If the library function is unavailable, this doesn't modify it. /// /// Returns true if any attributes were set and false otherwise. - bool inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name, - const TargetLibraryInfo &TLI); - bool inferNonMandatoryLibFuncAttrs(Function &F, const TargetLibraryInfo &TLI); - - /// Calls getOrInsertFunction() and then makes sure to add mandatory - /// argument attributes. - FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, FunctionType *T, - AttributeList AttributeList); - FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, FunctionType *T); - template - FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, AttributeList AttributeList, - Type *RetTy, ArgsTy... Args) { - SmallVector ArgTys{Args...}; - return getOrInsertLibFunc(M, TLI, TheLibFunc, - FunctionType::get(RetTy, ArgTys, false), - AttributeList); - } - /// Same as above, but without the attributes. - template - FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, Type *RetTy, ArgsTy... Args) { - return getOrInsertLibFunc(M, TLI, TheLibFunc, AttributeList{}, RetTy, - Args...); - } - // Avoid an incorrect ordering that'd otherwise compile incorrectly. - template - FunctionCallee - getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, AttributeList AttributeList, - FunctionType *Invalid, ArgsTy... Args) = delete; + bool inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI); + bool inferLibFuncAttributes(Module *M, StringRef Name, const TargetLibraryInfo &TLI); /// Check whether the overloaded floating point function /// corresponding to \a Ty is available. @@ -68,10 +35,10 @@ namespace llvm { LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn); /// Get the name of the overloaded floating point function - /// corresponding to \a Ty. Return the LibFunc in \a TheLibFunc. - StringRef getFloatFn(const TargetLibraryInfo *TLI, Type *Ty, - LibFunc DoubleFn, LibFunc FloatFn, - LibFunc LongDoubleFn, LibFunc &TheLibFunc); + /// corresponding to \a Ty. + StringRef getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty, + LibFunc DoubleFn, LibFunc FloatFn, + LibFunc LongDoubleFn); /// Return V if it is an i8*, otherwise cast it to i8*. Value *castToCStr(Value *V, IRBuilderBase &B); @@ -181,8 +148,7 @@ namespace llvm { /// function is known to take a single of type matching 'Op' and returns one /// value with the same type. If 'Op' is a long double, 'l' is added as the /// suffix of name, if 'Op' is a float, we add a 'f' suffix. - Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, - StringRef Name, IRBuilderBase &B, + Value *emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs); /// Emit a call to the unary function DoubleFn, FloatFn or LongDoubleFn, @@ -196,10 +162,8 @@ namespace llvm { /// function is known to take type matching 'Op1' and 'Op2' and return one /// value with the same type. If 'Op1/Op2' are long double, 'l' is added as /// the suffix of name, if 'Op1/Op2' are float, we add a 'f' suffix. - Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2, - const TargetLibraryInfo *TLI, - StringRef Name, IRBuilderBase &B, - const AttributeList &Attrs); + Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, + IRBuilderBase &B, const AttributeList &Attrs); /// Emit a call to the binary function DoubleFn, FloatFn or LongDoubleFn, /// depending of the type of Op1. diff --git a/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp index 76f8f1a..6ec3c61 100644 --- a/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp @@ -29,7 +29,7 @@ static bool inferAllPrototypeAttributes( // explicitly visited by CGSCC passes in the new pass manager.) if (F.isDeclaration() && !F.hasOptNone()) { if (!F.hasFnAttribute(Attribute::NoBuiltin)) - Changed |= inferNonMandatoryLibFuncAttrs(F, GetTLI(F)); + Changed |= inferLibFuncAttributes(F, GetTLI(F)); Changed |= inferAttributesFromOthers(F); } diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index b58a3ea..7d5ff6b 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -1188,9 +1188,9 @@ bool LoopIdiomRecognize::processLoopStridedStore( Module *M = TheStore->getModule(); StringRef FuncName = "memset_pattern16"; - FunctionCallee MSP = getOrInsertLibFunc(M, *TLI, LibFunc_memset_pattern16, - Builder.getVoidTy(), Int8PtrTy, Int8PtrTy, IntIdxTy); - inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI); + FunctionCallee MSP = M->getOrInsertFunction(FuncName, Builder.getVoidTy(), + Int8PtrTy, Int8PtrTy, IntIdxTy); + inferLibFuncAttributes(M, FuncName, *TLI); // Otherwise we should form a memset_pattern16. PatternValue is known to be // an constant array of 16-bytes. Plop the value into a mergable global. diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index 09bd1bd7..1f4f1c9 100644 --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -39,6 +39,7 @@ STATISTIC(NumInaccessibleMemOrArgMemOnly, STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind"); STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture"); STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly"); +STATISTIC(NumExtArg, "Number of arguments inferred as signext/zeroext."); STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly"); STATISTIC(NumNoAlias, "Number of function returns inferred as noalias"); STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns"); @@ -146,6 +147,16 @@ static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) { return true; } +static bool setArgExtAttr(Function &F, unsigned ArgNo, + const TargetLibraryInfo &TLI, bool Signed = true) { + Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed); + if (ExtAttr == Attribute::None || F.hasParamAttribute(ArgNo, ExtAttr)) + return false; + F.addParamAttr(ArgNo, ExtAttr); + ++NumExtArg; + return true; +} + static bool setRetNoUndef(Function &F) { if (!F.getReturnType()->isVoidTy() && !F.hasRetAttribute(Attribute::NoUndef)) { @@ -229,16 +240,15 @@ static bool setAllocSize(Function &F, unsigned ElemSizeArg, return true; } -bool llvm::inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name, - const TargetLibraryInfo &TLI) { +bool llvm::inferLibFuncAttributes(Module *M, StringRef Name, + const TargetLibraryInfo &TLI) { Function *F = M->getFunction(Name); if (!F) return false; - return inferNonMandatoryLibFuncAttrs(*F, TLI); + return inferLibFuncAttributes(*F, TLI); } -bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, - const TargetLibraryInfo &TLI) { +bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { LibFunc TheLibFunc; if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc))) return false; @@ -835,6 +845,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, case LibFunc_putchar: case LibFunc_putchar_unlocked: Changed |= setRetAndArgsNoUndef(F); + Changed |= setArgExtAttr(F, 0, TLI); Changed |= setDoesNotThrow(F); return Changed; case LibFunc_popen: @@ -1055,6 +1066,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, case LibFunc_ldexp: case LibFunc_ldexpf: case LibFunc_ldexpl: + Changed |= setArgExtAttr(F, 1, TLI); Changed |= setWillReturn(F); return Changed; case LibFunc_abs: @@ -1191,83 +1203,6 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, } } -static void setArgExtAttr(Function &F, unsigned ArgNo, - const TargetLibraryInfo &TLI, bool Signed = true) { - Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed); - if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, ExtAttr)) - F.addParamAttr(ArgNo, ExtAttr); -} - -FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, FunctionType *T, - AttributeList AttributeList) { - assert(TLI.has(TheLibFunc) && - "Creating call to non-existing library function."); - StringRef Name = TLI.getName(TheLibFunc); - FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList); - - // Make sure any mandatory argument attributes are added. - - // Any outgoing i32 argument should be handled with setArgExtAttr() which - // will add an extension attribute if the target ABI requires it. Adding - // argument extensions is typically done by the front end but when an - // optimizer is building a library call on its own it has to take care of - // this. Each such generated function must be handled here with sign or - // zero extensions as needed. - Function &F = *M->getFunction(Name); - switch (TheLibFunc) { - case LibFunc_fputc: - case LibFunc_putchar: - setArgExtAttr(F, 0, TLI); - break; - case LibFunc_ldexp: - case LibFunc_ldexpf: - case LibFunc_ldexpl: - case LibFunc_memchr: - case LibFunc_strchr: - setArgExtAttr(F, 1, TLI); - break; - case LibFunc_memccpy: - setArgExtAttr(F, 2, TLI); - break; - - // These are functions that are known to not need any argument extension - // on any target: A size_t argument (which may be an i32 on some targets) - // should not trigger the assert below. - case LibFunc_bcmp: - case LibFunc_calloc: - case LibFunc_fwrite: - case LibFunc_malloc: - case LibFunc_memcmp: - case LibFunc_memcpy_chk: - case LibFunc_mempcpy: - case LibFunc_memset_pattern16: - case LibFunc_snprintf: - case LibFunc_strlcat: - case LibFunc_strlcpy: - case LibFunc_strncat: - case LibFunc_strncmp: - case LibFunc_strncpy: - case LibFunc_vsnprintf: - break; - - default: -#ifndef NDEBUG - for (unsigned i = 0; i < T->getNumParams(); i++) - assert(!isa(T->getParamType(i)) && - "Unhandled integer argument."); -#endif - break; - } - - return C; -} - -FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, - LibFunc TheLibFunc, FunctionType *T) { - return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList()); -} - bool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty, LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) { switch (Ty->getTypeID()) { @@ -1282,9 +1217,9 @@ bool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty, } } -StringRef llvm::getFloatFn(const TargetLibraryInfo *TLI, Type *Ty, - LibFunc DoubleFn, LibFunc FloatFn, - LibFunc LongDoubleFn, LibFunc &TheLibFunc) { +StringRef llvm::getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty, + LibFunc DoubleFn, LibFunc FloatFn, + LibFunc LongDoubleFn) { assert(hasFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) && "Cannot get name for unavailable function!"); @@ -1292,13 +1227,10 @@ StringRef llvm::getFloatFn(const TargetLibraryInfo *TLI, Type *Ty, case Type::HalfTyID: llvm_unreachable("No name for HalfTy!"); case Type::FloatTyID: - TheLibFunc = FloatFn; return TLI->getName(FloatFn); case Type::DoubleTyID: - TheLibFunc = DoubleFn; return TLI->getName(DoubleFn); default: - TheLibFunc = LongDoubleFn; return TLI->getName(LongDoubleFn); } } @@ -1321,8 +1253,8 @@ static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType, Module *M = B.GetInsertBlock()->getModule(); StringRef FuncName = TLI->getName(TheLibFunc); FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs); - FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType); - inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI); + FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType); + inferLibFuncAttributes(M, FuncName, *TLI); CallInst *CI = B.CreateCall(Callee, Operands, FuncName); if (const Function *F = dyn_cast(Callee.getCallee()->stripPointerCasts())) @@ -1399,8 +1331,8 @@ Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex, Attribute::NoUnwind); LLVMContext &Context = B.GetInsertBlock()->getContext(); - FunctionCallee MemCpy = getOrInsertLibFunc(M, *TLI, LibFunc_memcpy_chk, - AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(), + FunctionCallee MemCpy = M->getOrInsertFunction( + "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), DL.getIntPtrType(Context)); Dst = castToCStr(Dst, B); @@ -1534,15 +1466,14 @@ static void appendTypeSuffix(Value *Op, StringRef &Name, } } -static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc, - StringRef Name, IRBuilderBase &B, - const AttributeList &Attrs, - const TargetLibraryInfo *TLI) { +static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name, + IRBuilderBase &B, + const AttributeList &Attrs) { assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall"); Module *M = B.GetInsertBlock()->getModule(); - FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op->getType(), - Op->getType()); + FunctionCallee Callee = + M->getOrInsertFunction(Name, Op->getType(), Op->getType()); CallInst *CI = B.CreateCall(Callee, Op, Name); // The incoming attribute set may have come from a speculatable intrinsic, but @@ -1557,16 +1488,12 @@ static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc, return CI; } -Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, - StringRef Name, IRBuilderBase &B, +Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs) { SmallString<20> NameBuffer; appendTypeSuffix(Op, Name, NameBuffer); - LibFunc TheLibFunc; - TLI->getLibFunc(Name, TheLibFunc); - - return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI); + return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs); } Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, @@ -1574,24 +1501,23 @@ Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, LibFunc LongDoubleFn, IRBuilderBase &B, const AttributeList &Attrs) { // Get the name of the function according to TLI. - LibFunc TheLibFunc; - StringRef Name = getFloatFn(TLI, Op->getType(), DoubleFn, FloatFn, - LongDoubleFn, TheLibFunc); + StringRef Name = getFloatFnName(TLI, Op->getType(), + DoubleFn, FloatFn, LongDoubleFn); - return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI); + return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs); } static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2, - LibFunc TheLibFunc, StringRef Name, IRBuilderBase &B, const AttributeList &Attrs, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI = nullptr) { assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); Module *M = B.GetInsertBlock()->getModule(); - FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op1->getType(), - Op1->getType(), Op2->getType()); - inferNonMandatoryLibFuncAttrs(M, Name, *TLI); + FunctionCallee Callee = M->getOrInsertFunction(Name, Op1->getType(), + Op1->getType(), Op2->getType()); + if (TLI != nullptr) + inferLibFuncAttributes(M, Name, *TLI); CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name); // The incoming attribute set may have come from a speculatable intrinsic, but @@ -1606,19 +1532,15 @@ static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2, return CI; } -Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, - const TargetLibraryInfo *TLI, - StringRef Name, IRBuilderBase &B, +Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, + IRBuilderBase &B, const AttributeList &Attrs) { assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); SmallString<20> NameBuffer; appendTypeSuffix(Op1, Name, NameBuffer); - LibFunc TheLibFunc; - TLI->getLibFunc(Name, TheLibFunc); - - return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI); + return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs); } Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, @@ -1627,11 +1549,10 @@ Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, LibFunc LongDoubleFn, IRBuilderBase &B, const AttributeList &Attrs) { // Get the name of the function according to TLI. - LibFunc TheLibFunc; - StringRef Name = getFloatFn(TLI, Op1->getType(), DoubleFn, FloatFn, - LongDoubleFn, TheLibFunc); + StringRef Name = getFloatFnName(TLI, Op1->getType(), + DoubleFn, FloatFn, LongDoubleFn); - return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI); + return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs, TLI); } Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B, @@ -1641,9 +1562,9 @@ Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B, Module *M = B.GetInsertBlock()->getModule(); StringRef PutCharName = TLI->getName(LibFunc_putchar); - FunctionCallee PutChar = getOrInsertLibFunc(M, *TLI, LibFunc_putchar, - B.getInt32Ty(), B.getInt32Ty()); - inferNonMandatoryLibFuncAttrs(M, PutCharName, *TLI); + FunctionCallee PutChar = + M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty()); + inferLibFuncAttributes(M, PutCharName, *TLI); CallInst *CI = B.CreateCall(PutChar, B.CreateIntCast(Char, B.getInt32Ty(), @@ -1664,9 +1585,9 @@ Value *llvm::emitPutS(Value *Str, IRBuilderBase &B, Module *M = B.GetInsertBlock()->getModule(); StringRef PutsName = TLI->getName(LibFunc_puts); - FunctionCallee PutS = getOrInsertLibFunc(M, *TLI, LibFunc_puts, B.getInt32Ty(), - B.getInt8PtrTy()); - inferNonMandatoryLibFuncAttrs(M, PutsName, *TLI); + FunctionCallee PutS = + M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy()); + inferLibFuncAttributes(M, PutsName, *TLI); CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName); if (const Function *F = dyn_cast(PutS.getCallee()->stripPointerCasts())) @@ -1681,10 +1602,10 @@ Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B, Module *M = B.GetInsertBlock()->getModule(); StringRef FPutcName = TLI->getName(LibFunc_fputc); - FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputc, B.getInt32Ty(), - B.getInt32Ty(), File->getType()); + FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), + B.getInt32Ty(), File->getType()); if (File->getType()->isPointerTy()) - inferNonMandatoryLibFuncAttrs(M, FPutcName, *TLI); + inferLibFuncAttributes(M, FPutcName, *TLI); Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, "chari"); CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName); @@ -1702,10 +1623,10 @@ Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B, Module *M = B.GetInsertBlock()->getModule(); StringRef FPutsName = TLI->getName(LibFunc_fputs); - FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputs, B.getInt32Ty(), - B.getInt8PtrTy(), File->getType()); + FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), + B.getInt8PtrTy(), File->getType()); if (File->getType()->isPointerTy()) - inferNonMandatoryLibFuncAttrs(M, FPutsName, *TLI); + inferLibFuncAttributes(M, FPutsName, *TLI); CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName); if (const Function *Fn = @@ -1722,12 +1643,12 @@ Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, Module *M = B.GetInsertBlock()->getModule(); LLVMContext &Context = B.GetInsertBlock()->getContext(); StringRef FWriteName = TLI->getName(LibFunc_fwrite); - FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fwrite, - DL.getIntPtrType(Context), B.getInt8PtrTy(), DL.getIntPtrType(Context), - DL.getIntPtrType(Context), File->getType()); + FunctionCallee F = M->getOrInsertFunction( + FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(), + DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); if (File->getType()->isPointerTy()) - inferNonMandatoryLibFuncAttrs(M, FWriteName, *TLI); + inferLibFuncAttributes(M, FWriteName, *TLI); CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, ConstantInt::get(DL.getIntPtrType(Context), 1), File}); @@ -1746,9 +1667,9 @@ Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL, Module *M = B.GetInsertBlock()->getModule(); StringRef MallocName = TLI->getName(LibFunc_malloc); LLVMContext &Context = B.GetInsertBlock()->getContext(); - FunctionCallee Malloc = getOrInsertLibFunc(M, *TLI, LibFunc_malloc, - B.getInt8PtrTy(), DL.getIntPtrType(Context)); - inferNonMandatoryLibFuncAttrs(M, MallocName, *TLI); + FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(), + DL.getIntPtrType(Context)); + inferLibFuncAttributes(M, MallocName, *TLI); CallInst *CI = B.CreateCall(Malloc, Num, MallocName); if (const Function *F = @@ -1767,9 +1688,9 @@ Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B, StringRef CallocName = TLI.getName(LibFunc_calloc); const DataLayout &DL = M->getDataLayout(); IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext())); - FunctionCallee Calloc = getOrInsertLibFunc(M, TLI, LibFunc_calloc, - B.getInt8PtrTy(), PtrType, PtrType); - inferNonMandatoryLibFuncAttrs(M, CallocName, TLI); + FunctionCallee Calloc = + M->getOrInsertFunction(CallocName, B.getInt8PtrTy(), PtrType, PtrType); + inferLibFuncAttributes(M, CallocName, TLI); CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName); if (const auto *F = diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index ca354e0..e130ffb 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1254,8 +1254,7 @@ static Value *valueHasFloatPrecision(Value *Val) { /// Shrink double -> float functions. static Value *optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, - bool isBinary, const TargetLibraryInfo *TLI, - bool isPrecise = false) { + bool isBinary, bool isPrecise = false) { Function *CalleeFn = CI->getCalledFunction(); if (!CI->getType()->isDoubleTy() || !CalleeFn) return nullptr; @@ -1305,25 +1304,22 @@ static Value *optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, R = isBinary ? B.CreateCall(Fn, V) : B.CreateCall(Fn, V[0]); } else { AttributeList CalleeAttrs = CalleeFn->getAttributes(); - R = isBinary ? emitBinaryFloatFnCall(V[0], V[1], TLI, CalleeName, B, - CalleeAttrs) - : emitUnaryFloatFnCall(V[0], TLI, CalleeName, B, CalleeAttrs); + R = isBinary ? emitBinaryFloatFnCall(V[0], V[1], CalleeName, B, CalleeAttrs) + : emitUnaryFloatFnCall(V[0], CalleeName, B, CalleeAttrs); } return B.CreateFPExt(R, B.getDoubleTy()); } /// Shrink double -> float for unary functions. static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilderBase &B, - const TargetLibraryInfo *TLI, bool isPrecise = false) { - return optimizeDoubleFP(CI, B, false, TLI, isPrecise); + return optimizeDoubleFP(CI, B, false, isPrecise); } /// Shrink double -> float for binary functions. static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B, - const TargetLibraryInfo *TLI, bool isPrecise = false) { - return optimizeDoubleFP(CI, B, true, TLI, isPrecise); + return optimizeDoubleFP(CI, B, true, isPrecise); } // cabs(z) -> sqrt((creal(z)*creal(z)) + (cimag(z)*cimag(z))) @@ -1791,7 +1787,7 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) { // unless the result is expected to be double precision. if (UnsafeFPShrink && Name == TLI->getName(LibFunc_pow) && hasFloatVersion(Name)) { - if (Value *Shrunk = optimizeBinaryDoubleFP(Pow, B, TLI, true)) + if (Value *Shrunk = optimizeBinaryDoubleFP(Pow, B, true)) return Shrunk; } @@ -1805,7 +1801,7 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) { Value *Ret = nullptr; if (UnsafeFPShrink && Name == TLI->getName(LibFunc_exp2) && hasFloatVersion(Name)) - Ret = optimizeUnaryDoubleFP(CI, B, TLI, true); + Ret = optimizeUnaryDoubleFP(CI, B, true); Type *Ty = CI->getType(); Value *Op = CI->getArgOperand(0); @@ -1829,7 +1825,7 @@ Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilderBase &B) { Function *Callee = CI->getCalledFunction(); StringRef Name = Callee->getName(); if ((Name == "fmin" || Name == "fmax") && hasFloatVersion(Name)) - if (Value *Ret = optimizeBinaryDoubleFP(CI, B, TLI)) + if (Value *Ret = optimizeBinaryDoubleFP(CI, B)) return Ret; // The LLVM intrinsics minnum/maxnum correspond to fmin/fmax. Canonicalize to @@ -1861,7 +1857,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { Value *Ret = nullptr; if (UnsafeFPShrink && hasFloatVersion(LogNm)) - Ret = optimizeUnaryDoubleFP(Log, B, TLI, true); + Ret = optimizeUnaryDoubleFP(Log, B, true); // The earlier call must also be 'fast' in order to do these transforms. CallInst *Arg = dyn_cast(Log->getArgOperand(0)); @@ -1969,7 +1965,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { Log->doesNotAccessMemory() ? B.CreateCall(Intrinsic::getDeclaration(Mod, LogID, Ty), Arg->getOperand(0), "log") - : emitUnaryFloatFnCall(Arg->getOperand(0), TLI, LogNm, B, Attrs); + : emitUnaryFloatFnCall(Arg->getOperand(0), LogNm, B, Attrs); Value *MulY = B.CreateFMul(Arg->getArgOperand(1), LogX, "mul"); // Since pow() may have side effects, e.g. errno, // dead code elimination may not be trusted to remove it. @@ -1992,7 +1988,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { Value *LogE = Log->doesNotAccessMemory() ? B.CreateCall(Intrinsic::getDeclaration(Mod, LogID, Ty), Eul, "log") - : emitUnaryFloatFnCall(Eul, TLI, LogNm, B, Attrs); + : emitUnaryFloatFnCall(Eul, LogNm, B, Attrs); Value *MulY = B.CreateFMul(Arg->getArgOperand(0), LogE, "mul"); // Since exp() may have side effects, e.g. errno, // dead code elimination may not be trusted to remove it. @@ -2011,7 +2007,7 @@ Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilderBase &B) { // condition below. if (TLI->has(LibFunc_sqrtf) && (Callee->getName() == "sqrt" || Callee->getIntrinsicID() == Intrinsic::sqrt)) - Ret = optimizeUnaryDoubleFP(CI, B, TLI, true); + Ret = optimizeUnaryDoubleFP(CI, B, true); if (!CI->isFast()) return Ret; @@ -2077,7 +2073,7 @@ Value *LibCallSimplifier::optimizeTan(CallInst *CI, IRBuilderBase &B) { Value *Ret = nullptr; StringRef Name = Callee->getName(); if (UnsafeFPShrink && Name == "tan" && hasFloatVersion(Name)) - Ret = optimizeUnaryDoubleFP(CI, B, TLI, true); + Ret = optimizeUnaryDoubleFP(CI, B, true); Value *Op1 = CI->getArgOperand(0); auto *OpC = dyn_cast(Op1); @@ -3014,11 +3010,11 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI, case LibFunc_sinh: case LibFunc_tanh: if (UnsafeFPShrink && hasFloatVersion(CI->getCalledFunction()->getName())) - return optimizeUnaryDoubleFP(CI, Builder, TLI, true); + return optimizeUnaryDoubleFP(CI, Builder, true); return nullptr; case LibFunc_copysign: if (hasFloatVersion(CI->getCalledFunction()->getName())) - return optimizeBinaryDoubleFP(CI, Builder, TLI); + return optimizeBinaryDoubleFP(CI, Builder); return nullptr; case LibFunc_fminf: case LibFunc_fmin: diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll index 4c1d035..950a8ce 100644 --- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -3,6 +3,7 @@ ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.8.0 -inferattrs -S | FileCheck --match-full-lines --check-prefixes=CHECK,CHECK-KNOWN,CHECK-NOLINUX,CHECK-OPEN,CHECK-DARWIN %s ; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -inferattrs -S | FileCheck --match-full-lines --check-prefixes=CHECK,CHECK-KNOWN,CHECK-LINUX %s ; RUN: opt < %s -mtriple=nvptx -inferattrs -S | FileCheck --match-full-lines --check-prefixes=CHECK-NOLINUX,CHECK-NVPTX %s +; RUN: opt < %s -mtriple=s390x-linux-gnu -inferattrs -S | FileCheck --check-prefixes=CHECK-SYSTEMZ %s declare i32 @__nvvm_reflect(i8*) ; CHECK-NVPTX: declare noundef i32 @__nvvm_reflect(i8* noundef) [[NOFREE_NOUNWIND_READNONE:#[0-9]+]] @@ -591,9 +592,11 @@ declare i64 @labs(i64) declare i32 @lchown(i8*, i32, i32) ; CHECK: declare double @ldexp(double, i32) [[NOFREE_WILLRETURN:#[0-9]+]] +; CHECK-SYSTEMZ: declare double @ldexp(double, i32 signext) declare double @ldexp(double, i32) ; CHECK: declare float @ldexpf(float, i32) [[NOFREE_WILLRETURN]] +; CHECK-SYSTEMZ: declare float @ldexpf(float, i32 signext) declare float @ldexpf(float, i32) ; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NOFREE_WILLRETURN]] @@ -753,10 +756,12 @@ declare i32 @printf(i8*, ...) declare i32 @putc(i32, %opaque*) ; CHECK: declare noundef i32 @putchar(i32 noundef) [[NOFREE_NOUNWIND]] +; CHECK-SYSTEMZ: declare noundef i32 @putchar(i32 noundef signext) declare i32 @putchar(i32) ; CHECK-KNOWN: declare noundef i32 @putchar_unlocked(i32 noundef) [[NOFREE_NOUNWIND]] ; CHECK-UNKNOWN: declare i32 @putchar_unlocked(i32){{$}} +; CHECK-SYSTEMZ: declare noundef i32 @putchar_unlocked(i32 noundef signext) declare i32 @putchar_unlocked(i32) ; CHECK: declare noundef i32 @puts(i8* nocapture noundef readonly) [[NOFREE_NOUNWIND]] diff --git a/llvm/test/Transforms/InstCombine/SystemZ/libcall-arg-exts.ll b/llvm/test/Transforms/InstCombine/SystemZ/libcall-arg-exts.ll deleted file mode 100644 index dbd9204..0000000 --- a/llvm/test/Transforms/InstCombine/SystemZ/libcall-arg-exts.ll +++ /dev/null @@ -1,98 +0,0 @@ -; RUN: opt < %s -passes=instcombine -S -mtriple=systemz-unknown | FileCheck %s -; -; Check that i32 arguments to generated libcalls have the proper extension -; attributes. - - -declare double @exp2(double) -declare float @exp2f(float) -declare fp128 @exp2l(fp128) - -define double @fun1(i32 %x) { -; CHECK-LABEL: @fun1 -; CHECK: call double @ldexp - %conv = sitofp i32 %x to double - %ret = call double @exp2(double %conv) - ret double %ret -} - -define float @fun2(i32 %x) { -; CHECK-LABEL: @fun2 -; CHECK: call float @ldexpf - %conv = sitofp i32 %x to float - %ret = call float @exp2f(float %conv) - ret float %ret -} - -define fp128 @fun3(i8 zeroext %x) { -; CHECK-LABEL: @fun3 -; CHECK: call fp128 @ldexpl - %conv = uitofp i8 %x to fp128 - %ret = call fp128 @exp2l(fp128 %conv) - ret fp128 %ret -} - -@a = common global [60 x i8] zeroinitializer, align 1 -@b = common global [60 x i8] zeroinitializer, align 1 -declare i8* @__memccpy_chk(i8*, i8*, i32, i64, i64) -define i8* @fun4() { -; CHECK-LABEL: @fun4 -; CHECK: call i8* @memccpy - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 -1) - ret i8* %ret -} - -%FILE = type { } -@A = constant [2 x i8] c"A\00" -declare i32 @fputs(i8*, %FILE*) -define void @fun5(%FILE* %fp) { -; CHECK-LABEL: @fun5 -; CHECK: call i32 @fputc - %str = getelementptr [2 x i8], [2 x i8]* @A, i32 0, i32 0 - call i32 @fputs(i8* %str, %FILE* %fp) - ret void -} - -@empty = constant [1 x i8] zeroinitializer -declare i32 @puts(i8*) -define void @fun6() { -; CHECK-LABEL: @fun6 -; CHECK: call i32 @putchar - %str = getelementptr [1 x i8], [1 x i8]* @empty, i32 0, i32 0 - call i32 @puts(i8* %str) - ret void -} - -@.str1 = private constant [2 x i8] c"a\00" -declare i8* @strstr(i8*, i8*) -define i8* @fun7(i8* %str) { -; CHECK-LABEL: @fun7 -; CHECK: call i8* @strchr - %pat = getelementptr inbounds [2 x i8], [2 x i8]* @.str1, i32 0, i32 0 - %ret = call i8* @strstr(i8* %str, i8* %pat) - ret i8* %ret -} - -; CHECK: declare i8* @strchr(i8*, i32 signext) - -@hello = constant [14 x i8] c"hello world\5Cn\00" -@chp = global i8* zeroinitializer -declare i8* @strchr(i8*, i32) -define void @fun8(i32 %chr) { -; CHECK-LABEL: @fun8 -; CHECK: call i8* @memchr - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @strchr(i8* %src, i32 %chr) - store i8* %dst, i8** @chp - ret void -} - -; CHECK: declare double @ldexp(double, i32 signext) -; CHECK: declare float @ldexpf(float, i32 signext) -; CHECK: declare fp128 @ldexpl(fp128, i32 signext) -; CHECK: declare i8* @memccpy(i8* noalias writeonly, i8* noalias nocapture readonly, i32 signext, i64) -; CHECK: declare noundef i32 @fputc(i32 noundef signext, %FILE* nocapture noundef) -; CHECK: declare noundef i32 @putchar(i32 noundef signext) -; CHECK: declare i8* @memchr(i8*, i32 signext, i64) diff --git a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll index 85c9a01..13bf554 100644 --- a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll +++ b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll @@ -346,7 +346,7 @@ define float @logb_test1(float %f) { ; LINUX-NEXT: [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]]) ; LINUX-NEXT: ret float [[LOGBF]] ; MS32: [[POWF:%.*]] = call fast double @logb(double [[F:%.*]]) -; MS64-NEXT: [[LOGBF:%.*]] = call fast float @_logbf(float [[F:%.*]]) +; MS64-NEXT: [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @logb(double %conv) -- 2.7.4