There are a few inline comments, but a few additional items:
- This patch should also add cmake targets.
- Why not also add fminl?
We want to get rid of BitPatterns.h, FloatOperations.h and FloatProperites.h. Look at this to see how we can do it: https://github.com/llvm/llvm-project/blob/master/libc/test/src/math/ceill_test.cpp
Same for fmin_test.cpp as well.
Can we also add tests for non-special numbers?
|1 ↗||(On Diff #275074)|
On cppreference.com, fmin et al are listed under Basic operations. So, lets put their implementations in BasicOperations.h.
|30 ↗||(On Diff #275074)|
After the NaN checks, can we just do:
return x > y ? y : x;
|32 ↗||(On Diff #275074)|
This might become irrelevant if we can do as I suggested above. But, absBits(..) returns an integer. So, the integers are being compared here and not the underlying floating point numbers.
The actual implementation LGTM. My comments are all for the test infrastructure. I have left comments only in fminl_test.cpp, but most of them are relevant for other tests as well. One of them is about using MPFR for testing fmin and friends. While what you have added to MPFRUtil will be required for functions like hypot, fma etc., it seems like it is an overkill for fmin. That said, feel free to convince me otherwise.
Wouldn't casting to unsigned long long lead to truncation? If you actually feel strongly about this setup, I would suggest adding an __uint128 overload to EXPECT_EQ and friends.
This makes the code concise, but I am finding it really hard to read. Instead of having just one SpecialNumbers test class. What do you think of having three test classes like NaNArg, InfArg, BothZero. The NaNArg class tests with at least one NaN against a variety of numbers. The InfArg test would be similar. The BothZero test would test with (+0, +0), (+0, -0), (-0, +0), (-0, -0).
+1 for this arrangement.
Continuing on x == 0 skips comparisons for the kind fmin(0, <non-zero, non-inf. non-nan>). May be skip only if x == 0 && y == 0.
Do we really need MPFR here? Considering all special numbers (including zero) are tested separately, wouldn't it be sufficient to test this way:
if (x < y) ASSERT_FP_EQ(fmin(x, y), x); else ASSERT_FP_EQ(fmix(x, y), y);
Still, overall LGTM. I have some inline comments for further chiseling. Also:
- Can you split the UnitTest changes into a separate patch?
- The variable naming style in Test.h and Test.cpp is old style like VarName. To keep the files uniform, please follow the existing style.
|11 ↗||(On Diff #278027)|
I would prefer not to need this, especially for tests.
|111 ↗||(On Diff #278027)|
Isn't this always true? For, ValType is integral or floating point type anyway?
|124 ↗||(On Diff #278027)|
Instead of printing hex values conditioned on printHex (which I think is always true), WDYT of this when streaming out LHS and RHS values:
<< " Which is: " << describeValue(LHS) << '\n';
The function describeValue is a template function which does this:
|82 ↗||(On Diff #278027)|
Instead of checking for __uint128_t, you should extend IsIntegral trait to include __uint128_t.
The tests look so much more readable now. Thanks for patiently working through the comments.
Just a note for future: We should setup differential fuzzers for math functions comparing LLVM libc results with results from system libc like glibc. And may be also a doc listing how we differ from glibc and the justification.
I have accepted this revision, but I guess you need to wait for the other patch to land before you can submit this. Also, I left couple nits inline. Please fix them if relevant.
Here, and in the other test files, I don't think you need the static_cast. We have implicit conversion operators for FPBits.