On 11/10/22 14:34, Philipp Tomsich wrote:
Sequences of the form "a | C" with C being the positive half of a
signed immediate's range with one extra bit set in addtion are mapped
to ori and one binvi to avoid using a temporary (and a multi-insn
sequence to load C into that temporary).

gcc/ChangeLog:

        * config/riscv/bitmanip.md (*bseti<mode>_extrabit): New pattern

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zbs-bseti.c: New test.

Signed-off-by: Philipp Tomsich <philipp.toms...@vrull.eu>
---
- Depends on a predicate posted in "RISC-V: Optimize branches testing
   a bit-range or a shifted immediate".  Depending on the order of
   applying these, I'll take care to pull that part out of the other
   patch if needed.

  gcc/config/riscv/bitmanip.md               | 19 +++++++++++++++
  gcc/testsuite/gcc.target/riscv/zbs-bseti.c | 27 ++++++++++++++++++++++
  2 files changed, 46 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-bseti.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 06126ac4819..436ff4ba958 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmani
@@ -512,6 +512,25 @@
    "bseti\t%0,%1,%S2"
    [(set_attr "type" "bitmanip")])
+; Catch those cases where we can use a bseti + ori or bseti + bseti
+; instead of a lui + addi + or sequence.
+(define_insn_and_split "*bseti<mode>_extrabit"
+  [(set (match_operand:X 0 "register_operand" "=r")
+       (ior:X (match_operand:X 1 "register_operand" "r")
+              (match_operand:X 2 "uimm_extra_bit_operand" "i")))]
+  "TARGET_ZBS"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (ior:X (match_dup 1) (match_dup 3)))
+   (set (match_dup 0) (ior:X (match_dup 0) (match_dup 4)))]
+{
+       unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
+       unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
+
+       operands[3] = GEN_INT (bits &~ topbit);
+       operands[4] = GEN_INT (topbit);
+})

I briefly thought you might need an earlyclobber for the output, but you consume the input register in the first generated insn, so you should be OK.


OK.

jeff


Reply via email to