Hi all,

The PR shows us attaching REG_CFA_ADJUST_CFA notes to stack pointer
adjustments emitted in cmse_nonsecure_call_inline_register_clear (when
-march=armv8.1-m.main). However, the stack pointer is not guaranteed to
be the CFA reg. If we're at -O0 or we have -fno-omit-frame-pointer, then
the frame pointer will be used as the CFA reg, and these notes on the sp
adjustments will lead to ICEs in dwarf2out_frame_debug_adjust_cfa.

This patch avoids emitting these notes if the current function has a
frame pointer.

Testing:
 * Bootstrapped and regtested on arm-linux-gnueabihf, no regressions.
 * Regtested an arm-eabi cross configured with --with-arch=armv8.1-m.main, no
   regressions.

OK for trunk and backports as appropriate?

Thanks,
Alex

gcc/ChangeLog:

        PR target/99725
        * config/arm/arm.c (cmse_nonsecure_call_inline_register_clear):
        Avoid emitting CFA adjusts on the sp if we have the fp.

gcc/testsuite/ChangeLog:

        PR target/99725
        * gcc.target/arm/cmse/pr99725.c: New test.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0371d9818fd..2962071adfd 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -18774,10 +18774,14 @@ cmse_nonsecure_call_inline_register_clear (void)
                  imm = gen_int_mode (- lazy_store_stack_frame_size, SImode);
                  add_insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
                                                    stack_pointer_rtx, imm));
-                 arm_add_cfa_adjust_cfa_note (add_insn,
-                                              - lazy_store_stack_frame_size,
-                                              stack_pointer_rtx,
-                                              stack_pointer_rtx);
+                 /* If we have the frame pointer, then it will be the
+                    CFA reg.  Otherwise, the stack pointer is the CFA
+                    reg, so we need to emit a CFA adjust.  */
+                 if (!frame_pointer_needed)
+                   arm_add_cfa_adjust_cfa_note (add_insn,
+                                                - lazy_store_stack_frame_size,
+                                                stack_pointer_rtx,
+                                                stack_pointer_rtx);
                  emit_insn (gen_lazy_store_multiple_insn (stack_pointer_rtx));
                }
              /* Save VFP callee-saved registers.  */
@@ -18815,10 +18819,11 @@ cmse_nonsecure_call_inline_register_clear (void)
                  rtx_insn *add_insn =
                    emit_insn (gen_addsi3 (stack_pointer_rtx,
                                           stack_pointer_rtx, imm));
-                 arm_add_cfa_adjust_cfa_note (add_insn,
-                                              lazy_store_stack_frame_size,
-                                              stack_pointer_rtx,
-                                              stack_pointer_rtx);
+                 if (!frame_pointer_needed)
+                   arm_add_cfa_adjust_cfa_note (add_insn,
+                                                lazy_store_stack_frame_size,
+                                                stack_pointer_rtx,
+                                                stack_pointer_rtx);
                }
              /* Restore VFP callee-saved registers.  */
              else
diff --git a/gcc/testsuite/gcc.target/arm/cmse/pr99725.c 
b/gcc/testsuite/gcc.target/arm/cmse/pr99725.c
new file mode 100644
index 00000000000..284da184f96
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cmse/pr99725.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mcmse -g" } */
+typedef int __attribute__((cmse_nonsecure_call)) (*t)();
+t f;
+void g() { f(); }

Reply via email to