diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-07-18 06:12:29 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-07-18 12:21:24 -0700 |
commit | 5586e7e85de381f3df843091494889f8ad8e3e1f (patch) | |
tree | 63053b13cd02751f972af62587de4a541dbc0145 /gcc | |
parent | 5cca4131e4aabf70a18e362620ad65a3cebf227a (diff) | |
download | gcc-5586e7e85de381f3df843091494889f8ad8e3e1f.zip gcc-5586e7e85de381f3df843091494889f8ad8e3e1f.tar.gz gcc-5586e7e85de381f3df843091494889f8ad8e3e1f.tar.bz2 |
x86: Don't issue vzeroupper if callee returns AVX register
Don't issue vzeroupper before function call if callee returns AVX
register since callee must be compiled with AVX.
gcc/
PR target/101495
* config/i386/i386.c (ix86_check_avx_upper_stores): Moved before
ix86_avx_u128_mode_needed.
(ix86_avx_u128_mode_needed): Return AVX_U128_DIRTY if callee
returns AVX register.
gcc/testsuite/
PR target/101495
* gcc.target/i386/avx-vzeroupper-28.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/avx-vzeroupper-28.c | 17 |
2 files changed, 37 insertions, 12 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9d74b7a..8481693 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -14093,6 +14093,18 @@ ix86_check_avx_upper_register (const_rtx exp) && GET_MODE_BITSIZE (GET_MODE (exp)) > 128); } +/* Check if a 256bit or 512bit AVX register is referenced in stores. */ + +static void +ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data) + { + if (ix86_check_avx_upper_register (dest)) + { + bool *used = (bool *) data; + *used = true; + } + } + /* Return needed mode for entity in optimize_mode_switching pass. */ static int @@ -14117,6 +14129,14 @@ ix86_avx_u128_mode_needed (rtx_insn *insn) } } + /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit + nor 512bit registers used in the function return register. */ + bool avx_upper_reg_found = false; + note_stores (insn, ix86_check_avx_upper_stores, + &avx_upper_reg_found); + if (avx_upper_reg_found) + return AVX_U128_DIRTY; + /* If the function is known to preserve some SSE registers, RA and previous passes can legitimately rely on that for modes wider than 256 bits. It's only safe to issue a @@ -14217,18 +14237,6 @@ ix86_mode_needed (int entity, rtx_insn *insn) return 0; } -/* Check if a 256bit or 512bit AVX register is referenced in stores. */ - -static void -ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data) - { - if (ix86_check_avx_upper_register (dest)) - { - bool *used = (bool *) data; - *used = true; - } - } - /* Calculate mode of upper 128bit AVX registers after the insn. */ static int diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-28.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-28.c new file mode 100644 index 0000000..381ee9a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-28.c @@ -0,0 +1,17 @@ +/* PR target/101495 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx2 -mtune=generic -dp" } */ + +#include <immintrin.h> + +extern __m256 x, y; +extern __m256 bar (void); + +__m256 +foo () +{ + x = y; + return bar (); +} + +/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */ |