https://gcc.gnu.org/g:713299077407bd1472e14fa10a8d4565932da8da
commit r16-3495-g713299077407bd1472e14fa10a8d4565932da8da Author: Yoshinori Sato <yoshinori.s...@nifty.com> Date: Mon Sep 1 11:12:17 2025 -0600 PR target/89828 Inernal compiler error on "-fno-omit-frame-pointer" The problem was caused by an erroneous note about creating a stack frame, which caused the cur_cfa reg to fail to assert with a value other than the frame pointer. This fix will generate notes that correctly update cur_cfa. v2 changes. Add testcase. All tests that failed with "internal compiler error: in dwarf2out_frame_debug_adjust_cfa, at dwarf2cfi.cc" now pass. PR target/89828 gcc * config/rx/rx.cc (add_pop_cfi_notes): Release the frame pointer if it is used. (rx_expand_prologue): Redesigned stack pointer and frame pointer update process. gcc/testsuite/ * gcc.dg/pr89828.c: New. Diff: --- gcc/config/rx/rx.cc | 49 +++++++++++++++--------------------------- gcc/testsuite/gcc.dg/pr89828.c | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 32 deletions(-) diff --git a/gcc/config/rx/rx.cc b/gcc/config/rx/rx.cc index dd730dca3c01..c5638817d08c 100644 --- a/gcc/config/rx/rx.cc +++ b/gcc/config/rx/rx.cc @@ -1648,16 +1648,20 @@ mark_frame_related (rtx insn) static void add_pop_cfi_notes (rtx_insn *insn, unsigned int high, unsigned int low) { - rtx t = plus_constant (Pmode, stack_pointer_rtx, - (high - low + 1) * UNITS_PER_WORD); + rtx src = stack_pointer_rtx; + rtx t; + for (unsigned int i = low; i <= high; i++) + { + add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (word_mode, i)); + if (i == FRAME_POINTER_REGNUM && frame_pointer_needed) + src = frame_pointer_rtx; + } + t = plus_constant (Pmode, src, (high - low + 1) * UNITS_PER_WORD); t = gen_rtx_SET (stack_pointer_rtx, t); add_reg_note (insn, REG_CFA_ADJUST_CFA, t); RTX_FRAME_RELATED_P (insn) = 1; - for (unsigned int i = low; i <= high; i++) - add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (word_mode, i)); } - static bool ok_for_max_constant (HOST_WIDE_INT val) { @@ -1816,36 +1820,17 @@ rx_expand_prologue (void) } } - /* If needed, set up the frame pointer. */ - if (frame_pointer_needed) - gen_safe_add (frame_pointer_rtx, stack_pointer_rtx, - GEN_INT (- (HOST_WIDE_INT) frame_size), true); - - /* Allocate space for the outgoing args. - If the stack frame has not already been set up then handle this as well. */ - if (stack_size) + if (stack_size || frame_size) { - if (frame_size) - { - if (frame_pointer_needed) - gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, - GEN_INT (- (HOST_WIDE_INT) stack_size), true); - else - gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (- (HOST_WIDE_INT) (frame_size + stack_size)), - true); - } - else - gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (- (HOST_WIDE_INT) stack_size), true); + gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (- (HOST_WIDE_INT) (stack_size + frame_size)), + true); } - else if (frame_size) + if (frame_pointer_needed) { - if (! frame_pointer_needed) - gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (- (HOST_WIDE_INT) frame_size), true); - else - gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX, true); + gen_safe_add (frame_pointer_rtx, stack_pointer_rtx, + GEN_INT ((HOST_WIDE_INT) stack_size), + true); } } diff --git a/gcc/testsuite/gcc.dg/pr89828.c b/gcc/testsuite/gcc.dg/pr89828.c new file mode 100644 index 000000000000..d41fbae4cfab --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr89828.c @@ -0,0 +1,49 @@ +/* { dg-do compile { target rx-*-* } } */ +/* { dg-options "-O2 -g -fno-omit-frame-pointer" } */ +struct baz; +struct foo { + struct baz *c; + unsigned int flags; +}; +struct bar { + const struct bar *b; + void (*func)(struct foo *a, struct baz *c, int flags); +}; +struct baz { + int flag; + const struct bar *b; +}; +static inline +__attribute__((always_inline)) +__attribute__((no_instrument_function)) void inline1(struct foo *a) +{ + a->flags |= 1; +} +static inline +__attribute__((always_inline)) +__attribute__((no_instrument_function)) int inline2(struct baz *c) +{ + return c->flag == 1; +} +extern const struct bar _bar; +extern void func(struct foo *a); +void pr89828(struct foo *a, struct baz *c, int flags) +{ + const struct bar *b; + + if (c->b == a->c->b) { + a->c->b->func(a, c, flags); + } else { + for (b = (&_bar); b; b = b->b) { + if (b == a->c->b) + break; + if (b == c->b) { + func(a); + break; + } + } + } + + if (inline2(a->c)) + inline1(a); +}