115 lines
4.2 KiB
Diff
115 lines
4.2 KiB
Diff
From c6d4efda0fa064dfe1d3cc1b9abf8051a82cd74f Mon Sep 17 00:00:00 2001
|
|
From: Lulu Cheng <chenglulu@loongson.cn>
|
|
Date: Sat, 2 Sep 2023 10:59:55 +0800
|
|
Subject: [PATCH 056/124] LoongArch: Optimize switch with sign-extended index.
|
|
|
|
The patch refers to the submission of RISCV
|
|
7bbce9b50302959286381d9177818642bceaf301.
|
|
|
|
gcc/ChangeLog:
|
|
|
|
* config/loongarch/loongarch.cc (loongarch_extend_comparands):
|
|
In unsigned QImode test, check for sign extended subreg and/or
|
|
constant operands, and do a sign extension in that case.
|
|
* config/loongarch/loongarch.md (TARGET_64BIT): Define
|
|
template cbranchqi4.
|
|
|
|
gcc/testsuite/ChangeLog:
|
|
|
|
* gcc.target/loongarch/switch-qi.c: New test.
|
|
|
|
Signed-off-by: Peng Fan <fanpeng@loongson.cn>
|
|
Signed-off-by: ticat_fp <fanpeng@loongson.cn>
|
|
---
|
|
gcc/config/loongarch/loongarch.cc | 16 +++++++++++++---
|
|
gcc/config/loongarch/loongarch.md | 10 +++++++---
|
|
gcc/testsuite/gcc.target/loongarch/switch-qi.c | 16 ++++++++++++++++
|
|
3 files changed, 36 insertions(+), 6 deletions(-)
|
|
create mode 100644 gcc/testsuite/gcc.target/loongarch/switch-qi.c
|
|
|
|
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
|
|
index 7b48e3216..41d344b82 100644
|
|
--- a/gcc/config/loongarch/loongarch.cc
|
|
+++ b/gcc/config/loongarch/loongarch.cc
|
|
@@ -4221,11 +4221,21 @@ loongarch_allocate_fcc (machine_mode mode)
|
|
static void
|
|
loongarch_extend_comparands (rtx_code code, rtx *op0, rtx *op1)
|
|
{
|
|
- /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
|
|
+ /* Comparisons consider all GRLEN bits, so extend sub-GRLEN values. */
|
|
if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)))
|
|
{
|
|
- /* TODO: checkout It is more profitable to zero-extend QImode values. */
|
|
- if (unsigned_condition (code) == code && GET_MODE (*op0) == QImode)
|
|
+ /* It is more profitable to zero-extend QImode values. But not if the
|
|
+ first operand has already been sign-extended, and the second one is
|
|
+ is a constant or has already been sign-extended also. */
|
|
+ if (unsigned_condition (code) == code
|
|
+ && (GET_MODE (*op0) == QImode
|
|
+ && ! (GET_CODE (*op0) == SUBREG
|
|
+ && SUBREG_PROMOTED_VAR_P (*op0)
|
|
+ && SUBREG_PROMOTED_SIGNED_P (*op0)
|
|
+ && (CONST_INT_P (*op1)
|
|
+ || (GET_CODE (*op1) == SUBREG
|
|
+ && SUBREG_PROMOTED_VAR_P (*op1)
|
|
+ && SUBREG_PROMOTED_SIGNED_P (*op1))))))
|
|
{
|
|
*op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0);
|
|
if (CONST_INT_P (*op1))
|
|
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
|
|
index cf7441e0b..a5e9352ca 100644
|
|
--- a/gcc/config/loongarch/loongarch.md
|
|
+++ b/gcc/config/loongarch/loongarch.md
|
|
@@ -357,7 +357,7 @@
|
|
;; pointer-sized quantities. Exactly one of the two alternatives will match.
|
|
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
|
|
|
|
-;; Likewise, but for XLEN-sized quantities.
|
|
+;; Likewise, but for GRLEN-sized quantities.
|
|
(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
|
|
|
|
;; 64-bit modes for which we provide move patterns.
|
|
@@ -2733,11 +2733,15 @@
|
|
[(set_attr "type" "branch")])
|
|
|
|
|
|
+;; Branches operate on GRLEN-sized quantities, but for LoongArch64 we accept
|
|
+;; QImode values so we can force zero-extension.
|
|
+(define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
|
|
+
|
|
(define_expand "cbranch<mode>4"
|
|
[(set (pc)
|
|
(if_then_else (match_operator 0 "comparison_operator"
|
|
- [(match_operand:GPR 1 "register_operand")
|
|
- (match_operand:GPR 2 "nonmemory_operand")])
|
|
+ [(match_operand:BR 1 "register_operand")
|
|
+ (match_operand:BR 2 "nonmemory_operand")])
|
|
(label_ref (match_operand 3 ""))
|
|
(pc)))]
|
|
""
|
|
diff --git a/gcc/testsuite/gcc.target/loongarch/switch-qi.c b/gcc/testsuite/gcc.target/loongarch/switch-qi.c
|
|
new file mode 100644
|
|
index 000000000..dd192fd49
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.target/loongarch/switch-qi.c
|
|
@@ -0,0 +1,16 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-march=loongarch64 -mabi=lp64d" } */
|
|
+/* { dg-final { scan-assembler-not "bstrpick" } } */
|
|
+
|
|
+/* Test for loongarch_extend_comparands patch. */
|
|
+extern void asdf (int);
|
|
+void
|
|
+foo (signed char x) {
|
|
+ switch (x) {
|
|
+ case 0: asdf (10); break;
|
|
+ case 1: asdf (11); break;
|
|
+ case 2: asdf (12); break;
|
|
+ case 3: asdf (13); break;
|
|
+ case 4: asdf (14); break;
|
|
+ }
|
|
+}
|
|
--
|
|
2.33.0
|
|
|