aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose E. Marchesi <jose.marchesi@oracle.com>2023-08-10 10:53:16 +0200
committerJose E. Marchesi <jose.marchesi@oracle.com>2023-08-11 20:34:56 +0200
commit6103df1e4fae5192c507484b1d32f00c42c70b54 (patch)
tree2bad387074928099025ef17642ff8af1216c02ce
parent38c00edd65c39b07166aa0913c79adb9bcac943c (diff)
downloadgcc-6103df1e4fae5192c507484b1d32f00c42c70b54.zip
gcc-6103df1e4fae5192c507484b1d32f00c42c70b54.tar.gz
gcc-6103df1e4fae5192c507484b1d32f00c42c70b54.tar.bz2
bpf: allow exceeding max num of args in BPF when always_inline
BPF currently limits the number of registers used to pass arguments to functions to five registers. There is a check for this at function expansion time. However, if a function is guaranteed to be always inlined (and its body never generated) by virtue of the always_inline attribute, it can "receive" any number of arguments. Tested in host x86_64-linux-gnu and target bpf-unknown-none. gcc/ChangeLog * config/bpf/bpf.cc (bpf_function_arg_advance): Do not complain about too many arguments if function is always inlined. gcc/testsuite/ChangeLog * gcc.target/bpf/diag-funargs-inline-1.c: New test. * gcc.target/bpf/diag-funargs.c: Adapt test.
-rw-r--r--gcc/config/bpf/bpf.cc9
-rw-r--r--gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c21
-rw-r--r--gcc/testsuite/gcc.target/bpf/diag-funargs.c8
3 files changed, 36 insertions, 2 deletions
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 33218b3..d27a971 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -732,7 +732,14 @@ bpf_function_arg_advance (cumulative_args_t ca,
unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD);
if (*cum <= 5 && *cum + num_words > 5)
- error ("too many function arguments for eBPF");
+ {
+ /* Too many arguments for BPF. However, if the function is
+ gonna be inline for sure, we let it pass. Otherwise, issue
+ an error. */
+ if (!lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (cfun->decl)))
+ error ("too many function arguments for eBPF");
+ }
*cum += num_words;
}
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c
new file mode 100644
index 0000000..e917ef1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+inline int __attribute__ ((always_inline))
+foo (int a1,
+ int a2,
+ int a3,
+ int a4,
+ int a5,
+ int a6)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6;
+}
+
+int
+bar (int i1, int i2, int i3, int i4, int i5)
+{
+ return foo (i1, i2, i3, i4, i5, 10);
+}
+
+/* { dg-final { scan-assembler-not "call\t.*" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs.c b/gcc/testsuite/gcc.target/bpf/diag-funargs.c
index d4e9c06..42b5f05 100644
--- a/gcc/testsuite/gcc.target/bpf/diag-funargs.c
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs.c
@@ -11,5 +11,11 @@ foo (int a1, /* { dg-error "too many function arguments" } */
int a5,
int a6)
{
- return a6;
+ return a1 + a2 + a3 + a4 + a5 + a6;
+}
+
+int
+bar (int i1, int i2, int i3, int i4, int i5)
+{
+ return foo (i1, i2, i3, i4, i5, 10);
}