diff --git a/gcc/config/epiphany/epiphany-protos.h b/gcc/config/epiphany/epiphany-protos.h
index ef49a1e06a4..ff8987ea99e 100644
--- a/gcc/config/epiphany/epiphany-protos.h
+++ b/gcc/config/epiphany/epiphany-protos.h
@@ -46,8 +46,9 @@ extern void epiphany_insert_mode_switch_use (rtx_insn *insn, int, int);
 extern void epiphany_expand_set_fp_mode (rtx *operands);
 #ifdef HARD_CONST
 extern int epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET);
+extern int epiphany_mode_after (int entity, int last_mode, rtx_insn *insn,
+				HARD_REG_SET);
 #endif
-extern int epiphany_mode_after (int entity, int last_mode, rtx_insn *insn);
 extern bool epiphany_epilogue_uses (int regno);
 extern bool epiphany_optimize_mode_switching (int entity);
 extern bool epiphany_is_interrupt_p (tree);
diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc
index 60a9b49d8a4..68e748c688e 100644
--- a/gcc/config/epiphany/epiphany.cc
+++ b/gcc/config/epiphany/epiphany.cc
@@ -2437,7 +2437,7 @@ epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
     return 2;
   case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
     if (recog_memoized (insn) == CODE_FOR_set_fp_mode)
-      mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn);
+      mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn, {});
     /* Fall through.  */
   case EPIPHANY_MSW_ENTITY_NEAREST:
   case EPIPHANY_MSW_ENTITY_TRUNC:
@@ -2498,7 +2498,8 @@ epiphany_mode_entry_exit (int entity, bool exit)
 }
 
 int
-epiphany_mode_after (int entity, int last_mode, rtx_insn *insn)
+epiphany_mode_after (int entity, int last_mode, rtx_insn *insn,
+		     HARD_REG_SET)
 {
   /* We have too few call-saved registers to hope to keep the masks across
      calls.  */
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 7a5a9a966e8..7b72aabf0da 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -15110,7 +15110,7 @@ ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
 /* Return the mode that an insn results in.  */
 
 static int
-ix86_mode_after (int entity, int mode, rtx_insn *insn)
+ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
 {
   switch (entity)
     {
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f915de7ed56..e36b5fb9bd0 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -9514,7 +9514,7 @@ riscv_frm_mode_after (rtx_insn *insn, int mode)
 /* Return the mode that an insn results in.  */
 
 static int
-riscv_mode_after (int entity, int mode, rtx_insn *insn)
+riscv_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
 {
   switch (entity)
     {
diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index c363490e852..6ec2eecf754 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -196,7 +196,7 @@ static HOST_WIDE_INT rounded_frame_size (int);
 static bool sh_frame_pointer_required (void);
 static void sh_emit_mode_set (int, int, int, HARD_REG_SET);
 static int sh_mode_needed (int, rtx_insn *, HARD_REG_SET);
-static int sh_mode_after (int, int, rtx_insn *);
+static int sh_mode_after (int, int, rtx_insn *, HARD_REG_SET);
 static int sh_mode_entry (int);
 static int sh_mode_exit (int);
 static int sh_mode_priority (int entity, int n);
@@ -12537,7 +12537,8 @@ sh_mode_needed (int entity ATTRIBUTE_UNUSED, rtx_insn *insn, HARD_REG_SET)
 }
 
 static int
-sh_mode_after (int entity ATTRIBUTE_UNUSED, int mode, rtx_insn *insn)
+sh_mode_after (int entity ATTRIBUTE_UNUSED, int mode, rtx_insn *insn,
+	       HARD_REG_SET)
 {
   if (TARGET_HITACHI && recog_memoized (insn) >= 0 &&
       get_attr_fp_set (insn) != FP_SET_NONE)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 144b3f88c37..b730b5bf658 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10423,12 +10423,14 @@ such requirement.  @var{regs_live} contains the set of hard registers
 that are live before @var{insn}.
 @end deftypefn
 
-@deftypefn {Target Hook} int TARGET_MODE_AFTER (int @var{entity}, int @var{mode}, rtx_insn *@var{insn})
+@deftypefn {Target Hook} int TARGET_MODE_AFTER (int @var{entity}, int @var{mode}, rtx_insn *@var{insn}, HARD_REG_SET @var{regs_live})
 @var{entity} is an integer specifying a mode-switched entity.
 If this hook is defined, it is evaluated for every @var{insn} during mode
 switching.  It returns the mode that @var{entity} is in after @var{insn}
 has been executed.  @var{mode} is the mode that @var{entity} was in
 before @var{insn} was executed, taking account of @var{TARGET_MODE_NEEDED}.
+@var{regs_live} is the set of hard registers that are live after @var{insn}
+has been executed.
 
 @var{mode} is equal to the number of modes defined for @var{entity}
 if the mode before @var{insn} is unknown.  The hook should likewise return
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index c5fe90ba449..7a5c4993d65 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -632,10 +632,6 @@ optimize_mode_switching (void)
 		      last_mode = mode;
 		    }
 
-		  if (targetm.mode_switching.after)
-		    last_mode = targetm.mode_switching.after (e, last_mode,
-							      insn);
-
 		  /* Update LIVE_NOW.  */
 		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
 		    if (REG_NOTE_KIND (link) == REG_DEAD)
@@ -645,6 +641,10 @@ optimize_mode_switching (void)
 		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
 		    if (REG_NOTE_KIND (link) == REG_UNUSED)
 		      reg_dies (XEXP (link, 0), &live_now);
+
+		  if (targetm.mode_switching.after)
+		    last_mode = targetm.mode_switching.after (e, last_mode,
+							      insn, live_now);
 		}
 	    }
 
diff --git a/gcc/target.def b/gcc/target.def
index 50bad184aca..9b14c037d3f 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -7042,6 +7042,8 @@ If this hook is defined, it is evaluated for every @var{insn} during mode\n\
 switching.  It returns the mode that @var{entity} is in after @var{insn}\n\
 has been executed.  @var{mode} is the mode that @var{entity} was in\n\
 before @var{insn} was executed, taking account of @var{TARGET_MODE_NEEDED}.\n\
+@var{regs_live} is the set of hard registers that are live after @var{insn}\n\
+has been executed.\n\
 \n\
 @var{mode} is equal to the number of modes defined for @var{entity}\n\
 if the mode before @var{insn} is unknown.  The hook should likewise return\n\
@@ -7049,7 +7051,7 @@ the number of modes if it does not know what mode @var{entity} has after\n\
 @var{insn}.\n\
 \n\
 Not defining the hook is equivalent to returning @var{mode}.",
- int, (int entity, int mode, rtx_insn *insn), NULL)
+ int, (int entity, int mode, rtx_insn *insn, HARD_REG_SET regs_live), NULL)
 
 DEFHOOK
 (entry,
