diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4da1c6227520..9eda3cd36d9a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2018-10-01  Tamar Christina  <tamar.christina@arm.com>
+
+	PR target/86486
+	* explow.c (anti_adjust_stack_and_probe_stack_clash): Support custom
+	probe ranges.
+	* target.def (stack_clash_protection_alloca_probe_range): New.
+	(stack_clash_protection_final_dynamic_probe): Remove.
+	* targhooks.h (default_stack_clash_protection_alloca_probe_range) New.
+	(default_stack_clash_protection_final_dynamic_probe): Remove.
+	* targhooks.c: Likewise.
+	* doc/tm.texi.in (TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE): New.
+	(TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE): Remove.
+	* doc/tm.texi: Regenerate.
+
 2018-10-01  Tamar Christina  <tamar.christina@arm.com>
 
 	PR target/86486
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 561bda38899d..b00e4b60bc55 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3450,8 +3450,12 @@ GCC computed the default from the values of the above macros and you will
 normally not need to override that default.
 @end defmac
 
-@deftypefn {Target Hook} bool TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE (rtx @var{residual})
-Some targets make optimistic assumptions about the state of stack probing when they emit their prologues.  On such targets a probe into the end of any dynamically allocated space is likely required for safety against stack clash style attacks.  Define this variable to return nonzero if such a probe is required or zero otherwise.  You need not define this macro if it would always have the value zero.
+@deftypefn {Target Hook} HOST_WIDE_INT TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE (void)
+Some targets have an ABI defined interval for which no probing needs to be done.
+When a probe does need to be done this same interval is used as the probe distance up when doing stack clash protection for alloca.
+On such targets this value can be set to override the default probing up interval.
+Define this variable to return nonzero if such a probe range is required or zero otherwise.  Defining this hook also requires your functions which make use of alloca to have at least 8 byesof outgoing arguments.  If this is not the case the stack will be corrupted.
+You need not define this macro if it would always have the value zero.
 @end deftypefn
 
 @need 2000
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index c509a9b4be66..e2b6f945d298 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2841,7 +2841,7 @@ GCC computed the default from the values of the above macros and you will
 normally not need to override that default.
 @end defmac
 
-@hook TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE
+@hook TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE
 
 @need 2000
 @node Frame Registers
diff --git a/gcc/explow.c b/gcc/explow.c
index 7d83eb16b6dd..1dabd6ff9aa9 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -1958,10 +1958,21 @@ anti_adjust_stack_and_probe_stack_clash (rtx size)
 
   /* We can get here with a constant size on some targets.  */
   rtx rounded_size, last_addr, residual;
-  HOST_WIDE_INT probe_interval;
+  HOST_WIDE_INT probe_interval, probe_range;
+  bool target_probe_range_p = false;
   compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
 					    &residual, &probe_interval, size);
 
+  /* Get the back-end specific probe ranges.  */
+  probe_range = targetm.stack_clash_protection_alloca_probe_range ();
+  target_probe_range_p = probe_range != 0;
+  gcc_assert (probe_range >= 0);
+
+  /* If no back-end specific range defined, default to the top of the newly
+     allocated range.  */
+  if (probe_range == 0)
+    probe_range = probe_interval - GET_MODE_SIZE (word_mode);
+
   if (rounded_size != CONST0_RTX (Pmode))
     {
       if (CONST_INT_P (rounded_size)
@@ -1972,13 +1983,12 @@ anti_adjust_stack_and_probe_stack_clash (rtx size)
 	       i += probe_interval)
 	    {
 	      anti_adjust_stack (GEN_INT (probe_interval));
-
 	      /* The prologue does not probe residuals.  Thus the offset
 		 here to probe just beyond what the prologue had already
 		 allocated.  */
 	      emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
-					       (probe_interval
-						- GET_MODE_SIZE (word_mode))));
+					       probe_range));
+
 	      emit_insn (gen_blockage ());
 	    }
 	}
@@ -1992,10 +2002,10 @@ anti_adjust_stack_and_probe_stack_clash (rtx size)
 	  anti_adjust_stack (GEN_INT (probe_interval));
 
 	  /* The prologue does not probe residuals.  Thus the offset here
-	     to probe just beyond what the prologue had already allocated.  */
+	     to probe just beyond what the prologue had already
+	     allocated.  */
 	  emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
-					   (probe_interval
-					    - GET_MODE_SIZE (word_mode))));
+					   probe_range));
 
 	  emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
 						      last_addr, rotate_loop);
@@ -2010,48 +2020,55 @@ anti_adjust_stack_and_probe_stack_clash (rtx size)
 	 hold live data.  Furthermore, we do not want to probe into the
 	 red zone.
 
-	 Go ahead and just guard the probe at *sp on RESIDUAL != 0 at
-	 runtime if RESIDUAL is not a compile time constant.  */
-      if (!CONST_INT_P (residual))
-	{
-	  label = gen_label_rtx ();
-	  emit_cmp_and_jump_insns (residual, CONST0_RTX (GET_MODE (residual)),
-				   EQ, NULL_RTX, Pmode, 1, label);
-	}
+	 If TARGET_PROBE_RANGE_P then the target has promised it's safe to
+	 probe at offset 0.  In which case we no longer have to check for
+	 RESIDUAL == 0.  However we still need to probe at the right offset
+	 when RESIDUAL > PROBE_RANGE, in which case we probe at PROBE_RANGE.
 
-      rtx x = force_reg (Pmode, plus_constant (Pmode, residual,
-					       -GET_MODE_SIZE (word_mode)));
+	 If !TARGET_PROBE_RANGE_P then go ahead and just guard the probe at *sp
+	 on RESIDUAL != 0 at runtime if RESIDUAL is not a compile time constant.
+	 */
       anti_adjust_stack (residual);
-      emit_stack_probe (gen_rtx_PLUS (Pmode, stack_pointer_rtx, x));
-      emit_insn (gen_blockage ());
+
       if (!CONST_INT_P (residual))
-	emit_label (label);
-    }
-
-  /* Some targets make optimistic assumptions in their prologues about
-     how the caller may have probed the stack.  Make sure we honor
-     those assumptions when needed.  */
-  if (size != CONST0_RTX (Pmode)
-      && targetm.stack_clash_protection_final_dynamic_probe (residual))
-    {
-      /* SIZE could be zero at runtime and in that case *sp could hold
-	 live data.  Furthermore, we don't want to probe into the red
-	 zone.
-
-	 Go ahead and just guard the probe at *sp on SIZE != 0 at runtime
-	 if SIZE is not a compile time constant.  */
-      rtx label = NULL_RTX;
-      if (!CONST_INT_P (size))
 	{
 	  label = gen_label_rtx ();
-	  emit_cmp_and_jump_insns (size, CONST0_RTX (GET_MODE (size)),
-				   EQ, NULL_RTX, Pmode, 1, label);
+	  rtx_code op = target_probe_range_p ? LT : EQ;
+	  rtx probe_cmp_value = target_probe_range_p
+	    ? gen_rtx_CONST_INT (GET_MODE (residual), probe_range)
+	    : CONST0_RTX (GET_MODE (residual));
+
+	  if (target_probe_range_p)
+	    emit_stack_probe (stack_pointer_rtx);
+
+	  emit_cmp_and_jump_insns (residual, probe_cmp_value,
+				   op, NULL_RTX, Pmode, 1, label);
 	}
 
-      emit_stack_probe (stack_pointer_rtx);
+      rtx x = NULL_RTX;
+
+      /* If RESIDUAL isn't a constant and TARGET_PROBE_RANGE_P then we probe up
+	 by the ABI defined safe value.  */
+      if (!CONST_INT_P (residual) && target_probe_range_p)
+	x = GEN_INT (probe_range);
+      /* If RESIDUAL is a constant but smaller than the ABI defined safe value,
+	 we still want to probe up, but the safest amount if a word.  */
+      else if (target_probe_range_p)
+	{
+	  if (INTVAL (residual) <= probe_range)
+	    x = GEN_INT (GET_MODE_SIZE (word_mode));
+	  else
+	    x = GEN_INT (probe_range);
+	}
+      else
+      /* If nothing else, probe at the top of the new allocation.  */
+	x = plus_constant (Pmode, residual, -GET_MODE_SIZE (word_mode));
+
+      emit_stack_probe (gen_rtx_PLUS (Pmode, stack_pointer_rtx, x));
+
       emit_insn (gen_blockage ());
-      if (!CONST_INT_P (size))
-	emit_label (label);
+      if (!CONST_INT_P (residual))
+	  emit_label (label);
     }
 }
 
diff --git a/gcc/target.def b/gcc/target.def
index 9e22423d466c..9733edff8139 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5854,10 +5854,17 @@ these registers when the target switches are opposed to them.)",
  hook_void_void)
 
 DEFHOOK
-(stack_clash_protection_final_dynamic_probe,
- "Some targets make optimistic assumptions about the state of stack probing when they emit their prologues.  On such targets a probe into the end of any dynamically allocated space is likely required for safety against stack clash style attacks.  Define this variable to return nonzero if such a probe is required or zero otherwise.  You need not define this macro if it would always have the value zero.",
- bool, (rtx residual),
- default_stack_clash_protection_final_dynamic_probe)
+(stack_clash_protection_alloca_probe_range,
+ "Some targets have an ABI defined interval for which no probing needs to be done.\n\
+When a probe does need to be done this same interval is used as the probe distance \
+up when doing stack clash protection for alloca.\n\
+On such targets this value can be set to override the default probing up interval.\n\
+Define this variable to return nonzero if such a probe range is required or zero otherwise.  \
+Defining this hook also requires your functions which make use of alloca to have at least 8 byes\
+of outgoing arguments.  If this is not the case the stack will be corrupted.\n\
+You need not define this macro if it would always have the value zero.",
+ HOST_WIDE_INT, (void),
+ default_stack_clash_protection_alloca_probe_range)
 
 
 /* Functions specific to the C family of frontends.  */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index afd56f3ec457..3d8b3b9d69be 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -2310,8 +2310,10 @@ default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED)
   return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
 }
 
-bool
-default_stack_clash_protection_final_dynamic_probe (rtx residual ATTRIBUTE_UNUSED)
+/* Default implementation for
+  TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE.  */
+HOST_WIDE_INT
+default_stack_clash_protection_alloca_probe_range (void)
 {
   return 0;
 }
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index f92ca5ca997d..176c64d23f53 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -277,7 +277,7 @@ extern unsigned int default_min_arithmetic_precision (void);
 
 extern enum flt_eval_method
 default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED);
-extern bool default_stack_clash_protection_final_dynamic_probe (rtx);
+extern HOST_WIDE_INT default_stack_clash_protection_alloca_probe_range (void);
 extern void default_select_early_remat_modes (sbitmap);
 extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *);