i386: Hopefully last set of -mavx512vl -mno-avx512bw fixes [PR99321]
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Mar 2021 13:34:32 +0000 (14:34 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 12 Mar 2021 13:34:32 +0000 (14:34 +0100)
commit3bb345c9313ad8f6a6c24abd7d5eaa11413bbe22
treeebbaa793e577ffbd4e28087df95a8fdf2bfc9e84
parent425afe1f0c907e6469cef1672160c9c95177e71a
i386: Hopefully last set of -mavx512vl -mno-avx512bw fixes [PR99321]

This is the final patch of the series started with
https://gcc.gnu.org/pipermail/gcc-patches/2021-March/566139.html
and continued with
https://gcc.gnu.org/pipermail/gcc-patches/2021-March/566356.html
This time, I went through all the remaining instructions marked
by gas as requiring both AVX512BW and AVX512VL and for each checked
tmp-mddump.md, figure out if it ever could be a problem (e.g. instructions
that require AVX512BW+AVX512VL, but didn't exist before AVX512F are usually
fine, the patterns have the right conditions, the bugs are typically on
pre-AVX512F patterns where we have just blindly added v while they actually
can't access those unless AVX512BW+AVX512VL), added test where possible
(the test doesn't cover MMX though)and fixed md bugs.

For mmx pextr[bw]/pinsr[bw] patterns it introduces per discussions
a new YW constraint that only requires AVX512BW and not AVX512VL, because
those instructions only require the former and not latter when using EVEX
encoding.

There are some other interesting details, e.g. most of the 8 interleave
patterns (vpunck[hl]{bw,wd}) had correctly
&& <mask_avx512vl_condition> && <mask_avx512bw_condition>
in the conditions because for masking it needs to be always EVEX encoded
and then it needs both VL+BW, but 2 of those 8 had just
&& <mask_avx512vl_condition>
and so again would run into the -mavx512vl -mno-avx512bw problems.

Another problem different from others was mmx eq/gt comparisons, that was
using Yv constraints, so would happily accept %xmm16+ registers for
-mavx512vl, but there actually are no such EVEX encoded instructions,
as AVX512 comparisons work with %k* registers instead.

The newly added testcase without the patch fails with:
/tmp/ccVROLo2.s: Assembler messages:
/tmp/ccVROLo2.s:9: Error: unsupported instruction `vpabsb'
/tmp/ccVROLo2.s:20: Error: unsupported instruction `vpabsb'
/tmp/ccVROLo2.s:31: Error: unsupported instruction `vpabsw'
/tmp/ccVROLo2.s:42: Error: unsupported instruction `vpabsw'
/tmp/ccVROLo2.s:53: Error: unsupported instruction `vpaddsb'
/tmp/ccVROLo2.s:64: Error: unsupported instruction `vpaddsb'
/tmp/ccVROLo2.s:75: Error: unsupported instruction `vpaddsw'
/tmp/ccVROLo2.s:86: Error: unsupported instruction `vpaddsw'
/tmp/ccVROLo2.s:97: Error: unsupported instruction `vpsubsb'
/tmp/ccVROLo2.s:108: Error: unsupported instruction `vpsubsb'
/tmp/ccVROLo2.s:119: Error: unsupported instruction `vpsubsw'
/tmp/ccVROLo2.s:130: Error: unsupported instruction `vpsubsw'
/tmp/ccVROLo2.s:141: Error: unsupported instruction `vpaddusb'
/tmp/ccVROLo2.s:152: Error: unsupported instruction `vpaddusb'
/tmp/ccVROLo2.s:163: Error: unsupported instruction `vpaddusw'
/tmp/ccVROLo2.s:174: Error: unsupported instruction `vpaddusw'
/tmp/ccVROLo2.s:185: Error: unsupported instruction `vpsubusb'
/tmp/ccVROLo2.s:196: Error: unsupported instruction `vpsubusb'
/tmp/ccVROLo2.s:207: Error: unsupported instruction `vpsubusw'
/tmp/ccVROLo2.s:218: Error: unsupported instruction `vpsubusw'
/tmp/ccVROLo2.s:258: Error: unsupported instruction `vpaddusw'
/tmp/ccVROLo2.s:269: Error: unsupported instruction `vpavgb'
/tmp/ccVROLo2.s:280: Error: unsupported instruction `vpavgb'
/tmp/ccVROLo2.s:291: Error: unsupported instruction `vpavgw'
/tmp/ccVROLo2.s:302: Error: unsupported instruction `vpavgw'
/tmp/ccVROLo2.s:475: Error: unsupported instruction `vpmovsxbw'
/tmp/ccVROLo2.s:486: Error: unsupported instruction `vpmovsxbw'
/tmp/ccVROLo2.s:497: Error: unsupported instruction `vpmovzxbw'
/tmp/ccVROLo2.s:508: Error: unsupported instruction `vpmovzxbw'
/tmp/ccVROLo2.s:548: Error: unsupported instruction `vpmulhuw'
/tmp/ccVROLo2.s:559: Error: unsupported instruction `vpmulhuw'
/tmp/ccVROLo2.s:570: Error: unsupported instruction `vpmulhw'
/tmp/ccVROLo2.s:581: Error: unsupported instruction `vpmulhw'
/tmp/ccVROLo2.s:592: Error: unsupported instruction `vpsadbw'
/tmp/ccVROLo2.s:603: Error: unsupported instruction `vpsadbw'
/tmp/ccVROLo2.s:643: Error: unsupported instruction `vpshufhw'
/tmp/ccVROLo2.s:654: Error: unsupported instruction `vpshufhw'
/tmp/ccVROLo2.s:665: Error: unsupported instruction `vpshuflw'
/tmp/ccVROLo2.s:676: Error: unsupported instruction `vpshuflw'
/tmp/ccVROLo2.s:687: Error: unsupported instruction `vpslldq'
/tmp/ccVROLo2.s:698: Error: unsupported instruction `vpslldq'
/tmp/ccVROLo2.s:709: Error: unsupported instruction `vpsrldq'
/tmp/ccVROLo2.s:720: Error: unsupported instruction `vpsrldq'
/tmp/ccVROLo2.s:899: Error: unsupported instruction `vpunpckhbw'
/tmp/ccVROLo2.s:910: Error: unsupported instruction `vpunpckhbw'
/tmp/ccVROLo2.s:921: Error: unsupported instruction `vpunpckhwd'
/tmp/ccVROLo2.s:932: Error: unsupported instruction `vpunpckhwd'
/tmp/ccVROLo2.s:943: Error: unsupported instruction `vpunpcklbw'
/tmp/ccVROLo2.s:954: Error: unsupported instruction `vpunpcklbw'
/tmp/ccVROLo2.s:965: Error: unsupported instruction `vpunpcklwd'
/tmp/ccVROLo2.s:976: Error: unsupported instruction `vpunpcklwd'

2021-03-12  Jakub Jelinek  <jakub@redhat.com>

PR target/99321
* config/i386/constraints.md (YW): New internal constraint.
* config/i386/sse.md (v_Yw): Add V4TI, V2TI, V1TI and TI cases.
(*<sse2_avx2>_<insn><mode>3<mask_name>,
*<sse2_avx2>_uavg<mode>3<mask_name>, *abs<mode>2,
*<s>mul<mode>3_highpart<mask_name>): Use <v_Yw> instead of v in
constraints.
(<sse2_avx2>_psadbw): Use YW instead of v in constraints.
(*avx2_pmaddwd, *sse2_pmaddwd, *<code>v8hi3, *<code>v16qi3,
avx2_pmaddubsw256, ssse3_pmaddubsw128): Merge last two alternatives
into one, use Yw instead of former x,v.
(ashr<mode>3, <insn><mode>3): Use <v_Yw> instead of x in constraints of
the last alternative.
(<sse2_avx2>_packsswb<mask_name>, <sse2_avx2>_packssdw<mask_name>,
<sse2_avx2>_packuswb<mask_name>, <sse4_1_avx2>_packusdw<mask_name>,
*<ssse3_avx2>_pmulhrsw<mode>3<mask_name>, <ssse3_avx2>_palignr<mode>,
<ssse3_avx2>_pshufb<mode>3<mask_name>): Merge last two alternatives
into one, use <v_Yw> instead of former x,v.
(avx2_interleave_highv32qi<mask_name>,
vec_interleave_highv16qi<mask_name>): Use Yw instead of v in
constraints.  Add && <mask_avx512bw_condition> to condition.
(avx2_interleave_lowv32qi<mask_name>,
vec_interleave_lowv16qi<mask_name>,
avx2_interleave_highv16hi<mask_name>,
vec_interleave_highv8hi<mask_name>,
avx2_interleave_lowv16hi<mask_name>, vec_interleave_lowv8hi<mask_name>,
avx2_pshuflw_1<mask_name>, sse2_pshuflw_1<mask_name>,
avx2_pshufhw_1<mask_name>, sse2_pshufhw_1<mask_name>,
avx2_<code>v16qiv16hi2<mask_name>, sse4_1_<code>v8qiv8hi2<mask_name>,
*sse4_1_<code>v8qiv8hi2<mask_name>_1, <sse2_avx2>_<insn><mode>3): Use
Yw instead of v in constraints.
* config/i386/mmx.md (Yv_Yw): New define_mode_attr.
(*mmx_<insn><mode>3, mmx_ashr<mode>3, mmx_<insn><mode>3): Use <Yv_Yw>
instead of Yv in constraints.
(*mmx_<insn><mode>3, *mmx_mulv4hi3, *mmx_smulv4hi3_highpart,
*mmx_umulv4hi3_highpart, *mmx_pmaddwd, *mmx_<code>v4hi3,
*mmx_<code>v8qi3, mmx_pack<s_trunsuffix>swb, mmx_packssdw,
mmx_punpckhbw, mmx_punpcklbw, mmx_punpckhwd, mmx_punpcklwd,
*mmx_uavgv8qi3, *mmx_uavgv4hi3, mmx_psadbw): Use Yw instead of Yv in
constraints.
(*mmx_pinsrw, *mmx_pinsrb, *mmx_pextrw, *mmx_pextrw_zext, *mmx_pextrb,
*mmx_pextrb_zext): Use YW instead of Yv in constraints.
(*mmx_eq<mode>3, mmx_gt<mode>3): Use x instead of Yv in constraints.
(mmx_andnot<mode>3, *mmx_<code><mode>3): Split last alternative into
two, one with just x, another isa avx512vl with v.

* gcc.target/i386/avx512vl-pr99321-2.c: New test.
gcc/config/i386/constraints.md
gcc/config/i386/mmx.md
gcc/config/i386/sse.md
gcc/testsuite/gcc.target/i386/avx512vl-pr99321-2.c [new file with mode: 0644]