i386.c (ix86_expand_prologue): Emit a memory blockage after restoring registers saved...
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 6 Feb 2019 21:03:03 +0000 (21:03 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 6 Feb 2019 21:03:03 +0000 (21:03 +0000)
* config/i386/i386.c (ix86_expand_prologue): Emit a memory blockage
after restoring registers saved to allocate the frame on Windows.

From-SVN: r268593

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/opt76.adb [new file with mode: 0644]

index 712e768a353d81ed0893adda986d9a5f33109b1f..21d1434ce6f96548887a87932d3bef16b96f5701 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * config/i386/i386.c (ix86_expand_prologue): Emit a memory blockage
+       after restoring registers saved to allocate the frame on Windows.
+
 2019-02-06  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/89182
index 789a53501ee5e3d4f56fd97a1f630f83926f136e..579a3ee3037af9668da9bf05e0ed7454fe84ca64 100644 (file)
@@ -13579,8 +13579,9 @@ ix86_expand_prologue (void)
        }
       m->fs.sp_offset += allocate;
 
-      /* Use stack_pointer_rtx for relative addressing so that code
-        works for realigned stack, too.  */
+      /* Use stack_pointer_rtx for relative addressing so that code works for
+        realigned stack.  But this means that we need a blockage to prevent
+        stores based on the frame pointer from being scheduled before.  */
       if (r10_live && eax_live)
         {
          t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
@@ -13589,6 +13590,7 @@ ix86_expand_prologue (void)
          t = plus_constant (Pmode, t, UNITS_PER_WORD);
          emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
                          gen_frame_mem (word_mode, t));
+         emit_insn (gen_memory_blockage ());
        }
       else if (eax_live || r10_live)
        {
@@ -13596,6 +13598,7 @@ ix86_expand_prologue (void)
          emit_move_insn (gen_rtx_REG (word_mode,
                                       (eax_live ? AX_REG : R10_REG)),
                          gen_frame_mem (word_mode, t));
+         emit_insn (gen_memory_blockage ());
        }
     }
   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
index 53f4cd3f75d4112dba841e77c949bac684470037..ad12b335f581b4343ad07c39f2b98774d45597e6 100644 (file)
@@ -1,3 +1,7 @@
+2019-02-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/opt76.adb: New test.
+
 2019-02-06  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/71860
diff --git a/gcc/testsuite/gnat.dg/opt76.adb b/gcc/testsuite/gnat.dg/opt76.adb
new file mode 100644 (file)
index 0000000..50f3cee
--- /dev/null
@@ -0,0 +1,36 @@
+-- { dg-do run }
+-- { dg-options "-O2 -gnatp -fno-omit-frame-pointer" }
+
+procedure Opt76 is
+
+   type Integer_Access is access Integer;
+   type Registry_Array is array (Natural range <>) of Integer_Access;
+
+   procedure Nested (Input, Parser : Integer; A, B : Boolean) is
+
+      Index : Registry_Array (1 .. 1024);
+      Not_B : constant Boolean := not B;
+
+      procedure Inner (Input : Integer) is
+      begin
+         if Input /= 1 then
+            raise Program_Error;
+         end if;
+
+         if Parser = 128 and then A and then Not_B then
+            Inner (Input);
+            Index (Index'First) := null;
+         end if;
+      end;
+
+   begin
+      Inner (Input);
+   end;
+
+   Input : Integer := 1 with Volatile;
+   Parser : Integer := 2 with Volatile;
+      
+begin
+   Nested (Input, Parser, False, True);
+   Nested (Input, Parser, True, False);
+end;