[libcxx-commits] [PATCH] D107036: [WIP] [libc++] [P1614] Various unimplemented parts of <compare>. [WIP]

Kent Ross via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Aug 17 21:36:23 PDT 2021


mumbleskates added inline comments.


================
Comment at: libcxx/include/__compare/cmp_alg.h:66
+            // These two NaNs should be ordered by their payload bits,
+            // but there's no way to get at that information portably.
+            return _VSTD::signbit(__f) <=> _VSTD::signbit(__e);
----------------
Quuxplusone wrote:
> mumbleskates wrote:
> > mumbleskates wrote:
> > > I would hope that we can order them by union view of the data in memory if such a thing is allowed (or memcpy, if that's better) once we know that the sign and signaling bits are the same, because the specifics of the payload ordering are unspecified by totalOrder. Any way that we can look at the raw data in memory without UB should be sufficient.
> > Ah I see, there are literally no standard implementation for the `isSignaling` predicate for iec559 types in C++. However, it does look like ISO C has an `issignaling` macro as part of the Floating-point extensions part 1, which I gather was accepted into the C23 standard in 2019 (ISO/IEC TS 60559-1, of interest section 7.12.3.7). Complete implementation of C++ `strong_order` for iec559 floating point types might be considered to be blocked on the implementation of this part of the standard as that seems like the best place to get it.
> > 
> > Implementing this just for `strong_order` is messy, very complex, and generally inadvisable. (Even for binary floating point values, ignoring the existence of decimal floating point types, some platforms -- notably PA-RISC -- use the opposite interpretation for the signaling bit in IEC559 floating point types, even though it's in the same location.) Unless we can strongly declare that we don't support any platforms other than say ARM and x86 this seems like a no-go, and it just seems better to take the platform support directly from the llvm C standard implementation.
> @mumbleskates: I doubt I understand your two comments. In case it's not already obvious: the IEEE 754 "total order" predicate is well-defined and we //must// implement `std::strong_order` consistently with it, on IEEE 754 platforms, because the Standard says so. (On other platforms, C++ doesn't care so much, because those platforms are dumb. :)) `std::strong_order(x,y)` is //the// way that C++20 exposes the "total order" predicate to end-users; there is no isolable floating-point-total-order library function for us to delegate to (because WG21 doesn't do software engineering).
> 
> Is there an isolable "llvm C standard implementation" we could be exploiting here — some kind of `__builtin_totalorder` we could use when it's available? That would be really cool.
> I do think that this will eventually need to use either constexpr-friendly `__builtin_memcpy`, or else `std::bit_cast`; I just haven't gotten around to revisiting it.
> 
> A bit of googling turned up this solution which maybe just needs to be tweaked a tiny bit: https://stackoverflow.com/a/20154751/1424877
> 
That general solution in the stackoverflow link works, but may only be correct for x86/ARM binary representation floating point types. (I don't know enough about the decimal types to know if they would also sort this way, but they are unsupported by by x86/ARM silicon.)

What it boils down to is that the *only* predicate we are missing, for any given iec559 type, is `isSignaling`: detecting whether a NaN is signaling or not. If we have that we can use it to complete the implementation here. Such a predicate does exist in standard C, but I believe it is not yet implemented in llvm's libc.

I know exactly how to do this on x86 and ARM with bit twiddling for pretty much any floating point type in the standard, but there are platforms with iec559 implementations where the signaling bit has the opposite meaning, and I think there might exist platforms where it is in a different place. Because signaling/non-signaling NaN implementation details are a property of the platform this immediately becomes a question of platform support; it's probably best to centralize this implementation knowledge as much as possible, but I don't know much about our approach to that in the llvm project.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107036/new/

https://reviews.llvm.org/D107036



More information about the libcxx-commits mailing list