Unsigned Ranges
When testing for a value within a range we can apply the unsigned
range optimisation:
- Shift the range down so its minimum is zero.
- Cast to
unsigned.
- ⇒ Any negative values become large positive values.
This means we can do a single test rather than two.
Eliminates branching.
Examples
int insideRange1(int v, int min, int max)
{
return v >= min && v < max;
}
insideRange1 CMP r0,r1
BLT |L1.20|
CMP r0,r2
MOVLT r0,#1
MOVLT pc,lr
|L1.20|
MOV r0,#0
MOV pc,lr
int insideRange2(int v, int min, int max)
{
return (unsigned) (v - min) < (max - min);
}
insideRange2 SUB r0,r0,r1
SUB r1,r2,r1
CMP r0,r1
MOVCS r0,#0
MOVCC r0,#1
MOV pc,lr
Remarks
In some cases the compiler can make this transformation itself.
It’s now branchless but mightn’t terminate as early.
This is especially beneficial when ‘min’ is zero. Of course this becomes even more beneficial when testing 2D and 3D ranges.