Hi!

Most AVX* instructions have the same insn name between VEX and EVEX
encoded insns and whether it is EVEX or VEX encoded is determined by
the operands by the assembler (if there is masking/broadcast, or
%[xy]mm16+ operands are present, or when using 512-bit vectors).
This is not the case for the logical instruction, we have VEX
encoded VP{AND,OR,XOR,ANDN} and EVEX encoded VP{AND,OR,XOR,ANDN}{D,Q}.

Right now we use the d or q suffixes for -mavx512vl even when we could
use VEX encoded insn, which results in larger opcode.

The following patch fixes that, by emitting the suffix only when needed.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-10-04  Jakub Jelinek  <ja...@redhat.com>

        PR target/82370
        * config/i386/sse.md (*andnot<mode>3,
        <mask_codefor><code><mode>3<mask_name>, *<code><mode>3): Split
        (=v,v,vm) alternative into (=x,x,xm) and (=v,v,vm), for 128-bit
        and 256-bit vectors, the (=x,x,xm) alternative and when mask is
        not applied use empty suffix even for TARGET_AVX512VL.
        * config/i386/subst.md (mask_prefix3, mask_prefix4): When mask
        is applied, supply evex,evex or evex,evex,evex instead of just
        evex.

--- gcc/config/i386/sse.md.jj   2017-09-22 20:51:51.000000000 +0200
+++ gcc/config/i386/sse.md      2017-10-03 18:25:24.289527626 +0200
@@ -11568,10 +11568,10 @@ (define_expand "<sse2_avx2>_andnot<mode>
   "TARGET_AVX512BW")
 
 (define_insn "*andnot<mode>3"
-  [(set (match_operand:VI 0 "register_operand" "=x,v")
+  [(set (match_operand:VI 0 "register_operand" "=x,x,v")
        (and:VI
-         (not:VI (match_operand:VI 1 "register_operand" "0,v"))
-         (match_operand:VI 2 "vector_operand" "xBm,vm")))]
+         (not:VI (match_operand:VI 1 "register_operand" "0,x,v"))
+         (match_operand:VI 2 "vector_operand" "xBm,xm,vm")))]
   "TARGET_SSE"
 {
   static char buf[64];
@@ -11606,10 +11606,11 @@ (define_insn "*andnot<mode>3"
        case E_V4DImode:
        case E_V4SImode:
        case E_V2DImode:
-         ssesuffix = TARGET_AVX512VL ? "<ssemodesuffix>" : "";
+         ssesuffix = (TARGET_AVX512VL && which_alternative == 2
+                      ? "<ssemodesuffix>" : "");
          break;
        default:
-         ssesuffix = TARGET_AVX512VL ? "q" : "";
+         ssesuffix = TARGET_AVX512VL && which_alternative == 2 ? "q" : "";
        }
       break;
 
@@ -11635,6 +11636,7 @@ (define_insn "*andnot<mode>3"
       ops = "%s%s\t{%%2, %%0|%%0, %%2}";
       break;
     case 1:
+    case 2:
       ops = "v%s%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
       break;
     default:
@@ -11644,7 +11646,7 @@ (define_insn "*andnot<mode>3"
   snprintf (buf, sizeof (buf), ops, tmp, ssesuffix);
   return buf;
 }
-  [(set_attr "isa" "noavx,avx")
+  [(set_attr "isa" "noavx,avx,avx")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
@@ -11652,7 +11654,7 @@ (define_insn "*andnot<mode>3"
            (eq_attr "mode" "TI"))
        (const_string "1")
        (const_string "*")))
-   (set_attr "prefix" "orig,vex")
+   (set_attr "prefix" "orig,vex,evex")
    (set (attr "mode")
        (cond [(and (match_test "<MODE_SIZE> == 16")
                    (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
@@ -11697,10 +11699,10 @@ (define_expand "<code><mode>3"
 })
 
 (define_insn "<mask_codefor><code><mode>3<mask_name>"
-  [(set (match_operand:VI48_AVX_AVX512F 0 "register_operand" "=x,v")
+  [(set (match_operand:VI48_AVX_AVX512F 0 "register_operand" "=x,x,v")
        (any_logic:VI48_AVX_AVX512F
-         (match_operand:VI48_AVX_AVX512F 1 "vector_operand" "%0,v")
-         (match_operand:VI48_AVX_AVX512F 2 "vector_operand" "xBm,vm")))]
+         (match_operand:VI48_AVX_AVX512F 1 "vector_operand" "%0,x,v")
+         (match_operand:VI48_AVX_AVX512F 2 "vector_operand" "xBm,xm,vm")))]
   "TARGET_SSE && <mask_mode512bit_condition>
    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
 {
@@ -11730,7 +11732,9 @@ (define_insn "<mask_codefor><code><mode>
        case E_V4DImode:
        case E_V4SImode:
        case E_V2DImode:
-         ssesuffix = TARGET_AVX512VL ? "<ssemodesuffix>" : "";
+         ssesuffix = (TARGET_AVX512VL
+                      && (<mask_applied> || which_alternative == 2)
+                      ? "<ssemodesuffix>" : "");
          break;
        default:
          gcc_unreachable ();
@@ -11759,6 +11763,7 @@ (define_insn "<mask_codefor><code><mode>
         ops = "%s%s\t{%%2, %%0|%%0, %%2}";
       break;
     case 1:
+    case 2:
       ops = "v%s%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, 
%%2}";
       break;
     default:
@@ -11768,7 +11773,7 @@ (define_insn "<mask_codefor><code><mode>
   snprintf (buf, sizeof (buf), ops, tmp, ssesuffix);
   return buf;
 }
-  [(set_attr "isa" "noavx,avx")
+  [(set_attr "isa" "noavx,avx,avx")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
@@ -11776,7 +11781,7 @@ (define_insn "<mask_codefor><code><mode>
            (eq_attr "mode" "TI"))
        (const_string "1")
        (const_string "*")))
-   (set_attr "prefix" "<mask_prefix3>")
+   (set_attr "prefix" "<mask_prefix3>,evex")
    (set (attr "mode")
        (cond [(and (match_test "<MODE_SIZE> == 16")
                    (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
@@ -11795,10 +11800,10 @@ (define_insn "<mask_codefor><code><mode>
              (const_string "<sseinsnmode>")))])
 
 (define_insn "*<code><mode>3"
-  [(set (match_operand:VI12_AVX_AVX512F 0 "register_operand" "=x,v")
+  [(set (match_operand:VI12_AVX_AVX512F 0 "register_operand" "=x,x,v")
        (any_logic: VI12_AVX_AVX512F
-         (match_operand:VI12_AVX_AVX512F 1 "vector_operand" "%0,v")
-         (match_operand:VI12_AVX_AVX512F 2 "vector_operand" "xBm,vm")))]
+         (match_operand:VI12_AVX_AVX512F 1 "vector_operand" "%0,x,v")
+         (match_operand:VI12_AVX_AVX512F 2 "vector_operand" "xBm,xm,vm")))]
   "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
 {
   static char buf[64];
@@ -11827,7 +11832,7 @@ (define_insn "*<code><mode>3"
        case E_V16HImode:
        case E_V16QImode:
        case E_V8HImode:
-         ssesuffix = TARGET_AVX512VL ? "q" : "";
+         ssesuffix = TARGET_AVX512VL && which_alternative == 2 ? "q" : "";
          break;
        default:
          gcc_unreachable ();
@@ -11853,6 +11858,7 @@ (define_insn "*<code><mode>3"
       ops = "%s%s\t{%%2, %%0|%%0, %%2}";
       break;
     case 1:
+    case 2:
       ops = "v%s%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
       break;
     default:
@@ -11862,7 +11868,7 @@ (define_insn "*<code><mode>3"
   snprintf (buf, sizeof (buf), ops, tmp, ssesuffix);
   return buf;
 }
-  [(set_attr "isa" "noavx,avx")
+  [(set_attr "isa" "noavx,avx,avx")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
@@ -11870,7 +11876,7 @@ (define_insn "*<code><mode>3"
            (eq_attr "mode" "TI"))
        (const_string "1")
        (const_string "*")))
-   (set_attr "prefix" "<mask_prefix3>")
+   (set_attr "prefix" "<mask_prefix3>,evex")
    (set (attr "mode")
        (cond [(and (match_test "<MODE_SIZE> == 16")
                    (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
--- gcc/config/i386/subst.md.jj 2017-07-06 20:31:45.000000000 +0200
+++ gcc/config/i386/subst.md    2017-10-03 18:20:45.605867446 +0200
@@ -62,8 +62,8 @@ (define_subst_attr "store_mask_constrain
 (define_subst_attr "store_mask_predicate" "mask" "nonimmediate_operand" 
"register_operand")
 (define_subst_attr "mask_prefix" "mask" "vex" "evex")
 (define_subst_attr "mask_prefix2" "mask" "maybe_vex" "evex")
-(define_subst_attr "mask_prefix3" "mask" "orig,vex" "evex")
-(define_subst_attr "mask_prefix4" "mask" "orig,orig,vex" "evex")
+(define_subst_attr "mask_prefix3" "mask" "orig,vex" "evex,evex")
+(define_subst_attr "mask_prefix4" "mask" "orig,orig,vex" "evex,evex,evex")
 (define_subst_attr "mask_expand_op3" "mask" "3" "5")
 
 (define_subst "mask"

        Jakub

Reply via email to