Use MOVSBL instead of MOVSBW for QImode-to-HImode sign extension to avoid
a 16-bit partial register write and to eliminate 0x66 operand size prefix.

    PR target/125636

gcc/ChangeLog:

    * config/i386/i386.md (extendqihi2): Use movsbl instead of movsbw.
    Adjust the destination operand to use %k0 and update the mode
    attribute accordingly.

gcc/testsuite/ChangeLog:

    * gcc.target/i386/pr89954.c: Update assembler scan
    directives to expect movsbl instead of movsbw.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 223fdb538cf..8db5d3b0152 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -5303,11 +5303,11 @@ (define_insn "extendqihi2"
     case 0:
       return "{cbtw|cbw}";
     default:
-      return "movs{bw|x}\t{%1, %0|%0, %1}";
+      return "movs{bl|x}\t{%1, %k0|%k0, %1}";
     }
 }
   [(set_attr "type" "imovx")
-   (set_attr "mode" "HI")
+   (set_attr "mode" "HI,SI")
    (set (attr "prefix_0f")
      ;; movsx is short decodable while cwtl is vector decoded.
      (if_then_else (and (eq_attr "cpu" "!k6")
diff --git a/gcc/testsuite/gcc.target/i386/pr89954.c 
b/gcc/testsuite/gcc.target/i386/pr89954.c
index c1e9f3a9562..99523903313 100644
--- a/gcc/testsuite/gcc.target/i386/pr89954.c
+++ b/gcc/testsuite/gcc.target/i386/pr89954.c
@@ -36,8 +36,7 @@ long long sext_xorlq (void) { return al ^ -4; }
 
 #endif
 
-/* { dg-final { scan-assembler-times "movsbw" 3 } } */
-/* { dg-final { scan-assembler-times "movsbl" 3 } } */
+/* { dg-final { scan-assembler-times "movsbl" 6 } } */
 /* { dg-final { scan-assembler-times "movswl" 3 } } */
 
 /* { dg-final { scan-assembler-times "movsbq" 3 { target { ! ia32 } } } } */

Reply via email to