aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c10
2 files changed, 16 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 43c3455..acdcd91 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
+ * config/i386/i386.c: Include function-abi.h.
+ (ix86_avx_u128_mode_needed): Treat function calls as AVX_U128_ANY
+ if they preserve some 256-bit or 512-bit SSE registers.
+
+2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
+
* target.def (insn_callee_abi): New hook.
(remove_extra_call_preserved_regs): Delete.
* doc/tm.texi.in (TARGET_INSN_CALLEE_ABI): New macro.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9a87413..a13aef8 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -95,6 +95,7 @@ along with GCC; see the file COPYING3. If not see
#include "i386-builtins.h"
#include "i386-expand.h"
#include "i386-features.h"
+#include "function-abi.h"
/* This file should be included last. */
#include "target-def.h"
@@ -13511,6 +13512,15 @@ ix86_avx_u128_mode_needed (rtx_insn *insn)
}
}
+ /* 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
+ vzeroupper if all SSE registers are clobbered. */
+ const function_abi &abi = insn_callee_abi (insn);
+ if (!hard_reg_set_subset_p (reg_class_contents[ALL_SSE_REGS],
+ abi.mode_clobbers (V4DImode)))
+ return AVX_U128_ANY;
+
return AVX_U128_CLEAN;
}