Quiz Entry - updated: 2026.07.14
How do compilers multiply by constants without using imul?
They combine lea and shifts: lea (%rdi,%rdi,2) gives 3x, shl $2 gives 4x, and chaining them builds other constants — usually faster than a hardware multiply.
| Constant | Compiled as |
|---|---|
x * 2 |
add %rdi, %rdi or shl $1, %rdi |
x * 3 |
lea (%rdi,%rdi,2), %rax |
x * 4 |
shl $2, %rdi |
x * 5 |
lea (%rdi,%rdi,4), %rax |
x * 7 |
lea (%rdi,%rdi,2), %rax then lea (%rdi,%rax,2), %rax |
x * 9 |
lea (%rdi,%rdi,8), %rax |
x * 12 |
lea (%rdi,%rdi,2), %rax then shl $2, %rax |
Tip: When you see a lea followed by shl or another lea, it's likely multiplication by a constant. Work out the math: lea (%rdi,%rdi,2) = 3*rdi, then shl $2 = *4, total = 12*rdi.
Division by constant uses imul with a magic number followed by shifts — this is the compiler's "multiply by reciprocal" trick.
Go deeper: