1 Star 0 Fork 94

胡宇彪 / gcc

forked from src-openEuler / gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
LoongArch-Optimized-multiply-instruction-generation.patch 7.58 KB
一键复制 编辑 原始数据 按行查看 历史
ticat_fp 提交于 2024-03-26 09:26 . LoongArch: update from gcc upstream
From aa1dc79c9a5ff3df241a94cbfb1c857cfa89c686 Mon Sep 17 00:00:00 2001
From: Lulu Cheng <chenglulu@loongson.cn>
Date: Tue, 5 Sep 2023 11:09:03 +0800
Subject: [PATCH 074/124] LoongArch: Optimized multiply instruction generation.
1. Can generate mulh.w[u] instruction.
2. Can generate mulw.d.wu instruction.
gcc/ChangeLog:
* config/loongarch/loongarch.md (mulsidi3_64bit):
Field unsigned extension support.
(<u>muldi3_highpart): Modify template name.
(<u>mulsi3_highpart): Likewise.
(<u>mulsidi3_64bit): Field unsigned extension support.
(<su>muldi3_highpart): Modify muldi3_highpart to
smuldi3_highpart.
(<su>mulsi3_highpart): Modify mulsi3_highpart to
smulsi3_highpart.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/mulw_d_wu.c: New test.
* gcc.target/loongarch/smuldi3_highpart.c: New test.
* gcc.target/loongarch/smulsi3_highpart.c: New test.
* gcc.target/loongarch/umulsi3_highpart.c: New test.
Signed-off-by: Peng Fan <fanpeng@loongson.cn>
Signed-off-by: ticat_fp <fanpeng@loongson.cn>
---
gcc/config/loongarch/loongarch.md | 66 ++++++++++++-------
.../gcc.target/loongarch/mulw_d_wu.c | 9 +++
.../gcc.target/loongarch/smuldi3_highpart.c | 13 ++++
.../gcc.target/loongarch/smulsi3_highpart.c | 15 +++++
.../gcc.target/loongarch/umulsi3_highpart.c | 14 ++++
5 files changed, 94 insertions(+), 23 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c
create mode 100644 gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c
create mode 100644 gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c
create mode 100644 gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 11c18bf15..264cd325c 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -750,15 +750,6 @@
[(set_attr "type" "imul")
(set_attr "mode" "<MODE>")])
-(define_insn "mulsidi3_64bit"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
- "TARGET_64BIT"
- "mulw.d.w\t%0,%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "DI")])
-
(define_insn "*mulsi3_extended"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
@@ -787,14 +778,14 @@
emit_insn (gen_muldi3 (low, operands[1], operands[2]));
rtx high = gen_reg_rtx (DImode);
- emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
+ emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
emit_move_insn (gen_lowpart (DImode, operands[0]), low);
emit_move_insn (gen_highpart (DImode, operands[0]), high);
DONE;
})
-(define_insn "<u>muldi3_highpart"
+(define_insn "<su>muldi3_highpart"
[(set (match_operand:DI 0 "register_operand" "=r")
(truncate:DI
(lshiftrt:TI
@@ -809,22 +800,34 @@
(set_attr "mode" "DI")])
(define_expand "<u>mulsidi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
+ [(set (match_operand:DI 0 "register_operand")
(mult:DI (any_extend:DI
- (match_operand:SI 1 "register_operand" " r"))
+ (match_operand:SI 1 "register_operand"))
(any_extend:DI
- (match_operand:SI 2 "register_operand" " r"))))]
- "!TARGET_64BIT"
+ (match_operand:SI 2 "register_operand"))))]
+ ""
{
- rtx temp = gen_reg_rtx (SImode);
- emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
- emit_insn (gen_<u>mulsi3_highpart (loongarch_subword (operands[0], true),
- operands[1], operands[2]));
- emit_insn (gen_movsi (loongarch_subword (operands[0], false), temp));
- DONE;
+ if (!TARGET_64BIT)
+ {
+ rtx temp = gen_reg_rtx (SImode);
+ emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
+ emit_insn (gen_<su>mulsi3_highpart (loongarch_subword (operands[0], true),
+ operands[1], operands[2]));
+ emit_insn (gen_movsi (loongarch_subword (operands[0], false), temp));
+ DONE;
+ }
})
-(define_insn "<u>mulsi3_highpart"
+(define_insn "<u>mulsidi3_64bit"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
+ "TARGET_64BIT"
+ "mulw.d.w<u>\t%0,%1,%2"
+ [(set_attr "type" "imul")
+ (set_attr "mode" "DI")])
+
+(define_insn "<su>mulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "=r")
(truncate:SI
(lshiftrt:DI
@@ -833,11 +836,28 @@
(any_extend:DI
(match_operand:SI 2 "register_operand" " r")))
(const_int 32))))]
- "!TARGET_64BIT"
+ ""
"mulh.w<u>\t%0,%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")])
+;; Under the LoongArch architecture, the mulh.w[u] instruction performs
+;; sign extension by default, so the sign extension instruction can be
+;; eliminated.
+(define_peephole
+ [(set (match_operand:SI 0 "register_operand")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI (any_extend:DI
+ (match_operand:SI 1 "register_operand"))
+ (any_extend:DI
+ (match_operand:SI 2 "register_operand")))
+ (const_int 32))))
+ (set (match_operand:DI 3 "register_operand")
+ (sign_extend:DI (match_dup 0)))]
+ "TARGET_64BIT && REGNO (operands[0]) == REGNO (operands[3])"
+ "mulh.w<u>\t%0,%1,%2")
+
;;
;; ....................
;;
diff --git a/gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c b/gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c
new file mode 100644
index 000000000..16163d667
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mabi=lp64d" } */
+/* { dg-final { scan-assembler "mulw.d.wu" } } */
+
+__attribute__((noipa, noinline)) unsigned long
+f(unsigned long a, unsigned long b)
+{
+ return (unsigned long)(unsigned int)a * (unsigned long)(unsigned int)b;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c
new file mode 100644
index 000000000..6f5c686ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-expand-all" } */
+
+typedef int TI __attribute ((mode(TI)));
+typedef int DI __attribute__((mode(DI)));
+
+DI
+test (DI x, DI y)
+{
+ return ((TI)x * y) >> 64;
+}
+
+/* { dg-final { scan-rtl-dump "highparttmp" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c
new file mode 100644
index 000000000..c4dbf8afc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-expand-all" } */
+
+typedef unsigned int DI __attribute__((mode(DI)));
+typedef unsigned int SI __attribute__((mode(SI)));
+
+SI
+f (SI x, SI y)
+{
+ return ((DI) x * y) >> 32;
+}
+
+/* { dg-final { scan-rtl-dump "highparttmp" "expand" } } */
+/* { dg-final { scan-assembler "mulh\\.w" } } */
+/* { dg-final { scan-assembler-not "slli\\.w" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c
new file mode 100644
index 000000000..e208803e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned int DI __attribute__((mode(DI)));
+typedef unsigned int SI __attribute__((mode(SI)));
+
+SI
+f (SI x, SI y)
+{
+ return ((DI) x * y) >> 32;
+}
+
+/* { dg-final { scan-assembler "mulh\\.wu" } } */
+/* { dg-final { scan-assembler-not "slli\\.w" } } */
--
2.33.0
1
https://gitee.com/huyubiao/gcc.git
git@gitee.com:huyubiao/gcc.git
huyubiao
gcc
gcc
master

搜索帮助