Message ID | aa84243c-860b-ddf8-bfde-7e080a197cd1@suse.com |
---|---|
State | New |
Headers | show |
Series | x86: correct and improve "*vec_dupv2di" | expand |
On Thu, Jun 15, 2023 at 8:03 AM Jan Beulich via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > The input constraint for the %vmovddup alternative was wrong, as the > upper 16 XMM registers require AVX512VL to be used with this insn. To > compensate, introduce a new alternative permitting all 32 registers, by > broadcasting to the full 512 bits in that case if AVX512VL is not > available. > > gcc/ > > * config/i386/sse.md (vec_dupv2di): Correct %vmovddup input > constraint. Add new AVX512F alternative. > --- > Strictly speaking the new alternative could be enabled from AVX2 > onwards, but vmovddup can frequently be a shorter encoding (VEX2 > vs VEX3). > > --- a/gcc/config/i386/sse.md > +++ b/gcc/config/i386/sse.md > @@ -25851,19 +25851,39 @@ > (symbol_ref "true")))]) > > (define_insn "*vec_dupv2di" > - [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,x") > + [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,v,x") > (vec_duplicate:V2DI > - (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,vm,0")))] > + (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,vm,Yvm,0")))] > "TARGET_SSE" > - "@ > - punpcklqdq\t%0, %0 > - vpunpcklqdq\t{%d1, %0|%0, %d1} > - %vmovddup\t{%1, %0|%0, %1} > - movlhps\t%0, %0" > - [(set_attr "isa" "sse2_noavx,avx,sse3,noavx") > - (set_attr "type" "sselog1,sselog1,sselog1,ssemov") > - (set_attr "prefix" "orig,maybe_evex,maybe_vex,orig") > - (set_attr "mode" "TI,TI,DF,V4SF")]) > +{ > + switch (which_alternative) > + { > + case 0: > + return "punpcklqdq\t%0, %0"; > + case 1: > + return "vpunpcklqdq\t{%d1, %0|%0, %d1}"; > + case 2: > + if (TARGET_AVX512VL) > + return "vpbroadcastq\t{%1, %0|%0, %1}"; > + return "vpbroadcastq\t{%1, %g0|%g0, %1}"; You can use * return TARGET_AVX512VL ? \"vpbroadcastq\t{%1, %0|%0, %1}\" : \"vpbroadcastq\t{%1, %g0|%g0, %1}\"; directly in a multi-output insn template to avoid the above C code. See e.g. sse2_cvtpd2pi for an example. Uros. > + case 3: > + return "%vmovddup\t{%1, %0|%0, %1}"; > + case 4: > + return "movlhps\t%0, %0"; > + default: > + gcc_unreachable (); > + } > +} > + [(set_attr "isa" "sse2_noavx,avx,avx512f,sse3,noavx") > + (set_attr "type" "sselog1,sselog1,ssemov,sselog1,ssemov") > + (set_attr "prefix" "orig,maybe_evex,evex,maybe_vex,orig") > + (set_attr "mode" "TI,TI,TI,DF,V4SF") > + (set (attr "enabled") > + (if_then_else > + (eq_attr "alternative" "2") > + (symbol_ref "TARGET_AVX512VL > + || (TARGET_AVX512F && !TARGET_PREFER_AVX256)") > + (const_string "*")))]) > > (define_insn "avx2_vbroadcasti128_<mode>" > [(set (match_operand:VI_256 0 "register_operand" "=x,v,v")
On Thu, Jun 15, 2023 at 3:07 PM Uros Bizjak via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On Thu, Jun 15, 2023 at 8:03 AM Jan Beulich via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: > > > > The input constraint for the %vmovddup alternative was wrong, as the > > upper 16 XMM registers require AVX512VL to be used with this insn. To > > compensate, introduce a new alternative permitting all 32 registers, by > > broadcasting to the full 512 bits in that case if AVX512VL is not > > available. > > > > gcc/ > > > > * config/i386/sse.md (vec_dupv2di): Correct %vmovddup input > > constraint. Add new AVX512F alternative. > > --- > > Strictly speaking the new alternative could be enabled from AVX2 > > onwards, but vmovddup can frequently be a shorter encoding (VEX2 > > vs VEX3). > > > > --- a/gcc/config/i386/sse.md > > +++ b/gcc/config/i386/sse.md > > @@ -25851,19 +25851,39 @@ > > (symbol_ref "true")))]) > > > > (define_insn "*vec_dupv2di" > > - [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,x") > > + [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,v,x") > > (vec_duplicate:V2DI > > - (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,vm,0")))] > > + (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,vm,Yvm,0")))] > > "TARGET_SSE" > > - "@ > > - punpcklqdq\t%0, %0 > > - vpunpcklqdq\t{%d1, %0|%0, %d1} > > - %vmovddup\t{%1, %0|%0, %1} > > - movlhps\t%0, %0" > > - [(set_attr "isa" "sse2_noavx,avx,sse3,noavx") > > - (set_attr "type" "sselog1,sselog1,sselog1,ssemov") > > - (set_attr "prefix" "orig,maybe_evex,maybe_vex,orig") > > - (set_attr "mode" "TI,TI,DF,V4SF")]) > > +{ > > + switch (which_alternative) > > + { > > + case 0: > > + return "punpcklqdq\t%0, %0"; > > + case 1: > > + return "vpunpcklqdq\t{%d1, %0|%0, %d1}"; > > + case 2: > > + if (TARGET_AVX512VL) > > + return "vpbroadcastq\t{%1, %0|%0, %1}"; > > + return "vpbroadcastq\t{%1, %g0|%g0, %1}"; > > You can use > > * return TARGET_AVX512VL ? \"vpbroadcastq\t{%1, %0|%0, %1}\" : > \"vpbroadcastq\t{%1, %g0|%g0, %1}\"; > > directly in a multi-output insn template to avoid the above C code. > See e.g. sse2_cvtpd2pi for an example. > > Uros. > > > + case 3: > > + return "%vmovddup\t{%1, %0|%0, %1}"; > > + case 4: > > + return "movlhps\t%0, %0"; > > + default: > > + gcc_unreachable (); > > + } > > +} > > + [(set_attr "isa" "sse2_noavx,avx,avx512f,sse3,noavx") > > + (set_attr "type" "sselog1,sselog1,ssemov,sselog1,ssemov") > > + (set_attr "prefix" "orig,maybe_evex,evex,maybe_vex,orig") > > + (set_attr "mode" "TI,TI,TI,DF,V4SF") alternative 2 should be XImode when !TARGET_AVX512VL. > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "2") > > + (symbol_ref "TARGET_AVX512VL > > + || (TARGET_AVX512F && !TARGET_PREFER_AVX256)") > > + (const_string "*")))]) > > > > (define_insn "avx2_vbroadcasti128_<mode>" > > [(set (match_operand:VI_256 0 "register_operand" "=x,v,v")
On 15.06.2023 09:45, Hongtao Liu wrote: > On Thu, Jun 15, 2023 at 3:07 PM Uros Bizjak via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: >> On Thu, Jun 15, 2023 at 8:03 AM Jan Beulich via Gcc-patches >> <gcc-patches@gcc.gnu.org> wrote: >>> + case 3: >>> + return "%vmovddup\t{%1, %0|%0, %1}"; >>> + case 4: >>> + return "movlhps\t%0, %0"; >>> + default: >>> + gcc_unreachable (); >>> + } >>> +} >>> + [(set_attr "isa" "sse2_noavx,avx,avx512f,sse3,noavx") >>> + (set_attr "type" "sselog1,sselog1,ssemov,sselog1,ssemov") >>> + (set_attr "prefix" "orig,maybe_evex,evex,maybe_vex,orig") >>> + (set_attr "mode" "TI,TI,TI,DF,V4SF") > alternative 2 should be XImode when !TARGET_AVX512VL. This gives me a chance to actually raise a related question I stumbled across several times: Which operand does the mode attribute actually describe? I've seen places where it's the source, but I've also seen places where it's the destination. Because of this mix I wasn't really sure that getting this attribute entirely correct is actually necessary, and hence I hoped it would be okay to not further complicate the attribute here. Jan
On Thu, Jun 15, 2023 at 10:15 AM Jan Beulich <jbeulich@suse.com> wrote: > > On 15.06.2023 09:45, Hongtao Liu wrote: > > On Thu, Jun 15, 2023 at 3:07 PM Uros Bizjak via Gcc-patches > > <gcc-patches@gcc.gnu.org> wrote: > >> On Thu, Jun 15, 2023 at 8:03 AM Jan Beulich via Gcc-patches > >> <gcc-patches@gcc.gnu.org> wrote: > >>> + case 3: > >>> + return "%vmovddup\t{%1, %0|%0, %1}"; > >>> + case 4: > >>> + return "movlhps\t%0, %0"; > >>> + default: > >>> + gcc_unreachable (); > >>> + } > >>> +} > >>> + [(set_attr "isa" "sse2_noavx,avx,avx512f,sse3,noavx") > >>> + (set_attr "type" "sselog1,sselog1,ssemov,sselog1,ssemov") > >>> + (set_attr "prefix" "orig,maybe_evex,evex,maybe_vex,orig") > >>> + (set_attr "mode" "TI,TI,TI,DF,V4SF") > > alternative 2 should be XImode when !TARGET_AVX512VL. > > This gives me a chance to actually raise a related question I stumbled > across several times: Which operand does the mode attribute actually > describe? I've seen places where it's the source, but I've also seen > places where it's the destination. Because of this mix I wasn't really > sure that getting this attribute entirely correct is actually > necessary, and hence I hoped it would be okay to not further complicate > the attribute here. It should be the mode the insn is operating in. So, zero-extended SImode add is still operating in SImode, even if its output is DImode, and TARGET_MMX_WITH_SSE are V4SFmode, even if their operands are all V2SFmode. Uros.
--- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -25851,19 +25851,39 @@ (symbol_ref "true")))]) (define_insn "*vec_dupv2di" - [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,x") + [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,v,x") (vec_duplicate:V2DI - (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,vm,0")))] + (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,vm,Yvm,0")))] "TARGET_SSE" - "@ - punpcklqdq\t%0, %0 - vpunpcklqdq\t{%d1, %0|%0, %d1} - %vmovddup\t{%1, %0|%0, %1} - movlhps\t%0, %0" - [(set_attr "isa" "sse2_noavx,avx,sse3,noavx") - (set_attr "type" "sselog1,sselog1,sselog1,ssemov") - (set_attr "prefix" "orig,maybe_evex,maybe_vex,orig") - (set_attr "mode" "TI,TI,DF,V4SF")]) +{ + switch (which_alternative) + { + case 0: + return "punpcklqdq\t%0, %0"; + case 1: + return "vpunpcklqdq\t{%d1, %0|%0, %d1}"; + case 2: + if (TARGET_AVX512VL) + return "vpbroadcastq\t{%1, %0|%0, %1}"; + return "vpbroadcastq\t{%1, %g0|%g0, %1}"; + case 3: + return "%vmovddup\t{%1, %0|%0, %1}"; + case 4: + return "movlhps\t%0, %0"; + default: + gcc_unreachable (); + } +} + [(set_attr "isa" "sse2_noavx,avx,avx512f,sse3,noavx") + (set_attr "type" "sselog1,sselog1,ssemov,sselog1,ssemov") + (set_attr "prefix" "orig,maybe_evex,evex,maybe_vex,orig") + (set_attr "mode" "TI,TI,TI,DF,V4SF") + (set (attr "enabled") + (if_then_else + (eq_attr "alternative" "2") + (symbol_ref "TARGET_AVX512VL + || (TARGET_AVX512F && !TARGET_PREFER_AVX256)") + (const_string "*")))]) (define_insn "avx2_vbroadcasti128_<mode>" [(set (match_operand:VI_256 0 "register_operand" "=x,v,v")