From 73eb0027ef4c4a85b9233a37a2e281f1222b1f90 Mon Sep 17 00:00:00 2001 From: Lulu Cheng Date: Thu, 30 Oct 2025 11:16:32 +0800 Subject: [PATCH] LoongArch: When loading an immediate value, promote mode to word_mode. This optimization can eliminate redundant immediate load instructions during CSE optimization. gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_legitimize_move): Optimize. gcc/testsuite/ChangeLog: * gcc.target/loongarch/sign-extend-6.c: New test. --- gcc/config/loongarch/loongarch.cc | 15 ++++++++++++++- .../gcc.target/loongarch/sign-extend-6.c | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/sign-extend-6.c diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index d11fe496a01..4e53635a7b9 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -3534,7 +3534,20 @@ loongarch_legitimize_move (machine_mode mode, rtx dest, rtx src) { if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode)) { - loongarch_emit_move (dest, force_reg (mode, src)); + /* When loading fixed-point scalar data, if the size of the mode + is smaller than the size of `word_mode`, the immediate value + is first loaded into a register of type `word_mode`. + This facilitates the elimination of common self-expressions. + This reduces redundant immediate value loading instructions. */ + rtx tmp; + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_CODE (src) == CONST_INT + && GET_MODE_SIZE (mode) < UNITS_PER_WORD) + tmp = gen_lowpart (mode, force_reg (word_mode, src)); + else + tmp = force_reg (mode, src); + + loongarch_emit_move (dest, tmp); return true; } diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-6.c b/gcc/testsuite/gcc.target/loongarch/sign-extend-6.c new file mode 100644 index 00000000000..74d0e589b1e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-6.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-times "addi.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,1\t" 1 } } */ + +extern unsigned short d; +int +test (int a, unsigned short b) +{ + if (a > 0) + { + d = 1; + if (b > d) + return 10; + } + + return 50; +} -- 2.47.3