4 ms·
It's a single instruction to then subtract 1 from the result of SLT/SLTI, which then gives you 0xffffffff or 0x00000000 rather than 0 or 1, which you can use as
by jleahy 7y ago
It's a single instruction to then subtract 1 from the result of SLT/SLTI, which then gives you 0xffffffff or 0x00000000 rather than 0 or 1, which you can use as a mask.
RISC-V was designed to be a good target for a C compiler, given that's what people almost always need. Compilers frequently see code line `int x = (a > b)` and SLT is perfect for that. Compilers don't do clever masking tricks to avoid branches, in general (there are a few hard-coded tricks like divide by signed constant).
- ncmncm 7y agoIn other words, two more instructions, instead of zero. That compilers fail to do clever masking tricks to avoid branches frequently results in 2x slower programs.
- avianes 7y agoNo, as jleahy said, it cost a single instruction to transform 0 to 0b00..00 and 1 to 0b11..11 - SUB X, $0, X. And your proposal - using the zero register as a flag register - breaks way more micro-optimizations (like the simple ones described in "The RISC-V Reader" book) than it allows
- bonzini 7y ago> Compilers don't do clever masking tricks to avoid branches, in general They actually do a lot of such tricks. Check out the GCC sources, for example tree-ssa-phiopt.c[1] and ifcvt.c[2] [1] https://github.com/gcc-mirror/gcc/blob/master/gcc/tree-ssa-phiopt.c https://github.com/gcc-mirror/gcc/blob/master/gcc/tree-ssa-p... [2] https://github.com/gcc-mirror/gcc/blob/master/gcc/ifcvt.c https://github.com/gcc-mirror/gcc/blob/master/gcc/ifcvt.c