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