]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/60264 (ARM ICE in dwarf2out_frame_debug_adjust_cfa, at dwarf2cfi.c:1090)
authorChristian Bruel <christian.bruel@st.com>
Wed, 12 Mar 2014 11:31:19 +0000 (12:31 +0100)
committerChristian Bruel <chrbr@gcc.gnu.org>
Wed, 12 Mar 2014 11:31:19 +0000 (12:31 +0100)
2014-03-12  Christian Bruel  <christian.bruel@st.com>

        PR target/60264
        * config/arm/arm.c (arm_emit_vfp_multi_reg_pop): Emit a REG_CFA_DEF_CFA
        note.
        (arm_expand_epilogue_apcs_frame): call arm_add_cfa_adjust_cfa_note.
        (arm_unwind_emit): Allow REG_CFA_DEF_CFA.

From-SVN: r208511

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr60264.c [new file with mode: 0644]

index c76fc807dd4159f81815195fced3f35e39de90be..05127c811cfa0d0f9b0366eb2b8f33e5760436c9 100644 (file)
@@ -1,3 +1,11 @@
+2014-03-12  Christian Bruel  <christian.bruel@st.com>
+
+       PR target/60264
+       * config/arm/arm.c (arm_emit_vfp_multi_reg_pop): Emit a REG_CFA_DEF_CFA
+       note.
+       (arm_expand_epilogue_apcs_frame): call arm_add_cfa_adjust_cfa_note.
+       (arm_unwind_emit): Allow REG_CFA_DEF_CFA.
+
 2014-03-12  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        PR tree-optimization/60454
index af5666bfb1246029cb4d614cfdcde644cef3e2b6..a68ed8da1ca4c41796801be5ce2a16654371be71 100644 (file)
@@ -19914,8 +19914,15 @@ arm_emit_vfp_multi_reg_pop (int first_reg, int num_regs, rtx base_reg)
   par = emit_insn (par);
   REG_NOTES (par) = dwarf;
 
-  arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs,
-                              base_reg, base_reg);
+  /* Make sure cfa doesn't leave with IP_REGNUM to allow unwinding fron FP.  */
+  if (TARGET_VFP && REGNO (base_reg) == IP_REGNUM)
+    {
+      RTX_FRAME_RELATED_P (par) = 1;
+      add_reg_note (par, REG_CFA_DEF_CFA, hard_frame_pointer_rtx);
+    }
+  else
+    arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs,
+                                base_reg, base_reg);
 }
 
 /* Generate and emit a pattern that will be recognized as LDRD pattern.  If even
@@ -27108,15 +27115,19 @@ arm_expand_epilogue_apcs_frame (bool really_return)
   if (TARGET_HARD_FLOAT && TARGET_VFP)
     {
       int start_reg;
+      rtx ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
 
       /* The offset is from IP_REGNUM.  */
       int saved_size = arm_get_vfp_saved_size ();
       if (saved_size > 0)
         {
+         rtx insn;
           floats_from_frame += saved_size;
-          emit_insn (gen_addsi3 (gen_rtx_REG (SImode, IP_REGNUM),
-                                 hard_frame_pointer_rtx,
-                                 GEN_INT (-floats_from_frame)));
+          insn = emit_insn (gen_addsi3 (ip_rtx,
+                                       hard_frame_pointer_rtx,
+                                       GEN_INT (-floats_from_frame)));
+         arm_add_cfa_adjust_cfa_note (insn, -floats_from_frame,
+                                      ip_rtx, hard_frame_pointer_rtx);
         }
 
       /* Generate VFP register multi-pop.  */
@@ -27189,11 +27200,15 @@ arm_expand_epilogue_apcs_frame (bool really_return)
   num_regs = bit_count (saved_regs_mask);
   if ((offsets->outgoing_args != (1 + num_regs)) || cfun->calls_alloca)
     {
+      rtx insn;
       emit_insn (gen_blockage ());
       /* Unwind the stack to just below the saved registers.  */
-      emit_insn (gen_addsi3 (stack_pointer_rtx,
-                             hard_frame_pointer_rtx,
-                             GEN_INT (- 4 * num_regs)));
+      insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+                                   hard_frame_pointer_rtx,
+                                   GEN_INT (- 4 * num_regs)));
+
+      arm_add_cfa_adjust_cfa_note (insn, - 4 * num_regs,
+                                  stack_pointer_rtx, hard_frame_pointer_rtx);
     }
 
   arm_emit_multi_reg_pop (saved_regs_mask);
@@ -28985,11 +29000,11 @@ arm_unwind_emit (FILE * asm_out_file, rtx insn)
           emit unwind information for it because these are used either for
           pretend arguments or notes to adjust sp and restore registers from
           stack.  */
+       case REG_CFA_DEF_CFA:
        case REG_CFA_ADJUST_CFA:
        case REG_CFA_RESTORE:
          return;
 
-       case REG_CFA_DEF_CFA:
        case REG_CFA_EXPRESSION:
        case REG_CFA_OFFSET:
          /* ??? Only handling here what we actually emit.  */
index dde17b02a9eff1bad6adc4f16169ba73ea674f64..154ebc6254d296934edf7db03e4834a24f14bf6a 100644 (file)
@@ -1,3 +1,8 @@
+2014-03-12  Christian Bruel  <christian.bruel@st.com>
+
+       PR target/60264
+       * gcc.target/arm/pr60264.c
+
 2014-03-12  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        PR tree-optimization/60454
diff --git a/gcc/testsuite/gcc.target/arm/pr60264.c b/gcc/testsuite/gcc.target/arm/pr60264.c
new file mode 100644 (file)
index 0000000..4fe6aed
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mapcs -g" } */
+
+double bar(void);
+
+int foo(void)
+{
+  int i = bar() + bar();
+
+  return i;
+}
+