===================================================================
@@ -172,8 +172,11 @@ extern int ix86_mode_needed (int, rtx);
extern int ix86_mode_after (int, int, rtx);
extern int ix86_mode_entry (int);
extern int ix86_mode_exit (int);
-extern void ix86_emit_mode_set (int, int);
+#ifdef HARD_CONST
+extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
+#endif
+
extern void x86_order_regs_for_local_alloc (void);
extern void x86_function_profiler (FILE *, int);
extern void x86_emit_floatuns (rtx [2]);
===================================================================
@@ -15277,16 +15284,38 @@ emit_i387_cw_initialization (int mode)
emit_move_insn (new_mode, reg);
}
+/* Emit vzeroupper. */
+
+void
+ix86_avx_emit_vzeroupper (HARD_REG_SET regs_live)
+{
+ int i;
+
+ /* Cancel automatic vzeroupper insertion if there are
+ live call-saved SSE registers at the insertion point. */
+
+ for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
+ if (!call_used_regs[i] && TEST_HARD_REG_BIT (regs_live, i))
+ return;
+
+ if (TARGET_64BIT)
+ for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
+ if (!call_used_regs[i] && TEST_HARD_REG_BIT (regs_live, i))
+ return;
+
+ emit_insn (gen_avx_vzeroupper ());
+}
+
/* Generate one or more insns to set ENTITY to MODE. */
void
-ix86_emit_mode_set (int entity, int mode)
+ix86_emit_mode_set (int entity, int mode, HARD_REG_SET regs_live)
{
switch (entity)
{
case AVX_U128:
if (mode == AVX_U128_CLEAN)
- emit_insn (gen_avx_vzeroupper ());
+ ix86_avx_emit_vzeroupper (regs_live);
break;
case I387_TRUNC:
case I387_FLOOR:
===================================================================
@@ -2223,7 +2227,7 @@ enum avx_u128_state
are to be inserted. */
#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
- ix86_emit_mode_set ((ENTITY), (MODE))
+ ix86_emit_mode_set ((ENTITY), (MODE), (HARD_REGS_LIVE))
/* Avoid renaming of stack registers, as doing so in combination with
scheduling just increases amount of live registers at time and in