https://gcc.gnu.org/g:d03e12672200b90972cb0f6f592ac01be1ca6b7d
commit d03e12672200b90972cb0f6f592ac01be1ca6b7d Author: Alexandre Oliva <ol...@adacore.com> Date: Wed Dec 18 16:28:48 2024 -0300 expand: drop stack adjustments after barrier [PR118006] A block with __builtin_unreachable () can't have code after it, and gimple optimizers ensure there isn't any, even without optimization. But if the block requires stack adjustments, e.g. because of a call that passes arguments on the stack, we will emit that after the barrier, and then rtl checkers rightfully complain. Strub expanders seem to be necessary to bring about the exact conditions that require stack adjustments after the block that ends with a __builtin_unreachable call. for gcc/ChangeLog PR middle-end/118006 * cfgexpand.cc (expand_gimple_basic_block): Do not emit pending stack adjustments after a barrier. for gcc/testsuite/ChangeLog PR middle-end/118006 * gcc.target/i386/strub-pr118006.c: New. Diff: --- gcc/cfgexpand.cc | 10 +++++++++- gcc/testsuite/gcc.target/i386/strub-pr118006.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index ea08810df045..aaca6a781e0c 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -6216,7 +6216,15 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) emit_insn_after_noloc (gen_move_insn (dummy, dummy), last, NULL); } - do_pending_stack_adjust (); + /* A __builtin_unreachable () will insert a barrier that should end + the basic block. In gimple, any code after it will have already + deleted, even without optimization. If we emit additional code + here, as we would to adjust the stack after a call, it should be + eventually deleted, but it confuses internal checkers (PR118006) + and optimizers before it does, because we don't expect to find + barriers inside basic blocks. */ + if (!BARRIER_P (get_last_insn ())) + do_pending_stack_adjust (); /* Find the block tail. The last insn in the block is the insn before a barrier and/or table jump insn. */ diff --git a/gcc/testsuite/gcc.target/i386/strub-pr118006.c b/gcc/testsuite/gcc.target/i386/strub-pr118006.c new file mode 100644 index 000000000000..62aa63c08c62 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/strub-pr118006.c @@ -0,0 +1,16 @@ +/* { dg-require-effective-target strub } */ +/* { dg-do compile } */ +/* { dg-options "-fstrub=all -O2 -m32 -mno-accumulate-outgoing-args" } */ + +__attribute__((noipa)) +long _raw_syscall(void *, long, long) { + __builtin_abort(); +} + +static int privileged_traced_syscall() { + return _raw_syscall(0, 0, 0); +} + +__attribute__((noreturn)) void privileged_traced_raise() { + privileged_traced_syscall(); +}