https://gcc.gnu.org/g:b1fabc31774a8917426c9bdae59da45417d3c052
commit b1fabc31774a8917426c9bdae59da45417d3c052 Author: Josef Melcr <melcr...@fit.cvut.cz> Date: Wed Apr 2 22:23:10 2025 +0200 omp-cp: Add testcases for omp-cp and callback attribute. gcc/testsuite/ChangeLog: * gcc.dg/attr-callback.c: New test. * gcc.dg/ipa/ipcp-cb1.c: New test. * gcc.dg/ipa/ipcp-cb2.c: New test. Signed-off-by: Josef Melcr <melcr...@fit.cvut.cz> Diff: --- gcc/testsuite/gcc.dg/attr-callback.c | 79 ++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c | 25 ++++++++++++ gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c | 53 ++++++++++++++++++++++++ 3 files changed, 157 insertions(+) diff --git a/gcc/testsuite/gcc.dg/attr-callback.c b/gcc/testsuite/gcc.dg/attr-callback.c new file mode 100644 index 000000000000..def371193f59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-callback.c @@ -0,0 +1,79 @@ +/* Test callback attribute error checking. */ + +/* { dg-do compile } */ + +void +__attribute__((callback(1, 2))) +correct_1(void (*)(int*), int*); + +void +__attribute__((callback(1, 2, 3))) +correct_2(void (*)(int*, double*), int*, double*); + +void +__attribute__((callback(1, 0))) +unknown_1(void (*)(int*)); + +void +__attribute__((callback(1, 2, 0))) +unknown_2(void (*)(int*, double*), int*, double*, char*); + +void +__attribute__((callback(1, 0, 3, 3))) +too_many(void (*)(int*, double*), int*, double*); /* { dg-error "argument number mismatch, 2 expected, got 3" }*/ + +void +__attribute__((callback(1, 2))) +too_few_1(void (*)(int*, double*), int*, double*); /* { dg-error "argument number mismatch, 2 expected, got 1" }*/ + +void +__attribute__((callback(1))) +too_few_2(void (*)(int*, double*), int*, double*); /* { dg-error "argument number mismatch, 2 expected, got 0" }*/ + +void +__attribute__((callback(3, 1))) +promotion(char*, float, int (*)(int*)); + +void +__attribute__((callback(2, 3))) +downcast(char*, void* (*)(float*), double*); + +void +__attribute__((callback(1, 2, 5))) +out_of_range_1(char (*)(float*, double*), float*, double*, int*); /* { dg-error "callback argument index 5 is out of range" } */ + +void +__attribute__((callback(1, -2, 3))) +out_of_range_2(char (*)(float*, double*), float*, double*, int*); /* { dg-error "callback argument index -2 is out of range" } */ + +void +__attribute__((callback(-1, 2, 3))) +out_of_range_3(char (*)(float*, double*), float*, double*, int*); /* { dg-error "callback function position out of range" } */ + +void +__attribute__((callback(0, 2, 3))) +unknown_fn(char (*)(float*, double*), float*, double*, int*); /* { dg-error "callback function position cannot be marked as unknown" } */ + +void +__attribute__((callback(1, 2))) +not_a_fn(int, int); /* { dg-error "argument no. 1 is not an address of a function" } */ + +struct S{ + int x; +}; + +void +__attribute__((callback(1, 2))) +incompatible_types_1(void (*)(struct S*), struct S); /* { dg-error "argument type at index 2 is not compatible with callback argument type at index 1" } */ + +void +__attribute__((callback(1, 3, 2))) +incompatible_types_2(void (*)(struct S*, int*), int*, double); /* { dg-error "argument type at index 3 is not compatible with callback argument type at index 1" } */ + +void +__attribute__((callback(1, "2"))) +wrong_arg_type_1(void (*)(void*), void*); /* { dg-error "argument no. 1 is not an integer constant" } */ + +void +__attribute__((callback("not a number", 2, 2))) +wrong_arg_type_2(void (*)(void*, void*), void*); /* { dg-error "argument specifying callback function position is not an integer constant" } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c new file mode 100644 index 000000000000..5f672a506f46 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c @@ -0,0 +1,25 @@ +/* Test that we can propagate constants into outlined OpenMP kernels. + This tests the underlying callback attribute and its related edges. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */ +/* { dg-require-effective-target fopenmp } */ +/* { dg-require-effective-target lto } */ + +int a[100]; +void test(int c) { +#pragma omp parallel for + for (int i = 0; i < c; i++) { + if (!__builtin_constant_p(c)) { + __builtin_abort(); + } + a[i] = i; + } +} +int main() { + test(100); + return a[5] - 5; +} + +/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of test._omp_fn" "cp" } } */ +/* { dg-final { scan-wpa-ipa-dump "Aggregate replacements: 0\\\[0]=100\\(by_ref\\)" "cp" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c new file mode 100644 index 000000000000..b42c2a09d8bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c @@ -0,0 +1,53 @@ +/* Test that we can handle multiple callback attributes and use them to + propagate into callbacks. 'cb1' body borrowed from a ipa-cp test to get the + pass to work. */ + +/* { dg-xfail-if "Linking will fail" { *-*-* } } */ +/* { dg-do link } */ +/* { dg-options "-O3 -flto -fdump-ipa-cp-details" } */ +/* { dg-require-effective-target lto } */ + +struct S { + int a, b, c; +}; + +extern void *blah(int, void *); + +extern __attribute__((callback(1, 2), callback(3, 4, 5))) void +call(void (*fn1)(struct S *), struct S *a, void (*fn2)(struct S *, struct S *), + struct S *b, struct S *c); + +void cb1(struct S *p) { + int i, c = p->c; + int b = p->b; + void *v = (void *)p; + + for (i = 0; i < c; i++) + v = blah(b + i, v); +} + +void cb2(struct S *a, struct S *b) { + cb1(a); + cb1(b); +} + +void test(int a, int b, int c) { + struct S s; + s.a = a; + s.b = b; + s.c = c; + struct S ss; + ss.a = s.c; + ss.b = s.b; + ss.c = s.a; + call(cb1, &s, cb2, &s, &ss); +} + +int main() { + test(1, 64, 32); + return 0; +} + +/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of cb1" "cp" } } */ +/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of cb2" "cp" } } */ +/* { dg-final { scan-wpa-ipa-dump-times "Aggregate replacements: " 2 "cp" } } */