public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r15-125] tree-inline: Add __builtin_stack_{save, restore} pair about inline calls with calls to alloca [PR1135
Date: Fri,  3 May 2024 07:45:33 +0000 (GMT)	[thread overview]
Message-ID: <20240503074533.32C4F385E836@sourceware.org> (raw)

https://gcc.gnu.org/g:7117e1f6bf6de25c1ff26c4d7abcc79b407ca221

commit r15-125-g7117e1f6bf6de25c1ff26c4d7abcc79b407ca221
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri May 3 09:44:30 2024 +0200

    tree-inline: Add __builtin_stack_{save,restore} pair about inline calls with calls to alloca [PR113596]
    
    The following patch adds save_NNN = __builtin_stack_save (); ...
    __builtin_stack_restore (save_NNN);
    pair around inline calls which call alloca (alloca calls because of
    VLA vars are ignored in that decision).
    The patch doesn't change anything on whether we try to inline such calls or
    not, it just fixes the behavior when we inline them despite those checks.
    The stack save/restore restores the behavior that alloca acquired regions
    are freed at the end of the containing call.
    
    2024-05-03  Jakub Jelinek  <jakub@redhat.com>
    
            PR middle-end/113596
            * tree-inline.cc (expand_call_inline): Emit __builtin_stack_save
            and __builtin_stack_restore calls around inlined functions which
            call alloca.
    
            * gcc.dg/pr113596.c: New test.
            * gcc.dg/tree-ssa/pr113596.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/pr113596.c          | 24 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr113596.c | 37 ++++++++++++++++++++++++++++++++
 gcc/tree-inline.cc                       | 34 +++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/pr113596.c b/gcc/testsuite/gcc.dg/pr113596.c
new file mode 100644
index 00000000000..19e0ab6dc46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr113596.c
@@ -0,0 +1,24 @@
+/* PR middle-end/113596 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+__attribute__((noipa)) void
+bar (char *p, int n)
+{
+  p[0] = 1;
+  p[n - 1] = 2;
+}
+
+static inline __attribute__((always_inline)) void
+foo (int n)
+{
+  char *p = __builtin_alloca (n);
+  bar (p, n);
+}
+
+int
+main ()
+{
+  for (int i = 2; i < 8192; ++i)
+    foo (i);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr113596.c b/gcc/testsuite/gcc.dg/tree-ssa/pr113596.c
new file mode 100644
index 00000000000..37626850628
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr113596.c
@@ -0,0 +1,37 @@
+/* PR middle-end/113596 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-einline" } */
+/* { dg-final { scan-tree-dump-times "__builtin_stack_save \\\(" 3 "einline" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_stack_restore \\\(" 3 "einline" } } */
+
+void baz (char *p, int n);
+volatile int v;
+
+static inline __attribute__((always_inline)) void
+foo (int n)
+{
+  ++v;
+  {
+    char *p = __builtin_alloca (n);
+    baz (p, n);
+  }
+  ++v;
+}
+
+static inline __attribute__((always_inline)) void
+bar (int n)
+{
+  ++v;
+  {
+    char p[n];
+    baz (p, n);
+  }
+  ++v;
+}
+
+void
+qux (int n)
+{
+  foo (n);
+  bar (n);
+}
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 238afb7de80..b9fe2099d4f 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -4794,6 +4794,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
   use_operand_p use;
   gimple *simtenter_stmt = NULL;
   vec<tree> *simtvars_save;
+  tree save_stack = NULL_TREE;
 
   /* The gimplifier uses input_location in too many places, such as
      internal_get_tmp_var ().  */
@@ -5042,6 +5043,28 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
 			GSI_NEW_STMT);
     }
 
+  /* If function to be inlined calls alloca, wrap the inlined function
+     in between save_stack = __builtin_stack_save (); and
+     __builtin_stack_restore (save_stack); calls.  */
+  if (id->src_cfun->calls_alloca && !gimple_call_noreturn_p (stmt))
+    /* Don't do this for VLA allocations though, just for user alloca
+       calls.  */
+    for (struct cgraph_edge *e = id->src_node->callees; e; e = e->next_callee)
+      if (gimple_maybe_alloca_call_p (e->call_stmt)
+	  && !gimple_call_alloca_for_var_p (e->call_stmt))
+	{
+	  tree fn = builtin_decl_implicit (BUILT_IN_STACK_SAVE);
+	  gcall *call = gimple_build_call (fn, 0);
+	  save_stack = make_ssa_name (ptr_type_node);
+	  gimple_call_set_lhs (call, save_stack);
+	  gimple_stmt_iterator si = gsi_last_bb (bb);
+	  gsi_insert_after (&si, call, GSI_NEW_STMT);
+	  struct cgraph_node *dest = cgraph_node::get_create (fn);
+	  id->dst_node->create_edge (dest, call, bb->count)->inline_failed
+	    = CIF_BODY_NOT_AVAILABLE;
+	  break;
+	}
+
   if (DECL_INITIAL (fn))
     {
       if (gimple_block (stmt))
@@ -5165,6 +5188,17 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
 	    }
 	}
 
+  if (save_stack)
+    {
+      tree fn = builtin_decl_implicit (BUILT_IN_STACK_RESTORE);
+      gcall *call = gimple_build_call (fn, 1, save_stack);
+      gsi_insert_before (&stmt_gsi, call, GSI_SAME_STMT);
+      struct cgraph_node *dest = cgraph_node::get_create (fn);
+      id->dst_node->create_edge (dest, call,
+				 return_block->count)->inline_failed
+	= CIF_BODY_NOT_AVAILABLE;
+    }
+
   /* Reset the escaped solution.  */
   if (cfun->gimple_df)
     {

                 reply	other threads:[~2024-05-03  7:45 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240503074533.32C4F385E836@sourceware.org \
    --to=jakub@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).