<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/115719>115719</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[LIBC]: Implementation of `stdc_first_trailing_one` seems wrong
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
strncmp
</td>
</tr>
</table>
<pre>
While studying the code of LLVM libc I spotted this [function](https://github.com/llvm/llvm-project/blob/bc368e4b578730bf0b10acd5412e476ccf7a5807/libc/src/__support/math_extras.h#L149) which is the backend implementation of the `stdc_first_trailing_one` family. The edge case testing seems wrong, since the max value (a value filled with ones) would yield zero, meaning that no bits set to the value one were found. That's wrong according the the standard. This function returns zero, only when it cannot find the first trailing bit set to one. The only value with this property is zero, but the function tests for the max value instead. Here is the wording from [N3220](https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf):
![εικόνα](https://github.com/user-attachments/assets/4995916e-4e51-4176-b799-4908ec9b4a30)
The implementation should be something like the following:
```Cpp
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_trailing_one(T value) {
return value == T(0) ? 0 : cpp::countr_zero(value) + 1;
}
```
I also tested the [gcc intrinsics](https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fstdc_005ffirst_005ftrailing_005fone) where the results seem to follow the wording of the standard.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVU1v4zYQ_TX0ZWBDor4PPsT2unWRbg8NukeBIkcSuxQpkFQc99cXpOyk3S5aNIgpSqJm3rx5M8Ock4NG3JPiQIrThi1-NHbvvNV8mjedEbf9l1EqBOcXcZN6AD8icCMQTA_Pz7_9DEp2HC7gZuM9CvCjdECKQ79o7qXRpDgRWo_ez45kT4SeCT0P0o9Lt-NmIvSs1Ovjsp2t-R25J_TcKdOFC8_KGvOuqOoqS7o-6dKEcVHkKcW8KjnvK1bUSRUMyI4TenY2rG3rlnk2NpiamB9bfPOWud1IaPac5g2hDVxHyUeQLobUMf4VtQA5zQon1J4F8CHI8JaUifOCt720zrfeMqmkHlqjkZQJ9GyS6raDlxEBxYDAmUPw6HwgzCFODq7W6IHQIzipOUajE3uDV6YWBEJrdt_2UikUcJV-BKPRRaBmUQJuEpWAP9CaYGZCptd0MA_aQCe9A4cevInGV2tGI1zRIvRm0SIgZJ7Q6g4HGOfGikdWw895pgWz8ah08EgiWPSL1e7dvdHqBtcRNUgPnGltPPRSi2gksgQPlgK0BzKjcaUpfr9ijKFG1czWzGj9LeTk4ahb_GrzgSTQ6qA39hsOpXYemdjBjyHee1av9_B6a6Ygys8Zpcn3FHm9XndmRr11XuyMHQg9__RyTAk9_3qklNDzlx_SfD1H6FkY7gg962BtN4ue0CZYSk4keSI0DcV0_EQORVybuD6R45nUx7g_xTX9z8pYHNot857xMSgyuGTOYdzkTVM0aYnbHIt0m6dVue2qptnmTVIjb7qcZUmAFTEFxr8RthujqDoEZyb0Y2BJya-rCnqjlLlKPXxEVSbr_3Ge1ycep1kxj0Cyo7_NqNmE8EKyT_cPQkM5aCOk48yKEGtxgufL4dhePj9fPn8CbkLG3mYLfJ6Do-wJNesUtrJvPcmO74-laxcdG5VoX0l2jF7oEaT27_6-U5m0flm1EWqIVIf1INy1_Ci97ESyE7wQWifxXHaGBEj29IGKm0V7266KrD8s0gOkJLubJdXpG6bW2wsw5UxULa7VQYrDwHkAb6V2krvv6oDz3aCXuxSNVlLjXXUDDw3uFz-i3R4WqbzUbjf6SRGaSS3wbdsmSdHHpVvfx31sYGGzUhV273SFm0hZ6IqhfgJQi25RsavgFIp3VcXf6ureHt-7xkbsM9FkDdvgPq2yNMvyMk02475JGO0ZYlUXZS9K0WHaCUrrggkmirzZyD1NaJ6Gvzwti2RXN5Q1eVkmLKWF6ATJE5yYVLswKAIvG-ncgvs0Laq02SjWoXJxjlG6jgIaJprdx8HSLYMjeaKk8-7DgpdexdkXdBnSkD3B5R8D4N-b_1_a-2axav-_J10MIyT2Hsnrnv4ZAAD__wdndPI">