aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRaphael Zinsly <rzinsly@ventanamicro.com>2024-06-10 07:03:00 -0600
committerJeff Law <jlaw@ventanamicro.com>2024-06-10 07:03:00 -0600
commit3472c1b500cf9184766237bfd3d102aa8451b99f (patch)
treeed4f1f3bbee306ded8d55d0f9a3e35f975f516b9 /gcc
parent818e760528d436ea8f6c28ef620e2bb82d456ea1 (diff)
downloadgcc-3472c1b500cf9184766237bfd3d102aa8451b99f.zip
gcc-3472c1b500cf9184766237bfd3d102aa8451b99f.tar.gz
gcc-3472c1b500cf9184766237bfd3d102aa8451b99f.tar.bz2
[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/bext-ext.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/bitmanip.md12
-rw-r--r--gcc/testsuite/gcc.target/riscv/bext-ext.c27
2 files changed, 39 insertions, 0 deletions
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 8769a6b..7e716d2 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -754,6 +754,18 @@
"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 0000000..eeef07d
--- /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"} } */