]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[to-be-committed,RISC-V] Improve variable bit set for rv64
authorJeff Law <jlaw@ventanamicro.com>
Mon, 17 Jun 2024 13:04:13 +0000 (07:04 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 17 Jun 2024 13:04:13 +0000 (07:04 -0600)
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.

gcc/config/riscv/bitmanip.md
gcc/testsuite/gcc.target/riscv/zbs-zext-2.c [new file with mode: 0644]

index 0d35fb786e11eade6d10845c9901534bbf859076..311f0d373c000d7cde7d27c567a73936510f0112 100644 (file)
   "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 (file)
index 0000000..ebd269d
--- /dev/null
@@ -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"} } */