Message ID | 20200411214822.1469452-1-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | i386: Remove mode size check in ix86_get_ssemov | expand |
On Sat, Apr 11, 2020 at 02:48:22PM -0700, H.J. Lu via Gcc-patches wrote: > Even though ix86_hard_regno_mode_ok doesn't allow xmm16-xmm31 nor > ymm16-ymm31 in 128/256 bit modes when AVX512VL is disabled, reload > can still generate reg to reg moves with xmm16-xmm31 and ymm16-ymm31 > in 128/256 bit modes. Remove mode size check in ix86_get_ssemov. Looking at the testcase, LRA doesn't have good choices, (define_insn ("*avx512f_gatherdiv16si") [ (set (match_operand:V16SI 0 ("register_operand") ("=&v")) (unspec:V16SI [ (match_operand:V8SI 1 ("register_operand") ("0")) ... so if the output is chosen to be zmm16+, then LRA is required to stick a V8SI pseudo into that register, even when ix86_hard_regno_mode_ok isn't ok with that. Unless we changed all the patterns with such issues (i.e. where a 128-bit/256-bit operand uses matching constraint to 512-bit one with v) so that it uses just x on the matching operand unless avx512vl. Before your changes, we would just emit the *mov<mode>_internal even in those cases, so your change matches what we used to do. > > gcc/ > > PR target/94561 > * config/i386/i386.c (ix86_get_ssemov): Remove mode size check. > > gcc/testsuite/ > > PR target/94561 > * gcc.target/i386/pr94561.c: New test. Ok. Jakub
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ca3b7dc06c2..d88f5127d11 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4969,12 +4969,12 @@ ix86_get_ssemov (rtx *operands, unsigned size, && !TARGET_AVX512VL && GET_MODE_SIZE (mode) < 64) { - /* NB: Since ix86_hard_regno_mode_ok only allows xmm16-xmm31 or - ymm16-ymm31 in 128/256 bit modes when AVX512VL is enabled, - we get here only for xmm16-xmm31 or ymm16-ymm31 in 32/64 bit + /* NB: Even though ix86_hard_regno_mode_ok doesn't allow + xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when + AVX512VL is disabled, reload can still generate reg to + reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit modes. */ - if (GET_MODE_SIZE (mode) >= 16 - || memory_operand (operands[0], mode) + if (memory_operand (operands[0], mode) || memory_operand (operands[1], mode)) gcc_unreachable (); size = 64; diff --git a/gcc/testsuite/gcc.target/i386/pr94561.c b/gcc/testsuite/gcc.target/i386/pr94561.c new file mode 100644 index 00000000000..49fdf7e687d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr94561.c @@ -0,0 +1,36 @@ +/* PR target/94561 */ +/* { dg-do compile } */ +/* { dg-options "-march=knl -O3 -funroll-loops" } */ + +struct xi { + long int mg; + int lx; +}; + +struct xi *di; +int *eu; + +void +he (void); + +int +m8 (int we, int i8) +{ + int wd, cj = 0; + + for (wd = 0; wd < 80; ++wd) + { + if (di->mg == 0 && (eu[wd] | !!we) == 0 && di->lx == 0) + continue; + + if (i8 == 0) + he (); + + ++cj; + } + + return cj; +} + +/* { dg-final { scan-assembler-not "vmov\[^\n\r]*%\[xy\]mm1\[6-9\].*" } } */ +/* { dg-final { scan-assembler-not "vmov\[^\n\r]*%\[xy\]mm\[23\]\[0-9\].*" } } */