diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-03-06 09:35:37 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2024-03-06 09:35:37 +0100 |
commit | 1157d5de35b41eabe5ee51d532224864173c37bd (patch) | |
tree | 72246e28e6381c00826a49df62afdcb8be6bb3e3 | |
parent | 21edfb0051ed8d0ff46d5638c2bce2dd71f26d1f (diff) | |
download | gcc-1157d5de35b41eabe5ee51d532224864173c37bd.zip gcc-1157d5de35b41eabe5ee51d532224864173c37bd.tar.gz gcc-1157d5de35b41eabe5ee51d532224864173c37bd.tar.bz2 |
i386: Fix up the vzeroupper REG_DEAD/REG_UNUSED note workaround [PR114190]
When writing the rest_of_handle_insert_vzeroupper workaround to manually
remove all the REG_DEAD/REG_UNUSED notes from the IL, I've missed that
there is a df_analyze () call right after it and that the problems added
earlier in the pass, like df_note_add_problem () done during mode switching,
doesn't affect just the next df_analyze () call right after it, but all
other df_analyze () calls until the end of the current pass where
df_finish_pass removes the optional problems.
So, as can be seen on the following patch, the workaround doesn't actually
work there, because while rest_of_handle_insert_vzeroupper carefully removes
all REG_DEAD/REG_UNUSED notes, the df_analyze () call at the end of the
function immediately adds them in again (so, I must say I have no idea
why the workaround worked on the earlier testcases).
Now, I could move the df_analyze () call just before the REG_DEAD/REG_UNUSED
note removal loop, but I think the following patch is better, because
the df_analyze () call doesn't have to recompute the problem when we don't
care about it and will actively strip all traces of it away.
2024-03-06 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/114190
* config/i386/i386-features.cc (rest_of_handle_insert_vzeroupper):
Call df_remove_problem for df_note before calling df_analyze.
* gcc.target/i386/avx-pr114190.c: New test.
-rw-r--r-- | gcc/config/i386/i386-features.cc | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/avx-pr114190.c | 27 |
2 files changed, 28 insertions, 0 deletions
diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index d3b9ae8..1de2a07 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -2690,6 +2690,7 @@ rest_of_handle_insert_vzeroupper (void) } } + df_remove_problem (df_note); df_analyze (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/avx-pr114190.c b/gcc/testsuite/gcc.target/i386/avx-pr114190.c new file mode 100644 index 0000000..fc5b261 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-pr114190.c @@ -0,0 +1,27 @@ +/* PR rtl-optimization/114190 */ +/* { dg-do run { target avx } } */ +/* { dg-options "-O2 -fno-dce -fharden-compares -mavx --param=max-rtl-if-conversion-unpredictable-cost=136 -mno-avx512f -Wno-psabi" } */ + +#include "avx-check.h" + +typedef unsigned char U __attribute__((vector_size (64))); +typedef unsigned int V __attribute__((vector_size (64))); +U u; + +V +foo (V a, V b) +{ + u[0] = __builtin_sub_overflow (0, (int) a[0], &a[b[7] & 5]) ? -u[1] : -b[3]; + b ^= 0 != b; + return (V) u + (V) a + (V) b; +} + +static void +avx_test (void) +{ + V x = foo ((V) { 1 }, (V) { 0, 0, 0, 1 }); + if (x[0] != -1U) + __builtin_abort (); + if (x[3] != -2U) + __builtin_abort (); +} |