https://gcc.gnu.org/g:643cf7193d65e1ad4c2e7116d4a07a14360dc59e

commit 643cf7193d65e1ad4c2e7116d4a07a14360dc59e
Author: Raphael Zinsly <rzin...@ventanamicro.com>
Date:   Mon Jun 10 14:16:16 2024 -0600

    [to-be-committed] [RISC-V] Use bext for extracting a bit into a SImode 
object
    
    bext is defined as (src >> n) & 1.  With that formulation, particularly the
    "&1" means the result is implicitly zero extended.  So we can safely use it 
on
    SI objects for rv64 without the need to do any explicit extension.
    
    This patch adds the obvious pattern and a few testcases.   I think one of 
the
    tests is derived from coremark, the other two from spec2017.
    
    This has churned through Ventana's CI system repeatedly since it was first
    written.  Assuming pre-commit CI doesn't complain, I'll commit it on 
Raphael's
    behalf later today or Monday.
    
    gcc/
            * config/riscv/bitmanip.md (*bextdisi): New pattern.
    
    gcc/testsuite
    
            * gcc.target/riscv/zbs-ext.c: New test.
    
    (cherry picked from commit 9aaf29b9ba5ffe332220d002ddde85d96fd6657d)

Diff:
---
 gcc/config/riscv/bitmanip.md             | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/riscv/zbs-ext.c | 15 +++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 965e6b5b188..0d46226aec9 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -684,6 +684,23 @@
 }
 [(set_attr "type" "bitmanip")])
 
+;; An outer AND with a constant where bits 31..63 are 0 can be seen as
+;; a virtual zero extension from 31 to 64 bits.
+(define_split
+  [(set (match_operand:DI 0 "register_operand")
+    (and:DI (not:DI (subreg:DI
+                     (ashift:SI (const_int 1)
+                                (match_operand:QI 1 "register_operand")) 0))
+            (match_operand:DI 2 "arith_operand")))
+   (clobber (match_operand:DI 3 "register_operand"))]
+  "TARGET_64BIT && TARGET_ZBS
+   && clz_hwi (INTVAL (operands[2])) >= 33"
+  [(set (match_dup 3)
+        (match_dup 2))
+   (set (match_dup 0)
+         (and:DI (rotate:DI (const_int -2) (match_dup 1))
+                 (match_dup 3)))])
+
 (define_insn "*binv<mode>"
   [(set (match_operand:X 0 "register_operand" "=r")
        (xor:X (ashift:X (const_int 1)
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-ext.c 
b/gcc/testsuite/gcc.target/riscv/zbs-ext.c
new file mode 100644
index 00000000000..65f42545b5f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-ext.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+typedef unsigned long uint64_t;
+typedef unsigned int uint32_t;
+
+uint64_t bclr (const uint32_t i)
+{
+  uint64_t checks = 10;
+  checks &= ~(1U << i);
+  return checks;
+}
+
+/* { dg-final { scan-assembler-times "bclr\t" 1 } } */
+/* { dg-final { scan-assembler-not "sllw\t"} } */

Reply via email to