Page MenuHomePhabricator

Mark libm builtins as such.
ClosedPublic

Authored by chatur01 on May 21 2015, 7:45 AM.

Details

Reviewers
rengolin
Summary

The builtins didn't have the F flag set on them. D9912 relies on this change.

Diff Detail

Event Timeline

chatur01 retitled this revision from to Mark libm builtins as such..
chatur01 updated this object.
chatur01 edited the test plan for this revision. (Show Details)
chatur01 set the repository for this revision to rL LLVM.
chatur01 added a subscriber: Unknown Object (MLST).

Isn't this the case for the others below, too?

chatur01 added a reviewer: rengolin.
chatur01 removed rL LLVM as the repository for this revision.

I missed signbit, the other maths related builtins do not appear to be standard libm builtins, so I've left them out.

Thanks very much for the review :)

Make the signbit parameter generic to handle real-floating type.

rengolin edited edge metadata.Jun 23 2015, 5:05 AM

Hi Charlie,

I think this looks ok, but can you enlighten me a bit?

From what I read here [1], these builtins can be compiler replacements for library functions, especially if they have the "__builtin" prefix:

"... may be handled as built-in functions. All these functions have corresponding versions prefixed with __builtin_ ..."

And from the bug report [2], what Android needs is for it to be re-declared differently, and that's why you're adding them as library calls, so that can happen.

Is then, this patch ultimately linked to D9912? Or does this make sense on its own? If it does, I'm failing to see why. :)

cheers,
--renato

[1] https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
[2] https://llvm.org/bugs/show_bug.cgi?id=20958

Hey Renato, thanks very much for taking another look.

From what I read here [1], these builtins can be compiler replacements for library functions, especially if they have the "__builtin" prefix:

Right. There are still some omissions in what Clang marks up a library builtin and what GCC does outside strict ISO C mode.

You already pointed out the signbit omissions, but here are all the ones I still haven't marked up after this patch

BUILTIN(__builtin_signbitf, "if", "nc")
BUILTIN(__builtin_signbitl, "iLd", "nc")
BUILTIN(__builtin_ffsll, "iLLi", "nc")
BUILTIN(__builtin_bcmp, "iv*v*z", "n")
BUILTIN(__builtin_alloca, "v*z"   , "n")

I wasn't sure if Clang would be interested in compatibility in this case. So I originally focused on the C99 floating point stuff that is part of a standard I could read. Do you think I should patch up the above missing bits too?

"... may be handled as built-in functions. All these functions have corresponding versions prefixed with __builtin_ ..."

And from the bug report [2], what Android needs is for it to be re-declared differently, and that's why you're adding them as library calls, so that can happen.

That's basically it. These C99 floating-point functions are defined as taking either a float, a double or a long double as argument(s). Operationally, we don't want to commit to declaring one of these options too soon, since the user (as in the Android case) might want to redeclare it in an incompatible (but legal) way later. What Clang currently does is declare the type-generic builtins like this with an empty parameter list, which gives weird behaviour in both C and C++ when you try to redeclare them. I'm marking them up as library calls so that I can selectively handle just the builtins I need to in my patch in D9912.

Is then, this patch ultimately linked to D9912? Or does this make sense on its own? If it does, I'm failing to see why. :)

I tried to mention that with my link in Phabricator, but I realize I've failed to make it clear. There doesn't seem to be a good way of posting a logical patch set to Phab. Aside from D9912 relying on this change, I also think it's fine to go in on its own, since these builtins should be marked up as "F", given that they're listed in the C99 standard. Do you agree?

Thanks again for your time,

  • Charlie.

[1] https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
[2] https://llvm.org/bugs/show_bug.cgi?id=20958

I wasn't sure if Clang would be interested in compatibility in this case. So I originally focused on the C99 floating point stuff that is part of a standard I could read. Do you think I should patch up the above missing bits too?

That's my point. If this patch makes sense on its own, we should mark them all. I have no idea how to test it, though.

What Clang currently does is declare the type-generic builtins like this with an empty parameter list, which gives weird behaviour in both C and C++ when you try to redeclare them. I'm marking them up as library calls so that I can selectively handle just the builtins I need to in my patch in D9912.

There are many odd things about this... First, Clang declaring it empty looks like a hack in Clang to "cross that bridge when we get there" kind of "solution". Second, marking them as library calls, when they're really builtin versions of library calls, is also a bit dodgy. Finally, Android has a bad reputation of re-implementing low-level libraries by calling higher-level libraries (for example, __aeabi_memcpy calling libc's memcpy), which is *also* shoddy.

I have no preference, but it would be good to be only as consistent as we need to be. Ie. not enable things we're not going to use just because it's similar to the ones we will use.

Since this smells like another hack to make Android work without really fixing Clang, I'd suggest moving it to the original patch (D9912) with a good comment about the reason we're doing this.

I tried to mention that with my link in Phabricator, but I realize I've failed to make it clear. There doesn't seem to be a good way of posting a logical patch set to Phab.

There isn't. That's why I do a (git diff -U999 master > patch) every time and deal with patch-sets only locally. Gerrit seems to be a lot better on this, but once you have submitted a patch set, squashing and rebasing gets *a lot* worse, so I'm not fond of either way. Github is better.

Aside from D9912 relying on this change, I also think it's fine to go in on its own, since these builtins should be marked up as "F", given that they're listed in the C99 standard. Do you agree?

AFAICS, they're not listed in C99, only their counterparts without the __builtin_ are. IIUC, these builtins are the compiler trying to be smart about implementation details, and that's why Android shouldn't be fiddling with them in the first place. But alas, that's the way of the Android. Whatever compiles, ship it.

My opinion is to move this into D9912 and only change the ones you really need, with a comment on why you're changing (maybe a FIXME?).

cheers,
--renato

hfinkel added a subscriber: hfinkel.Jul 9 2015, 5:33 PM

I wasn't sure if Clang would be interested in compatibility in this case. So I originally focused on the C99 floating point stuff that is part of a standard I could read. Do you think I should patch up the above missing bits too?

That's my point. If this patch makes sense on its own, we should mark them all.

I agree.

I have no idea how to test it, though.

What Clang currently does is declare the type-generic builtins like this with an empty parameter list, which gives weird behaviour in both C and C++ when you try to redeclare them. I'm marking them up as library calls so that I can selectively handle just the builtins I need to in my patch in D9912.

There are many odd things about this... First, Clang declaring it empty looks like a hack in Clang to "cross that bridge when we get there" kind of "solution". Second, marking them as library calls, when they're really builtin versions of library calls, is also a bit dodgy. Finally, Android has a bad reputation of re-implementing low-level libraries by calling higher-level libraries (for example, __aeabi_memcpy calling libc's memcpy), which is *also* shoddy.

I have no preference, but it would be good to be only as consistent as we need to be. Ie. not enable things we're not going to use just because it's similar to the ones we will use.

Since this smells like another hack to make Android work without really fixing Clang, I'd suggest moving it to the original patch (D9912) with a good comment about the reason we're doing this.

I tried to mention that with my link in Phabricator, but I realize I've failed to make it clear. There doesn't seem to be a good way of posting a logical patch set to Phab.

There isn't. That's why I do a (git diff -U999 master > patch) every time and deal with patch-sets only locally. Gerrit seems to be a lot better on this, but once you have submitted a patch set, squashing and rebasing gets *a lot* worse, so I'm not fond of either way. Github is better.

Aside from D9912 relying on this change, I also think it's fine to go in on its own, since these builtins should be marked up as "F", given that they're listed in the C99 standard. Do you agree?

AFAICS, they're not listed in C99, only their counterparts without the __builtin_ are. IIUC, these builtins are the compiler trying to be smart about implementation details

I don't understand this part of the conversation. include/clang/Basic/Builtins.def says:

//  F -> this is a libc/libm function with a '__builtin_' prefix added.
//  f -> this is a libc/libm function without the '__builtin_' prefix. It can
//       be followed by ':headername:' to state which header this function
//       comes from.

this patch does not mark these with 'f', but with 'F', and they are indeed libm functions with __builtin_ added.

, and that's why Android shouldn't be fiddling with them in the first place. But alas, that's the way of the Android. Whatever compiles, ship it.

My opinion is to move this into D9912 and only change the ones you really need, with a comment on why you're changing (maybe a FIXME?).

cheers,
--renato

That's my point. If this patch makes sense on its own, we should mark them all.

I agree.

Ok, let's just do it then. I believe this is clearly a typo/forgotten kind of thing.

Charlie, can you mark all of the affected builtins with "F"?

I don't understand this part of the conversation. include/clang/Basic/Builtins.def says:

//  F -> this is a libc/libm function with a '__builtin_' prefix added.
//  f -> this is a libc/libm function without the '__builtin_' prefix. It can
//       be followed by ':headername:' to state which header this function
//       comes from.

this patch does not mark these with 'f', but with 'F', and they are indeed libm functions with __builtin_ added.

That's the point. "f" is for libc functions that don't get overriden by the compiler with a "__builtin_" prefix. All of these *do* have prefix, so they need to be marked as "F".

The point here being that __builtin_isnan, for instance, is a builtin that can be either lowered as a sequence of instructions, or as a libc call to isnan, depending on the target. This is precisely the meaning of "F".

cheers,
--renato

chatur01 edited edge metadata.

Thanks very much Renato and Hal for giving this one another look and apologies for my delay getting back, I've been on holiday.

I have updated the patch to mark up all libm functions as described in the first section of,

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

Which are the functions GCC has defined as being part of libc implementations. The other builtins listed on that page are there just for optimization purposes.

The way I tested this was to take each chunk of functions listed in each of the ISO C* paragraphs from the above page, and grep for each function name in Builtins.def, checking whether F was part of that builtin's mark up. After this patch, all those checks pass.

OK to land?

rengolin accepted this revision.Jul 20 2015, 6:29 AM
rengolin edited edge metadata.
This revision is now accepted and ready to land.Jul 20 2015, 6:29 AM
chatur01 closed this revision.Jul 20 2015, 7:37 AM

Thanks Renato, r242675 landed.