https://gcc.gnu.org/g:cbeb7708210c45a85126e87c69aa80adf3e3f320
commit r16-4642-gcbeb7708210c45a85126e87c69aa80adf3e3f320 Author: Guo Jie <[email protected]> Date: Sat Oct 25 10:33:49 2025 +0800 LoongArch: Add a combiner to eliminate redundant extension When the bit width of the data type before extension plus the bit count of the left-shift operation equals 32, optimizations similar to the following can from: ext.w.b $r4,$r5 slli.d $r4,$r4,24 to: slli.w $r4,$r5,24 gcc/ChangeLog: * config/loongarch/loongarch.md (sign_extend_ashift<GPR:mode><SHORT:mode>): New combiner. gcc/testsuite/ChangeLog: * gcc.target/loongarch/sign_extend_ashift.c: New test. Diff: --- gcc/config/loongarch/loongarch.md | 10 ++++++++++ gcc/testsuite/gcc.target/loongarch/sign_extend_ashift.c | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index a275a2d0158e..933db2c252d5 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -3041,6 +3041,16 @@ [(set_attr "type" "shift") (set_attr "mode" "SI")]) +(define_insn "sign_extend_ashift<GPR:mode><SHORT:mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (ashift:GPR + (sign_extend:GPR (match_operand:SHORT 1 "register_operand" "r")) + (match_operand:SI 2 "const_uimm5_operand")))] + "(GET_MODE_BITSIZE (<SHORT:MODE>mode) + INTVAL (operands[2])) == 32" + "slli.w\t%0,%1,%2" + [(set_attr "type" "shift") + (set_attr "mode" "<GPR:MODE>")]) + (define_insn "*rotr<mode>3" [(set (match_operand:GPR 0 "register_operand" "=r,r") (rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r") diff --git a/gcc/testsuite/gcc.target/loongarch/sign_extend_ashift.c b/gcc/testsuite/gcc.target/loongarch/sign_extend_ashift.c new file mode 100644 index 000000000000..921fda9093ed --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/sign_extend_ashift.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3" } */ +/* { dg-final { scan-assembler "slli\\.w" } } */ +/* { dg-final { scan-assembler-not "slli\\.d" } } */ +/* { dg-final { scan-assembler-not "ext\\.w\\.b" } } */ + +unsigned int +test (unsigned int id) +{ + return id << 24; +}
