Ryan Taylor via llvm-dev
2016-Jun-07 15:03 UTC
[llvm-dev] llvm intrinsics/libc/libm question
I'm trying to figure out exactly how the intrinsics/libc/libm work in llvm. 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? Also, there are certain "standard C library functions" included in LLVM that I'd like to remove without modifying core code, is this possible? I'm also curious how LLVM handles pure functions in regards to optimizations. For example, libm functions such as acos. 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. 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? Thanks, Ryan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160607/dc0548f5/attachment.html>
Ahmed Bougacha via llvm-dev
2016-Jun-07 16:23 UTC
[llvm-dev] llvm intrinsics/libc/libm question
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 >
mats petersson via llvm-dev
2016-Jun-07 16:42 UTC
[llvm-dev] llvm intrinsics/libc/libm question
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. So, expecting clang + LLVM to handle this "correctly" (whatever you believe is correct) is perhaps a bit of wishful thinking. 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. -- Mats On 7 June 2016 at 17:23, Ahmed Bougacha via llvm-dev < llvm-dev at lists.llvm.org> 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 > > > _______________________________________________ > 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/95b54324/attachment.html>
Ryan Taylor via llvm-dev
2016-Jun-07 20:24 UTC
[llvm-dev] llvm intrinsics/libc/libm question
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>