A gimple 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, expand will
emit that after the barrier, and then rtl checkers rightfully
complain. Arrange to discard adjustments after a barrier.
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.
Regstrapped on x86_64-linux-gnu. Ok to install?
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.
---
gcc/cfgexpand.cc | 12 +++++++++++-
gcc/testsuite/gcc.target/i386/strub-pr118006.c | 17 +++++++++++++++++
2 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/strub-pr118006.c
diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index ea08810df0457..b89ea999a8409 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -6216,7 +6216,17 @@ 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 ();
+ else
+ discard_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 0000000000000..6337ce10df31f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/strub-pr118006.c
@@ -0,0 +1,17 @@
+/* { 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);
+}
+
+void privileged_traced_raise() {
+ privileged_traced_syscall();
+ __builtin_unreachable ();
+}
--
Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/
Free Software Activist GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive