https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111209
--- Comment #5 from cqwrteur <unlvsur at live dot com> --- (In reply to Jakub Jelinek from comment #4) > (In reply to cqwrteur from comment #3) > > (In reply to Jakub Jelinek from comment #1) > > > Just use __int128 addition if all you want is double-word addition (or > > > long > > > long for 32-bit arches)? > > > > Well, I've presented this merely as an illustrative example. The length can > > actually be arbitrary. > > No, it was working with all the other lengths. This might come across as unusual. I frequently engage in manipulations involving the carry flag. like this implementation for 128 bit division (for 32 bit machine and Microsoft compiler) auto shift = static_cast<unsigned>(::std::countl_zero(divisorhigh) - ::std::countl_zero(dividendhigh)); divisorhigh = ::fast_io::intrinsics::shiftleft(divisorlow,divisorhigh,shift); divisorlow <<= shift; quotientlow = 0; bool carry; do { carry=0; dividendlow=intrinsics::subc(dividendlow,divisorlow,carry,carry); dividendhigh=intrinsics::subc(dividendhigh,divisorhigh,carry,carry); constexpr T zero{}; T mask{zero-carry}; T templow{divisorlow&mask},temphigh{divisorhigh&mask}; carry=!carry; quotientlow=intrinsics::addc(quotientlow,quotientlow,carry,carry); carry=0; dividendlow=intrinsics::addc(dividendlow,templow,carry,carry); dividendhigh=intrinsics::addc(dividendhigh,temphigh,carry,carry); divisorlow = intrinsics::shiftright(divisorlow,divisorhigh,1u); divisorhigh >>= 1u; } while(shift--); return {quotientlow,0,dividendlow,dividendhigh};