https://gcc.gnu.org/g:9041a047fe957232d9f9127791a08643b1087a36

commit 9041a047fe957232d9f9127791a08643b1087a36
Author: Christoph Müllner <christoph.muell...@vrull.eu>
Date:   Tue May 7 23:26:02 2024 +0200

    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.muell...@vrull.eu>
    (cherry picked from commit 4e46a3537ff57938a0d98fa524ac2fff8b08ae6d)

Diff:
---
 gcc/config/riscv/iterators.md                  |  6 ++++++
 gcc/config/riscv/riscv.md                      |  9 +++++----
 gcc/testsuite/gcc.target/riscv/sign-extend-1.c | 14 ++++++++++++++
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 32e1b1403051..c5ca01f382a9 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 24558682eb8f..b7fc13e4e611 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 e9056ec0d424..d8c18dd1aaa7 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" } } */

Reply via email to