This patch adds a peephole2 optimization that combines a 'bclr' followed by a 'binv' into a single 'bset' instruction when the Zbs extension is enabled.
The motivation for this patch is that PR116398 limits 2→2 RTL combinations, which prevents certain simplifications in the combiner pass. As a result, combining 'bclr' and 'binv' through standard RTL combination is not feasible when Zbs is enabled. An example is the testcase g++.target/riscv/redundant-bitmap-2.C[1] from Jeff Law's patch[2]. PR116398: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=4d7a634f6d41029811cdcbd5f7282b5b07890094 [1] https://godbolt.org/z/dhYoTMY1v [2] https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=05daf617ea22e1d818295ed2d037456937e23530 gcc/ChangeLog: * config/riscv/bitmanip.md (*bset<mode>_2): New pattern. * config/riscv/peephole.md: Ditto. Signed-off-by: Jiawei <jia...@iscas.ac.cn> --- gcc/config/riscv/bitmanip.md | 9 +++++++++ gcc/config/riscv/peephole.md | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 21426f49679..1bd66c4aa19 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -615,6 +615,15 @@ "bset\t%0,x0,%1" [(set_attr "type" "bitmanip")]) +(define_insn "*bset<mode>_2" + [(set (match_operand:X 0 "register_operand" "=r") + (ior:X (match_operand:X 1 "register_operand" "r") + (ashift:X (const_int 1) + (match_operand:QI 2 "register_operand" "r"))))] + "TARGET_ZBS" + "bset\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + ;; The result will always have bits 32..63 clear, so the zero-extend ;; is redundant. We could split it to bset<mode>_1, but it seems ;; unnecessary. diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md index b5cc1924c76..1d5d15e9005 100644 --- a/gcc/config/riscv/peephole.md +++ b/gcc/config/riscv/peephole.md @@ -39,6 +39,22 @@ operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5])); }) +;; ZBS +(define_peephole2 + [(set (match_operand:X 1 "register_operand") + (and:X (rotate:X (const_int -2) + (match_operand:QI 3 "register_operand")) + (match_operand:X 2 "register_operand"))) + (set (match_operand:X 0 "register_operand") + (xor:X (ashift:X (const_int 1) + (match_dup 3)) + (match_dup 1)))] + "TARGET_ZBS" + [(set (match_dup 0) + (ior:X (match_dup 2) + (ashift:X (const_int 1) + (match_dup 3))))]) + ;; ZCMP (define_peephole2 [(set (match_operand:X 0 "a0a1_reg_operand") -- 2.43.0