When traversing gimple to introduce CO-RE relocation entries to expressions that are accesses to attributed perserve_access_index types, the access is likely to be split in multiple gimple statments. In order to keep doing the proper CO-RE convertion we will need to mark the LHS tree nodes of gimple expressions as explicit CO-RE accesses, such that the gimple traverser will further convert the sub-expressions.
This patch makes sure that this LHS marking will not happen in case the gimple statement is a function call, which case it is no longer expecting to keep generating CO-RE accesses with the remaining of the expression. --- gcc/config/bpf/core-builtins.cc | 1 + .../gcc.target/bpf/core-attr-calls.c | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 gcc/testsuite/gcc.target/bpf/core-attr-calls.c diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc index 86e2e9d6e39..cdfb356660e 100644 --- a/gcc/config/bpf/core-builtins.cc +++ b/gcc/config/bpf/core-builtins.cc @@ -1822,6 +1822,7 @@ make_gimple_core_safe_access_index (tree *tp, tree lhs; if (!wi->is_lhs + && gimple_code (wi->stmt) != GIMPLE_CALL && (lhs = gimple_get_lhs (wi->stmt)) != NULL_TREE) core_mark_as_access_index (lhs); } diff --git a/gcc/testsuite/gcc.target/bpf/core-attr-calls.c b/gcc/testsuite/gcc.target/bpf/core-attr-calls.c new file mode 100644 index 00000000000..87290c5c211 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/core-attr-calls.c @@ -0,0 +1,49 @@ +/* Test for BPF CO-RE __attribute__((preserve_access_index)) with accesses on + LHS and both LHS and RHS of assignment with calls involved. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -dA -gbtf -mco-re -masm=normal" } */ + +struct U { + int c; + struct V { + int d; + int e[4]; + int f; + int *g; + } v; +}; + +struct T { + int a; + int b; + struct U u; + struct U *ptr_u; + struct U *array_u; +} __attribute__((preserve_access_index)); + +extern struct U *get_other_u(struct U *); +extern struct V *get_other_v(struct V *); + +void +func (struct T *t, int i) +{ + /* Since we are using the builtin all accesses are converted to CO-RE. */ + /* 0:3 0:0 */ + __builtin_preserve_access_index(({ get_other_u(t->ptr_u)->c = 42; })); + + /* This should not pass-through CO-RE accesses beyond the call since struct U + is not explicitly marked with preserve_access_index. */ + /* 0:3 */ + get_other_u(t->ptr_u)->c = 43; + + /* 0:2:1 */ + get_other_v(&t->u.v)->d = 44; +} + +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0:3\"\\)" 2 } } */ +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0:0\"\\)" 1 } } */ +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0:2:1\"\\)" 1 } } */ +/* { dg-final { scan-assembler-times "bpfcr_type \\(struct T\\)" 3 } } */ +/* { dg-final { scan-assembler-times "bpfcr_type \\(struct U\\)" 1 } } */ + -- 2.39.5