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.
[(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")
--- /dev/null
+/* { 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;
+}