Blame SOURCES/gcc48-rh1537828-3.patch

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