Branchless Programming
Eliminating if-else branches with bitwise operations for better CPU pipeline performance.
The use of if-then-else statements, switch cases, and even gotos are considered branch operations. In computing, the single operation that slows down the pipeline of instructions the most is the branch. The reason is that a branch instruction depends on the result of the previous instruction. The whole concept of branch prediction is another topic that deserves its own discussion.
Imagine you have the following code:
int isGreater(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
Notice that there exists an if-else clause in the code.
int isGreaterBL(int a, int b) {
int mask = -(a > b);
return (mask & a) | (~mask & b);
}
We removed the branch by replacing the if-else clause with bitwise operations. The trick is that -(a > b) converts the boolean result (0 or 1) into a full bitmask — either all 0s or all 1s — which can then cleanly select between a and b.
Another cool example is computing the absolute value of an integer, by Jobin Johnson.
int abs(int a) {
if (a < 0) {
return -a;
} else {
return a;
}
}
int abs(int a) {
int mask = a >> 31;
a ^= mask;
a -= mask;
return a;
}
Here, the arithmetic right shift fills mask with all 1s when a is negative, and all 0s otherwise. XORing with all 1s flips every bit (equivalent to ~a, which is -a - 1 in two’s complement), and subtracting -1 adds back the 1 to give -a.
Branchless techniques like these trade readability for performance in tight loops where branch mispredictions are costly. In practice, modern compilers will often generate branchless code on their own with the right optimization flags — but understanding the underlying bit manipulation is still valuable when you need to reason about what the machine is actually doing.