Hello!

This patch cleans and improves mask op patterns a bit. The patch uses
insn mode attribute to control emission of word-mode operations and
macroizes a couple of patterns.

No functional changes.

2016-11-23  Uros Bizjak  <ubiz...@gmail.com>

    * gcc.target/config/i386.md (*movqi_internal): Calculate mode
    attribute of alternatives 7,8,9 depending on TARGET_AVX512DQ.
    <TYPE_MSKMOV>: Emit kmovw for MODE_HI insn mode attribute.
    (*k<logic><mode>): Calculate mode attribute depending on
    TARGET_AVX512DQ.  Emit k<logic>w for MODE_HI insn mode attribute.
    (*andqi_1): Calculate mode attribute of alternative 3 depending
    on TARGET_AVX512DQ.  Emit kandw for MODE_HI insn mode attribute.
    (kandn<mode>): Calculate mode attribute of alternative 2 depending
    on TARGET_AVX512DQ.  Emit kandnw for MODE_HI insn mode attribute.
    (kxnor<mode>): Merge insn patterns using SWI1248_AVX512BW mode
    iterator.  Calculate mode attribute of alternative 1 depending
    on TARGET_AVX512DQ.  Emit kxnorw for MODE_HI insn mode attribute.
    (*one_cmplqi2_1): Calculate mode attribute of alternative 2 depending
    on TARGET_AVX512DQ.  Emit knotw for MODE_HI insn mode attribute.

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 242765)
+++ config/i386/i386.md (working copy)
@@ -970,6 +970,11 @@
 (define_mode_iterator SWI1248_AVX512BWDQ
   [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
 
+;; All integer modes with AVX512BW, where HImode operation
+;; can be used instead of QImode.
+(define_mode_iterator SWI1248_AVX512BW
+  [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
+
 ;; All integer modes without QImode.
 (define_mode_iterator SWI248x [HI SI DI])
 
@@ -2574,11 +2582,15 @@
 
 (define_insn "*movqi_internal"
   [(set (match_operand:QI 0 "nonimmediate_operand"
-                       "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
+                       "=q,q ,q ,r,r ,?r,m ,k,k,r,m,k")
        (match_operand:QI 1 "general_operand"
-                       "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
+                       "q ,qn,qm,q,rn,qm,qn,r,k,k,k,m"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
+  static char buf[128];
+  const char *ops;
+  const char *suffix;
+
   switch (get_attr_type (insn))
     {
     case TYPE_IMOVX:
@@ -2588,24 +2600,33 @@
     case TYPE_MSKMOV:
       switch (which_alternative)
         {
-       case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
-                                      : "kmovw\t{%k1, %0|%0, %k1}";
-       case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
-                                      : "kmovw\t{%1, %0|%0, %1}";
-       case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
-                                      : "kmovw\t{%1, %k0|%k0, %1}";
+       case 7:
+         ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
+         break;
+       case 9:
+         ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
+         break;
        case 10:
        case 11:
          gcc_assert (TARGET_AVX512DQ);
-         return "kmovb\t{%1, %0|%0, %1}";
-       default: gcc_unreachable ();
+         /* FALLTHRU */
+       case 8:
+         ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
+         break;
+       default:
+         gcc_unreachable ();
        }
 
+      suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
+
+      snprintf (buf, sizeof (buf), ops, suffix);
+      return buf;
+
     default:
       if (get_attr_mode (insn) == MODE_SI)
-        return "mov{l}\t{%k1, %k0|%k0, %k1}";
+       return "mov{l}\t{%k1, %k0|%k0, %k1}";
       else
-        return "mov{b}\t{%1, %0|%0, %1}";
+       return "mov{b}\t{%1, %0|%0, %1}";
     }
 }
   [(set (attr "isa")
@@ -2640,6 +2661,9 @@
               (const_string "SI")
             (eq_attr "alternative" "6")
               (const_string "QI")
+            (and (eq_attr "alternative" "7,8,9")
+                 (not (match_test "TARGET_AVX512DQ")))
+              (const_string "HI")
             (eq_attr "type" "imovx")
               (const_string "SI")
             (and (eq_attr "type" "imov")
@@ -8055,23 +8079,26 @@
        (any_logic:SWI1248x (match_dup 1)
                            (match_dup 2)))])
 
-(define_mode_iterator SWI1248_AVX512BW
-  [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
-
 (define_insn "*k<logic><mode>"
   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
-       (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 
"mask_reg_operand" "k")
-                                   (match_operand:SWI1248_AVX512BW 2 
"mask_reg_operand" "k")))]
+       (any_logic:SWI1248_AVX512BW
+         (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
+         (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
   "TARGET_AVX512F"
   {
-    if (!TARGET_AVX512DQ && <MODE>mode == QImode)
+    if (get_attr_mode (insn) == MODE_HI)
       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
     else
       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
   }
-  [(set_attr "mode" "<MODE>")
-   (set_attr "type" "msklog")
-   (set_attr "prefix" "vex")])
+  [(set_attr "type" "msklog")
+   (set_attr "prefix" "vex")
+   (set (attr "mode")
+     (cond [(and (match_test "<MODE>mode == QImode")
+                (not (match_test "TARGET_AVX512DQ")))
+              (const_string "HI")
+          ]
+          (const_string "<MODE>")))])
 
 ;; %%% This used to optimize known byte-wide and operations to memory,
 ;; and sometimes to QImode registers.  If this is considered useful,
@@ -8278,14 +8305,22 @@
     case 2:
       return "and{l}\t{%k2, %k0|%k0, %k2}";
     case 3:
-      return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
-                            : "kandw\t{%2, %1, %0|%0, %1, %2}";
+      if (get_attr_mode (insn) == MODE_HI)
+       return "kandw\t{%2, %1, %0|%0, %1, %2}";
+      else
+       return "kandb\t{%2, %1, %0|%0, %1, %2}";
     default:
       gcc_unreachable ();
     }
 }
   [(set_attr "type" "alu,alu,alu,msklog")
-   (set_attr "mode" "QI,QI,SI,HI")
+   (set (attr "mode")
+      (cond [(eq_attr "alternative" "2")
+              (const_string "SI")
+            (and (eq_attr "alternative" "3")
+                 (not (match_test "TARGET_AVX512DQ")))
+              (const_string "HI")]
+           (const_string "QI")))
    ;; Potential partial reg stall on alternative 2.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "2")
@@ -8319,10 +8354,10 @@
     case 1:
       return "#";
     case 2:
-      if (TARGET_AVX512DQ && <MODE>mode == QImode)
-       return "kandnb\t{%2, %1, %0|%0, %1, %2}";
+      if (get_attr_mode (insn) == MODE_HI)
+       return "kandnw\t{%2, %1, %0|%0, %1, %2}";
       else
-       return "kandnw\t{%2, %1, %0|%0, %1, %2}";
+       return "kandn<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
     default:
       gcc_unreachable ();
     }
@@ -8331,7 +8366,13 @@
    (set_attr "type" "bitmanip,*,msklog")
    (set_attr "prefix" "*,*,vex")
    (set_attr "btver2_decode" "direct,*,*")
-   (set_attr "mode" "<MODE>")])
+   (set (attr "mode")
+     (cond [(and (eq_attr "alternative" "2")
+                (and (match_test "<MODE>mode == QImode")
+                     (not (match_test "TARGET_AVX512DQ"))))
+              (const_string "HI")
+          ]
+          (const_string "<MODE>")))])
 
 (define_split
   [(set (match_operand:SWI12 0 "general_reg_operand")
@@ -8843,37 +8884,32 @@
    (set_attr "mode" "<MODE>")])
 
 (define_insn "kxnor<mode>"
-  [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
-       (not:SWI12
-         (xor:SWI12
-           (match_operand:SWI12 1 "register_operand" "0,k")
-           (match_operand:SWI12 2 "register_operand" "r,k"))))
+  [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=r,!k")
+       (not:SWI1248_AVX512BW
+         (xor:SWI1248_AVX512BW
+           (match_operand:SWI1248_AVX512BW 1 "register_operand" "0,k")
+           (match_operand:SWI1248_AVX512BW 2 "register_operand" "r,k"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_AVX512F"
 {
-  if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
-    return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
-  return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
+  if (which_alternative == 0)
+    return "#";
+
+  if (get_attr_mode (insn) == MODE_HI)
+    return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
+  else
+    return "kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
 }
   [(set_attr "type" "*,msklog")
    (set_attr "prefix" "*,vex")
-   (set_attr "mode" "<MODE>")])
+   (set (attr "mode")
+     (cond [(and (eq_attr "alternative" "1")
+                (and (match_test "<MODE>mode == QImode")
+                     (not (match_test "TARGET_AVX512DQ"))))
+             (const_string "HI")
+          ]
+          (const_string "<MODE>")))])
 
-(define_insn "kxnor<mode>"
-  [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
-       (not:SWI48x
-         (xor:SWI48x
-           (match_operand:SWI48x 1 "register_operand" "0,k")
-           (match_operand:SWI48x 2 "register_operand" "r,k"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_AVX512BW"
-  "@
-   #
-   kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "*,msklog")
-   (set_attr "prefix" "*,vex")
-   (set_attr "mode" "<MODE>")])
-
 (define_split
   [(set (match_operand:SWI1248x 0 "general_reg_operand")
        (not:SWI1248x
@@ -9583,9 +9619,10 @@
     case 1:
       return "not{l}\t%k0";
     case 2:
-      if (TARGET_AVX512DQ)
+      if (get_attr_mode (insn) == MODE_HI)
+       return "knotw\t{%1, %0|%0, %1}";
+      else
        return "knotb\t{%1, %0|%0, %1}";
-      return "knotw\t{%1, %0|%0, %1}";
     default:
       gcc_unreachable ();
     }
@@ -9593,7 +9630,13 @@
   [(set_attr "isa" "*,*,avx512f")
    (set_attr "type" "negnot,negnot,msklog")
    (set_attr "prefix" "*,*,vex")
-   (set_attr "mode" "QI,SI,QI")
+   (set (attr "mode")
+      (cond [(eq_attr "alternative" "1")
+              (const_string "SI")
+            (and (eq_attr "alternative" "2")
+                 (not (match_test "TARGET_AVX512DQ")))
+              (const_string "HI")]
+           (const_string "QI")))
    ;; Potential partial reg stall on alternative 1.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "1")

Reply via email to