https://gcc.gnu.org/g:e0b2a59719a3807695c05681114324dc4b31570f

commit e0b2a59719a3807695c05681114324dc4b31570f
Author: Jeff Law <j...@ventanamicro.com>
Date:   Mon Jun 17 07:04:13 2024 -0600

    [to-be-committed,RISC-V] Improve variable bit set for rv64
    
    Another case of being able to safely use bset for 1 << n.  In this case
    the (1 << n)  is explicitly zero extended from SI to DI.  Two things to
    keep in mind.  The (1 << n) is done in SImode.  So it doesn't directly
    define bits 32..63 and those bits are cleared by the explicit zero
    extension.  Second if N is out of SImode's range, then the original
    source level construct was undefined.
    
    Thus we can use bset with x0 as our source input.
    
    I think this testcase was from the RAU team.  It doesn't immediately
    look like something from SPEC, but that's where they were primarily focused.
    
    This has been through Ventana's CI system in the past.  I've also
    recently added zbs testing to my own tester and naturally this passed
    there as well.  I'll wait for the pre-commit CI to do its thing before
    moving forward.  The plan would be to commit after passing.
    
    gcc/
            * config/riscv/bitmanip.md (bsetdi_2): New pattern.
    
    gcc/testsuite/
    
            * gcc.target/riscv/zbs-zext-2.c: New test.
    
    (cherry picked from commit 83aad89fb99d0e82209734717c12f5aaca477970)

Diff:
---
 gcc/config/riscv/bitmanip.md                | 12 ++++++++++++
 gcc/testsuite/gcc.target/riscv/zbs-zext-2.c | 12 ++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 0d35fb786e1..311f0d373c0 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -597,6 +597,18 @@
   "bset\t%0,x0,%1"
   [(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.
+(define_insn "*bsetdi_2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (ashift:SI (const_int 1)
+                    (match_operand:QI 1 "register_operand" "r"))))]
+  "TARGET_64BIT && TARGET_ZBS"
+  "bset\t%0,x0,%1"
+  [(set_attr "type" "bitmanip")])
+
 (define_insn "*bset<mode>_1_mask"
   [(set (match_operand:X 0 "register_operand" "=r")
        (ashift:X (const_int 1)
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-zext-2.c 
b/gcc/testsuite/gcc.target/riscv/zbs-zext-2.c
new file mode 100644
index 00000000000..ebd269d1695
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-zext-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+unsigned long long foo(long long symbol)
+{
+        return 1u << symbol;
+}
+
+/* { dg-final { scan-assembler-times "bset\t" 1 } } */
+/* { dg-final { scan-assembler-not "li\t"} } */
+/* { dg-final { scan-assembler-not "sllw\t"} } */
+/* { dg-final { scan-assembler-not "zext.w\t"} } */

Reply via email to