Question Details

No question body available.

Tags

c++ x86-64 modulo integer-division

Answers (1)

January 17, 2026 Score: 4 Rep: 1,451 Quality: Medium Completeness: 80%

Thanks to @Jarod42, I was able to find the proper function for calculating the missing value. This uses an example from the Modular multiplicative inverse wikipedia-article:

struct DivMagic64 {
    int64t multiply;
    uint64t compare;
};

constexpr uint64t modinv64(uint64t d) { uint64t x = d; for (int i = 0; i < 5; i++) { x *= 2 - d * x; } return x; }

constexpr DivMagic64 computeDivMagic(uint64
t d) { assert(d >= 1 && (d & 1)); // only works for odd divisors

const uint64t cmp = ~uint64t(0) / d + 1;

const int64_t multiply = modinv64(d); // this was the missing factor

return { multiply, cmp }; }

This calculates the same two factors that clang uses for their optimization. The only limitation being, that it only works for odd divisors - even ones would require some other calculation for "modinv64" (as well as instructions), which I did not bother to figure out since my case only involves odd divisors. This can the be used to generate the (pseudo)asm:

const auto magic = computeDivMagic(number);

// for full syntax, refer to OP imul rdi, magic.multiply cmp rdi, magic.compare setb al

// equivalent to: xor edx, edx div number // assuming input in RAX test rdx, rdx setz al // return remainder == 0