2026-05-22
Subreddit: r/asm
Discussion: View on Reddit (0 points, 1 comments)
This post links to a deep technical write-up on one of the oldest tricks in the compiler-optimization playbook: replacing integer division with multiplication by a precomputed "magic number." The article walks through how it's done on RISC-V, but the underlying technique applies anywhere — it's the same transformation that GCC, LLVM, and every serious compiler perform silently when you write x / 7 with a constant divisor.
The core idea: division is brutally slow on most CPUs (often 20–40+ cycles, often not pipelined), while multiplication is fast and pipelined (3–5 cycles). If the divisor is a known constant, you can mathematically rewrite n / d as (n * m) >> s, where m is a carefully chosen "multiplicative inverse" and s is a shift amount. The hard part is picking m and s so the result is exact for every possible n in the range — not just approximately right.
What makes this particularly interesting for r/asm readers:
mulh (high half of a multiply), arithmetic shift, and add. No hidden microcode magic.The technique traces back to Granlund & Montgomery's 1994 paper "Division by Invariant Integers using Multiplication," and Hacker's Delight devotes a full chapter to it. But seeing it implemented in modern RISC-V assembly — with a working derivation rather than just the formula — is the clearest way to actually internalize why the magic numbers work, not just what they are.
If you've ever wondered why x / 10 compiles to a multiply followed by a shift, this is the explanation.
