On Tue, Nov 07, 2017 at 11:21:15AM +0100, Uros Bizjak wrote: > On Tue, Nov 7, 2017 at 11:10 AM, Jakub Jelinek <ja...@redhat.com> wrote: > > >> > Isn't it sufficient that moves disparage slightly the k alternatives? > >> > Or are you worried about the case where the pseudo would need to be > >> > spilled > >> > and LRA would choose to reload it into a %kN register? > >> > >> The later... Perhaps it is possible to prevent unwanted reloads with > >> ?k (or even ??k, we already have ?m<r>, IDK). I have used *k in > >> zero-extend patterns to prevent unwanted reloads, which is perhaps too > >> strong, but we have ree pass that eliminates unwanted moves in this > >> case (*k in move patterns is handled by other regmove elimination > >> passes). > > > > ?k gives the same IRA decisions as *k, in both cases it considers > > GENERAL_REGS as expensive as MASK_EVEX_REGS and picks up GENERAL_REGS > > rather than MASK_EVEX_REGS for the pseudo, which results in > > kmovb %k1, %eax; test. > > Can we use some of the new RA modifiers here?
So, for the testcase in question, GENERAL_REGS have cost 2000: k works (MASK_EVEX_REGS cost 0) *k doesn't work, IRA chooses GENERAL_REGS (MASK_EVEX_REGS cost 2000) ?k doesn't work, IRA chooses GENERAL_REGS (MASK_EVEX_REGS cost 2000) !k works (MASK_EVEX_REGS cost 0) ^k doesn't work, IRA chooses GENERAL_REGS (MASK_EVEX_REGS cost 2000) $k works (MASK_EVEX_REGS cost 0) > --cut here-- > '?' > Disparage slightly the alternative that the '?' appears in, as a > choice when no alternative applies exactly. The compiler regards > this alternative as one unit more costly for each '?' that appears > in it. > > '!' > Disparage severely the alternative that the '!' appears in. This > alternative can still be used if it fits without reloading, but if > reloading is needed, some other alternative will be used. > > '^' > This constraint is analogous to '?' but it disparages slightly the > alternative only if the operand with the '^' needs a reload. > > '$' > This constraint is analogous to '!' but it disparages severely the > alternative only if the operand with the '$' needs a reload. > --cut here-- > > '$' looks promising to prevent unwanted reloads to kN register. So, ok for trunk if it passes bootstrap/regtest? 2017-11-07 Jakub Jelinek <ja...@redhat.com> PR target/82855 * config/i386/i386.md (SWI1248_AVX512BWDQ2_64): New mode iterator. (*cmp<mode>_ccz_1): New insn with $k alternative. * gcc.target/i386/avx512dq-pr82855.c: New test. --- gcc/config/i386/i386.md.jj 2017-11-06 17:23:10.674996727 +0100 +++ gcc/config/i386/i386.md 2017-11-07 11:44:40.081328781 +0100 @@ -1275,6 +1275,26 @@ (define_expand "cmp<mode>_1" (compare:CC (match_operand:SWI48 0 "nonimmediate_operand") (match_operand:SWI48 1 "<general_operand>")))]) +(define_mode_iterator SWI1248_AVX512BWDQ2_64 + [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ") + (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")]) + +(define_insn "*cmp<mode>_ccz_1" + [(set (reg FLAGS_REG) + (compare (match_operand:SWI1248_AVX512BWDQ2_64 0 + "nonimmediate_operand" "<r>,?m<r>,$k") + (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))] + "ix86_match_ccmode (insn, CCZmode)" + "@ + test{<imodesuffix>}\t%0, %0 + cmp{<imodesuffix>}\t{%1, %0|%0, %1} + ktest<mskmodesuffix>\t%0, %0" + [(set_attr "type" "test,icmp,msklog") + (set_attr "length_immediate" "0,1,*") + (set_attr "modrm_class" "op0,unknown,*") + (set_attr "prefix" "*,*,vex") + (set_attr "mode" "<MODE>")]) + (define_insn "*cmp<mode>_ccno_1" [(set (reg FLAGS_REG) (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") --- gcc/testsuite/gcc.target/i386/avx512dq-pr82855.c.jj 2017-11-07 08:56:02.910321163 +0100 +++ gcc/testsuite/gcc.target/i386/avx512dq-pr82855.c 2017-11-07 08:56:02.910321163 +0100 @@ -0,0 +1,14 @@ +/* PR target/82855 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512vl -mavx512dq" } */ +/* { dg-final { scan-assembler {\mktestb\M} } } */ + +#include <immintrin.h> + +int +foo (const __m256i *ptr) +{ + __m256i v = _mm256_loadu_si256 (ptr); + __mmask8 m = _mm256_cmpeq_epi32_mask (v, _mm256_setzero_si256 ()); + return 0 == m; +} Jakub