]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Cover sign-extensions in lshrsi3_zero_extend_2
authorChristoph Müllner <christoph.muellner@vrull.eu>
Tue, 7 May 2024 21:26:02 +0000 (23:26 +0200)
committerChristoph Müllner <christoph.muellner@vrull.eu>
Wed, 8 May 2024 14:00:51 +0000 (16:00 +0200)
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>
gcc/config/riscv/iterators.md
gcc/config/riscv/riscv.md
gcc/testsuite/gcc.target/riscv/sign-extend-1.c

index 32e1b14030517e43f748d42a4fe8ff41701246ab..c5ca01f382a91eadbc7ee82a0b0754fbe961296d 100644 (file)
 ;; 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])
index 24558682eb8fb1bc891e3b793a38ffa8d943cc3b..b7fc13e4e611aa8c42a87bb136f7319569e3546f 100644 (file)
   [(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")])
index e9056ec0d424b568294dd31c4bc11cb3834894c5..d8c18dd1aaa7f6ea646596f605f8d79cb93e5678 100644 (file)
@@ -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" } } */