I would like to propose that when available, if a C builtin function has an equivalent llvm intrinsic, that the intrinsic be the preferred form. The equivalent clang __builtin should emit the intrinsic, and SimplifyLibCalls should replace calls with the intrinsic.
1. Intrinsics have additional properties that help optimizations. They are more widely considered by optimization passes, such as being vectorizable and speculatively executable.
2. More useful for targets where the concept of libcalls is not useful. On GPU targets where there is no machine level linked library, a correct TargetLibraryInfo would report no supported library functions, disabling optimizations on that function. Ideally we could specify libcalls as another function defined in the IR, but that is a separate problem.
3. Consistency. Some __builtins emit the llvm intrinsics, and others do not.
4. It seems unnatural to me to emit a special DAG node for specific calls, then for most targets to later on expand it again as a call later.
5. Eliminate redundant code. Places like ConstantFolding currently have to handle the intrinsic and the libcall
As long as you make sure that it deals properly with renames used on the
prototypes... E.g. a call to "double sin(double)" can easily be forced
to use "my_better_sin_function" on the C level. One huge problem with
the "everything as __builtin mess" GCC introduced was to effectively
remove any sane way to model such behavior.
I'm not familiar with what happened to GCC, but I like this proposal
because I know there are optimization holes due to not matching both the
intrinsic and the libcall. Double --> float shrinking and fmax/fmin are
cases I noticed recently. Pulling the intrinsic optimizations out of
SimplifyLibCalls should also make it easier to refactor the library
function prototype checking. I made a few changes here after https://llvm.org/bugs/show_bug.cgi?id=26211 , but it's still a mess.
cc'ing Davide as he might have some ideas about cleaning up
SimplifyLibCalls too.
I would like to propose that when available, if a C builtin function has an equivalent llvm intrinsic, that the intrinsic be the preferred form. The equivalent clang __builtin should emit the intrinsic, and SimplifyLibCalls should replace calls with the intrinsic.
+1
I think this is a really good cleanup. In particular, the legality matching for known library calls should be in one place and one place only. It's currently spread out all over the place.