On Fri, Sep 26, 2014 at 2:32 PM, Kirill Yukhin <kirill.yuk...@gmail.com> wrote: > Hello, > This patch extends andnot and any_logic insn > patterns. > > Bootstrapped. > AVX-512* tests on top of patch-set all pass > under simulator. > > Is it ok for trunk? > > gcc/ > * config/i386/sse.md > (define_insn "<sse>_andnot<VF_128_256:mode>3<mask_name>"): Add > masking, > use VF_128_256 mode iterator and update assembler emit code. > (define_insn "<sse>_andnot<VF_512:mode>3<mask_name>"): New. > (define_expand "<any_logic:code><VF_128_256:mode>3<mask_name>"): > Add masking, use VF_128_256 mode iterator. > (define_expand "<any_logic:code><VF_512:mode>3<mask_name>"): New. > (define_insn "*<any_logic:code><VF_128_256:mode>3<mask_name>"): > Add masking, use VF_128_256 mode iterator and update assembler emit > code. > (define_insn "*<any_logic:code><VF_512:mode>3<mask_name>"): New. > (define_mode_attr avx512flogicsuff): Delete. > (define_insn "avx512f_<logic><mode>"): Ditto. > (define_insn "*andnot<mode>3<mask_name>"): Update MODE_XI, MODE_OI, > MODE_TI. > (define_insn "<mask_codefor><code><mode>3<mask_name>"): Ditto. > > -- > Thanks, K > > diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md > index 91d6778..9835234 100644 > --- a/gcc/config/i386/sse.md > +++ b/gcc/config/i386/sse.md > @@ -2687,15 +2687,15 @@ > ;; > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > -(define_insn "<sse>_andnot<mode>3" > - [(set (match_operand:VF 0 "register_operand" "=x,v") > - (and:VF > - (not:VF > - (match_operand:VF 1 "register_operand" "0,v")) > - (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))] > - "TARGET_SSE" > +(define_insn "<sse>_andnot<mode>3<mask_name>" > + [(set (match_operand:VF_128_256 0 "register_operand" "=x,v") > + (and:VF_128_256 > + (not:VF_128_256 > + (match_operand:VF_128_256 1 "register_operand" "0,v")) > + (match_operand:VF_128_256 2 "nonimmediate_operand" "xm,vm")))] > + "TARGET_SSE && <mask_avx512vl_condition>" > { > - static char buf[32]; > + static char buf[128]; > const char *ops; > const char *suffix; > > @@ -2715,17 +2715,17 @@ > ops = "andn%s\t{%%2, %%0|%%0, %%2}"; > break; > case 1: > - ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; > + ops = "vandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, > %%1, %%2}"; > break; > default: > gcc_unreachable (); > } > > - /* There is no vandnp[sd]. Use vpandnq. */ > - if (<MODE_SIZE> == 64) > + /* There is no vandnp[sd] in avx512f. Use vpandn[qd]. */ > + if (<mask_applied> && !TARGET_AVX512DQ) > { > - suffix = "q"; > - ops = "vpandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; > + suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d"; > + ops = "vpandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, > %%1, %%2}"; > } > > snprintf (buf, sizeof (buf), ops, suffix); > @@ -2745,30 +2745,63 @@ > ] > (const_string "<MODE>")))]) > > -(define_expand "<code><mode>3" > + > +(define_insn "<sse>_andnot<mode>3<mask_name>" > + [(set (match_operand:VF_512 0 "register_operand" "=v") > + (and:VF_512 > + (not:VF_512 > + (match_operand:VF_512 1 "register_operand" "v")) > + (match_operand:VF_512 2 "nonimmediate_operand" "vm")))] > + "TARGET_AVX512F" > +{ > + static char buf[128]; > + const char *ops; > + const char *suffix; > + > + suffix = "<ssemodesuffix>"; > + ops = ""; > + > + /* There is no vandnp[sd] in avx512f. Use vpandn[qd]. */ > + if (!TARGET_AVX512DQ)
All other patterns also have "<mask_applied> &&" condition here. Is the above condition correct? > + { > + suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d"; > + ops = "p"; > + } > + > + snprintf (buf, sizeof (buf), > + "v%sandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, > %%1, %%2}", > + ops, suffix); > + return buf; > +} > + [(set_attr "type" "sselog") > + (set_attr "prefix" "evex") > + (set_attr "mode" "<sseinsnmode>")]) > + > +(define_expand "<code><mode>3<mask_name>" > [(set (match_operand:VF_128_256 0 "register_operand") > - (any_logic:VF_128_256 > - (match_operand:VF_128_256 1 "nonimmediate_operand") > - (match_operand:VF_128_256 2 "nonimmediate_operand")))] > - "TARGET_SSE" > + (any_logic:VF_128_256 > + (match_operand:VF_128_256 1 "nonimmediate_operand") > + (match_operand:VF_128_256 2 "nonimmediate_operand")))] > + "TARGET_SSE && <mask_avx512vl_condition>" > "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") > > -(define_expand "<code><mode>3" > +(define_expand "<code><mode>3<mask_name>" > [(set (match_operand:VF_512 0 "register_operand") > - (fpint_logic:VF_512 > + (any_logic:VF_512 > (match_operand:VF_512 1 "nonimmediate_operand") > (match_operand:VF_512 2 "nonimmediate_operand")))] > "TARGET_AVX512F" > "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") > > -(define_insn "*<code><mode>3" > - [(set (match_operand:VF 0 "register_operand" "=x,v") > - (any_logic:VF > - (match_operand:VF 1 "nonimmediate_operand" "%0,v") > - (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))] > - "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" > +(define_insn "*<code><mode>3<mask_name>" > + [(set (match_operand:VF_128_256 0 "register_operand" "=x,v") > + (any_logic:VF_128_256 > + (match_operand:VF_128_256 1 "nonimmediate_operand" "%0,v") > + (match_operand:VF_128_256 2 "nonimmediate_operand" "xm,vm")))] > + "TARGET_SSE && <mask_avx512vl_condition> > + && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" > { > - static char buf[32]; > + static char buf[128]; > const char *ops; > const char *suffix; > > @@ -2788,17 +2821,17 @@ > ops = "<logic>%s\t{%%2, %%0|%%0, %%2}"; > break; > case 1: > - ops = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; > + ops = "v<logic>%s\t{%%2, %%1, > %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}"; > break; > default: > gcc_unreachable (); > } > > - /* There is no v<logic>p[sd]. Use vp<logic>q. */ > - if (<MODE_SIZE> == 64) > + /* There is no v<logic>p[sd] in avx512f. Use vp<logic>[dq]. */ > + if (<mask_applied> && !TARGET_AVX512DQ) > { > - suffix = "q"; > - ops = "vp<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; > + suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d"; > + ops = "vp<logic>%s\t{%%2, %%1, > %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}"; > } > > snprintf (buf, sizeof (buf), ops, suffix); > @@ -2818,6 +2851,36 @@ > ] > (const_string "<MODE>")))]) > > +(define_insn "*<code><mode>3<mask_name>" > + [(set (match_operand:VF_512 0 "register_operand" "=v") > + (any_logic:VF_512 > + (match_operand:VF_512 1 "nonimmediate_operand" "%v") > + (match_operand:VF_512 2 "nonimmediate_operand" "vm")))] > + "TARGET_AVX512F && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" > +{ > + static char buf[128]; > + const char *ops; > + const char *suffix; > + > + suffix = "<ssemodesuffix>"; > + ops = ""; > + > + /* There is no v<logic>p[sd] in avx512f. Use vp<logic>[dq]. */ > + if ((<MODE_SIZE> == 64 || <mask_applied>) && !TARGET_AVX512DQ) > + { > + suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d"; > + ops = "p"; > + } > + > + snprintf (buf, sizeof (buf), > + "v%s<logic>%s\t{%%2, %%1, > %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}", > + ops, suffix); > + return buf; > +} > + [(set_attr "type" "sselog") > + (set_attr "prefix" "evex") > + (set_attr "mode" "<sseinsnmode>")]) > + > (define_expand "copysign<mode>3" > [(set (match_dup 4) > (and:VF > @@ -3027,23 +3090,6 @@ > ] > (const_string "TI")))]) > > -;; There are no floating point xor for V16SF and V8DF in avx512f > -;; but we need them for negation. Instead we use int versions of > -;; xor. Maybe there could be a better way to do that. > - > -(define_mode_attr avx512flogicsuff > - [(V16SF "d") (V8DF "q")]) > - > -(define_insn "avx512f_<logic><mode>" > - [(set (match_operand:VF_512 0 "register_operand" "=v") > - (fpint_logic:VF_512 > - (match_operand:VF_512 1 "register_operand" "v") > - (match_operand:VF_512 2 "nonimmediate_operand" "vm")))] > - "TARGET_AVX512F" > - "vp<logic><avx512flogicsuff>\t{%2, %1, %0|%0, %1, %2}" > - [(set_attr "type" "sselog") > - (set_attr "prefix" "evex")]) > - > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;; > ;; FMA floating point multiply/accumulate instructions. These include > @@ -10674,16 +10720,31 @@ > { > case MODE_XI: > gcc_assert (TARGET_AVX512F); > - > - tmp = "pandn<ssemodesuffix>"; > - break; > - > case MODE_OI: > - gcc_assert (TARGET_AVX2); > + gcc_assert (TARGET_AVX2 || TARGET_AVX512VL); > case MODE_TI: > - gcc_assert (TARGET_SSE2); > - > - tmp = "pandn"; > + gcc_assert (TARGET_SSE2 || TARGET_AVX512VL); > + switch (<MODE>mode) > + { > + case V16SImode: > + case V8DImode: > + if (TARGET_AVX512F) > + { > + tmp = "pandn<ssemodesuffix>"; > + break; > + } > + case V8SImode: > + case V4DImode: > + case V4SImode: > + case V2DImode: > + if (TARGET_AVX512VL) > + { > + tmp = "pandn<ssemodesuffix>"; > + break; > + } > + default: > + tmp = TARGET_AVX512VL ? "pandnq" : "pandn"; > + } > break; > > case MODE_V16SF: > @@ -10798,16 +10859,31 @@ > { > case MODE_XI: > gcc_assert (TARGET_AVX512F); > - > - tmp = "p<logic><ssemodesuffix>"; > - break; > - > case MODE_OI: > - gcc_assert (TARGET_AVX2); > + gcc_assert (TARGET_AVX2 || TARGET_AVX512VL); > case MODE_TI: > - gcc_assert (TARGET_SSE2); > - > - tmp = "p<logic>"; > + gcc_assert (TARGET_SSE2 || TARGET_AVX512VL); > + switch (<MODE>mode) > + { > + case V16SImode: > + case V8DImode: > + if (TARGET_AVX512F) > + { > + tmp = "p<logic><ssemodesuffix>"; > + break; > + } > + case V8SImode: > + case V4DImode: > + case V4SImode: > + case V2DImode: > + if (TARGET_AVX512VL) > + { > + tmp = "p<logic><ssemodesuffix>"; > + break; > + } > + default: > + tmp = TARGET_AVX512VL ? "p<logic>q" : "p<logic>"; > + } > break; > > case MODE_V16SF: