https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89602
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- We don't even have such instructions in the machine description. So I guess the first question is how to represent those. Here is a possible draft: --- sse.md.jj2 2019-02-20 23:40:17.119140235 +0100 +++ sse.md 2019-03-06 13:48:26.286128346 +0100 @@ -1151,6 +1151,75 @@ (set_attr "memory" "none,load") (set_attr "mode" "<sseinsnmode>")]) +(define_insn "avx512f_mov<ssescalarmodelower>_mask" + [(set (match_operand:VF_128 0 "register_operand" "=v") + (vec_merge:VF_128 + (vec_merge:VF_128 + (match_operand:VF_128 2 "register_operand" "v") + (match_operand:VF_128 3 "nonimm_or_0_operand" "0C") + (match_operand:QI 4 "register_operand" "Yk")) + (match_operand:VF_128 1 "register_operand" "v") + (const_int 1)))] + "TARGET_AVX512F" + "vmov<ssescalarmodesuffix>\t{%2, %1, %0%{%4%}%N3|%0%{%4%}%N3, %1, %2}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "evex") + (set_attr "mode" "<ssescalarmode>")]) + +(define_expand "avx512f_load<mode>_mask" + [(set (match_operand:<ssevecmode> 0 "register_operand") + (vec_merge:<ssevecmode> + (vec_merge:<ssevecmode> + (vec_duplicate:<ssevecmode> + (match_operand:MODEF 1 "memory_operand")) + (match_operand:<ssevecmode> 2 "nonimm_or_0_operand") + (match_operand:QI 3 "nonmemory_operand")) + (match_dup 4) + (const_int 1)))] + "TARGET_AVX512F" + "operands[4] = CONST0_RTX (<ssevecmode>mode);") + +(define_insn "*avx512f_load<mode>_mask" + [(set (match_operand:<ssevecmode> 0 "register_operand" "=v") + (vec_merge:<ssevecmode> + (vec_merge:<ssevecmode> + (vec_duplicate:<ssevecmode> + (match_operand:MODEF 1 "memory_operand" "m")) + (match_operand:<ssevecmode> 2 "nonimm_or_0_operand" "0C") + (match_operand:QI 3 "nonmemory_operand" "Yk")) + (match_operand:<ssevecmode> 4 "const0_operand" "C") + (const_int 1)))] + "TARGET_AVX512F" + "vmov<ssescalarmodesuffix>\t{%1, %0%{%3%}%N2|%0%{3%}%N2, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "evex") + (set_attr "memory" "load") + (set_attr "mode" "<MODE>")]) + +(define_insn "avx512f_store<mode>_mask" + [(set (match_operand:MODEF 0 "memory_operand" "=m,m") + (if_then_else:MODEF + (ne:QI (and:QI (match_operand:QI 2 "nonmemory_operand" "Yk,n") + (const_int 1)) + (const_int 0)) + (vec_select:MODEF + (match_operand:<ssevecmode> 1 "register_operand" "v,v") + (parallel [(const_int 0)])) + (match_dup 0)))] + "TARGET_AVX512F" +{ + if (which_alternative == 0) + return "vmov<ssescalarmodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}"; + else if ((INTVAL (operands[2]) & 1) != 0) + return "vmov<ssescalarmodesuffix>\t{%1, %0|%0, %1}"; + else + return ""; +} + [(set_attr "type" "ssemov") + (set_attr "prefix" "evex,maybe_evex") + (set_attr "memory" "store") + (set_attr "mode" "<MODE>")]) + (define_insn "<avx512>_blendm<mode>" [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v") (vec_merge:V48_AVX512VL Guess we might want some patterns to catch the case where the mask is known constant with LSB set. The case when the mask is known constant with LSB clear doesn't seem to be representable easily, at least in some cases (especially {z} for vmovs{s,d} 3 register form and vmovs{s,d} load without {z}).