<div dir="ltr"><div>Note that the C standard [no, I can't remember the exact section/paragraph] says that "you should not use the names of existing functions in <std*.h>, <math.h>, <memory.h> and <string.h> [probably a few others too] for your own functions - the result of that is undefined" [I'm paraphrasing the spec]. In other words, functions listed by the standard as part of those header files are reserved functions, and if you use, for example, `acos` as a function name, it's not well-defined what the compiler will do. In this case, the compiler will think that it knows what `acos` does when it's declared but not defined before the call. If it's defined as well as declared before the use of it, the compiler actually knows what the function does, and thus knows that it's not "standard `acos`". But the compiler could also produce an error or do other things in this case.<br><br></div><div>So, expecting clang + LLVM to handle this "correctly" (whatever you believe is correct) is perhaps a bit of wishful thinking.<br><br></div><div>It would of course be nice to have a warning saying "redeclaration of acos, which is a library function". But as far as I see, the compiler is doing what is within the spec.<br><br>--<br></div><div>Mats<br></div><div><br><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 7 June 2016 at 17:23, Ahmed Bougacha via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><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" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div>