https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122769
Bug ID: 122769
Summary: RISC-V: Short branch can be elided for alu op
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: target
Assignee: vineetg at gcc dot gnu.org
Reporter: vineetg at gcc dot gnu.org
Target Milestone: ---
Target: risc-v
gcc is generating a short forward branch whereas llvm omits the branch
altogether.
typedef unsigned long uint64_t;
uint64_t updateLSB63(uint64_t val, uint64_t val2, int bits, int n) {
if (val & (1ULL << 63))
val2 ^= n;
return val2;
}
-O2 -mtune=generic -march=rv64gc_zba_zbb_zbs_zicond -mabi=lp64d
updateLSB63:
bge a0,zero,.L2
xor a1,a1,a3
.L2:
mv a0,a1
ret
LLVM OTOH generates
updateLSB63:
srai a0, a0, 63
and a0, a0, a3
xor a0, a0, a1
ret
Interestingly, if the const 63 is replaced with 62, gcc seems to elide the
branch for a conditional zero.
uint64_t updateLSB62(uint64_t val, uint64_t val2, int bits, int n) {
if (val & (1ULL << 62))
val2 ^= n;
return val2;
}
updateLSB62:
bseti a5,zero,62
and a0,a0,a5
czero.eqz a0,a3,a0
xor a0,a1,a0
ret
Granted this itself could be optimized BSETI + AND = BEXTI as a followup.