Patchwork [i386] : Optimize AND with 0xffffffff

login
register
mail settings
Submitter Uros Bizjak
Date Jan. 9, 2012, 5:59 p.m.
Message ID <CAFULd4Z9LksEY72zDPGsOsKcdrj04mfWcJFetB-pGZ0xa+cEFg@mail.gmail.com>
Download mbox | patch
Permalink /patch/135082/
State New
Headers show

Comments

Uros Bizjak - Jan. 9, 2012, 5:59 p.m.
Hello!

Attached patch fixes oversight with AND pattern and 0xffffffff
immediate. While ANDs with 0xff and 0xffff are converted to equivalent
zero_extend pattern, AND with 0xffffffff isn't. This problem leaves
important optimization that would substitute "movq    %rdi, %rax; andl
   $4294967295, %eax" sequence with "movl     %edi, %eax" ineffective.

This optimization happens ~100 times in cc1.

Moving to stage4 got me by a bit of surprise (I was away from the
keyboard for the weekend), so I will leave to RMs if this (otherwise
fairly safe patch) is OK for mainline.

2012-01-09  Uros Bizjak  <ubizjak@gmail.com>

	PR target/51681
	* config/i386/constraints.md ("L"): Return true for 0xffffffff.
	* config/i386/i386.c (*anddi_1): Emit AND with 0xffffffff as MOV.

So, OK for  mainline?

Uros.
Richard Guenther - Jan. 10, 2012, 8:55 a.m.
On Mon, 9 Jan 2012, Uros Bizjak wrote:

> Hello!
> 
> Attached patch fixes oversight with AND pattern and 0xffffffff
> immediate. While ANDs with 0xff and 0xffff are converted to equivalent
> zero_extend pattern, AND with 0xffffffff isn't. This problem leaves
> important optimization that would substitute "movq    %rdi, %rax; andl
>    $4294967295, %eax" sequence with "movl     %edi, %eax" ineffective.
> 
> This optimization happens ~100 times in cc1.
> 
> Moving to stage4 got me by a bit of surprise (I was away from the
> keyboard for the weekend), so I will leave to RMs if this (otherwise
> fairly safe patch) is OK for mainline.
> 
> 2012-01-09  Uros Bizjak  <ubizjak@gmail.com>
> 
> 	PR target/51681
> 	* config/i386/constraints.md ("L"): Return true for 0xffffffff.
> 	* config/i386/i386.c (*anddi_1): Emit AND with 0xffffffff as MOV.
> 
> So, OK for  mainline?

Ok from a RM perspective.

Richard.

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 183014)
+++ config/i386/i386.md	(working copy)
@@ -7678,19 +7678,23 @@ 
 	enum machine_mode mode;
 
 	gcc_assert (CONST_INT_P (operands[2]));
-        if (INTVAL (operands[2]) == 0xff)
-	  mode = QImode;
+	if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
+	  mode = SImode;
+	else if (INTVAL (operands[2]) == 0xffff)
+	  mode = HImode;
 	else
 	  {
-	    gcc_assert (INTVAL (operands[2]) == 0xffff);
-	    mode = HImode;
+	    gcc_assert (INTVAL (operands[2]) == 0xff);
+	    mode = QImode;
 	  }
 
 	operands[1] = gen_lowpart (mode, operands[1]);
-	if (mode == QImode)
+	if (mode == SImode)
+	  return "mov{l}\t{%1, %k0|%k0, %1}";
+	else if (mode == HImode)
+	  return "movz{wl|x}\t{%1, %k0|%k0, %1}";
+	else
 	  return "movz{bl|x}\t{%1, %k0|%k0, %1}";
-	else
-	  return "movz{wl|x}\t{%1, %k0|%k0, %1}";
       }
 
     default:
@@ -7726,19 +7730,19 @@ 
 	enum machine_mode mode;
 
 	gcc_assert (CONST_INT_P (operands[2]));
-        if (INTVAL (operands[2]) == 0xff)
-	  mode = QImode;
+        if (INTVAL (operands[2]) == 0xffff)
+	  mode = HImode;
 	else
 	  {
-	    gcc_assert (INTVAL (operands[2]) == 0xffff);
-	    mode = HImode;
+	    gcc_assert (INTVAL (operands[2]) == 0xff);
+	    mode = QImode;
 	  }
 
 	operands[1] = gen_lowpart (mode, operands[1]);
-	if (mode == QImode)
+	if (mode == HImode)
+	  return "movz{wl|x}\t{%1, %0|%0, %1}";
+	else
 	  return "movz{bl|x}\t{%1, %0|%0, %1}";
-	else
-	  return "movz{wl|x}\t{%1, %0|%0, %1}";
       }
 
     default:
Index: config/i386/constraints.md
===================================================================
--- config/i386/constraints.md	(revision 183014)
+++ config/i386/constraints.md	(working copy)
@@ -149,9 +149,11 @@ 
        (match_test "IN_RANGE (ival, -128, 127)")))
 
 (define_constraint "L"
-  "@code{0xFF} or @code{0xFFFF}, for andsi as a zero-extending move."
+  "@code{0xFF}, @code{0xFFFF} or @code{0xFFFFFFFF}
+   for AND as a zero-extending move."
   (and (match_code "const_int")
-       (match_test "ival == 0xFF || ival == 0xFFFF")))
+       (match_test "ival == 0xff || ival == 0xffff
+		    || ival == (HOST_WIDE_INT) 0xffffffff")))
 
 (define_constraint "M"
   "0, 1, 2, or 3 (shifts for the @code{lea} instruction)."