[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [committed][RISC-V][PR target/120333] Remove bogus bext pattern
Jeff Law
law@gcc.gnu.org
Fri Jan 30 06:38:23 GMT 2026
https://gcc.gnu.org/g:e0ba1b7946bc4543447abcde02da57882d071001
commit e0ba1b7946bc4543447abcde02da57882d071001
Author: Jeff Law <jlaw@ventanamicro.com>
Date: Mon May 19 16:55:15 2025 -0600
[committed][RISC-V][PR target/120333] Remove bogus bext pattern
I goof'd when doing analysis of missed bext cases. For the shift into the sign
bit, then shift into the low bit case (thankfully the least common), I got it
in my brain that the field is at the left shift count. It's actually at
word_size - 1 - left shift count.
One the subtraction is included, it's no longer profitable to turn those cases
into bext. Best case scenario would be sub+bext, but we can just as easily use
sll+srl which fuses in some designs into a single op.
So this patch removes those two patterns, adjusts the existing testcase and
adds the new execution test.
Given it's a partial reversion and has passed in my tester, I'm going to go
ahead and push it to the trunk rather than waiting for upstream CI.
PR target/120333
gcc/
* config/riscv/bitmanip.md: Remove bext formed from left+right
shift patterns.
gcc/testsuite/
* gcc.target/riscv/pr114512.c: Update expected output.
* gcc.target/riscv/pr120333.c: New test.
(cherry picked from commit 38fa6c0455ec14f2f42310a817b90765ad894aa4)
Diff:
---
gcc/config/riscv/bitmanip.md | 26 -------------------------
gcc/testsuite/gcc.target/riscv/pr114512.c | 32 +------------------------------
gcc/testsuite/gcc.target/riscv/pr120333.c | 15 +++++++++++++++
3 files changed, 16 insertions(+), 57 deletions(-)
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index c226c39f5801..7e6f3df51335 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -1337,32 +1337,6 @@
"bext\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
-
-;; Single bit extraction by first shifting it into the sign bit, then
-;; shifting it down to the low bit.
-(define_insn "*bext<mode>_position_masked"
- [(set (match_operand:X 0 "register_operand" "=r")
- (lshiftrt:X (ashift:X (match_operand:X 1 "register_operand" "r")
- (match_operand:QI 2 "register_operand" "r"))
- (match_operand:X 3 "bitpos_mask_operand" "n")))]
- "TARGET_ZBS"
- "bext\t%0,%1,%2"
- [(set_attr "type" "bitmanip")])
-
-;; Single bit extraction by shifting into the low bit, but with the
-;; position formed with a subreg of a mask.
-(define_insn "*bext<mode>_position_masked_subreg"
- [(set (match_operand:X 0 "register_operand" "=r")
- (lshiftrt:X
- (ashift:X (match_operand:X 1 "register_operand" "r")
- (subreg:QI
- (and:X (match_operand:X 2 "register_operand" "r")
- (match_operand:X 3 "bitpos_mask_operand" "n")) 0))
- (match_operand:X 4 "bitpos_mask_operand" "n")))]
- "TARGET_ZBS"
- "bext\t%0,%1,%2"
- [(set_attr "type" "bitmanip")])
-
;; This has shown up in testing. In particular we end up with an
;; immediate input. We can load that into a register and target
;; one of the above bext patterns.
diff --git a/gcc/testsuite/gcc.target/riscv/pr114512.c b/gcc/testsuite/gcc.target/riscv/pr114512.c
index 205071c0883b..70146f5c0236 100644
--- a/gcc/testsuite/gcc.target/riscv/pr114512.c
+++ b/gcc/testsuite/gcc.target/riscv/pr114512.c
@@ -47,22 +47,6 @@ _Bool my_isxdigit_2a(unsigned char ch) {
return 1;
}
-_Bool my_isxdigit_3(unsigned char ch) {
- utype mask1 = 0x7E00FFC0;
- if (!((mask1 << (MASK - (ch & MASK))) >> MASK))
- return 0;
-
- return 1;
-}
-
-_Bool my_isxdigit_3a(unsigned char ch) {
- utype mask2 = 0x7E00FFC0;
- if (!((mask2 << (MASK - ((ch >> 4) & MASK))) >> MASK))
- return 0;
-
- return 1;
-}
-
_Bool my_isxdigit_1_parm(unsigned char ch, utype mask1) {
if (!((mask1 >> (ch & MASK)) & 1))
return 0;
@@ -91,19 +75,5 @@ _Bool my_isxdigit_2a_parm(unsigned char ch, utype mask2) {
return 1;
}
-_Bool my_isxdigit_3_parm(unsigned char ch, utype mask1) {
- if (!((mask1 << (MASK - (ch & MASK))) >> MASK))
- return 0;
-
- return 1;
-}
-
-_Bool my_isxdigit_3a_parm(unsigned char ch, utype mask2) {
- if (!((mask2 << (MASK - ((ch >> 4) & MASK))) >> MASK))
- return 0;
-
- return 1;
-}
-
/* Each test should generate a single bext. */
-/* { dg-final { scan-assembler-times "bext\t" 12 } } */
+/* { dg-final { scan-assembler-times "bext\t" 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr120333.c b/gcc/testsuite/gcc.target/riscv/pr120333.c
new file mode 100644
index 000000000000..17b376f3adda
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr120333.c
@@ -0,0 +1,15 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-additional-options "-march=rv64gcb -std=gnu23" } */
+
+__attribute__ ((noipa)) _Bool
+foo (unsigned char ch, unsigned long mask) {
+ return (mask << (0x3f - (ch & 0x3f))) >> 0x3f;
+}
+
+int main()
+{
+ if (!foo (0x3f, 0x8000000000000000ul))
+ __builtin_abort ();
+ return 0;
+}
+
More information about the Gcc-cvs
mailing list