File gcc48-bnc981311.diff of Package gcc48.10984

This is a backport of the fix for PR63293, which hit us
in the kernel (at least btrfs) as bnc #981311.

Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	(revision 238821)
+++ gcc/config/aarch64/aarch64.c	(working copy)
@@ -1995,6 +1995,9 @@ aarch64_expand_epilogue (bool for_sibcal
   HOST_WIDE_INT fp_offset;
   rtx insn;
   rtx cfa_reg;
+  /* We need to add memory barrier to prevent read from deallocated stack.  */
+  bool need_barrier_p = (get_frame_size () != 0
+			 || cfun->machine->saved_varargs_size);
 
   aarch64_layout_frame ();
   original_frame_size = get_frame_size () + cfun->machine->saved_varargs_size;
@@ -2036,6 +2039,8 @@ aarch64_expand_epilogue (bool for_sibcal
   if (frame_pointer_needed
       && (crtl->outgoing_args_size || cfun->calls_alloca))
     {
+      if (cfun->calls_alloca)
+	emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
       insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
 				       hard_frame_pointer_rtx,
 				       GEN_INT (- fp_offset)));
@@ -2049,6 +2054,9 @@ aarch64_expand_epilogue (bool for_sibcal
   aarch64_save_or_restore_callee_save_registers
     (fp_offset + cfun->machine->frame.hardfp_offset, 1);
 
+  if (need_barrier_p)
+    emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
+
   /* Restore the frame pointer and lr if the frame pointer is needed.  */
   if (offset > 0)
     {
@@ -2146,6 +2154,9 @@ aarch64_expand_epilogue (bool for_sibcal
 
   if (frame_size > -1)
     {
+      if (need_barrier_p)
+	emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
+
       if (frame_size >= 0x1000000)
 	{
 	  rtx op0 = gen_rtx_REG (Pmode, IP0_REGNUM);