This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Assume that builtins for math.h functions are available
ClosedPublic

Authored by philnik on Oct 12 2022, 7:52 AM.

Details

Summary

All supported compilers support the builtins, so this removes dead code and simplifies a lot of the functions through that.

Diff Detail

Event Timeline

philnik created this revision.Oct 12 2022, 7:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 12 2022, 7:52 AM
philnik requested review of this revision.Oct 12 2022, 7:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 12 2022, 7:52 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik updated this revision to Diff 469400.Oct 20 2022, 4:22 PM

Rebase on top of main

philnik updated this revision to Diff 469541.Oct 21 2022, 4:01 AM

Try to fix CI

ldionne requested changes to this revision.Oct 27 2022, 10:12 AM
ldionne added inline comments.
libcxx/include/math.h
294

Mingw is failing the clang-tidy test, and only that. Can you please figure out what's wrong and add the missing tests?

516

Those all need to be inline for ODR.

637

You removed __promote here and in a bunch of other places. Can you please do that as a separate patch (including the ones that are trivial, i.e. __promote<T> where T is a floating point). That will make this change easier to validate.

1049

If the C library does not provide copysign(double, double), this is infinite recursion. This is too subtle and the failure mode is terrible, i.e. this should never be a runtime error. Instead, let's do this (per live review just now):

#include <type_traits>

// in C library
float copysignf(float, float);
double copysign(double, double);
long double copysignl(long double, long double);

// in libc++
inline auto copysign(float, float);
inline auto copysign(long double, long double);
template <class = int>
inline auto copysign(double x, double) { return x; }
template <class _Tp, class _Up,
          std::enable_if_t<std::is_arithmetic<_Tp>::value && std::is_arithmetic<_Up>::value, int> = 0>
inline auto copysign(_Tp __x, _Up __y);


int main() {
    double d = 0;
    copysign(d, d);
}
This revision now requires changes to proceed.Oct 27 2022, 10:12 AM
EricWF added a subscriber: EricWF.Oct 28 2022, 10:47 AM

Please start putting the rational in the change description.

How have you verified that these built ins are always provided?
Obviously, this would be less complex and nicer if we could assume their presence, but I have no doubt this more complicated code was written because we couldn't at some point.

Obviously, this would be less complex and nicer if we could assume their presence, but I have no doubt this more complicated code was written because we couldn't at some point.

Our compiler requirements have changed a lot since 2012, and nowadays the compilers we support are tested in the CI. I assume @philnik's reasoning was that "I'll try doing it, and if the CI is happy, then it means that all supported compilers are happy". That's what we normally do and it has led to large simplifications (e.g. in how we implement type_traits). I agree it would make sense to record that rationale (or whatever the rationale is in case I'm wrong) in the commit message though.

Obviously, this would be less complex and nicer if we could assume their presence, but I have no doubt this more complicated code was written because we couldn't at some point.

Our compiler requirements have changed a lot since 2012, and nowadays the compilers we support are tested in the CI. I assume @philnik's reasoning was that "I'll try doing it, and if the CI is happy, then it means that all supported compilers are happy". That's what we normally do and it has led to large simplifications (e.g. in how we implement type_traits). I agree it would make sense to record that rationale (or whatever the rationale is in case I'm wrong) in the commit message though.

It's my understanding that the availability of some of these builtins is a property of what math libraries happen to be on the system that compiled the compiler. As in, if the compiler doesn't have a math library which can perform the computation, it doesn't provide the builtin. Am I incorrect about that?

That would mean that the availability of the builtins is sometimes independent of compiler version.

philnik marked an inline comment as done.Oct 29 2022, 1:28 PM

Obviously, this would be less complex and nicer if we could assume their presence, but I have no doubt this more complicated code was written because we couldn't at some point.

Our compiler requirements have changed a lot since 2012, and nowadays the compilers we support are tested in the CI. I assume @philnik's reasoning was that "I'll try doing it, and if the CI is happy, then it means that all supported compilers are happy". That's what we normally do and it has led to large simplifications (e.g. in how we implement type_traits). I agree it would make sense to record that rationale (or whatever the rationale is in case I'm wrong) in the commit message though.

It's my understanding that the availability of some of these builtins is a property of what math libraries happen to be on the system that compiled the compiler. As in, if the compiler doesn't have a math library which can perform the computation, it doesn't provide the builtin. Am I incorrect about that?

That would mean that the availability of the builtins is sometimes independent of compiler version.

I can't find any indication that the builtins are provided conditionally. It also doesn't really make sense, since the compiler could still emit the call, even if the hosting environment doesn't provide the function.

libcxx/include/math.h
516

These are templates, so they are implicitly inline.

EricWF requested changes to this revision.Oct 30 2022, 10:57 AM

I can't find any indication that the builtins are provided conditionally. It also doesn't really make sense, since the compiler could still emit the call, even if the hosting environment doesn't provide the function.

Good point. We can ship this and see if anything blows up.

But @ldionnes comments need to be addressed. And are a good example of why changes like this should be scoped to a single type of change.

But this still needs a description before it proceeds.

libcxx/include/math.h
1049

Good spotting.

EricWF added a comment.EditedOct 30 2022, 11:22 AM

I can't find any indication that the builtins are provided conditionally. It also doesn't really make sense, since the compiler could still emit the call, even if the hosting environment doesn't provide the function.

Good point.

~~~What about -Xclang -fno-math-builtins? Clang provides an option to turn the builtins off, and libc++ currently works when it's specified. We should state why we don't care about supporting this option.~~~

There may be specific logic in clang to ignore -Xclang -fno-math-builtins inside the math.h header. So ignore the question.

But @ldionnes comments need to be addressed. And are a good example of why changes like this should be scoped to a single type of change.

But this still needs a description before it proceeds.

philnik marked 2 inline comments as done.Oct 30 2022, 11:54 AM

~~~What about -Xclang -fno-math-builtins? Clang provides an option to turn the builtins off, and libc++ currently works when it's specified. We should state why we don't care about supporting this option.~~~

AFAICT this is still supported. Clang just doesn't add any attributes to the math functions anymore: https://godbolt.org/z/EfKhx896Y

~~~What about -Xclang -fno-math-builtins? Clang provides an option to turn the builtins off, and libc++ currently works when it's specified. We should state why we don't care about supporting this option.~~~

AFAICT this is still supported. Clang just doesn't add any attributes to the math functions anymore: https://godbolt.org/z/EfKhx896Y

Great, thanks for correcting my ignorance here.

libcxx/include/math.h
617–618

Were'n

philnik updated this revision to Diff 471873.Oct 30 2022, 2:12 PM
philnik marked 4 inline comments as done.
  • Rebased
  • Address comments
  • Try to fix CI
libcxx/include/math.h
294

This should be fixed in D136908.

617–618

I guess this wasn't planned?

philnik edited the summary of this revision. (Show Details)Oct 30 2022, 2:13 PM
philnik updated this revision to Diff 472187.Oct 31 2022, 5:01 PM

Try to fix Windows

philnik updated this revision to Diff 472289.Nov 1 2022, 7:02 AM

Next trNext tryy

philnik updated this revision to Diff 472371.Nov 1 2022, 12:19 PM

enable overloads on MinGW

ldionne added inline comments.Nov 3 2022, 8:49 AM
libcxx/include/math.h
286

Can you try to:

  1. Reformat the existing code in a separate patch
  2. Make your change without packing the ifdefs
  3. Then pack the ifdefs as a different patch

If that doesn't make the diff any better, nvm we'll review as-is, but I find it tricky to validate in the current state of the diff.

EricWF accepted this revision as: EricWF.Nov 6 2022, 2:45 PM
ldionne accepted this revision.Nov 17 2022, 9:30 AM
ldionne added inline comments.
libcxx/include/math.h
1007–1008

Can you make a TODO to clean this up?

1049

@philnik Can you please triple check that this is not an issue anymore? I'm approving this but contingent on this not being an issue.

This behavior would be really, really not acceptable for users.

This revision is now accepted and ready to land.Nov 17 2022, 9:30 AM