re PR target/48142 (miscompilation with -Os -mpreferred-stack-boundary=5 -fstack...
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 31 Mar 2011 11:10:59 +0000 (11:10 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 31 Mar 2011 11:10:59 +0000 (11:10 +0000)
PR target/48142
* config/i386/i386.c (ix86_adjust_stack_and_probe): Differentiate
frame-related from frame-unrelated adjustments to the stack pointer.

From-SVN: r171777

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/i386-9.C [new file with mode: 0644]

index 8384f355dd2e60fbd1bff5a1ba20b649a50be9bc..714650e81c1c22ee49bc5afe858111b18b95b876 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-31  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/48142
+       * config/i386/i386.c (ix86_adjust_stack_and_probe): Differentiate
+       frame-related from frame-unrelated adjustments to the stack pointer.
+
 2011-03-31  Jakub Jelinek  <jakub@redhat.com>
 
        * common.opt (fdebug-types-section): Move earlier.
index a985b2b7691d188257df64aaa94353527b9910b4..738dc1c622bab19b0919c04da25314f1a498f62d 100644 (file)
@@ -10006,7 +10006,7 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size)
      probe that many bytes past the specified size to maintain a protection
      area at the botton of the stack.  */
   const int dope = 4 * UNITS_PER_WORD;
-  rtx size_rtx = GEN_INT (size);
+  rtx size_rtx = GEN_INT (size), last;
 
   /* See if we have a constant small number of probes to generate.  If so,
      that's the easy case.  The run-time loop is made up of 11 insns in the
@@ -10046,9 +10046,9 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size)
       emit_stack_probe (stack_pointer_rtx);
 
       /* Adjust back to account for the additional first interval.  */
-      emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
-                             plus_constant (stack_pointer_rtx,
-                                            PROBE_INTERVAL + dope)));
+      last = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                                    plus_constant (stack_pointer_rtx,
+                                                   PROBE_INTERVAL + dope)));
     }
 
   /* Otherwise, do the same as above, but in a loop.  Note that we must be
@@ -10109,15 +10109,33 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size)
        }
 
       /* Adjust back to account for the additional first interval.  */
-      emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
-                             plus_constant (stack_pointer_rtx,
-                                            PROBE_INTERVAL + dope)));
+      last = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                                    plus_constant (stack_pointer_rtx,
+                                                   PROBE_INTERVAL + dope)));
 
       release_scratch_register_on_entry (&sr);
     }
 
   gcc_assert (cfun->machine->fs.cfa_reg != stack_pointer_rtx);
-  cfun->machine->fs.sp_offset += size;
+
+  /* Even if the stack pointer isn't the CFA register, we need to correctly
+     describe the adjustments made to it, in particular differentiate the
+     frame-related ones from the frame-unrelated ones.  */
+  if (size > 0)
+    {
+      rtx expr = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (2));
+      XVECEXP (expr, 0, 0)
+       = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                      plus_constant (stack_pointer_rtx, -size));
+      XVECEXP (expr, 0, 1)
+       = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                      plus_constant (stack_pointer_rtx,
+                                     PROBE_INTERVAL + dope + size));
+      add_reg_note (last, REG_FRAME_RELATED_EXPR, expr);
+      RTX_FRAME_RELATED_P (last) = 1;
+
+      cfun->machine->fs.sp_offset += size;
+    }
 
   /* Make sure nothing is scheduled before we are done.  */
   emit_insn (gen_blockage ());
index f7436e1bd67d78b6259c416dfff81f4c7ff1ef51..6bb003d1992647d2c8837eec27b393790a771062 100644 (file)
@@ -1,7 +1,10 @@
+2011-03-31  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * g++.dg/other/i386-9.C: New test.
+
 2011-03-30  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
-       * go.test/go-test.exp (go-set-goarch): Use sparc64 for 64-bit
-       SPARC.
+       * go.test/go-test.exp (go-set-goarch): Use sparc64 for 64-bit SPARC.
 
 2011-03-30  Jason Merrill  <jason@redhat.com>
 
diff --git a/gcc/testsuite/g++.dg/other/i386-9.C b/gcc/testsuite/g++.dg/other/i386-9.C
new file mode 100644 (file)
index 0000000..7964057
--- /dev/null
@@ -0,0 +1,12 @@
+// PR target/48142
+// Testcase by Zdenek Sojka <zsojka@seznam.cz>
+
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-options "-Os -mpreferred-stack-boundary=5 -fstack-check -fno-omit-frame-pointer" }
+
+int main()
+{
+  try { throw 0; }
+  catch (...) {}
+  return 0;
+}