On Intel AVX, there is a possibility of branchless code. Instead of branching for case0 or case1, you can compute both cases, and blend the results based on a condition.
AVX does this 8 way for float using the vblendps instruction.
You can also do this in a scalar way, without a vector, using the x86 instruction CMOVcc which performs a move operation, conditionally.
NOTE: ARM has CSEL and NEON has VBSL.
Can RISCV64 do a scalar move like this, so that you do not have to branch for
a = c ? x : y;
As I understand, RISCV implementations are in-order, so it would benefit even more than x86 when not having to branch. (The latter can at least shuffle around some instructions, and even branch speculatively to hide latency.)
The closest I can find w.r.t branchless operation for riscv is SLT (Set Less Than) but that sets to 1 or 0, and then would need multiplications? Wouldn't it be more useful to have SLT set to -1 or 0 instead, so that we can AND that?
UPDATE
When doing:
int foo(int a, int b, int x, int y)
{
return a < b ? x : y;
}
I tried a poor-man's version of branchless using SLT. I am not sure if I did it completely right, by using bitmask as 0 - condition(0|1), I came up with:
branchless:
SLT t0,a0,a1
SUB t0,zero,t0
NOT t1,t0
AND t0,a2,t0
AND t1,a3,t1
OR a0,t0,t1
RET
.size branchless, .-branchless
as the branchless version of:
branched:
BGE a0,a1,.L2
MV a3,a2
.L2:
MV a0,a3
RET
.size branched, .-branched
I wonder if I used too many instructions for this, but I measured the branching version to be slightly faster than the non-branching one on random data, but not by much.