Blame SOURCES/gcc48-rh1537828-3.patch

b89248
commit 33839c8f8aa7857cc5f22ddb3f0960999cb0dfc7
b89248
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
b89248
Date:   Wed Jan 31 05:02:30 2018 +0000
b89248
b89248
            PR target/84064
b89248
            * i386.c (ix86_adjust_stack_and_probe_stack_clash): New argument
b89248
            INT_REGISTERS_SAVED.  Check it prior to calling
b89248
            get_scratch_register_on_entry.
b89248
            (ix86_adjust_stack_and_probe): Similarly.
b89248
            (ix86_emit_probe_stack_range): Similarly.
b89248
            (ix86_expand_prologue): Corresponding changes.
b89248
b89248
            PR target/84064
b89248
            * gcc.target/i386/pr84064: New test.
b89248
b89248
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
b89248
index 5230227..2fe2a0c 100644
b89248
--- a/gcc/config/i386/i386.c
b89248
+++ b/gcc/config/i386/i386.c
b89248
@@ -10206,10 +10206,14 @@ release_scratch_register_on_entry (struct scratch_reg *sr)
b89248
    This differs from the next routine in that it tries hard to prevent
b89248
    attacks that jump the stack guard.  Thus it is never allowed to allocate
b89248
    more than PROBE_INTERVAL bytes of stack space without a suitable
b89248
-   probe.  */
b89248
+   probe.
b89248
+
b89248
+   INT_REGISTERS_SAVED is true if integer registers have already been
b89248
+   pushed on the stack.  */
b89248
 
b89248
 static void
b89248
-ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size)
b89248
+ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
b89248
+					 const bool int_registers_saved)
b89248
 {
b89248
   struct machine_function *m = cfun->machine;
b89248
   struct ix86_frame frame;
b89248
@@ -10318,6 +10322,12 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size)
b89248
     }
b89248
   else
b89248
     {
b89248
+      /* We expect the GP registers to be saved when probes are used
b89248
+	 as the probing sequences might need a scratch register and
b89248
+	 the routine to allocate one assumes the integer registers
b89248
+	 have already been saved.  */
b89248
+      gcc_assert (int_registers_saved);
b89248
+
b89248
       struct scratch_reg sr;
b89248
       get_scratch_register_on_entry (&sr);
b89248
 
b89248
@@ -10376,10 +10386,14 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size)
b89248
   emit_insn (gen_blockage ());
b89248
 }
b89248
 
b89248
-/* Emit code to adjust the stack pointer by SIZE bytes while probing it.  */
b89248
+/* Emit code to adjust the stack pointer by SIZE bytes while probing it.
b89248
+
b89248
+   INT_REGISTERS_SAVED is true if integer registers have already been
b89248
+   pushed on the stack.  */
b89248
 
b89248
 static void
b89248
-ix86_adjust_stack_and_probe (const HOST_WIDE_INT size)
b89248
+ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
b89248
+			     const bool int_registers_saved)
b89248
 {
b89248
   /* We skip the probe for the first interval + a small dope of 4 words and
b89248
      probe that many bytes past the specified size to maintain a protection
b89248
@@ -10440,6 +10454,12 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size)
b89248
      equality test for the loop condition.  */
b89248
   else
b89248
     {
b89248
+      /* We expect the GP registers to be saved when probes are used
b89248
+	 as the probing sequences might need a scratch register and
b89248
+	 the routine to allocate one assumes the integer registers
b89248
+	 have already been saved.  */
b89248
+      gcc_assert (int_registers_saved);
b89248
+
b89248
       HOST_WIDE_INT rounded_size;
b89248
       struct scratch_reg sr;
b89248
 
b89248
@@ -10564,10 +10584,14 @@ output_adjust_stack_and_probe (rtx reg)
b89248
 }
b89248
 
b89248
 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
b89248
-   inclusive.  These are offsets from the current stack pointer.  */
b89248
+   inclusive.  These are offsets from the current stack pointer.
b89248
+
b89248
+   INT_REGISTERS_SAVED is true if integer registers have already been
b89248
+   pushed on the stack.  */
b89248
 
b89248
 static void
b89248
-ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
b89248
+ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
b89248
+			     const bool int_registers_saved)
b89248
 {
b89248
   /* See if we have a constant small number of probes to generate.  If so,
b89248
      that's the easy case.  The run-time loop is made up of 7 insns in the
b89248
@@ -10595,6 +10619,12 @@ ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
b89248
      equality test for the loop condition.  */
b89248
   else
b89248
     {
b89248
+      /* We expect the GP registers to be saved when probes are used
b89248
+	 as the probing sequences might need a scratch register and
b89248
+	 the routine to allocate one assumes the integer registers
b89248
+	 have already been saved.  */
b89248
+      gcc_assert (int_registers_saved);
b89248
+
b89248
       HOST_WIDE_INT rounded_size, last;
b89248
       struct scratch_reg sr;
b89248
 
b89248
@@ -11072,20 +11102,15 @@ ix86_expand_prologue (void)
b89248
       && (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
b89248
 	  || flag_stack_clash_protection))
b89248
     {
b89248
-      /* We expect the GP registers to be saved when probes are used
b89248
-	 as the probing sequences might need a scratch register and
b89248
-	 the routine to allocate one assumes the integer registers
b89248
-	 have already been saved.  */
b89248
-      gcc_assert (int_registers_saved);
b89248
-
b89248
       if (flag_stack_clash_protection)
b89248
 	{
b89248
-	  ix86_adjust_stack_and_probe_stack_clash (allocate);
b89248
+	  ix86_adjust_stack_and_probe_stack_clash (allocate,
b89248
+						   int_registers_saved);
b89248
 	  allocate = 0;
b89248
 	}
b89248
       else if (STACK_CHECK_MOVING_SP)
b89248
 	{
b89248
-	  ix86_adjust_stack_and_probe (allocate);
b89248
+	  ix86_adjust_stack_and_probe (allocate, int_registers_saved);
b89248
 	  allocate = 0;
b89248
 	}
b89248
       else
b89248
@@ -11096,9 +11121,11 @@ ix86_expand_prologue (void)
b89248
 	    size = 0x80000000 - get_stack_check_protect () - 1;
b89248
 
b89248
 	  if (TARGET_STACK_PROBE)
b89248
-	    ix86_emit_probe_stack_range (0, size + get_stack_check_protect ());
b89248
+	    ix86_emit_probe_stack_range (0, size + get_stack_check_protect (),
b89248
+					 int_registers_saved);
b89248
 	  else
b89248
-	    ix86_emit_probe_stack_range (get_stack_check_protect (), size);
b89248
+	    ix86_emit_probe_stack_range (get_stack_check_protect (), size,
b89248
+					 int_registers_saved);
b89248
 	}
b89248
     }
b89248
 
b89248
diff --git a/gcc/testsuite/gcc.target/i386/pr84064.c b/gcc/testsuite/gcc.target/i386/pr84064.c
b89248
new file mode 100644
b89248
index 0000000..01f8d9e
b89248
--- /dev/null
b89248
+++ b/gcc/testsuite/gcc.target/i386/pr84064.c
b89248
@@ -0,0 +1,10 @@
b89248
+/* { dg-do compile } */
b89248
+/* { dg-options "-O2 -march=i686 -fstack-clash-protection" } */
b89248
+/* { dg-require-effective-target ia32 } */
b89248
+
b89248
+void
b89248
+f (void *p1, void *p2)
b89248
+{
b89248
+  __builtin_memcpy (p1, p2, 1000);
b89248
+}
b89248
+