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  <ubiz...@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.
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)."

Reply via email to