diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b3434dd..65bf574 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2553,6 +2553,18 @@ ix86_using_red_zone (void)
 {
   return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;
 }
+
+/* Return the red zone size being supported by ABI.  */
+
+static int
+ix86_stack_red_zone_size (void)
+{
+  struct ix86_frame frame;
+  ix86_compute_frame_layout (&frame);
+
+  return frame.red_zone_size;
+}
+
 
 /* Return a string that documents the current -m options.  The caller is
    responsible for freeing the string.  */
@@ -34877,6 +34889,9 @@ ix86_autovectorize_vector_sizes (void)
 #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
 #endif
 
+#undef TARGET_STACK_RED_ZONE_SIZE
+#define TARGET_STACK_RED_ZONE_SIZE ix86_stack_red_zone_size
+
 #undef TARGET_FUNCTION_VALUE
 #define TARGET_FUNCTION_VALUE ix86_function_value
 
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a87280c..622ca79 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1536,6 +1536,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
 #endif
 
+#undef TARGET_STACK_RED_ZONE_SIZE
+#define TARGET_STACK_RED_ZONE_SIZE rs6000_stack_red_zone_size
+
 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
    The PowerPC architecture requires only weak consistency among
    processors--that is, memory accesses between processors need not be
@@ -20650,16 +20653,24 @@ rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
 	}
 }
 
-/* Return true if OFFSET from stack pointer can be clobbered by signals.
-   V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
-   below stack pointer not cloberred by signals.  */
+/* Return the red zone size by checking different ABIs. V.4 doesn't have any
+   stack cushion, AIX ABIs have 220 or 288 bytes below stack pointer not
+   cloberred by signals.  */
+
+static int
+rs6000_stack_red_zone_size (void)
+{
+  return (DEFAULT_ABI == ABI_V4
+	  ? 0
+	  : TARGET_32BIT ? 220 : 288);
+}
+
+/* Return true if OFFSET from stack pointer can be clobbered by signals.  */
 
 static inline bool
 offset_below_red_zone_p (HOST_WIDE_INT offset)
 {
-  return offset < (DEFAULT_ABI == ABI_V4
-		   ? 0
-		   : TARGET_32BIT ? -220 : -288);
+  return offset < (-rs6000_stack_red_zone_size());
 }
 
 /* Emit function epilogue as insns.  */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 341628b..78d6d36 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11261,6 +11261,11 @@ argument list due to stack realignment.  Return @code{NULL} if no DRAP
 is needed.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_STACK_RED_ZONE_SIZE (void)
+This hook returns the size of red zone beyond stack frame. Different ABI may
+provide different value.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS (void)
 When optimization is disabled, this hook indicates whether or not
 arguments should be allocated to stack slots.  Normally, GCC allocates
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f7c16e9..b6750bd 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -11168,6 +11168,11 @@ argument list due to stack realignment.  Return @code{NULL} if no DRAP
 is needed.
 @end deftypefn
 
+@hook TARGET_STACK_RED_ZONE_SIZE
+This hook returns the size of red zone beyond stack frame. Different ABI may
+provide different value.
+@end deftypefn
+
 @hook TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
 When optimization is disabled, this hook indicates whether or not
 arguments should be allocated to stack slots.  Normally, GCC allocates
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 343d03c..6ff0427 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2290,6 +2290,22 @@ sched_analyze_1 (struct deps_desc *deps, rtx x, rtx insn)
 			       FIRST_STACK_REG);
 	}
 #endif
+
+      /* We assume there doesn't exist red zone access before instruction
+         scheduling. If the stack is being adjusted, but by less than the size
+         of the red zone, we can ignore the adjustment for scheduling cases,
+         because the stack access beyond new stack frame must be inside new
+         red zone.  In all other cases we have to assume that the contents of
+         memory after this adjustment may have changed and insert a scheduling
+         barrier here.  */
+      if (dest == stack_pointer_rtx
+	  && !((code == SET)
+	       && (GET_CODE (SET_SRC (x)) == PLUS)
+	       && (XEXP (SET_SRC (x), 0) == stack_pointer_rtx)
+	       && CONST_INT_P (XEXP (SET_SRC (x), 1))
+	       && (abs (INTVAL (XEXP (SET_SRC (x), 1)))
+		   < targetm.calls.stack_red_zone_size ())))
+	flush_pending_lists (deps, insn, true, true);
     }
   else if (MEM_P (dest))
     {
diff --git a/gcc/target.def b/gcc/target.def
index c67f0ba..ba9a50c 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2074,6 +2074,13 @@ DEFHOOK
  "",
  rtx, (void), NULL)
 
+/* Returns the size of red zone beyond stack frame.  */
+DEFHOOK
+(stack_red_zone_size,
+ "",
+ int, (void),
+ default_stack_red_zone_size)
+
 /* Return true if all function parameters should be spilled to the
    stack.  */
 DEFHOOK
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index bcb8a12..fd3c322 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -727,6 +727,12 @@ default_hidden_stack_protect_fail (void)
 #endif
 }
 
+int
+default_stack_red_zone_size (void)
+{
+  return 0;
+}
+
 bool
 hook_bool_const_rtx_commutative_p (const_rtx x,
 				   int outer_code ATTRIBUTE_UNUSED)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ce89d32..5d1e01b 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -52,6 +52,8 @@ extern tree default_stack_protect_guard (void);
 extern tree default_external_stack_protect_fail (void);
 extern tree default_hidden_stack_protect_fail (void);
 
+extern int default_stack_red_zone_size (void);
+
 extern enum machine_mode default_mode_for_suffix (char);
 
 extern tree default_cxx_guard_type (void);
