aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChristoph Müllner <christoph.muellner@vrull.eu>2024-05-07 23:26:02 +0200
committerChristoph Müllner <christoph.muellner@vrull.eu>2024-05-08 16:00:51 +0200
commit4e46a3537ff57938a0d98fa524ac2fff8b08ae6d (patch)
tree4e0ddb6e303ded0c60a076dfa93a185b186c09cb /gcc
parentdd388198b8be52ab378c935fc517a269e0ba741c (diff)
downloadgcc-4e46a3537ff57938a0d98fa524ac2fff8b08ae6d.zip
gcc-4e46a3537ff57938a0d98fa524ac2fff8b08ae6d.tar.gz
gcc-4e46a3537ff57938a0d98fa524ac2fff8b08ae6d.tar.bz2
RISC-V: Cover sign-extensions in lshrsi3_zero_extend_2
The pattern lshrsi3_zero_extend_2 extracts the MSB bits of the lower 32-bit word and zero-extends it back to DImode. This is realized using srliw, which operates on 32-bit registers. The same optimziation can be applied to sign-extensions when emitting a sraiw instead of the srliw. Given these two optimizations are so similar, this patch simply converts the existing one to also cover the sign-extension case as well. gcc/ChangeLog: * config/riscv/iterators.md (sraiw): New code iterator 'any_extract'. New code attribute 'extract_sidi_shift'. * config/riscv/riscv.md (*lshrsi3_zero_extend_2): Rename to... (*lshrsi3_extend_2):...this and add support for sign-extensions. gcc/testsuite/ChangeLog: * gcc.target/riscv/sign-extend-1.c: Test sraiw 24 and sraiw 16. Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/iterators.md6
-rw-r--r--gcc/config/riscv/riscv.md9
-rw-r--r--gcc/testsuite/gcc.target/riscv/sign-extend-1.c14
3 files changed, 25 insertions, 4 deletions
diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 32e1b14..c5ca01f 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -150,6 +150,12 @@
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
+;; These code iterators allow unsigned and signed extraction to be generated
+;; from the same template.
+(define_code_iterator any_extract [sign_extract zero_extract])
+(define_code_attr extract_sidi_shift [(sign_extract "sraiw")
+ (zero_extract "srliw")])
+
;; This code iterator allows the two right shift instructions to be
;; generated from the same template.
(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 2455868..b7fc13e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2765,16 +2765,17 @@
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
-;; Canonical form for a zero-extend of a logical right shift.
-(define_insn "*lshrsi3_zero_extend_2"
+;; Canonical form for a sign/zero-extend of a logical right shift.
+;; Special case: extract MSB bits of lower 32-bit word
+(define_insn "*lshrsi3_extend_2"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
+ (any_extract:DI (match_operand:DI 1 "register_operand" " r")
(match_operand 2 "const_int_operand")
(match_operand 3 "const_int_operand")))]
"(TARGET_64BIT && (INTVAL (operands[3]) > 0)
&& (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
{
- return "srliw\t%0,%1,%3";
+ return "<extract_sidi_shift>\t%0,%1,%3";
}
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
diff --git a/gcc/testsuite/gcc.target/riscv/sign-extend-1.c b/gcc/testsuite/gcc.target/riscv/sign-extend-1.c
index e9056ec..d8c18dd 100644
--- a/gcc/testsuite/gcc.target/riscv/sign-extend-1.c
+++ b/gcc/testsuite/gcc.target/riscv/sign-extend-1.c
@@ -9,6 +9,20 @@ foo1 (int i)
}
/* { dg-final { scan-assembler "sraiw\ta\[0-9\],a\[0-9\],31" } } */
+signed char
+sub2 (long i)
+{
+ return i >> 24;
+}
+/* { dg-final { scan-assembler "sraiw\ta\[0-9\],a\[0-9\],24" } } */
+
+signed short
+sub3 (long i)
+{
+ return i >> 16;
+}
+/* { dg-final { scan-assembler "sraiw\ta\[0-9\],a\[0-9\],16" } } */
+
/* { dg-final { scan-assembler-not "srai\t" } } */
/* { dg-final { scan-assembler-not "srli\t" } } */
/* { dg-final { scan-assembler-not "srliw\t" } } */