4 ms·
I recently fixed some code that was doing the incorrect comparison with this alternative which avoids the overflow and is also branchless [1]: return (a >
by cmovq 3y ago
I recently fixed some code that was doing the incorrect comparison with this alternative which avoids the overflow and is also branchless [1]:
return (a > b) - (a < b);
[1]: https://godbolt.org/z/EnqsTr1jo https://godbolt.org/z/EnqsTr1jo
- kmoser 3y agoThat's clever, but I am not a fan: Booleans are implementation dependent; making the assumption that Boolean 'true' evaluates to 1, or even a number greater than what Boolean 'false' evaluates to, is not a good idea, even if it happens to be correct most of the time. Even if it is defined that way in the language specs, it might not be defined that way in a future version of that language or certainly not necessarily in other, simlar languages. Now, if you're exploiting that quirk for performance purposes, that's another story. But then the code should be labeled as such.
- deleted 3y ago[deleted]
- AgentME 3y agoThe comparison operators are specifically defined in the C standard to output 1 if true and 0 if false.
- viraptor 3y agoI was curious about the details. 6.5.8 in https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf Also 7.18 makes the bool macros explicitly 1 and 0.
- moonchild 3y agoHrm—that's another case of missing isel from gcc/clang (c.f. <https://pp.ipd.kit.edu/firm/selgen https://pp.ipd.kit.edu/firm/selgen>)—my implementation (<https://github.com/moon-chilled/fancy-memcmp/blob/master/memcmp-sse2.S#L82-L86 https://github.com/moon-chilled/fancy-memcmp/blob/master/mem...>) does it in one less instruction. (An alternative is to skip the xors and do cmp/setcc/setcc/sub/movsx, which matches my approach on instruction count, but relies on good handling of partial renames, which is uarch-dependent. And I can never remember if anybody can eliminate movsx. Otoh it is non-destructive.)