dce: Don't dead-code delete separately wrapped restores
authorSegher Boessenkool <segher@kernel.crashing.org>
Wed, 12 Oct 2016 15:21:38 +0000 (17:21 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Wed, 12 Oct 2016 15:21:38 +0000 (17:21 +0200)
If there is a separately wrapped register restore on some path that
is dead (say, control goes into an endless loop after it), then we
cannot delete that restore because that would confuse the DWARF CFI
(if there is another path joining).
This happens with gcc.dg/torture/pr53168.c, for example.

* dce.c (delete_unmarked_insns): Don't delete instructions with
a REG_CFA_RESTORE note.

From-SVN: r241060

gcc/ChangeLog
gcc/dce.c

index 323bf353a1cb0f666a73bde8016cca984c360fb4..77935447474ae2944bc05a600d0ecb702afcc073 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-12  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       * dce.c (delete_unmarked_insns): Don't delete instructions with
+       a REG_CFA_RESTORE note.
+
 2016-10-12  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * common.opt (-fshrink-wrap-separate): New flag.
index ea3fb00d433f60c4d58106ec917bc8d6a31f5aac..d5102873f60015a1c4c0eed3c09fe31b9c103e92 100644 (file)
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -587,6 +587,15 @@ delete_unmarked_insns (void)
          if (!dbg_cnt (dce))
            continue;
 
+         if (crtl->shrink_wrapped_separate
+             && find_reg_note (insn, REG_CFA_RESTORE, NULL))
+           {
+             if (dump_file)
+               fprintf (dump_file, "DCE: NOT deleting insn %d, it's a "
+                                   "callee-save restore\n", INSN_UID (insn));
+             continue;
+           }
+
          if (dump_file)
            fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));