[Bug rtl-optimization/125731] Improve RISC-V sequence for conditional xor with a constant
"cvs-commit at gcc dot gnu.org via Gcc-bugs" <[email protected]>
| Newsgroups | gmane.comp.gcc.bugs |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125731 --- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jeff Law <[email protected]>: https://gcc.gnu.org/g:af0cf36fb47a704a02dd2ead5f8db5d140e45351 commit r17-3306-gaf0cf36fb47a704a02dd2ead5f8db5d140e45351 Author: Shreya Munnangi <[email protected]> Date: Fri Aug 14 14:53:34 2026 -0600 [PATCH][RISC-V][PR rtl-optimization/125731] Improving sequences for conditional xor with a constant This is Shreya's work to address pr125731. I did some testing around this to verify riscv64-elf and riscv32-elf are happy. Testing on the K1/K3/c920 will fire up tonight, but not expecting significant issues there. -- In PR125731, We are generating inefficient sequences for conditional xor with a constant. Given this testcase, long fun_not1 (int a, long b) { if (!(a & 1)) b ^= 8; return b; } We are generating: fun_not1: andi a5,a0,1 mv a0,a1 bne a5,zero,.L3 xori a0,a1,8 .L3: ret However, this can be simplified into a branchless sequence. One such sequence: andi a5,a0,1 li a4,8 czero.nez a5,a4,a5 xor a0,a1,a5 ret Another form: andi a0,a0,1 seqz t0,a0 slli t1,t0,3 xor a0,a1,t1 ret -- I've edited Shreya's explanation a bit -- The if-converter's get_base_reg currently returns NULL if presented with a constant and that inhibits if conversion through the noce_try_cond_arith which can generate more efficient sequences than generalized conditional moves. So the first thing we need to do is support constants in get_base_reg. The return value from get_base_reg is used to generate a new pseudo register, so if get_base_reg starts returning constants, then we're going to run into problems generating the new pseudo because constants are VOIDmode. I changed the name to get_base_reg_or_constant to reflect that we are also handling constants, not just returning the base registers of a reg or subreg. The point where the caller uses the return value to get a mode for the new pseudo has been changed to get the mode from the other operand of the binary operation. Those changes are sufficient to if-convert this example as well as enabling more efficient code generation for other cases where we have a conditional operation where one operand is a constant. Although the newly generated sequence is the same number of insns, it will be much faster if the conditional branch is not easily predictable. PR rtl-optimization/125731 gcc/ * ifcvt.cc (get_base_reg_or_const): Renamed from get_base_reg. Handle CONST_INTs too. (noce_try_cond_arith): Use get_base_reg_or_const. Handle case where get_base_reg_or_const returns a CONST_INT. gcc/testsuite * gcc.target/riscv/pr125731.c: New test.