This is an archive of the discontinued LLVM Phabricator instance.

Add a emitUnaryFloatFnCall version that fetches the function name from TLI
ClosedPublic

Authored by uabelho on Oct 17 2018, 6:08 AM.

Details

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.

Diff Detail

Repository
rL LLVM

Event Timeline

uabelho created this revision.Oct 17 2018, 6:08 AM

Was it something like this you had in mind Eli?

lib/Transforms/Utils/SimplifyLibCalls.cpp
1081–1082 ↗(On Diff #169996)

I don't know if these calls pose any problem? Since we use the name of the function that we already called I suppose we at least shouldn't end up with a name like ""?

Also since we can deal with many different kinds of lib functions here I'm not sure how messy it is to find the double/float/long double versions of the function and use the new interface?

Suggestions?

bjope added a subscriber: bjope.Oct 17 2018, 6:32 AM
efriedma accepted this revision.Oct 17 2018, 12:24 PM
efriedma added a subscriber: efriedma.

LGTM.

It looks like you didn't touch LibCallSimplifier::optimizeLog, but I guess that's not necessary (it probably shouldn't be using emitUnaryFloatFnCall anyway).

lib/Transforms/Utils/SimplifyLibCalls.cpp
1081–1082 ↗(On Diff #169996)

In theory it's possible to run into a similar problem: the float version might not exist, or might not have the expected name. We should be using the LibFunc enum, rather than appending "f" to the name. And it's probably not that hard to fix; all the callers of optimizeBinaryDoubleFP and optimizeUnaryDoubleFP know exactly what function they're optimizing.

That said, all the callers of optimizeDoubleFP call hasFloatVersion(), which I think prevents any practical problems.

This revision is now accepted and ready to land.Oct 17 2018, 12:24 PM

LGTM.

It looks like you didn't touch LibCallSimplifier::optimizeLog, but I guess that's not necessary (it probably shouldn't be using emitUnaryFloatFnCall anyway).

Yes, I didn't touch optimizeLog or optimizeDoubleFP since they didn't use TLI->getName(), on the "double" version and thus wouldn't risk getting an empty name back from it.

But I'll submit this as is now then.

If you want me to do something with optimizeLog and/or optimizeDoubleFP I can do that in a follow-up commit.

Thanks!

lib/Transforms/Utils/SimplifyLibCalls.cpp
1081–1082 ↗(On Diff #169996)

Ok, yes we could let the callers of optimizeDoubleFP pass in the three lib versions then. Perhaps the same with optimizeLog?

This revision was automatically updated to reflect the committed changes.