Pushed to upstream master.
Thanks ! Jose E. Marchesi writes: > OK. > Thanks. > >> Hi, >> >> Resending this patch since I have noticed I had a testcase added in >> previous patch. Makes more sense here. >> >> Thanks, >> Cupertino >> >> From 334e9ae0f428f6573f2a5e8a3067a4d181b8b9c5 Mon Sep 17 00:00:00 2001 >> From: Cupertino Miranda <cupertino.mira...@oracle.com> >> Date: Thu, 27 Jul 2023 18:05:22 +0100 >> Subject: [PATCH v2 2/2] bpf: CO-RE builtins support tests. >> >> This patch adds tests for the following builtins: >> __builtin_preserve_enum_value >> __builtin_btf_type_id >> __builtin_preserve_type_info >> --- >> .../gcc.target/bpf/core-builtin-enumvalue.c | 52 +++++++++ >> .../bpf/core-builtin-enumvalue_errors.c | 22 ++++ >> .../bpf/core-builtin-enumvalue_opt.c | 35 ++++++ >> ...core-builtin-fieldinfo-const-elimination.c | 29 +++++ >> .../bpf/core-builtin-fieldinfo-errors-1.c | 2 +- >> .../bpf/core-builtin-fieldinfo-errors-2.c | 2 +- >> .../gcc.target/bpf/core-builtin-type-based.c | 58 ++++++++++ >> .../gcc.target/bpf/core-builtin-type-id.c | 40 +++++++ >> gcc/testsuite/gcc.target/bpf/core-support.h | 109 ++++++++++++++++++ >> 9 files changed, 347 insertions(+), 2 deletions(-) >> create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c >> create mode 100644 >> gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c >> create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_opt.c >> create mode 100644 >> gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c >> create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c >> create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-type-id.c >> create mode 100644 gcc/testsuite/gcc.target/bpf/core-support.h >> >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c >> new file mode 100644 >> index 000000000000..3e3334dc089a >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c >> @@ -0,0 +1,52 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O0 -dA -gbtf -mco-re" } */ >> + >> +#include "core-support.h" >> + >> +extern int *v; >> + >> +int foo(void *data) >> +{ >> + int i = 0; >> + enum named_ue64 named_unsigned64 = 0; >> + enum named_se64 named_signed64 = 0; >> + enum named_ue named_unsigned = 0; >> + enum named_se named_signed = 0; >> + >> + v[i++] = bpf_core_enum_value_exists (named_unsigned64, UE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_ue64, UE64_VAL2); >> + v[i++] = bpf_core_enum_value_exists (enum named_ue64, UE64_VAL3); >> + v[i++] = bpf_core_enum_value_exists (named_signed64, SE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_se64, SE64_VAL2); >> + v[i++] = bpf_core_enum_value_exists (enum named_se64, SE64_VAL3); >> + >> + v[i++] = bpf_core_enum_value (named_unsigned64, UE64_VAL1); >> + v[i++] = bpf_core_enum_value (named_unsigned64, UE64_VAL2); >> + v[i++] = bpf_core_enum_value (named_signed64, SE64_VAL1); >> + v[i++] = bpf_core_enum_value (named_signed64, SE64_VAL2); >> + >> + v[i++] = bpf_core_enum_value_exists (named_unsigned, UE_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_ue, UE_VAL2); >> + v[i++] = bpf_core_enum_value_exists (enum named_ue, UE_VAL3); >> + v[i++] = bpf_core_enum_value_exists (named_signed, SE_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_se, SE_VAL2); >> + v[i++] = bpf_core_enum_value_exists (enum named_se, SE_VAL3); >> + >> + v[i++] = bpf_core_enum_value (named_unsigned, UE_VAL1); >> + v[i++] = bpf_core_enum_value (named_unsigned, UE_VAL2); >> + v[i++] = bpf_core_enum_value (named_signed, SE_VAL1); >> + v[i++] = bpf_core_enum_value (named_signed, SE_VAL2); >> + >> + return 0; >> +} >> + >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x8\t; bpfcr_type >> \\(named_ue64\\)" 5 } } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x9\t; bpfcr_type >> \\(named_se64\\)" 5} } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_type >> \\(named_ue\\)" 5 } } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xc\t; bpfcr_type >> \\(named_se\\)" 5} } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 12 } } >> BPF_ENUMVAL_EXISTS */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 8 } } >> BPF_ENUMVAL_VALUE */ >> + >> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0\"\\)" 8 } } */ >> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"1\"\\)" 8 } } */ >> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"2\"\\)" 4 } } */ >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c >> new file mode 100644 >> index 000000000000..138e99895160 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c >> @@ -0,0 +1,22 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O0 -dA -gbtf -mco-re" } */ >> + >> +#include "core-support.h" >> + >> +extern int *v; >> + >> +unsigned long foo(void *data) >> +{ >> + int i = 0; >> + enum named_ue64 named_unsigned = 0; >> + enum named_se64 named_signed = 0; >> + typeof(enum named_ue64) a = 0; >> + >> + v[i++] = __builtin_preserve_enum_value (({ extern typeof(named_unsigned) >> *_type0; _type0; }), 0, BPF_ENUMVAL_EXISTS); /* { dg-error "invalid >> enum value argument for enum value builtin" } */ >> + v[i++] = __builtin_preserve_enum_value (({ extern typeof(enum named_ue64) >> *_type0; _type0; }), v, BPF_ENUMVAL_EXISTS); /* { dg-error "invalid enum >> value argument for enum value builtin" } */ >> + v[i++] = __builtin_preserve_enum_value (a, >> UE64_VAL3, BPF_ENUMVAL_EXISTS); /* { dg-error >> "invalid type argument format for enum value builtin" } */ >> + v[i++] = __builtin_preserve_enum_value (UE64_VAL3); /* { dg-error "wrong >> number of arguments for enum value core builtin" } */ >> + >> + >> + return 0; >> +} >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_opt.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_opt.c >> new file mode 100644 >> index 000000000000..363ad0c41ecc >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_opt.c >> @@ -0,0 +1,35 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -dA -gbtf -mco-re" } */ >> + >> +#include "core-support.h" >> + >> +extern int *v; >> + >> +unsigned long foo(void *data) >> +{ >> + enum named_ue64 named_unsigned = 0; >> + enum named_se64 named_signed = 0; >> + int i = 0; >> + >> + v[i++] = bpf_core_enum_value_exists (named_unsigned, UE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_ue64, UE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_ue64, UE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (named_signed, SE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_se64, SE64_VAL1); >> + v[i++] = bpf_core_enum_value_exists (enum named_se64, SE64_VAL1); >> + >> + v[i++] = bpf_core_enum_value (named_unsigned, UE64_VAL1); >> + v[i++] = bpf_core_enum_value (named_unsigned, UE64_VAL1); >> + v[i++] = bpf_core_enum_value (named_signed, SE64_VAL1); >> + v[i++] = bpf_core_enum_value (named_signed, SE64_VAL1); >> + >> + return 0; >> +} >> + >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x8\t; bpfcr_type >> \\(named_ue64\\)" 2 } } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x9\t; bpfcr_type >> \\(named_se64\\)" 2} } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 2 } } >> BPF_ENUMVAL_EXISTS */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 2 } } >> BPF_ENUMVAL_VALUE */ >> + >> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0\"\\)" 4 } } */ >> + >> diff --git >> a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c >> new file mode 100644 >> index 000000000000..5f8354874830 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c >> @@ -0,0 +1,29 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -dA -gbtf -mco-re" } */ >> + >> +struct S { >> + unsigned int a1: 7; >> + unsigned int a2: 4; >> + unsigned int a3: 13; >> + unsigned int a4: 5; >> + int x; >> +}; >> + >> +struct T { >> + unsigned int y; >> + struct S s[2]; >> + char c; >> + char d; >> +}; >> + >> +enum { >> + FIELD_BYTE_OFFSET = 0, >> +}; >> + >> +unsigned int foo (struct T *t) >> +{ >> + return __builtin_preserve_field_info (t->s[0].a1, FIELD_BYTE_OFFSET) + 1; >> +} >> + >> +/* { dg-final { scan-assembler-times "\[\t \]mov\[\t \]%r\[0-9\],4" 1 } } */ >> +/* { dg-final { scan-assembler-times "\[\t \]add32\[\t \]%r\[0-9\],1" 1 } } >> */ >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-1.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-1.c >> index 2c67c3840047..6f8c320ab8b6 100644 >> --- a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-1.c >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-1.c >> @@ -17,7 +17,7 @@ unsigned int test (struct F *f) { >> >> unsigned x = __builtin_preserve_field_info (f->arr, FIELD_BYTE_SIZE); /* >> { dg-error "unsupported variable size field access" } */ >> >> - unsigned y = __builtin_preserve_field_info (f->baz, 99); /* { dg-error >> "invalid second argument to built-in function" } */ >> + unsigned y = __builtin_preserve_field_info (f->baz, 99); /* { dg-error >> "invalid kind argument to core builtin" } */ >> >> return x + y; >> } >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-2.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-2.c >> index 31d7a03b7579..08fbdf016553 100644 >> --- a/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-2.c >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-errors-2.c >> @@ -17,7 +17,7 @@ int test (struct F *f) { >> unsigned x = __builtin_preserve_field_info (({ a = f->bar + f->baz; }), >> FIELD_BYTE_OFFSET); /* { dg-error "argument is not a field access" } */ >> >> int b; >> - unsigned y = __builtin_preserve_field_info (&(f->c), FIELD_BYTE_SIZE); /* >> { dg-error "argument is not a field access" } */ >> + unsigned y = __builtin_preserve_field_info (&(f->c), FIELD_BYTE_SIZE); /* >> { dg-error "argument is not a field access" "" { xfail *-*-* } } */ >> >> return a + b + x + y; >> } >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c >> new file mode 100644 >> index 000000000000..16b48ae0a00d >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c >> @@ -0,0 +1,58 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O0 -dA -gbtf -mco-re" } */ >> + >> +#include "core-support.h" >> + >> +extern int *v; >> + >> +int foo(void *data) >> +{ >> + int i = 0; >> + >> + v[i++] = bpf_core_type_exists (struct my_struct); >> + v[i++] = bpf_core_type_exists (struct my_complex_struct); >> + v[i++] = bpf_core_type_exists (union my_union); >> + v[i++] = bpf_core_type_exists (enum my_enum); >> + v[i++] = bpf_core_type_exists (named_struct_tdef); >> + v[i++] = bpf_core_type_exists (anon_struct_tdef); >> + v[i++] = bpf_core_type_exists (struct_ptr_tdef); >> + v[i++] = bpf_core_type_exists (int_tdef); >> + v[i++] = bpf_core_type_exists (enum_tdef); >> + v[i++] = bpf_core_type_exists (void_ptr_tdef); >> + v[i++] = bpf_core_type_exists (restrict_ptr_tdef); >> + v[i++] = bpf_core_type_exists (func_tdef); >> + v[i++] = bpf_core_type_exists (array_tdef); >> + >> + v[i++] = bpf_core_type_matches (struct my_struct); >> + v[i++] = bpf_core_type_matches (struct my_complex_struct); >> + v[i++] = bpf_core_type_matches (union my_union); >> + v[i++] = bpf_core_type_matches (enum my_enum); >> + v[i++] = bpf_core_type_matches (named_struct_tdef); >> + v[i++] = bpf_core_type_matches (anon_struct_tdef); >> + v[i++] = bpf_core_type_matches (struct_ptr_tdef); >> + v[i++] = bpf_core_type_matches (int_tdef); >> + v[i++] = bpf_core_type_matches (enum_tdef); >> + v[i++] = bpf_core_type_matches (void_ptr_tdef); >> + v[i++] = bpf_core_type_matches (restrict_ptr_tdef); >> + v[i++] = bpf_core_type_matches (func_tdef); >> + v[i++] = bpf_core_type_matches (array_tdef); >> + >> + v[i++] = bpf_core_type_size (struct my_struct); >> + v[i++] = bpf_core_type_size (union my_union); >> + v[i++] = bpf_core_type_size (enum my_enum); >> + v[i++] = bpf_core_type_size (named_struct_tdef); >> + v[i++] = bpf_core_type_size (anon_struct_tdef); >> + v[i++] = bpf_core_type_size (struct_ptr_tdef); >> + v[i++] = bpf_core_type_size (int_tdef); >> + v[i++] = bpf_core_type_size (enum_tdef); >> + v[i++] = bpf_core_type_size (void_ptr_tdef); >> + v[i++] = bpf_core_type_size (func_tdef); >> + v[i++] = bpf_core_type_size (array_tdef); >> + >> + return 0; >> +} >> + >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x0\t; bpfcr_type" 0 } } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x8\t; bpfcr_kind" 13 } } >> BPF_TYPE_EXISTS */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x9\t; bpfcr_kind" 11 } } >> BPF_TYPE_SIZE */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0xc\t; bpfcr_kind" 13 } } >> BPF_TYPE_MATCHES */ >> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-type-id.c >> b/gcc/testsuite/gcc.target/bpf/core-builtin-type-id.c >> new file mode 100644 >> index 000000000000..615bbc85a22c >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-type-id.c >> @@ -0,0 +1,40 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O0 -dA -gbtf -mco-re" } */ >> + >> +#include "core-support.h" >> + >> +extern int *v; >> + >> +int foo(void *data) >> +{ >> + int i = 0; >> + >> + v[i++] = bpf_core_type_id_local (struct { int a; }); >> + v[i++] = bpf_core_type_id_local (union { int a; }); >> + v[i++] = bpf_core_type_id_local (enum { A = 1 }); >> + v[i++] = bpf_core_type_id_local (char(*)(int)); >> + v[i++] = bpf_core_type_id_local (void *); >> + v[i++] = bpf_core_type_id_local (char[10]); >> + >> + v[i++] = bpf_core_type_id_local (struct my_struct); >> + v[i++] = bpf_core_type_id_local (union my_union); >> + v[i++] = bpf_core_type_id_local (enum my_enum); >> + v[i++] = bpf_core_type_id_local (int); >> + v[i++] = bpf_core_type_id_local (named_struct_tdef); >> + v[i++] = bpf_core_type_id_local (func_tdef); >> + v[i++] = bpf_core_type_id_local (array_tdef); >> + >> + v[i++] = bpf_core_type_id_target (struct my_struct); >> + v[i++] = bpf_core_type_id_target (union my_union); >> + v[i++] = bpf_core_type_id_target (enum my_enum); >> + v[i++] = bpf_core_type_id_target (int); >> + v[i++] = bpf_core_type_id_target (named_struct_tdef); >> + v[i++] = bpf_core_type_id_target (func_tdef); >> + v[i++] = bpf_core_type_id_target (array_tdef); >> + >> + return 0; >> +} >> + >> +/* { dg-final { scan-assembler-times "\t.4byte\t0\t; bpfcr_type" 0 { xfail >> *-*-* } } } */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x6\t; bpfcr_kind" 13 } } >> BPF_TYPE_ID_LOCAL */ >> +/* { dg-final { scan-assembler-times "\t.4byte\t0x7\t; bpfcr_kind" 7 } } >> BPF_TYPE_ID_TARGET */ >> diff --git a/gcc/testsuite/gcc.target/bpf/core-support.h >> b/gcc/testsuite/gcc.target/bpf/core-support.h >> new file mode 100644 >> index 000000000000..e030aa5ebf84 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/bpf/core-support.h >> @@ -0,0 +1,109 @@ >> +struct my_struct { >> + int a; >> +}; >> + >> +union my_union { >> + int b; >> + int c; >> +}; >> + >> +typedef struct my_struct named_struct_tdef; >> +typedef int (*func_tdef)(void *); >> + >> +typedef struct { >> + int d, e; >> +} *tdef_struct_ptr; >> + >> +enum my_enum { >> + MY_ENUM_VAL1 = 1, >> + MY_ENUM_VAL2 = 2, >> +}; >> +typedef enum { TE1, TE2, TE3 } enum_tdef; >> + >> +typedef int int_tdef; >> +typedef void *void_ptr_tdef; >> +typedef int *restrict restrict_ptr_tdef; >> +typedef int (*func_tdef)(void *); >> +typedef char array_tdef[10]; >> + >> +struct my_complex_struct { >> + int a; >> + int b; >> + union { >> + int *a; >> + struct my_struct *s; >> + } c; >> +}; >> + >> +typedef struct { >> + int a; >> +} anon_struct_tdef; >> + >> +typedef struct my_struct *struct_ptr_tdef; >> + >> +enum named_ue64 { >> + UE64_VAL1 = 0x1ffffffffULL, >> + UE64_VAL2 = 0x01fffffffULL, >> + UE64_VAL3 = 0x001ffffffULL, >> +}; >> + >> +enum named_se64 { >> + SE64_VAL1 = 0x1ffffffffLL, >> + SE64_VAL2 = 0x01fffffffLL, >> + SE64_VAL3 = -1, >> +}; >> + >> +enum named_ue { >> + UE_VAL1 = 0x1ffffff, >> + UE_VAL2 = 0x01fffff, >> + UE_VAL3 = 0x001ffff, >> +}; >> + >> +enum named_se { >> + SE_VAL1 = 0x1fffffff, >> + SE_VAL2 = 0x01ffffff, >> + SE_VAL3 = -1, >> +}; >> + >> + >> +/* BPF specific code */ >> + >> +enum bpf_type_id_kind { >> + BPF_TYPE_ID_LOCAL = 0, >> + BPF_TYPE_ID_TARGET = 1, >> +}; >> + >> +enum bpf_type_info_kind { >> + BPF_TYPE_EXISTS = 0, >> + BPF_TYPE_SIZE = 1, >> + BPF_TYPE_MATCHES = 2, >> +}; >> + >> +enum bpf_enum_value_kind { >> + BPF_ENUMVAL_EXISTS = 0, >> + BPF_ENUMVAL_VALUE = 1, >> +}; >> + >> +#define COMPOSE_VAR(t,s) t##s >> +#define bpf_type1(type, NR) ({ \ >> + extern typeof(type) *COMPOSE_VAR(bpf_type_tmp_, NR); \ >> + COMPOSE_VAR(bpf_type_tmp_, NR); \ >> +}) >> +#define bpf_type(type) bpf_type1(type, __COUNTER__) >> + >> +#define bpf_core_type_id_local(type) >> \ >> + __builtin_btf_type_id(*bpf_type(type), BPF_TYPE_ID_LOCAL) >> +#define bpf_core_type_id_target(type) >> \ >> + __builtin_btf_type_id(*bpf_type(type), BPF_TYPE_ID_TARGET) >> + >> +#define bpf_core_type_exists(type) \ >> + __builtin_preserve_type_info(*bpf_type(type), BPF_TYPE_EXISTS) >> +#define bpf_core_type_matches(type) \ >> + __builtin_preserve_type_info(*bpf_type(type), BPF_TYPE_MATCHES) >> +#define bpf_core_type_size(type) \ >> + __builtin_preserve_type_info(*bpf_type(type), BPF_TYPE_SIZE) >> + >> +#define bpf_core_enum_value_exists(enum_type, enum_value) \ >> + __builtin_preserve_enum_value(bpf_type(enum_type), enum_value, >> BPF_ENUMVAL_EXISTS) >> +#define bpf_core_enum_value(enum_type, enum_value) \ >> + __builtin_preserve_enum_value(bpf_type(enum_type), enum_value, >> BPF_ENUMVAL_VALUE)