https://gcc.gnu.org/g:31ab40016ae2864e4aa7741a1e3b6d867a6779cc
commit 31ab40016ae2864e4aa7741a1e3b6d867a6779cc 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 32e1b140305..c5ca01f382a 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 24558682eb8..b7fc13e4e61 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 e9056ec0d42..d8c18dd1aaa 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" } } */