diff mbox series

[to-be-committed,RISC-V] Use bext for extracting a bit into a SImode object

Message ID d5e4d4ef-676e-4324-9e9f-a4febb293400@ventanamicro.com
State New
Headers show
Series [to-be-committed,RISC-V] Use bext for extracting a bit into a SImode object | expand

Commit Message

Jeff Law June 9, 2024, 4:30 p.m. UTC
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.


Jeff
gcc/
	* config/riscv/bitmanip.md (*bextdisi): New pattern.

gcc/testsuite

	* gcc.target/riscv/bext-ext.c: New test.

commit e32599b6c863cffa594ab1eca8f4e11562c4bc6a
Author: Raphael Zinsly <rzinsly@ventanamicro.com>
Date:   Fri Mar 22 16:20:21 2024 -0600

    Improvement to bext discovery from Raphael.  Extracted from his "Add Zbs extended patterns" MR.
diff mbox series

Patch

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 00560be6161..6559d4d6950 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -854,6 +854,18 @@  (define_insn_and_split "*bextseqzdisi"
   "operands[1] = gen_lowpart (word_mode, operands[1]);"
   [(set_attr "type" "bitmanip")])
 
+;; The logical-and against 0x1 implicitly extends the result.   So we can treat
+;; an SImode bext as-if it's DImode without any explicit extension.
+(define_insn "*bextdisi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+    (and:DI (subreg:DI (lshiftrt:SI
+			 (match_operand:SI 1 "register_operand" "r")
+			 (match_operand:QI 2 "register_operand" "r")) 0)
+            (const_int 1)))]
+  "TARGET_64BIT && TARGET_ZBS"
+  "bext\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
+
 ;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
 ;; usually has the `bitno` typed as X-mode (i.e. no further
 ;; zero-extension is performed around the bitno).
diff --git a/gcc/testsuite/gcc.target/riscv/bext-ext.c b/gcc/testsuite/gcc.target/riscv/bext-ext.c
new file mode 100644
index 00000000000..eeef07d7013
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/bext-ext.c
@@ -0,0 +1,27 @@ 
+/* { 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 bext1 (int dst, const uint32_t i)
+{
+  uint64_t checks = 1U;
+  checks &= dst >> i;
+  return checks;
+}
+
+int bext2 (int dst, int i_denom)
+{
+  dst = 1 & (dst >> i_denom);
+  return dst;
+}
+
+const uint32_t bext3 (uint32_t bit_count, uint32_t symbol)
+{
+  return (symbol >> bit_count) & 1;
+}
+
+/* { dg-final { scan-assembler-times "bext\t" 3 } } */
+/* { dg-final { scan-assembler-not "sllw\t"} } */
+/* { dg-final { scan-assembler-not "srlw\t"} } */