[PR target/47192] Avoid unsafe code motion in m68k epilogue

Jeff Law law@redhat.com
Thu Nov 17 23:42:00 GMT 2016


Like so many ports, the m68k port forgot to emit a barrier prior to 
deallocation of the stack in its epilogue.

As a result, a memory reference could schedule after the stack 
deallocation.  That memory reference might refer to an object in the 
just allocated stack.  If we get an interrupt between the deallocation 
and the memory reference, boom!

This can be seen in the code for pr47192 when using the appropriate options.

Fixed in the usual way.  Verified the m68k target tests pass. 
Installing on the trunk.

jeff

-------------- next part --------------
commit 6dcf231a5ddf1f8dfcf1a6ec59fcf56520666271
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Nov 17 23:39:08 2016 +0000

    	PR target/47192
    	* config/m68k/m68k.c (m68k_expand_epilogue): Emit a scheduling
    	barrier prior to deallocating the stack.
    
    	PR target/47192
    	* gcc.target/m68k/pr47192.c: New test.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@242575 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 24ed0f8..86a8fdf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-11-17  Jeff Law  <law@redhat.com>
+
+	PR target/47192
+	* config/m68k/m68k.c (m68k_expand_epilogue): Emit a scheduling
+	barrier prior to deallocating the stack.
+
 2016-11-17  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* config/arc/arc.md (cmem bit/sign-extend peephole2): New peephole
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index ce56692..346c2dc 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -1205,6 +1205,7 @@ m68k_expand_epilogue (bool sibcall_p)
 	     stack-based restore.  */
 	  emit_move_insn (gen_rtx_REG (Pmode, A1_REG),
 			  GEN_INT (-(current_frame.offset + fsize)));
+	  emit_insn (gen_blockage ());
 	  emit_insn (gen_addsi3 (stack_pointer_rtx,
 				 gen_rtx_REG (Pmode, A1_REG),
 				 frame_pointer_rtx));
@@ -1306,6 +1307,7 @@ m68k_expand_epilogue (bool sibcall_p)
 			 current_frame.fpu_mask, false, false);
     }
 
+  emit_insn (gen_blockage ());
   if (frame_pointer_needed)
     emit_insn (gen_unlink (frame_pointer_rtx));
   else if (fsize_with_regs)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 356d75a..5dd6f56 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-17  Jeff Law  <law@redhat.com>
+
+	PR target/47192
+	* gcc.target/m68k/pr47192.c: New test.
+
 2016-11-17  Toma Tabacu  <toma.tabacu@imgtec.com>
 
 	* gcc.target/mips/branch-cost-1.c (dg-options): Use (HAS_MOVN)
diff --git a/gcc/testsuite/gcc.target/m68k/pr47192.c b/gcc/testsuite/gcc.target/m68k/pr47192.c
new file mode 100644
index 0000000..5bbef58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr47192.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=51qe -fdisable-ipa-pure-const -fdump-rtl-pro_and_epilogue" } */
+/* { dg-final { scan-rtl-dump-times "unspec_volatile" 1 "pro_and_epilogue"} } */
+
+
+char F(short *ty);
+
+short V(char cmd)
+{
+  static short st256;
+  static short stc;
+  short sc;
+  short scd;
+  short d;
+
+  F(&sc);
+
+  if (cmd == 4)
+  {
+    st256 = 0;
+    d = 0;
+  }
+  else
+  {
+    scd = sc - stc;
+    if (scd < -128)
+    {
+      scd += 256;
+    }
+    d = st256 >> 8;
+    st256 -= d << 8;
+  }
+  stc = sc;
+  return d;
+}
+


More information about the Gcc-patches mailing list