[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] [to-be-committed, RISC-V] Improve variable bit set for rv64
Jeff Law
law@gcc.gnu.org
Mon Jun 24 15:00:03 GMT 2024
https://gcc.gnu.org/g:e0b2a59719a3807695c05681114324dc4b31570f
commit e0b2a59719a3807695c05681114324dc4b31570f
Author: Jeff Law <jlaw@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"} } */
More information about the Gcc-cvs
mailing list