RISC-V defines Zicond extentsion: czero.eqz rd, rs1, rs2: moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd. czero.nez rd, rs1, rs2: moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd.
With this series, the following optimizations can be achieved. opcode=[add, sub, or, xor] case: Conditional op, if zero rd = (rc == 0) ? (rs1 op rs2) : rs1 --> czero.nez rd, rs2, rc opcode rd, rs1, rd Conditional op, if non-zero rd = (rc != 0) ? (rs1 op rs2) : rs1 --> czero.eqz rd, rs2, rc opcode rd, rs1, rd case for and: Conditional and, if zero rd = (rc == 0) ? (rs1 & rs2) : rs1 --> and rd, rs1, rs2 czero.eqz rtmp, rs1, rc or rd, rd, rtmp Conditional and, if non-zero rd = (rc != 0) ? (rs1 & rs2) : rs1 --> and rd, rs1, rs2 czero.nez rtmp, rs1, rc or rd, rd, rtmp Fei Gao (4): [RISC-V]add hook to control Zicond based ifcvt opt [ifcvt] if convert x=c ? y+z : y by RISC-V Zicond like insns [ifcvt] if convert x=c ? y op z : y by RISC-V Zicond like insns [ifcvt] if convert x=c ? y&z : y by RISC-V Zicond like insns gcc/config/riscv/riscv.cc | 10 + gcc/doc/tm.texi | 4 + gcc/doc/tm.texi.in | 2 + gcc/ifcvt.cc | 149 ++++ gcc/target.def | 7 + .../gcc.target/riscv/zicond_ifcvt_opt.c | 642 ++++++++++++++++++ 6 files changed, 814 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c -- 2.17.1