Hello!

Attached patch introduces bswaphi2 named insn pattern that results in
movbe instruction.

Without the patch, the following testcase:

void baz (char *buf, unsigned int data)
{
  buf[0] = data >> 8;
  buf[1] = data;
}

compiles to (-O2 -march=haswell):

        rolw    $8, %si
        movw    %si, (%rdi)

and with patched compiler:

        movbe   %si, (%rdi)

2017-11-20  Uros Bizjak  <ubiz...@gmail.com>

    * config/i386/i386.md (bswaphi2): New expander.
    (*bswaphi2_movbe): New insn pattern.
    (bswaphi -> rorhi pepehole2): New peephole pattern.

testsuite/ChangeLog:

2017-11-20  Uros Bizjak  <ubiz...@gmail.com>
        Jakub Jelinek  <ja...@redhat.com>

    * gcc.target/i386/movbe-5.c: New test.

Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 254958)
+++ config/i386/i386.md (working copy)
@@ -14091,6 +14091,39 @@
    (set_attr "modrm" "0")
    (set_attr "mode" "<MODE>")])
 
+(define_expand "bswaphi2"
+  [(set (match_operand:HI 0 "register_operand")
+       (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
+  "TARGET_MOVBE")
+
+(define_insn "*bswaphi2_movbe"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
+       (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_MOVBE
+   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    xchg{b}\t{%h0, %b0|%b0, %h0}
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "*,1,1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "pent_pair" "np,*,*")
+   (set_attr "athlon_decode" "vector,*,*")
+   (set_attr "amdfam10_decode" "double,*,*")
+   (set_attr "bdver1_decode" "double,*,*")
+   (set_attr "mode" "QI,HI,HI")])
+
+(define_peephole2
+  [(set (match_operand:HI 0 "general_reg_operand")
+       (bswap:HI (match_dup 0)))]
+  "TARGET_MOVBE
+   && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
+   && peep2_regno_dead_p (0, FLAGS_REG)"
+  [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
+             (clobber (reg:CC FLAGS_REG))])])
+
 (define_insn "*bswaphi_lowpart_1"
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
        (bswap:HI (match_dup 0)))
Index: testsuite/gcc.target/i386/movbe-5.c
===================================================================
--- testsuite/gcc.target/i386/movbe-5.c (nonexistent)
+++ testsuite/gcc.target/i386/movbe-5.c (working copy)
@@ -0,0 +1,18 @@
+/* PR tree-optimization/78821 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 } } */
+
+unsigned short
+foo (unsigned short *buf)
+{
+  unsigned short a = buf[0];
+  return ((unsigned short) (a >> 8)) | (unsigned short) (a << 8);
+}
+
+void
+bar (char *buf, unsigned int data)
+{
+  buf[0] = data >> 8;
+  buf[1] = data;
+}

Reply via email to