]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: bitmanip: add splitter to use bexti for "(a & (1 << BIT_NO)) ? 0 : -1"
authorPhilipp Tomsich <philipp.tomsich@vrull.eu>
Tue, 9 Nov 2021 17:54:54 +0000 (18:54 +0100)
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>
Thu, 17 Nov 2022 15:20:56 +0000 (16:20 +0100)
Consider creating a polarity-reversed mask from a set-bit (i.e., if
the bit is set, produce all-ones; otherwise: all-zeros).  Using Zbb,
this can be expressed as bexti, followed by an addi of minus-one.  To
enable the combiner to discover this opportunity, we need to split the
canonical expression for "(a & (1 << BIT_NO)) ? 0 : -1" into a form
combinable into bexti.

Consider the function:
    long f(long a)
    {
      return (a & (1 << BIT_NO)) ? 0 : -1;
    }
This produces the following sequence prior to this change:
andi a0,a0,16
seqz a0,a0
neg a0,a0
ret
Following this change, it results in:
bexti a0,a0,4
addi a0,a0,-1
ret

gcc/ChangeLog:

* config/riscv/bitmanip.md: Add a splitter to generate
  polarity-reversed masks from a set bit using bexti + addi.

gcc/testsuite/ChangeLog:

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

gcc/config/riscv/bitmanip.md
gcc/testsuite/gcc.target/riscv/zbs-bexti.c

index fb062f6eb43c4d19064f7bbc7996feae9fb5ebbe..0dd6ebbdd0bc05d483a1ba197ce803245a58030b 100644 (file)
                                      (const_int 1)
                                      (match_dup 2)))
    (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
+
+;; We can create a polarity-reversed mask (i.e. bit N -> { set = 0, clear = -1 })
+;; using a bext(i) followed by an addi instruction.
+;; This splits the canonical representation of "(a & (1 << BIT_NO)) ? 0 : -1".
+(define_split
+  [(set (match_operand:GPR 0 "register_operand")
+       (neg:GPR (eq:GPR (zero_extract:GPR (match_operand:GPR 1 "register_operand")
+                                          (const_int 1)
+                                          (match_operand 2))
+                        (const_int 0))))]
+  "TARGET_ZBS"
+  [(set (match_dup 0) (zero_extract:GPR (match_dup 1) (const_int 1) (match_dup 2)))
+   (set (match_dup 0) (plus:GPR (match_dup 0) (const_int -1)))])
index c15098eb6ccdd0524883d598d03fe5aae1a2768f..d7a89638f46c462f95e0d7931082d269cf269e45 100644 (file)
@@ -26,6 +26,6 @@ long bexti64_4(long a, char bitno)
 }
 
 /* { dg-final { scan-assembler-times "bexti\t" 4 } } */
-/* { dg-final { scan-assembler-times "xori\t|snez\t" 1 } } */
+/* { dg-final { scan-assembler-times "xori\t" 1 } } */
 /* { dg-final { scan-assembler-times "addi\t" 1 } } */
 /* { dg-final { scan-assembler-times "neg\t" 1 } } */