[llvm-dev] llvm intrinsics/libc/libm question

Ryan Taylor via llvm-dev
Tue, 07 Jun 2016 20:24:20 -0000

In the first code I see a 'tail call @acos', in the second code I see a
tail call @llvm.acos.f32'. (sorry, there should be only one input for acos,
I've been trying many libm/libc functions).

Not sure why it's called TargetLibraryInfo if it's not in target
specific
code? It seems that ALL targets use this code, making it generic. Am I
missing something here?

Basically you're saying if I changed/added the XXXacos in
TargetLibraryInfo::hasOptimizedCodeGen then the ConstantFolding (and other
opts) could then opt for this libm call?

Thanks,

Ryan

ps. The spec also states (albeit unclearly) that you can use "#undef"
to
omit a library function so that a user defined function of the same name
can be used but LLVM doesn't seem to support that.


On Tue, Jun 7, 2016 at 12:23 PM, Ahmed Bougacha <ahmed.bougacha at
gmail.com>
wrote:

> On Tue, Jun 7, 2016 at 8:03 AM, Ryan Taylor via llvm-dev
> <llvm-dev at lists.llvm.org> wrote:
> > I'm trying to figure out exactly how the intrinsics/libc/libm work
in
> llvm.
>
> Intrinsics are basically "lesser" instructions that aren't
guaranteed
> to have first-class support (e.g., work on all targets). They are
> specified in the LangRef.
>
> Target intrinsics are similar to generic intrinsics, but are
> specifically only available on one target. They are (intentionally
> under-) specified in the various Intrinsics<Target>.td files.
>
> Some functions (libc, libm, and a few others) are recognized as having
> well-defined behavior for the target platform;  this information is in
> TargetLibraryInfo.
>
> > For example, this code return user defined function:
> >
> >
> > float acos(float x, float y)
> > {
> >     return x+y;
> > }
> >
> > float a;
> > void foo(float b, float c)
> > {
> >  a = acos(b, c);
> > }
> >
> >
> > But this code returns llvm.intrinsic:
> >
> >
> > float acos(float, float);
> >
> > float a;
> > void foo(float b, float c)
> > {
> >  a = acos(b, c);
> > }
> >
> > float acos(float x, float y)
> > {
> >  return x+y;
> > }
> >
> > What is the expected behavior here?
>
> I don't see how they can behave differently.  What IR are you seeing?
>
> > Also, there are certain "standard C library functions"
included in LLVM
> that
> > I'd like to remove without modifying core code, is this possible?
>
> If you're using clang: -fno-builtin=acos is what you're looking
for.
>
> If you're using llvm: when setting up your pass pipeline, you should
> create an instance of TargetLibraryInfo (an example is in
> tools/opt/opt.cpp), and either use:
> - setUnavailable(LibFunc::acos): this marks acos as
"unavailable",
> preventing optimizations from making assumptions about its behavior.
> Equivalent to clang -fno-builtin-acos
> - disableAllFunctions(): this marks all known functions as
> unavailable.  Equivalent to clang -fno-builtin
>
> > I'm also curious how LLVM handles pure functions in regards to
> > optimizations. For example, libm functions such as acos.
>
> Note that I don't think libm functions are pure on most platform,
> because they can modify errno (-ffast-math/-fno-math-errno disables
> that, though).
>
> > It appears that X86
> > doesn't have acos as an intrinsic and instead just calls a
function "tail
> > call @acos...", is this still able to be optimized.
>
> Yes, because TLI knows about the name 'acos'.  However, the
prototype
> needs to be reasonably correct ('double @acos(double)'), but
isn't in
> your example.  (Specifically, ConstantFolding checks that @acos only
> has one operand, but yours has two.)
>
> > I see the hardcoded
> > 'name' lookup for 'acos' in ConstantFolding.cpp. It
doesn't appear that
> if
> > you slightly change the name from 'acos' to say
'XXX_acos' in your libm
> > it'll still be optimized?
>
> Correct, it won't be.
>
> It's possible to make that happen with a few patches, but there has
> been no need for that yet:
>
> - replace the various calls to TLI::has() or
> TLI::getLibFunc(StringRef, Func&) with TLI::getLibFunc(Function&,
> Func&).  Any of the former are probably hiding bugs related to
> incorrect prototypes
>
> - teach TLI::getLibFunc to check function availability using the
> custom name instead of always checking the standard name.  Again, this
> is (arguably) hiding bugs, where we recognize the standard name even
> though it's not what the target uses
>
> - fix canConstantFoldCallTo to pass it TLI or maybe remove it entirely
> (it's always used before ConstantFoldCall, which does check TLI)
>
> - tell TLI that 'acos' is available with name 'XXX_acos'
for your target
>
> -Ahmed
>
> > Thanks,
> >
> > Ryan
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > llvm-dev at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160607/a1a612c6/attachment.html>