[llvm] r344725 - Add a emitUnaryFloatFnCall version that fetches the function name from TLI
Mikael Holmen via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 17 23:27:54 PDT 2018
Author: uabelho
Date: Wed Oct 17 23:27:53 2018
New Revision: 344725
URL: http://llvm.org/viewvc/llvm-project?rev=344725&view=rev
Log:
Add a emitUnaryFloatFnCall version that fetches the function name from TLI
Summary:
In several places in the code we use the following pattern:
if (hasUnaryFloatFn(&TLI, Ty, LibFunc_tan, LibFunc_tanf, LibFunc_tanl)) {
[...]
Value *Res = emitUnaryFloatFnCall(X, TLI.getName(LibFunc_tan), B, Attrs);
[...]
}
In short, we check if there is a lib-function for a certain type, and then
we _always_ fetch the name of the "double" version of the lib function and
construct a call to the appropriate function, that we just checked exists,
using that "double" name as a basis.
This is of course a problem in cases where the target doesn't support the
"double" version, but e.g. only the "float" version.
In that case TLI.getName(LibFunc_tan) returns "", and
emitUnaryFloatFnCall happily appends an "f" to "", and we erroneously end
up with a call to a function called "f".
To solve this, the above pattern is changed to
if (hasUnaryFloatFn(&TLI, Ty, LibFunc_tan, LibFunc_tanf, LibFunc_tanl)) {
[...]
Value *Res = emitUnaryFloatFnCall(X, &TLI, LibFunc_tan, LibFunc_tanf,
LibFunc_tanl, B, Attrs);
[...]
}
I.e instead of first fetching the name of the "double" version and then
letting emitUnaryFloatFnCall() add the final "f" or "l", we let
emitUnaryFloatFnCall() fetch the right name from TLI.
Reviewers: eli.friedman, efriedma
Reviewed By: efriedma
Subscribers: efriedma, bjope, llvm-commits
Differential Revision: https://reviews.llvm.org/D53370
Modified:
llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h
llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp
llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
Modified: llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h?rev=344725&r1=344724&r2=344725&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BuildLibCalls.h Wed Oct 17 23:27:53 2018
@@ -37,6 +37,12 @@ namespace llvm {
LibFunc DoubleFn, LibFunc FloatFn,
LibFunc LongDoubleFn);
+ /// Get the name of the overloaded unary floating point function
+ /// corresponding to \a Ty.
+ StringRef getUnaryFloatFn(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, IRBuilder<> &B);
@@ -94,6 +100,13 @@ namespace llvm {
Value *emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
const AttributeList &Attrs);
+ /// Emit a call to the unary function DoubleFn, FloatFn or LongDoubleFn,
+ /// depending of the type of Op.
+ Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
+ LibFunc DoubleFn, LibFunc FloatFn,
+ LibFunc LongDoubleFn, IRBuilder<> &B,
+ const AttributeList &Attrs);
+
/// Emit a call to the binary function named 'Name' (e.g. 'fmin'). This
/// 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
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=344725&r1=344724&r2=344725&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Wed Oct 17 23:27:53 2018
@@ -1157,7 +1157,8 @@ Instruction *InstCombiner::visitFDiv(Bin
IRBuilder<>::FastMathFlagGuard FMFGuard(B);
B.setFastMathFlags(I.getFastMathFlags());
AttributeList Attrs = CallSite(Op0).getCalledFunction()->getAttributes();
- Value *Res = emitUnaryFloatFnCall(X, TLI.getName(LibFunc_tan), B, Attrs);
+ Value *Res = emitUnaryFloatFnCall(X, &TLI, LibFunc_tan, LibFunc_tanf,
+ LibFunc_tanl, B, Attrs);
if (IsCot)
Res = B.CreateFDiv(ConstantFP::get(I.getType(), 1.0), Res);
return replaceInstUsesWith(I, Res);
Modified: llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp?rev=344725&r1=344724&r2=344725&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp Wed Oct 17 23:27:53 2018
@@ -765,6 +765,24 @@ bool llvm::hasUnaryFloatFn(const TargetL
}
}
+StringRef llvm::getUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
+ LibFunc DoubleFn, LibFunc FloatFn,
+ LibFunc LongDoubleFn) {
+ assert(hasUnaryFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
+ "Cannot get name for unavailable function!");
+
+ switch (Ty->getTypeID()) {
+ case Type::HalfTyID:
+ llvm_unreachable("No name for HalfTy!");
+ case Type::FloatTyID:
+ return TLI->getName(FloatFn);
+ case Type::DoubleTyID:
+ return TLI->getName(DoubleFn);
+ default:
+ return TLI->getName(LongDoubleFn);
+ }
+}
+
//- Emit LibCalls ------------------------------------------------------------//
Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
@@ -942,10 +960,10 @@ static void appendTypeSuffix(Value *Op,
}
}
-Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
- const AttributeList &Attrs) {
- SmallString<20> NameBuffer;
- appendTypeSuffix(Op, Name, NameBuffer);
+static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
+ IRBuilder<> &B,
+ const AttributeList &Attrs) {
+ assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
Module *M = B.GetInsertBlock()->getModule();
Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
@@ -964,8 +982,29 @@ Value *llvm::emitUnaryFloatFnCall(Value
return CI;
}
+Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
+ const AttributeList &Attrs) {
+ SmallString<20> NameBuffer;
+ appendTypeSuffix(Op, Name, NameBuffer);
+
+ return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
+}
+
+Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
+ LibFunc DoubleFn, LibFunc FloatFn,
+ LibFunc LongDoubleFn, IRBuilder<> &B,
+ const AttributeList &Attrs) {
+ // Get the name of the function according to TLI.
+ StringRef Name = getUnaryFloatFn(TLI, Op->getType(),
+ DoubleFn, FloatFn, LongDoubleFn);
+
+ return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
+}
+
Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
IRBuilder<> &B, const AttributeList &Attrs) {
+ assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
+
SmallString<20> NameBuffer;
appendTypeSuffix(Op1, Name, NameBuffer);
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=344725&r1=344724&r2=344725&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Wed Oct 17 23:27:53 2018
@@ -1219,17 +1219,26 @@ Value *LibCallSimplifier::replacePowWith
StringRef ExpName;
Intrinsic::ID ID;
Value *ExpFn;
+ LibFunc LibFnFloat;
+ LibFunc LibFnDouble;
+ LibFunc LibFnLongDouble;
switch (LibFn) {
default:
return nullptr;
case LibFunc_expf: case LibFunc_exp: case LibFunc_expl:
- ExpName = TLI->getName(LibFunc_exp);
+ ExpName = "exp";
ID = Intrinsic::exp;
+ LibFnFloat = LibFunc_expf;
+ LibFnDouble = LibFunc_exp;
+ LibFnLongDouble = LibFunc_expl;
break;
case LibFunc_exp2f: case LibFunc_exp2: case LibFunc_exp2l:
- ExpName = TLI->getName(LibFunc_exp2);
+ ExpName = "exp2";
ID = Intrinsic::exp2;
+ LibFnFloat = LibFunc_exp2f;
+ LibFnDouble = LibFunc_exp2;
+ LibFnLongDouble = LibFunc_exp2l;
break;
}
@@ -1238,7 +1247,9 @@ Value *LibCallSimplifier::replacePowWith
ExpFn = BaseFn->doesNotAccessMemory()
? B.CreateCall(Intrinsic::getDeclaration(Mod, ID, Ty),
FMul, ExpName)
- : emitUnaryFloatFnCall(FMul, ExpName, B, BaseFn->getAttributes());
+ : emitUnaryFloatFnCall(FMul, TLI, LibFnDouble, LibFnFloat,
+ LibFnLongDouble, B,
+ BaseFn->getAttributes());
// Since the new exp{,2}() is different from the original one, dead code
// elimination cannot be trusted to remove it, since it may have side
@@ -1275,7 +1286,8 @@ Value *LibCallSimplifier::replacePowWith
return B.CreateCall(Intrinsic::getDeclaration(Mod, Intrinsic::exp2, Ty),
FMul, "exp2");
else
- return emitUnaryFloatFnCall(FMul, TLI->getName(LibFunc_exp2), B, Attrs);
+ return emitUnaryFloatFnCall(FMul, TLI, LibFunc_exp2, LibFunc_exp2f,
+ LibFunc_exp2l, B, Attrs);
}
}
@@ -1283,7 +1295,8 @@ Value *LibCallSimplifier::replacePowWith
// TODO: There is no exp10() intrinsic yet, but some day there shall be one.
if (match(Base, m_SpecificFP(10.0)) &&
hasUnaryFloatFn(TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
- return emitUnaryFloatFnCall(Expo, TLI->getName(LibFunc_exp10), B, Attrs);
+ return emitUnaryFloatFnCall(Expo, TLI, LibFunc_exp10, LibFunc_exp10f,
+ LibFunc_exp10l, B, Attrs);
return nullptr;
}
@@ -1304,7 +1317,8 @@ static Value *getSqrtCall(Value *V, Attr
// TODO: We also should check that the target can in fact lower the sqrt()
// libcall. We currently have no way to ask this question, so we ask if
// the target has a sqrt() libcall, which is not exactly the same.
- return emitUnaryFloatFnCall(V, TLI->getName(LibFunc_sqrt), B, Attrs);
+ return emitUnaryFloatFnCall(V, TLI, LibFunc_sqrt, LibFunc_sqrtf,
+ LibFunc_sqrtl, B, Attrs);
return nullptr;
}
More information about the llvm-commits
mailing list