In particular note insn 34, 42 and 43. Those are useless. Insns 36, 37, 38
are just a single bit extraction from a variable location (from one of the
if-converted blocks). I couldn't see a good way to fix the problem with insn
34/insn 42. The desire to make the then/else blocks independent is cmove_arith
is good, what's unclear is whether or not that code really cares about the
*destination* of the then/else blocks. But I set that aside.
We then thought that cleaning up the variable bit extraction would be the way
to go. So a pattern was constructed to match that form of variable bit extract
and the cost model was twiddled to return that it was a single fast
instruction. But even with those changes fwprop1 refused to make the
substitution. Sigh. At least combine recognizes the idiom later and cleans it
up.
Then we realized we really should just ignore the (set (reg) (const_int 0)) in
the if-converted sequence. We're going to be able to propagate that away in
nearly every case since we have a hard-wired zero register. Sure enough,
ignoring that insn was enough to tip the balance on this case and we get the
desired code.
Tested on riscv32-elf and riscv64-elf. Pioneer bootstrap is in flight, though
it won't really exercise this problem. The BPI's build hasn't started yet, so
it'll be at least 27hours before it's done.
Waiting on pre-commit CI before moving forward.
gcc/
* config/riscv/riscv.cc (riscv_noce_conversion_profitable_p): Ignore
assignments of (const_int 0) to a register. They will get propagated
away.
gcc/testsuite
* gcc.target/riscv/czero-bext.c: New test.