Hello Uros :) On 01/06/2023 10:40, Uros Bizjak wrote: > On Thu, Jun 1, 2023 at 9:42 AM Mason wrote: > >> As far as I can tell, intrinsics _addcarry_u64() and _addcarryx_u64() are >> plain wrappers around the same __builtin_ia32_addcarryx_u64() function. >> >> https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/adxintrin.h >> >> Thus, I wonder: what is the use-case for the wrappers? >> Why would a programmer not call the builtin directly? >> Is it for compatibility with Intel compilers? > > Builtins are internal implementation detail, it is not published API. > Although rarely, builtins can be changed for some reason or another, > while intrinsic functions from adxintrin.h follow published API. I'm confused. Built-ins are officially documented: https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html Using Vector Instructions through Built-in Functions Legacy __sync Built-in Functions for Atomic Memory Access Built-in Functions for Memory Model Aware Atomic Operations Built-in Functions to Perform Arithmetic with Overflow Checking Other Built-in Functions Provided by GCC Built-in Functions Specific to Particular Target Machines What do you mean by "not published API" ? Or perhaps you meant __builtin_ia32_addcarryx_u64 specifically? >> Also, based on the names, I would have assumed that >> _addcarry_u64 generates adc >> while >> _addcarryx_u64 generates adcx/adox ? > > No, they all generate add/adc. Why are there two wrappers for the same function? Is it because the API was not designed by GCC? (Intel ICC intrinsics perhaps?) > There is no use case to maintain two > interleaved carry chains, What do you mean by "there is no use-case" ? Are you saying ADCX/ADOX are useless? Regards