<div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, 29 Nov 2018 at 17:55, Stephan T. Lavavej via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Clang devs,<br>
<br>
WG21 has voted in a bunch of C++20 STL features that need compiler support via builtins/intrinsics. As usual, MSVC's STL would like to use identically-named builtins for Clang, C1XX, and EDG, so I wanted to ask if you've chosen any names (and interfaces) yet. Also as usual, I have utterly no opinion about naming - any name that gets the compiler to do my work for me is amazing (as long as all compilers are consistent). :-)<br>
<br>
* P0595R2 std::is_constant_evaluated()<br>
Should this be __is_constant_evaluated() or __builtin_is_constant_evaluated() or something else?<br></blockquote><div><br></div><div>For us (and I'd guess for GCC), __builtin_is_constant_evaluated() would be the most natural choice.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* P0482R6 char8_t<br>
Given std::is_constant_evaluated(), we might not need anything new here. Otherwise, should there be analogues of __builtin_memcmp(), __builtin_strlen(), and __builtin_char_memchr() for constexpr char_traits<char8_t>?<br></blockquote><div><br></div><div>These seem low-priority given std::is_constant_evaluated(), but I think it might still be nice to have the builtins even if you don't formally need them. Our __builtin_mem* and __builtin_str* are a lot faster to evaluate than the equivalent hand-rolled C++ code would be. (Clang has a __has_builtin builtin macro to allow these to be detected and used if available. Does MSVC have anything similar?)</div><div><br></div><div>Approximately following the naming convention of wcscmp etc, maybe __builtin_u8scmp, __builtin_u8slen, __builtin_u8scpy, ...? (Should we also add __builtin_u16s* and __builtin_u32s* while we're here?)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* P0476R2 std::bit_cast()<br>
This came up a month ago, where Richard Smith suggested __builtin_bit_cast(To, value) or __bit_cast<To>(value), preferring the former (for C friendliness). Was a final name chosen?<br></blockquote><div><br></div><div>(I need to keep reminding myself: this can't be __builtin_bit_cast(&dest, &src) because the To type might not be default-constructible.)</div><div><br></div><div>Unless someone wants to provide a counterargument, let's go with __builtin_bit_cast(To, value).</div><div><br></div><div>constexpr T __builtin_bit_cast(typename T, const U &src)</div><div>Effects: Bit-cast the value of src to type T. Ill-formed if T and U are of different sizes. Only guaranteed to be usable in constant expressions in the conditions specified for std::bit_cast.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* P0528R3 Atomic Compare-And-Exchange With Padding Bits<br>
We need compiler magic here, in some form. Billy O'Neal wrote to the C1XX team: "To implement the new atomic_ref as well as the change to compare the value representation of atomics only, the library needs a way to zero out the padding in arbitrary T, which we can't discover with library tech alone. We would like an intrinsic that accepts a trivially-copyable T and produces a copy with the padding zeroed, or takes a T* and zeros the padding inside that T, or similar."<br></blockquote><div><br></div><div>I think this should be done in-place in memory; producing a copy has the problem that you're passing around a value of type T, and that might permit the padding bits to become undefined again.</div><div><br></div><div>void __builtin_clear_padding(T *ptr)</div><div>Effects: Set to zero all bits that are padding bits in the representation of every value of type T.</div><div><br></div><div>Do we need to allow this to be called in constant expressions?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* P0758R1 std::is_nothrow_convertible<br>
This can be implemented without an intrinsic (std::is_nothrow_invocable_r already demands it; std::is_convertible plus noexcept plus library cleverness works), but an intrinsic is higher throughput (and simpler for third-party libraries that want to imitate the STL without using the STL for whatever reason). MSVC's spelling for the plain trait is __is_convertible_to(From, To); should the new trait be __is_nothrow_convertible_to(From, To) or __is_nothrow_convertible(From, To)?<br></blockquote><div><br></div><div>I would generally prefer that we expose traits that exactly match the library requirements with the same name as the library trait with a leading dunder, with an argument list matching the library trait. So:</div><div>Add __is_convertible(From, To) and __is_nothrow_convertible(From, To)</div><div>Make __is_convertible_to a (deprecated) synonym for __is_convertible.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* P1007R3 std::assume_aligned()<br>
MSVC supports a general __assume() although I'm unsure if it's applicable/desirable here. Should there be a dedicated builtin?<br></blockquote><div><br></div><div>Well, Clang already supports __assume() for MSVC compatibility (only in MS mode) and __builtin_assume() (our preferred spelling, available in general). But a general assume intrinsic is probably not the best choice here.</div><div><br></div><div>Clang and GCC also already have:</div><div><br></div><div>void *__builtin_assume_aligned(const void *p, size_t align, size_t offset_from_aligned = 0)<br></div><div>See <a href="https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html">https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html</a><br></div><div><br></div><div>That's not ideal because it's not const-correct.</div><div><br></div><div>Even for library wording, the spec is weak on specifying when a call to std::assume_aligned is allowed in constant expressions. For Clang at least, we treat a call to __builtin_assume_aligned as non-constant if we cannot prove the object is suitably aligned (that is, if the complete object's alignment and the offset within it don't result in a suitable alignment) even if we happen to know that (for instance) a global variable will typically be aligned to 16 bytes in practice.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* I think this list is complete but I might be missing some features.<br></blockquote><div><br></div><div>How about:</div><div>* invocation type traits from Library Fundamentals V1 </div><div>* source_location from Library Fundamentals V2</div></div></div></div>