diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -36,6 +36,7 @@ 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(NumSExtArg, "Number of arguments inferred as signext"); 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"); @@ -114,6 +115,13 @@ return true; } +static bool setSignExtendedArg(Function &F, unsigned ArgNo) { + if (F.hasParamAttribute(ArgNo, Attribute::SExt)) + return false; + F.addParamAttr(ArgNo, Attribute::SExt); + ++NumSExtArg; + return true; +} static bool setRetNoUndef(Function &F) { if (!F.getReturnType()->isVoidTy() && @@ -950,7 +958,11 @@ Changed |= setDoesNotAccessMemory(F); Changed |= setDoesNotThrow(F); return Changed; - + case LibFunc_ldexp: + case LibFunc_ldexpf: + case LibFunc_ldexpl: + Changed |= setSignExtendedArg(F, 1); + return Changed; default: // FIXME: It'd be really nice to cover all the library functions we're // aware of here. @@ -1265,12 +1277,15 @@ static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2, StringRef Name, IRBuilderBase &B, - const AttributeList &Attrs) { + const AttributeList &Attrs, + const TargetLibraryInfo *TLI = nullptr) { assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); Module *M = B.GetInsertBlock()->getModule(); 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 @@ -1306,7 +1321,7 @@ StringRef Name = getFloatFnName(TLI, Op1->getType(), DoubleFn, FloatFn, LongDoubleFn); - return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs); + return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs, TLI); } Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B, diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll --- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -550,13 +550,13 @@ ; CHECK: declare noundef i32 @lchown(i8* nocapture noundef readonly, i32 noundef, i32 noundef) [[G1]] declare i32 @lchown(i8*, i32, i32) -; CHECK: declare double @ldexp(double, i32) [[G0]] +; CHECK: declare double @ldexp(double, i32 signext) [[G0]] declare double @ldexp(double, i32) -; CHECK: declare float @ldexpf(float, i32) [[G0]] +; CHECK: declare float @ldexpf(float, i32 signext) [[G0]] declare float @ldexpf(float, i32) -; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32) [[G0]] +; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32 signext) [[G0]] declare x86_fp80 @ldexpl(x86_fp80, i32) ; CHECK: declare i64 @llabs(i64) [[G0]]