Blame SOURCES/gcc48-rh1469697-21.patch

5ed81e
	PR middle-end/83654
5ed81e
	* explow.c (anti_adjust_stack_and_probe_stack_clash): Test a
5ed81e
	non-constant residual for zero at runtime and avoid probing in
5ed81e
	that case.  Reorganize code for trailing problem to mirror handling
5ed81e
	of the residual.
5ed81e
5ed81e
	PR middle-end/83654
5ed81e
	* gcc.target/i386/stack-check-18.c: New test.
5ed81e
	* gcc.target/i386/stack-check-19.c: New test.
5ed81e
5ed81e
diff --git a/gcc/explow.c b/gcc/explow.c
5ed81e
index b6c56602152..042e71904ec 100644
5ed81e
--- a/gcc/explow.c
5ed81e
+++ b/gcc/explow.c
5ed81e
@@ -1997,11 +1997,27 @@ anti_adjust_stack_and_probe_stack_clash (rtx size)
5ed81e
 
5ed81e
   if (residual != CONST0_RTX (Pmode))
5ed81e
     {
5ed81e
+      rtx label = NULL_RTX;
5ed81e
+      /* RESIDUAL could be zero at runtime and in that case *sp could
5ed81e
+	 hold live data.  Furthermore, we do not want to probe into the
5ed81e
+	 red zone.
5ed81e
+
5ed81e
+	 Go ahead and just guard the probe at *sp on RESIDUAL != 0 at
5ed81e
+	 runtime if RESIDUAL is not a compile time constant.  */
5ed81e
+      if (!CONST_INT_P (residual))
5ed81e
+	{
5ed81e
+	  label = gen_label_rtx ();
5ed81e
+	  emit_cmp_and_jump_insns (residual, CONST0_RTX (GET_MODE (residual)),
5ed81e
+				   EQ, NULL_RTX, Pmode, 1, label);
5ed81e
+	}
5ed81e
+
5ed81e
       rtx x = force_reg (Pmode, plus_constant (Pmode, residual,
5ed81e
 					       -GET_MODE_SIZE (word_mode)));
5ed81e
       anti_adjust_stack (residual);
5ed81e
       emit_stack_probe (gen_rtx_PLUS (Pmode, stack_pointer_rtx, x));
5ed81e
       emit_insn (gen_blockage ());
5ed81e
+      if (!CONST_INT_P (residual))
5ed81e
+	emit_label (label);
5ed81e
     }
5ed81e
 
5ed81e
   /* Some targets make optimistic assumptions in their prologues about
5ed81e
@@ -2014,28 +2030,20 @@ anti_adjust_stack_and_probe_stack_clash (rtx size)
5ed81e
 	 live data.  Furthermore, we don't want to probe into the red
5ed81e
 	 zone.
5ed81e
 
5ed81e
-	 Go ahead and just guard a probe at *sp on SIZE != 0 at runtime
5ed81e
+	 Go ahead and just guard the probe at *sp on SIZE != 0 at runtime
5ed81e
 	 if SIZE is not a compile time constant.  */
5ed81e
-
5ed81e
-      /* Ideally we would just probe at *sp.  However, if SIZE is not
5ed81e
-	 a compile-time constant, but is zero at runtime, then *sp
5ed81e
-	 might hold live data.  So probe at *sp if we know that
5ed81e
-	 an allocation was made, otherwise probe into the red zone
5ed81e
-	 which is obviously undesirable.  */
5ed81e
-      if (CONST_INT_P (size))
5ed81e
-	{
5ed81e
-	  emit_stack_probe (stack_pointer_rtx);
5ed81e
-	  emit_insn (gen_blockage ());
5ed81e
-	}
5ed81e
-      else
5ed81e
+      rtx label = NULL_RTX;
5ed81e
+      if (!CONST_INT_P (size))
5ed81e
 	{
5ed81e
-	  rtx label = gen_label_rtx ();
5ed81e
+	  label = gen_label_rtx ();
5ed81e
 	  emit_cmp_and_jump_insns (size, CONST0_RTX (GET_MODE (size)),
5ed81e
 				   EQ, NULL_RTX, Pmode, 1, label);
5ed81e
-	  emit_stack_probe (stack_pointer_rtx);
5ed81e
-	  emit_insn (gen_blockage ());
5ed81e
-	  emit_label (label);
5ed81e
 	}
5ed81e
+
5ed81e
+      emit_stack_probe (stack_pointer_rtx);
5ed81e
+      emit_insn (gen_blockage ());
5ed81e
+      if (!CONST_INT_P (size))
5ed81e
+	emit_label (label);
5ed81e
     }
5ed81e
 }
5ed81e
 
5ed81e
diff --git a/gcc/testsuite/gcc.target/i386/stack-check-18.c b/gcc/testsuite/gcc.target/i386/stack-check-18.c
5ed81e
new file mode 100644
5ed81e
index 00000000000..6dbff4402da
5ed81e
--- /dev/null
5ed81e
+++ b/gcc/testsuite/gcc.target/i386/stack-check-18.c
5ed81e
@@ -0,0 +1,23 @@
5ed81e
+/* { dg-do compile } */
5ed81e
+/* { dg-options "-O2 -fstack-clash-protection -mtune=generic -fdump-rtl-expand" } */
5ed81e
+/* { dg-require-effective-target supports_stack_clash_protection } */
5ed81e
+
5ed81e
+int f1 (char *);
5ed81e
+
5ed81e
+int
5ed81e
+f2 (void)
5ed81e
+{
5ed81e
+  const int size = 4096;
5ed81e
+  char buffer[size];
5ed81e
+  return f1 (buffer);
5ed81e
+}
5ed81e
+
5ed81e
+/* So we want to verify that at expand time that we probed the main
5ed81e
+   VLA allocation as well as the residuals.  Then we want to verify
5ed81e
+   there was only one probe in the final assembly (implying the
5ed81e
+   residual probe was optimized away).  */
5ed81e
+/* { dg-final { scan-rtl-dump-times "allocation and probing in loop" 1 "expand" } } */
5ed81e
+/* { dg-final { scan-rtl-dump-times "allocation and probing residuals" 1 "expand" } } */
5ed81e
+
5ed81e
+/* { dg-final { scan-assembler-times "or\[ql\]" 1 } } */
5ed81e
+
5ed81e
diff --git a/gcc/testsuite/gcc.target/i386/stack-check-19.c b/gcc/testsuite/gcc.target/i386/stack-check-19.c
5ed81e
new file mode 100644
5ed81e
index 00000000000..b92c126d57f
5ed81e
--- /dev/null
5ed81e
+++ b/gcc/testsuite/gcc.target/i386/stack-check-19.c
5ed81e
@@ -0,0 +1,29 @@
5ed81e
+/* { dg-do compile } */
5ed81e
+/* { dg-options "-O2 -fstack-clash-protection -mtune=generic -fdump-rtl-expand" } */
5ed81e
+/* { dg-require-effective-target supports_stack_clash_protection } */
5ed81e
+
5ed81e
+int f1 (char *);
5ed81e
+
5ed81e
+int
5ed81e
+f2 (const int size)
5ed81e
+{
5ed81e
+  char buffer[size];
5ed81e
+  return f1 (buffer);
5ed81e
+}
5ed81e
+
5ed81e
+/* So we want to verify that at expand time that we probed the main
5ed81e
+   VLA allocation as well as the residuals.  Then we want to verify
5ed81e
+   there are two probes in the final assembly code.  */
5ed81e
+/* { dg-final { scan-rtl-dump-times "allocation and probing in loop" 1 "expand" } } */
5ed81e
+/* { dg-final { scan-rtl-dump-times "allocation and probing residuals" 1 "expand" } } */
5ed81e
+/* { dg-final { scan-assembler-times "or\[ql\]" 2 } } */
5ed81e
+
5ed81e
+/* We also want to verify (indirectly) that the residual probe is
5ed81e
+   guarded.  We do that by checking the number of conditional
5ed81e
+   branches.  There should be 3.  One that bypasses the probe loop, one
5ed81e
+   in the probe loop and one that bypasses the residual probe.
5ed81e
+
5ed81e
+   These will all be equality tests.  */
5ed81e
+/* { dg-final { scan-assembler-times "(\?:je|jne)" 3 } } */
5ed81e
+
5ed81e
+