diff mbox

[i386] : (Partially) fix PR78952, Combine does not convert 8-bit sign-extract to a zero-extract

Message ID CAFULd4bdNs6K8aj+Yr7shPmjDw36yFyE-j6Ci-Yh0f_FLWh-HA@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Jan. 18, 2017, 7:30 p.m. UTC
As suggested by Segher, we have to use code iterator to iterate RTX
pattern through zero- and sign-extract for 8 bit inserts. In a similar
way, we can use any_shiftrt in a RTX pattern involving 8-bit inserts.

While it would be nice to have a middle-end perform relevant
simplifications, these two places are all that matters for x86.

2017-01-18  Uros Bizjak  <ubizjak@gmail.com>

    PR rtl-optimization/78952
    * config/i386/i386.md (any_extract): New code iterator.
    (*insvqi_2): Use any_extract for source operand.
    (*insvqi_3): Use any_shiftrt for source operand.

testsuite/ChangeLog:

2017-01-18  Uros Bizjak  <ubizjak@gmail.com>

    PR rtl-optimization/78952
    * gcc.target/i386/pr78952-1.c: New test.
    * gcc.target/i386/pr78952-2.c: Ditto.

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

Committed to mainline SVN.

Uros.
diff mbox

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 244578)
+++ config/i386/i386.md	(working copy)
@@ -2960,13 +2960,15 @@ 
 	   (subreg:SI (match_dup 1) 0))
       (unspec [(const_int 0)] UNSPEC_NOREX_MEM)])])
 
+(define_code_iterator any_extract [sign_extract zero_extract])
+
 (define_insn "*insvqi_2"
   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
 			 (const_int 8)
 			 (const_int 8))
-	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
-			 (const_int 8)
-			 (const_int 8)))]
+	(any_extract:SI (match_operand 1 "ext_register_operand" "Q")
+			(const_int 8)
+			(const_int 8)))]
   ""
   "mov{b}\t{%h1, %h0|%h0, %h1}"
   [(set_attr "type" "imov")
@@ -2976,8 +2978,8 @@ 
   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
 			 (const_int 8)
 			 (const_int 8))
-	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
-		     (const_int 8)))]
+	(any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
+			(const_int 8)))]
   ""
   "mov{b}\t{%h1, %h0|%h0, %h1}"
   [(set_attr "type" "imov")
Index: testsuite/gcc.target/i386/pr78952-1.c
===================================================================
--- testsuite/gcc.target/i386/pr78952-1.c	(nonexistent)
+++ testsuite/gcc.target/i386/pr78952-1.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* PR target/78952 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movsbl" } } */
+
+struct S1
+{
+  char pad1;
+  char val;
+  short pad2;
+};
+
+struct S1 foo (struct S1 a, struct S1 b)
+{
+  a.val = b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+%.h, %.h" } } */
Index: testsuite/gcc.target/i386/pr78952-2.c
===================================================================
--- testsuite/gcc.target/i386/pr78952-2.c	(nonexistent)
+++ testsuite/gcc.target/i386/pr78952-2.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* PR target/78952 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "sarl" } } */
+
+struct S1
+{
+  char pad1;
+  char val;
+  short pad2;
+};
+
+struct S1 foo (struct S1 a, int b)
+{
+  a.val = b >> 8;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+%.h, %.h" } } */