From f34141730266600b615b91d563a85a0b60223b3e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 9 Jan 2024 10:14:29 +0100 Subject: [PATCH] Fix segfault during delay slot scheduling pass This is a small regression present on the mainline and 13 branch, although the underlying problem has probably been there for ages, in the form of a segfault during the delay slot scheduling pass, for a function that falls through to exit without any instruction generated for the end of function. gcc/ PR rtl-optimization/113140 * reorg.cc (fill_slots_from_thread): If we are to branch after the last instruction of the function, create an end label. gcc/testsuite/ * g++.dg/opt/delay-slot-2.C: New test. --- gcc/reorg.cc | 13 ++++++++----- gcc/testsuite/g++.dg/opt/delay-slot-2.C | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/delay-slot-2.C diff --git a/gcc/reorg.cc b/gcc/reorg.cc index e85af7134f4..99228a22c69 100644 --- a/gcc/reorg.cc +++ b/gcc/reorg.cc @@ -2641,7 +2641,8 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, arithmetic insn after the jump insn and put the arithmetic insn in the delay slot. If we can't do this, return. */ if (delay_list->is_empty () && likely - && new_thread && !ANY_RETURN_P (new_thread) + && new_thread + && !ANY_RETURN_P (new_thread) && NONJUMP_INSN_P (new_thread) && !RTX_FRAME_RELATED_P (new_thread) && GET_CODE (PATTERN (new_thread)) != ASM_INPUT @@ -2729,14 +2730,16 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, gcc_assert (thread_if_true); - if (new_thread && simplejump_or_return_p (new_thread) + if (new_thread + && simplejump_or_return_p (new_thread) && redirect_with_delay_list_safe_p (insn, JUMP_LABEL (new_thread), *delay_list)) - new_thread = follow_jumps (JUMP_LABEL (new_thread), insn, - &crossing); + new_thread = follow_jumps (JUMP_LABEL (new_thread), insn, &crossing); - if (ANY_RETURN_P (new_thread)) + if (!new_thread) + label = find_end_label (simple_return_rtx); + else if (ANY_RETURN_P (new_thread)) label = find_end_label (new_thread); else if (LABEL_P (new_thread)) label = new_thread; diff --git a/gcc/testsuite/g++.dg/opt/delay-slot-2.C b/gcc/testsuite/g++.dg/opt/delay-slot-2.C new file mode 100644 index 00000000000..3810503b1a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/delay-slot-2.C @@ -0,0 +1,32 @@ +// PR rtl-optimization/113140 +// Reduced testcase by Rainer Orth + +// { dg-options "-O -w" } + +int *m(); +struct StaticValue { + long _val; + void setM(int *) { _val = 0; } +}; +struct Value : StaticValue { + template T *as(); +}; +Value *alloc(); +struct Scoped { + Scoped() { + Value v; + ptr = alloc(); + Value *__trans_tmp_1 = v.as(); + ptr->setM(__trans_tmp_1 ? m() : 0); + } + Value *ptr; +}; +struct QObjectMethod { + unsigned long long callInternal() const; +}; +unsigned long long QObjectMethod::callInternal() const { + [] { + if (Scoped(); 0) + ; + }(); +} -- 2.11.4.GIT