diff options
Diffstat (limited to 'libgomp/testsuite/libgomp.c')
140 files changed, 8556 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c new file mode 100644 index 000000000..276ac6caa --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include <stdio.h> + +void +work (int n) +{ + printf ("[%d of %d], nested = %d, n = %d\n", omp_get_thread_num (), omp_get_num_threads(), omp_get_nested (), n); +} + +void +sub3 (int n) +{ + work (n); +#pragma omp barrier + work (n); +} + +void +sub2 (int k) +{ +#pragma omp parallel shared(k) + sub3 (k); +} + +void +sub1 (int n) +{ + int i; +#pragma omp parallel private(i) shared(n) + { +#pragma omp for + for (i = 0; i < n; i++) + sub2 (i); + } +} +int +main () +{ + sub1 (2); + sub2 (15); + sub3 (20); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c new file mode 100644 index 000000000..28a994a28 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ + +#include <stdio.h> + +float +work1 (int i) +{ + return 1.0 * i; +} + +float +work2 (int i) +{ + return 2.0 * i; +} + +void +a16 (float *x, float *y, int *index, int n) +{ + int i; +#pragma omp parallel for shared(x, y, index, n) + for (i = 0; i < n; i++) + { +#pragma omp atomic + x[index[i]] += work1 (i); + y[i] += work2 (i); + } +} +int +main () +{ + float x[1000]; + float y[10000]; + int index[10000]; + int i; + for (i = 0; i < 10000; i++) + { + index[i] = i % 1000; + y[i] = 0.0; + } + for (i = 0; i < 1000; i++) + x[i] = 0.0; + a16 (x, y, index, 10000); + for (i = 0; i < 10; i++) + printf ("x[%d] = %f, y[%d] = %f\n", i, x[i], i, y[i]); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c new file mode 100644 index 000000000..388763e59 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c @@ -0,0 +1,67 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdio.h> + +extern void abort (void); + +#define NUMBER_OF_THREADS 4 + +int synch[NUMBER_OF_THREADS]; +int work[NUMBER_OF_THREADS]; +int result[NUMBER_OF_THREADS]; +int +fn1 (int i) +{ + return i * 2; +} + +int +fn2 (int a, int b) +{ + return a + b; +} + +int +main () +{ + int i, iam, neighbor; + omp_set_num_threads (NUMBER_OF_THREADS); +#pragma omp parallel private(iam,neighbor) shared(work,synch) + { + iam = omp_get_thread_num (); + synch[iam] = 0; +#pragma omp barrier + /*Do computation into my portion of work array */ + work[iam] = fn1 (iam); + /* Announce that I am done with my work. The first flush + * ensures that my work is made visible before synch. + * The second flush ensures that synch is made visible. + */ +#pragma omp flush(work,synch) + synch[iam] = 1; +#pragma omp flush(synch) + /* Wait for neighbor. The first flush ensures that synch is read + * from memory, rather than from the temporary view of memory. + * The second flush ensures that work is read from memory, and + * is done so after the while loop exits. + */ + neighbor = (iam > 0 ? iam : omp_get_num_threads ()) - 1; + while (synch[neighbor] == 0) + { +#pragma omp flush(synch) + } +#pragma omp flush(work,synch) + /* Read neighbor's values of work array */ + result[iam] = fn2 (work[neighbor], work[iam]); + } + /* output result here */ + for (i = 0; i < NUMBER_OF_THREADS; i++) + { + neighbor = (i > 0 ? i : NUMBER_OF_THREADS) - 1; + if (result[i] != i * 2 + neighbor * 2) + abort (); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c new file mode 100644 index 000000000..65ffe624c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ + +int x, *p = &x; +extern void abort (void); +void +f1 (int *q) +{ + *q = 1; +#pragma omp flush + /* x, p, and *q are flushed */ + /* because they are shared and accessible */ + /* q is not flushed because it is not shared. */ +} + +void +f2 (int *q) +{ +#pragma omp barrier + *q = 2; +#pragma omp barrier + /* a barrier implies a flush */ + /* x, p, and *q are flushed */ + /* because they are shared and accessible */ + /* q is not flushed because it is not shared. */ +} + +int +g (int n) +{ + int i = 1, j, sum = 0; + *p = 1; +#pragma omp parallel reduction(+: sum) num_threads(2) + { + f1 (&j); + /* i, n and sum were not flushed */ + /* because they were not accessible in f1 */ + /* j was flushed because it was accessible */ + sum += j; + f2 (&j); + /* i, n, and sum were not flushed */ + /* because they were not accessible in f2 */ + /* j was flushed because it was accessible */ + sum += i + j + *p + n; + } + return sum; +} + +int +main () +{ + int result = g (10); + if (result != 30) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c new file mode 100644 index 000000000..f6ae4c7c5 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ + +#include <stdio.h> +#include <omp.h> +extern void abort (void); +int +main () +{ + int bad, x; + x = 2; + bad = 0; +#pragma omp parallel num_threads(2) shared(x, bad) + { + if (omp_get_thread_num () == 0) + { + volatile int i; + for (i = 0; i < 100000000; i++) + x = 5; + } + else + { + /* Print 1: the following read of x has a race */ + if (x != 2 && x != 5) + bad = 1; + } +#pragma omp barrier + if (omp_get_thread_num () == 0) + { + /* x must be 5 now. */ + if (x != 5) + bad = 1; + } + else + { + /* x must be 5 now. */ + if (x != 5) + bad = 1; + } + } + + if (bad) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c new file mode 100644 index 000000000..0c1c39a12 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +#include <stdio.h> +void +work (int k) +{ +#pragma omp ordered + printf (" %d\n", k); +} + +void +a21 (int lb, int ub, int stride) +{ + int i; +#pragma omp parallel for ordered schedule(dynamic) + for (i = lb; i < ub; i += stride) + work (i); +} + +int +main () +{ + a21 (0, 100, 5); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c new file mode 100644 index 000000000..e146fa204 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ + +#include <stdio.h> +int +main () +{ + int i, j; + i = 1; + j = 2; +#pragma omp parallel private(i) firstprivate(j) + { + i = 3; + j = j + 2; + } + printf ("%d %d\n", i, j); /* i and j are undefined */ + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c new file mode 100644 index 000000000..6f0f65fa0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +#include <assert.h> +int A[2][2] = { 1, 2, 3, 4 }; +void +f (int n, int B[n][n], int C[]) +{ + int D[2][2] = { 1, 2, 3, 4 }; + int E[n][n]; + assert (n >= 2); + E[1][1] = 4; +#pragma omp parallel firstprivate(B, C, D, E) + { + assert (sizeof (B) == sizeof (int (*)[n])); + assert (sizeof (C) == sizeof (int *)); + assert (sizeof (D) == 4 * sizeof (int)); + assert (sizeof (E) == n * n * sizeof (int)); + /* Private B and C have values of original B and C. */ + assert (&B[1][1] == &A[1][1]); + assert (&C[3] == &A[1][1]); + assert (D[1][1] == 4); + assert (E[1][1] == 4); + } +} +int +main () +{ + f (2, A, A[0]); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c new file mode 100644 index 000000000..9e7c24f75 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ + +#include <stdio.h> +int +main () +{ +# ifdef _OPENMP + printf ("Compiled by an OpenMP-compliant implementation.\n"); +# endif + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c b/libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c new file mode 100644 index 000000000..0b7f0197c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> +#include <omp.h> +omp_lock_t * +new_lock () +{ + omp_lock_t *lock_ptr; +#pragma omp single copyprivate(lock_ptr) + { + lock_ptr = (omp_lock_t *) malloc (sizeof (omp_lock_t)); + omp_init_lock (lock_ptr); + } + return lock_ptr; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c new file mode 100644 index 000000000..b60534d11 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> +void +do_by_16 (float *x, int iam, int ipoints) +{ +} + +void +a36 (float *x, int npoints) +{ + int iam, ipoints; + omp_set_dynamic (0); + omp_set_num_threads (16); +#pragma omp parallel shared(x, npoints) private(iam, ipoints) + { + if (omp_get_num_threads () != 16) + abort (); + iam = omp_get_thread_num (); + ipoints = npoints / 16; + do_by_16 (x, iam, ipoints); + } +} + +int main() +{ + float a[10]; + a36 (a, 10); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c new file mode 100644 index 000000000..a129e87fc --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +#include <stdio.h> +#include <omp.h> +void +skip (int i) +{ +} + +void +work (int i) +{ +} +int +main () +{ + omp_lock_t lck; + int id; + omp_init_lock (&lck); +#pragma omp parallel shared(lck) private(id) + { + id = omp_get_thread_num (); + omp_set_lock (&lck); + /* only one thread at a time can execute this printf */ + printf ("My thread id is %d.\n", id); + omp_unset_lock (&lck); + while (!omp_test_lock (&lck)) + { + skip (id); /* we do not yet have the lock, + so we must do something else */ + } + work (id); /* we now have the lock + and can do the work */ + omp_unset_lock (&lck); + } + omp_destroy_lock (&lck); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c new file mode 100644 index 000000000..c6be49090 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +#include <omp.h> +extern void abort (void); +void +subdomain (float *x, int istart, int ipoints) +{ + int i; + for (i = 0; i < ipoints; i++) + x[istart + i] = 123.456; +} + +void +sub (float *x, int npoints) +{ + int iam, nt, ipoints, istart; +#pragma omp parallel default(shared) private(iam,nt,ipoints,istart) + { + iam = omp_get_thread_num (); + nt = omp_get_num_threads (); + ipoints = npoints / nt; /* size of partition */ + istart = iam * ipoints; /* starting array index */ + if (iam == nt - 1) /* last thread may do more */ + ipoints = npoints - istart; + subdomain (x, istart, ipoints); + } +} +int +main () +{ + int i; + float array[10000]; + sub (array, 10000); + for (i = 0; i < 10000; i++) + if (array[i] < 123.45 || array[i] > 123.46) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c new file mode 100644 index 000000000..aa7b88d70 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ + +#include <omp.h> +typedef struct +{ + int a, b; + omp_nest_lock_t lck; +} pair; +int work1 (); +int work2 (); +int work3 (); +void +incr_a (pair * p, int a) +{ + /* Called only from incr_pair, no need to lock. */ + p->a += a; +} + +void +incr_b (pair * p, int b) +{ + /* Called both from incr_pair and elsewhere, */ + /* so need a nestable lock. */ + omp_set_nest_lock (&p->lck); + p->b += b; + omp_unset_nest_lock (&p->lck); +} + +void +incr_pair (pair * p, int a, int b) +{ + omp_set_nest_lock (&p->lck); + incr_a (p, a); + incr_b (p, b); + omp_unset_nest_lock (&p->lck); +} + +void +a40 (pair * p) +{ +#pragma omp parallel sections + { +#pragma omp section + incr_pair (p, work1 (), work2 ()); +#pragma omp section + incr_b (p, work3 ()); + } +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c new file mode 100644 index 000000000..b909c4ddb --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ + +#include <omp.h> +int +main () +{ + omp_set_dynamic (1); +#pragma omp parallel num_threads(10) + { + /* do work here */ + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-1.c b/libgomp/testsuite/libgomp.c/atomic-1.c new file mode 100644 index 000000000..b2be8f022 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-1.c @@ -0,0 +1,62 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -march=pentium" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#ifdef __i386__ +#include "cpuid.h" +#endif + +extern void abort (void); +double d; +struct +{ + int i; + double e; + int j; +} x; + +void +f1 (void) +{ + #pragma omp atomic + d += 7.5; + #pragma omp atomic + d *= 2.5; + #pragma omp atomic + d /= 0.25; +} + +void +f2 (void) +{ + #pragma omp atomic + x.e += 7.5; + #pragma omp atomic + x.e *= 2.5; + #pragma omp atomic + x.e /= 0.25; +} + +int +main (void) +{ +#ifdef __i386__ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + if (!(edx & bit_CMPXCHG8B)) + return 0; +#endif + + d = 1.0; + f1 (); + if (d != 85.0) + abort (); + + x.e = 1.0; + f2 (); + if (x.i != 0 || x.e != 85.0 || x.j != 0) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-10.c b/libgomp/testsuite/libgomp.c/atomic-10.c new file mode 100644 index 000000000..58edeed6c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-10.c @@ -0,0 +1,139 @@ +/* { dg-do run } */ + +extern void abort (void); +int x1, x2, x3, x4, x5; +volatile int y6 = 9, y2, y3, y4, y5; +volatile unsigned char z1, z2, z3, z4, z5; +float a1, a2, a3, a4; + +void +f1 (void) +{ + #pragma omp atomic + x1++; + #pragma omp atomic + x2--; + #pragma omp atomic + ++x3; + #pragma omp atomic + --x4; + #pragma omp atomic + x5 += 1; + #pragma omp atomic + x1 -= y6; + #pragma omp atomic + x2 |= 1; + #pragma omp atomic + x3 &= 1; + #pragma omp atomic + x4 ^= 1; + #pragma omp atomic + x5 *= 3; + #pragma omp atomic + x1 /= 3; + #pragma omp atomic + x2 /= 3; + #pragma omp atomic + x3 <<= 3; + #pragma omp atomic + x4 >>= 3; +} + +void +f2 (void) +{ + #pragma omp atomic + y6++; + #pragma omp atomic + y2--; + #pragma omp atomic + ++y3; + #pragma omp atomic + --y4; + #pragma omp atomic + y5 += 1; + #pragma omp atomic + y6 -= x1; + #pragma omp atomic + y2 |= 1; + #pragma omp atomic + y3 &= 1; + #pragma omp atomic + y4 ^= 1; + #pragma omp atomic + y5 *= 3; + #pragma omp atomic + y6 /= 3; + #pragma omp atomic + y2 /= 3; + #pragma omp atomic + y3 <<= 3; + #pragma omp atomic + y4 >>= 3; +} + +void +f3 (void) +{ + #pragma omp atomic + z1++; + #pragma omp atomic + z2--; + #pragma omp atomic + ++z3; + #pragma omp atomic + --z4; + #pragma omp atomic + z5 += 1; + #pragma omp atomic + z1 |= 1; + #pragma omp atomic + z2 &= 1; + #pragma omp atomic + z3 ^= 1; + #pragma omp atomic + z4 *= 3; + #pragma omp atomic + z5 /= 3; + #pragma omp atomic + z1 /= 3; + #pragma omp atomic + z2 <<= 3; + #pragma omp atomic + z3 >>= 3; +} + +void +f4 (void) +{ + #pragma omp atomic + a1 += 8.0; + #pragma omp atomic + a2 *= 3.5; + #pragma omp atomic + a3 -= a1 + a2; + #pragma omp atomic + a4 /= 2.0; +} + +int +main (void) +{ + f1 (); + if (x1 != -2 || x2 != 0 || x3 != 8 || x4 != -1 || x5 != 3) + abort (); + f2 (); + if (y6 != 4 || y2 != 0 || y3 != 8 || y4 != -1 || y5 != 3) + abort (); + f3 (); + if (z1 != 0 || z2 != 8 || z3 != 0 || z4 != 253 || z5 != 0) + abort (); + a1 = 7; + a2 = 10; + a3 = 11; + a4 = 13; + f4 (); + if (a1 != 15.0 || a2 != 35.0 || a3 != -39.0 || a4 != 6.5) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-2.c b/libgomp/testsuite/libgomp.c/atomic-2.c new file mode 100644 index 000000000..c8779483b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-2.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mcx16" { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ + +#ifdef __x86_64__ +#include "cpuid.h" +#endif + +double d = 1.5; +long double ld = 3; +extern void abort (void); + +void +test (void) +{ +#pragma omp atomic + d *= 1.25; +#pragma omp atomic + ld /= 0.75; + if (d != 1.875 || ld != 4.0L) + abort (); +} + +int +main (void) +{ +#ifdef __x86_64__ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + if (!(ecx & bit_CMPXCHG16B)) + return 0; +#endif + test (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-3.c b/libgomp/testsuite/libgomp.c/atomic-3.c new file mode 100644 index 000000000..5b8fdc1a7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-3.c @@ -0,0 +1,50 @@ +/* { dg-do run } */ +/* { dg-options "-fopenmp -O0" } */ + +#include <omp.h> +#include <stdlib.h> + +short e[64]; +int g; +_Complex double d, f; +int num_threads; + +__attribute__((noinline)) void +foo (int x, long long y) +{ +#pragma omp parallel num_threads (4) + { + int i; + #pragma omp barrier + for (i = 0; i < 2400; i++) + { + if (i == 0) + num_threads = omp_get_num_threads (); + #pragma omp atomic + e[0] += x; + #pragma omp atomic + e[16] += x; + #pragma omp atomic + g += y; + #pragma omp atomic + __real__ d += x; + #pragma omp atomic + __imag__ f += x; + } + } +} + +int +main (void) +{ + int i; + foo (3, 3LL); + if (g != 3 * 2400 * num_threads + || __real__ d != g || __imag__ d != 0 + || __real__ f != 0 || __imag__ f != g) + abort (); + for (i = 0; i < 64; i++) + if (e[i] != ((i && i != 16) ? 0 : g)) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-4.c b/libgomp/testsuite/libgomp.c/atomic-4.c new file mode 100644 index 000000000..10f8197b0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-4.c @@ -0,0 +1,18 @@ +/* PR middle-end/35611 */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +int +main (void) +{ + long double d = .0L; + int i; + #pragma omp parallel for shared (d) + for (i = 0; i < 1000; i++) + #pragma omp atomic + d += 1.0L; + if (d != 1000.0L) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-5.c b/libgomp/testsuite/libgomp.c/atomic-5.c new file mode 100644 index 000000000..168f68dd6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-5.c @@ -0,0 +1,41 @@ +/* PR middle-end/36106 */ +/* { dg-options "-O2" } */ +/* { dg-options "-O2 -mcx16" { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ + +#ifdef __x86_64__ +# include "cpuid.h" +#endif + +extern void abort (void); + +int __attribute__((noinline)) +do_test (void) +{ + long double d = .0L; + int i; + #pragma omp parallel for shared (d) + for (i = 0; i < 10; i++) + #pragma omp atomic + d += 1.0L; + if (d != 10.0L) + abort (); + return 0; +} + +int +main (void) +{ +#ifdef __x86_64__ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + if (!(ecx & bit_CMPXCHG16B)) + return 0; +#endif + + do_test (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-6.c b/libgomp/testsuite/libgomp.c/atomic-6.c new file mode 100644 index 000000000..59baf7dd3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-6.c @@ -0,0 +1,38 @@ +/* PR middle-end/36106 */ +/* { dg-options "-O2" } */ +/* { dg-options "-O2 -mieee" { target alpha*-*-* } } */ +/* { dg-options "-O2 -march=i586" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +#ifdef __i386__ +# include "cpuid.h" +#endif + +extern void abort (void); + +union { unsigned long long l; double d; } u = { .l = 0x7ff0000000072301ULL }; + +int __attribute__((noinline)) +do_test (void) +{ +#pragma omp atomic + u.d += 1.0L; + return 0; +} + +int +main (void) +{ +#ifdef __i386__ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + if (!(edx & bit_CMPXCHG8B)) + return 0; +#endif + + do_test (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/autopar-1.c b/libgomp/testsuite/libgomp.c/autopar-1.c new file mode 100644 index 000000000..e56549b48 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/autopar-1.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-options "-ftree-parallelize-loops=4 -O2 -ffast-math" } */ + +extern void abort (void); + +double d[1024], e[1024]; +int f[1024], g[1024]; + +double __attribute__((noinline)) +foo (void) +{ + double s = 0.0; + int i; + for (i = 0; i < 1024; i++) + s += d[i] - e[i]; + return s; +} + +int __attribute__((noinline)) +bar (void) +{ + int s = 0, i; + for (i = 0; i < 1024; i++) + s += f[i] - g[i]; + return s; +} + +int +main (void) +{ + int i; + for (i = 0; i < 1024; i++) + { + d[i] = i * 2; + e[i] = i; + f[i] = i * 2; + g[i] = i; + } + if (foo () != 1023 * 1024 / 2) + abort (); + if (bar () != 1023 * 1024 / 2) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/barrier-1.c b/libgomp/testsuite/libgomp.c/barrier-1.c new file mode 100644 index 000000000..1f8d1f0d3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/barrier-1.c @@ -0,0 +1,50 @@ +/* Trivial test of barrier. */ + +#include <omp.h> +#include <sys/time.h> +#include <unistd.h> +#include <assert.h> +#include "libgomp_g.h" + + +struct timeval stamps[3][3]; + +static void function(void *dummy) +{ + int iam = omp_get_thread_num (); + + gettimeofday (&stamps[iam][0], NULL); + if (iam == 0) + usleep (10); + + GOMP_barrier (); + + if (iam == 0) + { + gettimeofday (&stamps[0][1], NULL); + usleep (10); + } + + GOMP_barrier (); + + gettimeofday (&stamps[iam][2], NULL); +} + +int main() +{ + omp_set_dynamic (0); + + GOMP_parallel_start (function, NULL, 3); + function (NULL); + GOMP_parallel_end (); + + assert (!timercmp (&stamps[0][0], &stamps[0][1], >)); + assert (!timercmp (&stamps[1][0], &stamps[0][1], >)); + assert (!timercmp (&stamps[2][0], &stamps[0][1], >)); + + assert (!timercmp (&stamps[0][1], &stamps[0][2], >)); + assert (!timercmp (&stamps[0][1], &stamps[1][2], >)); + assert (!timercmp (&stamps[0][1], &stamps[2][2], >)); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/c.exp b/libgomp/testsuite/libgomp.c/c.exp new file mode 100644 index 000000000..980bb526f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/c.exp @@ -0,0 +1,30 @@ +if [info exists lang_library_path] then { + unset lang_library_path + unset lang_link_flags +} +if [info exists lang_test_file] then { + unset lang_test_file +} + +load_lib libgomp-dg.exp + +# If a testcase doesn't have special options, use these. +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS "-O2" +} + +# Initialize dg. +dg-init + +# Gather a list of all tests. +set tests [lsort [find $srcdir/$subdir *.c]] + +set ld_library_path $always_ld_library_path +append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] +set_ld_library_path_env_vars + +# Main loop. +dg-runtest $tests "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/libgomp/testsuite/libgomp.c/collapse-1.c b/libgomp/testsuite/libgomp.c/collapse-1.c new file mode 100644 index 000000000..84277ff55 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/collapse-1.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +#include <string.h> +#include <stdlib.h> + +int +main (void) +{ + int i, j, k, l = 0; + int a[3][3][3]; + + memset (a, '\0', sizeof (a)); + #pragma omp parallel for collapse(4 - 1) schedule(static, 4) + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + for (k = 0; k < 2; k++) + a[i][j][k] = i + j * 4 + k * 16; + #pragma omp parallel + { + #pragma omp for collapse(2) reduction(|:l) private(k) + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + for (k = 0; k < 2; k++) + if (a[i][j][k] != i + j * 4 + k * 16) + l = 1; + } + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/collapse-2.c b/libgomp/testsuite/libgomp.c/collapse-2.c new file mode 100644 index 000000000..b5c77d461 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/collapse-2.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +#include <stdlib.h> +#include <omp.h> + +int +main (void) +{ + int i, j, k, l = 0, f = 0; + int m1 = 4, m2 = -5, m3 = 17; + + #pragma omp parallel for num_threads (8) collapse(3) \ + schedule(static, 9) reduction(+:l) \ + firstprivate(f) + for (i = -2; i < m1; i++) + for (j = m2; j < -2; j++) + { + for (k = 13; k < m3; k++) + { + if (omp_get_num_threads () == 8 + && ((i + 2) * 12 + (j + 5) * 4 + (k - 13) + != (omp_get_thread_num () * 9 + + f++))) + l++; + } + } + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/collapse-3.c b/libgomp/testsuite/libgomp.c/collapse-3.c new file mode 100644 index 000000000..4674f83f4 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/collapse-3.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -std=gnu99" } */ + +#include <string.h> +#include <stdlib.h> + +int +main (void) +{ + int i2, l = 0; + int a[3][3][3]; + + memset (a, '\0', sizeof (a)); + #pragma omp parallel for collapse(4 - 1) schedule(static, 4) + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 2; k++) + a[i][j][k] = i + j * 4 + k * 16; + #pragma omp parallel + { + #pragma omp for collapse(2) reduction(|:l) + for (i2 = 0; i2 < 2; i2++) + for (int j = 0; j < 2; j++) + for (int k = 0; k < 2; k++) + if (a[i2][j][k] != i2 + j * 4 + k * 16) + l = 1; + } + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/copyin-1.c b/libgomp/testsuite/libgomp.c/copyin-1.c new file mode 100644 index 000000000..49c546004 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/copyin-1.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdlib.h> + +int thr = 32; +#pragma omp threadprivate (thr) + +int +main (void) +{ + int l = 0; + + omp_set_dynamic (0); + omp_set_num_threads (6); + +#pragma omp parallel copyin (thr) reduction (||:l) + { + l = thr != 32; + thr = omp_get_thread_num () + 11; + } + + if (l || thr != 11) + abort (); + +#pragma omp parallel reduction (||:l) + l = thr != omp_get_thread_num () + 11; + + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/copyin-2.c b/libgomp/testsuite/libgomp.c/copyin-2.c new file mode 100644 index 000000000..ae2451ef1 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/copyin-2.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdlib.h> + +struct { int t; char buf[64]; } thr = { 32, "" }; +#pragma omp threadprivate (thr) + +int +main (void) +{ + int l = 0; + + omp_set_dynamic (0); + omp_set_num_threads (6); + +#pragma omp parallel copyin (thr) reduction (||:l) + { + l = thr.t != 32; + thr.t = omp_get_thread_num () + 11; + } + + if (l || thr.t != 11) + abort (); + +#pragma omp parallel reduction (||:l) + l = thr.t != omp_get_thread_num () + 11; + + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/copyin-3.c b/libgomp/testsuite/libgomp.c/copyin-3.c new file mode 100644 index 000000000..86b0d691f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/copyin-3.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdlib.h> + +int thr; +#pragma omp threadprivate (thr) + +int +test (int l) +{ + return l || (thr != omp_get_thread_num () * 2); +} + +int +main (void) +{ + int l = 0; + + omp_set_dynamic (0); + omp_set_num_threads (6); + + thr = 8; + /* Broadcast the value to all threads. */ +#pragma omp parallel copyin (thr) + ; + +#pragma omp parallel reduction (||:l) + { + /* Now test if the broadcast succeeded. */ + l = thr != 8; + thr = omp_get_thread_num () * 2; +#pragma omp barrier + l = test (l); + } + + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/critical-1.c b/libgomp/testsuite/libgomp.c/critical-1.c new file mode 100644 index 000000000..2b8503be7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/critical-1.c @@ -0,0 +1,39 @@ +/* Trivial test of critical sections. */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <sys/time.h> +#include <unistd.h> +#include <assert.h> +#include "libgomp_g.h" + + +static volatile int test = -1; + +static void function(void *dummy) +{ + int iam = omp_get_thread_num (); + int old; + + GOMP_critical_start (); + + old = __sync_lock_test_and_set (&test, iam); + assert (old == -1); + + usleep (10); + test = -1; + + GOMP_critical_end (); +} + +int main() +{ + omp_set_dynamic (0); + + GOMP_parallel_start (function, NULL, 3); + function (NULL); + GOMP_parallel_end (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/critical-2.c b/libgomp/testsuite/libgomp.c/critical-2.c new file mode 100644 index 000000000..530a891f6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/critical-2.c @@ -0,0 +1,35 @@ +// { dg-do run } +// Test several constructs within a parallel. At one point in development, +// the critical directive clobbered the shared clause of the parallel. + +#include <omp.h> +#include <stdlib.h> + +#define N 2000 + +int main() +{ + int A[N]; + int nthreads; + int i; + +#pragma omp parallel shared (A, nthreads) + { + #pragma omp master + nthreads = omp_get_num_threads (); + + #pragma omp for + for (i = 0; i < N; i++) + A[i] = 0; + + #pragma omp critical + for (i = 0; i < N; i++) + A[i] += 1; + } + + for (i = 0; i < N; i++) + if (A[i] != nthreads) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/debug-1.c b/libgomp/testsuite/libgomp.c/debug-1.c new file mode 100644 index 000000000..09bcf7f3c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/debug-1.c @@ -0,0 +1,162 @@ +/* PR debug/36617 */ +/* { dg-do run } */ +/* { dg-options "-g -fopenmp -O0" } */ + +int +f1 (void) +{ + int v1i, v1j, v1k, v1l = 0; + v1i = 6; + v1j = 8; + #pragma omp parallel private (v1k) firstprivate (v1j) shared (v1i) reduction (+:v1l) + { + v1k = v1i + v1j; + { + int v1m = 1; + v1l = v1m; + } + } + return v1l; +} + +int v2k = 9; + +int +f2 (void) +{ + int v2i = 6, v2j = 7; + #pragma omp single private (v2i) firstprivate (v2k) + { + int v2l = v2j + v2k; + v2i = 8; + v2k = 10; + v2j = v2l + v2i; + } + return v2i + v2j; +} + +int +f3 (void) +{ + int v3i = 6, v3j = 7, v3k = 9; + #pragma omp parallel + { + #pragma omp master + v3i++; + #pragma omp single private (v3i) firstprivate (v3k) + { + int v3l = v3j + v3k; + v3i = 8; + v3k = 10; + v3j = v3l + v3i; + } + #pragma omp atomic + v3k++; + } + return v3i + v3j; +} + +int v4k = 9, v4l = 0; + +int +f4 (void) +{ + int v4i = 6, v4j = 7, v4n = 0; + #pragma omp sections private (v4i) firstprivate (v4k) reduction (+:v4l) + { + #pragma omp section + { + int v4m = v4j + v4k; + v4i = 8; + v4k = 10; + v4l++; + v4n = v4m + v4i; + } + #pragma omp section + { + int v4o = v4j + v4k; + v4i = 10; + v4k = 11; + v4l++; + } + } + return v4i + v4j + v4l + v4n; +} + +int +f5 (void) +{ + int v5i = 6, v5j = 7, v5k = 9, v5l = 0, v5n = 0, v5p = 0; + #pragma omp parallel + { + #pragma omp master + v5p++; + #pragma omp sections private (v5i) firstprivate (v5k) reduction (+:v5l) + { + #pragma omp section + { + int v5m = v5j + v5k; + v5i = 8; + v5k = 10; + v5l++; + v5n = v5m + v5i; + } + #pragma omp section + { + int v5o = v5j + v5k; + v5i = 10; + v5k = 11; + v5l++; + } + } + } + return v5i + v5j + v5l + v5n + v5p; +} + +int v6k = 9, v6l = 0; + +int +f6 (void) +{ + int v6i = 6, v6j = 7, v6n = 0; + #pragma omp for private (v6i) firstprivate (v6k) reduction (+:v6l) + for (v6n = 0; v6n < 3; v6n++) + { + int v6m = v6j + v6k; + v6i = 8; + v6l++; + } + return v6i + v6j + v6k + v6l + v6n; +} + +int +f7 (void) +{ + int v7i = 6, v7j = 7, v7k = 9, v7l = 0, v7n = 0, v7o = 1; + #pragma omp parallel + { + #pragma omp master + v7o++; + #pragma omp for private (v7i) firstprivate (v7k) reduction (+:v7l) + for (v7n = 0; v7n < 3; v7n++) + { + int v7m = v7j + v7k; + v7i = 8; + v7l++; + } + } + return v7i + v7j + v7k + v7l + v7n; +} + +int +main (void) +{ + f1 (); + f2 (); + f3 (); + f4 (); + f5 (); + f6 (); + f7 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/icv-1.c b/libgomp/testsuite/libgomp.c/icv-1.c new file mode 100644 index 000000000..99708f823 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/icv-1.c @@ -0,0 +1,33 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int err = 0; + + omp_set_num_threads (4); + if (omp_get_max_threads () != 4) + abort (); + #pragma omp parallel reduction(|: err) num_threads(1) + { + if (omp_get_max_threads () != 4) + err |= 1; + omp_set_num_threads (6); + #pragma omp task if(0) shared(err) + { + if (omp_get_max_threads () != 6) + err |= 2; + omp_set_num_threads (5); + if (omp_get_max_threads () != 5) + err |= 4; + } + if (omp_get_max_threads () != 6) + err |= 8; + } + if (err) + abort (); + if (omp_get_max_threads () != 4) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/icv-2.c b/libgomp/testsuite/libgomp.c/icv-2.c new file mode 100644 index 000000000..326f8eb40 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/icv-2.c @@ -0,0 +1,46 @@ +/* { dg-do run { target *-*-linux* } } */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#include <pthread.h> +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +pthread_barrier_t bar; + +void *tf (void *p) +{ + int l; + if (p) + omp_set_num_threads (3); + pthread_barrier_wait (&bar); + if (!p) + omp_set_num_threads (6); + pthread_barrier_wait (&bar); + omp_set_dynamic (0); + if (omp_get_max_threads () != (p ? 3 : 6)) + abort (); + l = 0; + #pragma omp parallel num_threads (6) reduction (|:l) + { + l |= omp_get_max_threads () != (p ? 3 : 6); + omp_set_num_threads ((p ? 3 : 6) + omp_get_thread_num ()); + l |= omp_get_max_threads () != ((p ? 3 : 6) + omp_get_thread_num ()); + } + if (l) + abort (); + return NULL; +} + +int +main (void) +{ + pthread_t th; + pthread_barrier_init (&bar, NULL, 2); + pthread_create (&th, NULL, tf, NULL); + tf (""); + pthread_join (th, NULL); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/lib-1.c b/libgomp/testsuite/libgomp.c/lib-1.c new file mode 100644 index 000000000..4839cf936 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/lib-1.c @@ -0,0 +1,99 @@ +#include <stdlib.h> +#include <omp.h> + +int +main (void) +{ + double d, e; + int l; + omp_lock_t lck; + omp_nest_lock_t nlck; + + d = omp_get_wtime (); + + omp_init_lock (&lck); + omp_set_lock (&lck); + if (omp_test_lock (&lck)) + abort (); + omp_unset_lock (&lck); + if (! omp_test_lock (&lck)) + abort (); + if (omp_test_lock (&lck)) + abort (); + omp_unset_lock (&lck); + omp_destroy_lock (&lck); + + omp_init_nest_lock (&nlck); + if (omp_test_nest_lock (&nlck) != 1) + abort (); + omp_set_nest_lock (&nlck); + if (omp_test_nest_lock (&nlck) != 3) + abort (); + omp_unset_nest_lock (&nlck); + omp_unset_nest_lock (&nlck); + if (omp_test_nest_lock (&nlck) != 2) + abort (); + omp_unset_nest_lock (&nlck); + omp_unset_nest_lock (&nlck); + omp_destroy_nest_lock (&nlck); + + omp_set_dynamic (1); + if (! omp_get_dynamic ()) + abort (); + omp_set_dynamic (0); + if (omp_get_dynamic ()) + abort (); + + omp_set_nested (1); + if (! omp_get_nested ()) + abort (); + omp_set_nested (0); + if (omp_get_nested ()) + abort (); + + omp_set_num_threads (5); + if (omp_get_num_threads () != 1) + abort (); + if (omp_get_max_threads () != 5) + abort (); + if (omp_get_thread_num () != 0) + abort (); + omp_set_num_threads (3); + if (omp_get_num_threads () != 1) + abort (); + if (omp_get_max_threads () != 3) + abort (); + if (omp_get_thread_num () != 0) + abort (); + l = 0; +#pragma omp parallel reduction (|:l) + { + l = omp_get_num_threads () != 3; + l |= omp_get_thread_num () < 0; + l |= omp_get_thread_num () >= 3; +#pragma omp master + l |= omp_get_thread_num () != 0; + } + if (l) + abort (); + + if (omp_get_num_procs () <= 0) + abort (); + if (omp_in_parallel ()) + abort (); +#pragma omp parallel reduction (|:l) + l = ! omp_in_parallel (); +#pragma omp parallel reduction (|:l) if (1) + l = ! omp_in_parallel (); + + e = omp_get_wtime (); + if (d > e) + abort (); + d = omp_get_wtick (); + /* Negative precision is definitely wrong, + bigger than 1s clock resolution is also strange. */ + if (d <= 0 || d > 1) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/lib-2.c b/libgomp/testsuite/libgomp.c/lib-2.c new file mode 100644 index 000000000..3a3b3f655 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/lib-2.c @@ -0,0 +1,25 @@ +#include <stdlib.h> +#include <omp.h> + +int +main (void) +{ + omp_sched_t kind; + int modifier; + + omp_set_schedule (omp_sched_static, 32); + omp_get_schedule (&kind, &modifier); + if (kind != omp_sched_static || modifier != 32) + abort (); + omp_set_schedule (omp_sched_guided, 4); + omp_get_schedule (&kind, &modifier); + if (kind != omp_sched_guided || modifier != 4) + abort (); + if (omp_get_thread_limit () < 0) + abort (); + omp_set_max_active_levels (6); + if (omp_get_max_active_levels () != 6) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/lock-1.c b/libgomp/testsuite/libgomp.c/lock-1.c new file mode 100644 index 000000000..e09645dbc --- /dev/null +++ b/libgomp/testsuite/libgomp.c/lock-1.c @@ -0,0 +1,31 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int l = 0; + omp_nest_lock_t lock; + omp_init_nest_lock (&lock); + if (omp_test_nest_lock (&lock) != 1) + abort (); + if (omp_test_nest_lock (&lock) != 2) + abort (); +#pragma omp parallel if (0) reduction (+:l) + { + /* In OpenMP 2.5 this was supposed to return 3, + but in OpenMP 3.0 the parallel region has a different + task and omp_*_lock_t are owned by tasks, not by threads. */ + if (omp_test_nest_lock (&lock) != 0) + l++; + } + if (l) + abort (); + if (omp_test_nest_lock (&lock) != 3) + abort (); + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + omp_destroy_nest_lock (&lock); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/lock-2.c b/libgomp/testsuite/libgomp.c/lock-2.c new file mode 100644 index 000000000..9009b12fe --- /dev/null +++ b/libgomp/testsuite/libgomp.c/lock-2.c @@ -0,0 +1,32 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int l = 0; + omp_nest_lock_t lock; + omp_init_nest_lock (&lock); +#pragma omp parallel reduction (+:l) num_threads (1) + { + if (omp_test_nest_lock (&lock) != 1) + l++; + if (omp_test_nest_lock (&lock) != 2) + l++; + #pragma omp task if (0) shared (lock, l) + { + if (omp_test_nest_lock (&lock) != 0) + l++; + } + #pragma omp taskwait + if (omp_test_nest_lock (&lock) != 3) + l++; + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + } + if (l) + abort (); + omp_destroy_nest_lock (&lock); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/lock-3.c b/libgomp/testsuite/libgomp.c/lock-3.c new file mode 100644 index 000000000..1fc83726d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/lock-3.c @@ -0,0 +1,60 @@ +/* { dg-do run { target *-*-linux* } } */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#include <pthread.h> +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +pthread_barrier_t bar; +omp_nest_lock_t lock; + +void *tf (void *p) +{ + int l; + if (p) + { + if (omp_test_nest_lock (&lock) != 1) + abort (); + if (omp_test_nest_lock (&lock) != 2) + abort (); + } + pthread_barrier_wait (&bar); + if (!p && omp_test_nest_lock (&lock) != 0) + abort (); + pthread_barrier_wait (&bar); + if (p) + { + if (omp_test_nest_lock (&lock) != 3) + abort (); + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + } + pthread_barrier_wait (&bar); + if (!p) + { + if (omp_test_nest_lock (&lock) != 1) + abort (); + if (omp_test_nest_lock (&lock) != 2) + abort (); + omp_unset_nest_lock (&lock); + omp_unset_nest_lock (&lock); + } + return NULL; +} + +int +main (void) +{ + pthread_t th; + omp_init_nest_lock (&lock); + pthread_barrier_init (&bar, NULL, 2); + pthread_create (&th, NULL, tf, NULL); + tf (""); + pthread_join (th, NULL); + omp_destroy_nest_lock (&lock); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-1.c b/libgomp/testsuite/libgomp.c/loop-1.c new file mode 100644 index 000000000..11348dcfe --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-1.c @@ -0,0 +1,140 @@ +/* Test that all loop iterations are touched. This doesn't verify + scheduling order, merely coverage. */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 10000 +static int S, E, INCR, CHUNK, NTHR; +static int data[N]; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int i, j; + + for (i = 0; i < S; ++i) + assert (data[i] == -1); + + for (j = 0; i < E; ++i, j = (j + 1) % INCR) + if (j == 0) + assert (data[i] != -1); + else + assert (data[i] == -1); + + for (; i < N; ++i) + assert (data[i] == -1); +} + +static void set_data (long i, int val) +{ + int old; + assert (i >= 0 && i < N); + old = __sync_lock_test_and_set (data+i, val); + assert (old == -1); +} + + +#define TMPL_1(sched) \ +static void f_##sched##_1 (void *dummy) \ +{ \ + int iam = omp_get_thread_num (); \ + long s0, e0, i; \ + if (GOMP_loop_##sched##_start (S, E, INCR, CHUNK, &s0, &e0)) \ + do \ + { \ + for (i = s0; i < e0; i += INCR) \ + set_data (i, iam); \ + } \ + while (GOMP_loop_##sched##_next (&s0, &e0)); \ + GOMP_loop_end (); \ +} \ +static void t_##sched##_1 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ + f_##sched##_1 (NULL); \ + GOMP_parallel_end (); \ + test_data (); \ +} + +TMPL_1(static) +TMPL_1(dynamic) +TMPL_1(guided) + +#define TMPL_2(sched) \ +static void f_##sched##_2 (void *dummy) \ +{ \ + int iam = omp_get_thread_num (); \ + long s0, e0, i; \ + while (GOMP_loop_##sched##_next (&s0, &e0)) \ + { \ + for (i = s0; i < e0; i += INCR) \ + set_data (i, iam); \ + } \ + GOMP_loop_end_nowait (); \ +} \ +static void t_##sched##_2 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_loop_##sched##_start \ + (f_##sched##_2, NULL, NTHR, S, E, INCR, CHUNK); \ + f_##sched##_2 (NULL); \ + GOMP_parallel_end (); \ + test_data (); \ +} + +TMPL_2(static) +TMPL_2(dynamic) +TMPL_2(guided) + +static void test (void) +{ + t_static_1 (); + t_dynamic_1 (); + t_guided_1 (); + t_static_2 (); + t_dynamic_2 (); + t_guided_2 (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + S = 0, E = N, INCR = 1, CHUNK = 4; + test (); + + S = 0, E = N, INCR = 2, CHUNK = 4; + test (); + + S = 1, E = N-1, INCR = 1, CHUNK = 5; + test (); + + S = 1, E = N-1, INCR = 2, CHUNK = 5; + test (); + + S = 2, E = 4, INCR = 1, CHUNK = 1; + test (); + + S = 0, E = N, INCR = 1, CHUNK = 0; + t_static_1 (); + t_static_2 (); + + S = 1, E = N-1, INCR = 1, CHUNK = 0; + t_static_1 (); + t_static_2 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-10.c b/libgomp/testsuite/libgomp.c/loop-10.c new file mode 100644 index 000000000..1b42c4bf1 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-10.c @@ -0,0 +1,30 @@ +extern void abort (void); + +int i = 8; + +int main (void) +{ + int j = 7, k = 0; + #pragma omp for + for (i = 0; i < 10; i++) + ; + #pragma omp for + for (j = 0; j < 10; j++) + ; + /* OpenMP 3.0 newly guarantees that the original list items can't + be shared with the privatized omp for iterators, even when + the original list items are already private. */ + if (i != 8 || j != 7) + abort (); + #pragma omp parallel private (i) reduction (+:k) + { + i = 6; + #pragma omp for + for (i = 0; i < 10; i++) + ; + k = (i != 6); + } + if (k) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-11.c b/libgomp/testsuite/libgomp.c/loop-11.c new file mode 100644 index 000000000..c5ac3c434 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-11.c @@ -0,0 +1,276 @@ +#include <omp.h> +#include <stdlib.h> +#include <string.h> + +int +test1 (void) +{ + short int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[10]; &buf[54] > p; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[3]; &buf[63] >= p; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[16]; &buf[51] > p; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[16]; &buf[40] >= p; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[53]; &buf[9] < p; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[63]; &buf[3] <= p; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[48]; &buf[15] < p; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[40]; &buf[16] <= p; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +test2 (void) +{ + int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[10]; &buf[54] > p; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[3]; &buf[63] >= p; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[16]; &buf[51] > p; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[16]; &buf[40] >= p; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[53]; &buf[9] < p; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[63]; &buf[3] <= p; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[48]; &buf[15] < p; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[40]; &buf[16] <= p; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +test3 (void) +{ + int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[10]; &buf[54] > p; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[3]; &buf[63] >= p; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[16]; &buf[51] > p; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[16]; &buf[40] >= p; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[53]; &buf[9] < p; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[63]; &buf[3] <= p; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[48]; &buf[15] < p; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[40]; &buf[16] <= p; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +test4 (void) +{ + int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[10]; &buf[54] > p; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[3]; &buf[63] >= p; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[16]; &buf[51] > p; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[16]; &buf[40] >= p; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[53]; &buf[9] < p; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[63]; &buf[3] <= p; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[48]; &buf[15] < p; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[40]; &buf[16] <= p; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +main (void) +{ + test1 (); + test2 (); + test3 (); + omp_set_schedule (omp_sched_static, 0); + test4 (); + omp_set_schedule (omp_sched_static, 3); + test4 (); + omp_set_schedule (omp_sched_dynamic, 5); + test4 (); + omp_set_schedule (omp_sched_guided, 2); + test4 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-12.c b/libgomp/testsuite/libgomp.c/loop-12.c new file mode 100644 index 000000000..395da363e --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-12.c @@ -0,0 +1,387 @@ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (void); + +#define LLONG_MAX __LONG_LONG_MAX__ +#define ULLONG_MAX (LLONG_MAX * 2ULL + 1) +#define INT_MAX __INT_MAX__ + +int arr[6 * 5]; + +void +set (int loopidx, int idx) +{ +#pragma omp atomic + arr[loopidx * 5 + idx]++; +} + +#define check(var, val, loopidx, idx) \ + if (var == (val)) set (loopidx, idx); else +#define test(loopidx, count) \ + for (idx = 0; idx < 5; idx++) \ + if (arr[loopidx * 5 + idx] != idx < count) \ + abort (); \ + else \ + arr[loopidx * 5 + idx] = 0 + +int +test1 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(dynamic,1) nowait + for (i = LLONG_MAX - 30001; LLONG_MAX - 10001 >= i; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (i = -LLONG_MAX + 30000; -LLONG_MAX + 10000 <= i; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (j = 20; LLONG_MAX - 70 >= j; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (j = ULLONG_MAX - 3; LLONG_MAX + 70ULL <= j; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (j = LLONG_MAX - 20000ULL; LLONG_MAX + 10000ULL >= j; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (i = -3LL * INT_MAX - 20000LL; INT_MAX + 10000LL >= i; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test2 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(guided,1) nowait + for (i = LLONG_MAX - 30001; LLONG_MAX - 10001 >= i; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (i = -LLONG_MAX + 30000; -LLONG_MAX + 10000 <= i; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (j = 20; LLONG_MAX - 70 >= j; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (j = ULLONG_MAX - 3; LLONG_MAX + 70ULL <= j; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (j = LLONG_MAX - 20000ULL; LLONG_MAX + 10000ULL >= j; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (i = -3LL * INT_MAX - 20000LL; INT_MAX + 10000LL >= i; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test3 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(static) nowait + for (i = LLONG_MAX - 30001; LLONG_MAX - 10001 >= i; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(static) nowait + for (i = -LLONG_MAX + 30000; -LLONG_MAX + 10000 <= i; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(static) nowait + for (j = 20; LLONG_MAX - 70 >= j; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(static) nowait + for (j = ULLONG_MAX - 3; LLONG_MAX + 70ULL <= j; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(static) nowait + for (j = LLONG_MAX - 20000ULL; LLONG_MAX + 10000ULL >= j; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(static) nowait + for (i = -3LL * INT_MAX - 20000LL; INT_MAX + 10000LL >= i; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test4 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(static,1) nowait + for (i = LLONG_MAX - 30001; LLONG_MAX - 10001 >= i; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (i = -LLONG_MAX + 30000; -LLONG_MAX + 10000 <= i; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (j = 20; LLONG_MAX - 70 >= j; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (j = ULLONG_MAX - 3; LLONG_MAX + 70ULL <= j; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (j = LLONG_MAX - 20000ULL; LLONG_MAX + 10000ULL >= j; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (i = -3LL * INT_MAX - 20000LL; INT_MAX + 10000LL >= i; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test5 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(runtime) nowait + for (i = LLONG_MAX - 30001; LLONG_MAX - 10001 >= i; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (i = -LLONG_MAX + 30000; -LLONG_MAX + 10000 <= i; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (j = 20; LLONG_MAX - 70 >= j; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (j = ULLONG_MAX - 3; LLONG_MAX + 70ULL <= j; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (j = LLONG_MAX - 20000ULL; LLONG_MAX + 10000ULL >= j; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (i = -3LL * INT_MAX - 20000LL; INT_MAX + 10000LL >= i; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +main (void) +{ + if (2 * sizeof (int) != sizeof (long long)) + return 0; + test1 (); + test2 (); + test3 (); + test4 (); + omp_set_schedule (omp_sched_static, 0); + test5 (); + omp_set_schedule (omp_sched_static, 3); + test5 (); + omp_set_schedule (omp_sched_dynamic, 5); + test5 (); + omp_set_schedule (omp_sched_guided, 2); + test5 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-2.c b/libgomp/testsuite/libgomp.c/loop-2.c new file mode 100644 index 000000000..4bae023c7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-2.c @@ -0,0 +1,114 @@ +/* Validate static scheduling iteration dispatch. We only test with + even thread distributions here; there are multiple valid solutions + for uneven thread distributions. */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 360 +static int data[N][2]; +static int INCR, NTHR, CHUNK; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int n, i, c, thr, iter, chunk; + + chunk = CHUNK; + if (chunk == 0) + chunk = N / INCR / NTHR; + + thr = iter = c = i = 0; + + for (n = 0; n < N; ++n) + { + if (i == 0) + { + assert (data[n][0] == thr); + assert (data[n][1] == iter); + } + else + { + assert (data[n][0] == -1); + assert (data[n][1] == -1); + } + + if (++i == INCR) + { + i = 0; + if (++c == chunk) + { + c = 0; + if (++thr == NTHR) + { + thr = 0; + ++iter; + } + } + } + } +} + +static void set_data (long i, int thr, int iter) +{ + int old; + assert (i >= 0 && i < N); + old = __sync_lock_test_and_set (&data[i][0], thr); + assert (old == -1); + old = __sync_lock_test_and_set (&data[i][1], iter); + assert (old == -1); +} + +static void f_static_1 (void *dummy) +{ + int iam = omp_get_thread_num (); + long s0, e0, i, count = 0; + if (GOMP_loop_static_start (0, N, INCR, CHUNK, &s0, &e0)) + do + { + for (i = s0; i < e0; i += INCR) + set_data (i, iam, count); + ++count; + } + while (GOMP_loop_static_next (&s0, &e0)); + GOMP_loop_end (); +} + +static void test (void) +{ + clean_data (); + GOMP_parallel_start (f_static_1, NULL, NTHR); + f_static_1 (NULL); + GOMP_parallel_end (); + test_data (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 5; + + INCR = 1, CHUNK = 0; /* chunk = 360 / 5 = 72 */ + test (); + + INCR = 4, CHUNK = 0; /* chunk = 360 / 4 / 5 = 18 */ + test (); + + INCR = 1, CHUNK = 4; /* 1 * 4 * 5 = 20 -> 360 / 20 = 18 iterations. */ + test (); + + INCR = 3, CHUNK = 4; /* 3 * 4 * 5 = 60 -> 360 / 60 = 6 iterations. */ + test (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-3.c b/libgomp/testsuite/libgomp.c/loop-3.c new file mode 100644 index 000000000..f0f9b4705 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-3.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +extern void abort (void); + +volatile int count; +static int test(void) +{ + return ++count > 0; +} + +int i; + +int main() +{ + #pragma omp for lastprivate (i) + for (i = 0; i < 10; ++i) + { + if (test()) + continue; + abort (); + } + if (i != count) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-4.c b/libgomp/testsuite/libgomp.c/loop-4.c new file mode 100644 index 000000000..bc57c043a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-4.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +extern void abort (void); + +int +main (void) +{ + int e = 0; +#pragma omp parallel num_threads (4) reduction(+:e) + { + long i; + #pragma omp for schedule(dynamic,1) + for (i = __LONG_MAX__ - 30001; i <= __LONG_MAX__ - 10001; i += 10000) + if (i != __LONG_MAX__ - 30001 + && i != __LONG_MAX__ - 20001 + && i != __LONG_MAX__ - 10001) + e = 1; + #pragma omp for schedule(dynamic,1) + for (i = -__LONG_MAX__ + 30000; i >= -__LONG_MAX__ + 10000; i -= 10000) + if (i != -__LONG_MAX__ + 30000 + && i != -__LONG_MAX__ + 20000 + && i != -__LONG_MAX__ + 10000) + e = 1; + } + if (e) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-5.c b/libgomp/testsuite/libgomp.c/loop-5.c new file mode 100644 index 000000000..3a5c7cf45 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-5.c @@ -0,0 +1,276 @@ +#include <omp.h> +#include <stdlib.h> +#include <string.h> + +int +test1 (void) +{ + short int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[10]; p < &buf[54]; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[3]; p <= &buf[63]; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[16]; p < &buf[51]; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[16]; p <= &buf[40]; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[53]; p > &buf[9]; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[63]; p >= &buf[3]; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[48]; p > &buf[15]; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for + for (p = &buf[40]; p >= &buf[16]; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +test2 (void) +{ + int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[10]; p < &buf[54]; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[3]; p <= &buf[63]; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[16]; p < &buf[51]; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[16]; p <= &buf[40]; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[53]; p > &buf[9]; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[63]; p >= &buf[3]; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[48]; p > &buf[15]; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (static, 3) + for (p = &buf[40]; p >= &buf[16]; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +test3 (void) +{ + int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[10]; p < &buf[54]; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[3]; p <= &buf[63]; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[16]; p < &buf[51]; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[16]; p <= &buf[40]; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[53]; p > &buf[9]; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[63]; p >= &buf[3]; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[48]; p > &buf[15]; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (dynamic, 3) + for (p = &buf[40]; p >= &buf[16]; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +test4 (void) +{ + int buf[64], *p; + int i; + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[10]; p < &buf[54]; p++) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[3]; p <= &buf[63]; p += 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[16]; p < &buf[51]; p = 4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[16]; p <= &buf[40]; p = p + 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[53]; p > &buf[9]; --p) + *p = 5; + for (i = 0; i < 64; i++) + if (buf[i] != 5 * (i >= 10 && i < 54)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[63]; p >= &buf[3]; p -= 2) + p[-2] = 6; + for (i = 0; i < 64; i++) + if (buf[i] != 6 * ((i & 1) && i <= 61)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[48]; p > &buf[15]; p = -4 + p) + p[2] = 7; + for (i = 0; i < 64; i++) + if (buf[i] != 7 * ((i & 3) == 2 && i >= 18 && i < 53)) + abort (); + memset (buf, '\0', sizeof (buf)); +#pragma omp parallel for schedule (runtime) + for (p = &buf[40]; p >= &buf[16]; p = p - 4ULL) + p[2] = -7; + for (i = 0; i < 64; i++) + if (buf[i] != -7 * ((i & 3) == 2 && i >= 18 && i <= 42)) + abort (); + return 0; +} + +int +main (void) +{ + test1 (); + test2 (); + test3 (); + omp_set_schedule (omp_sched_static, 0); + test4 (); + omp_set_schedule (omp_sched_static, 3); + test4 (); + omp_set_schedule (omp_sched_dynamic, 5); + test4 (); + omp_set_schedule (omp_sched_guided, 2); + test4 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-6.c b/libgomp/testsuite/libgomp.c/loop-6.c new file mode 100644 index 000000000..9029e181b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-6.c @@ -0,0 +1,387 @@ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (void); + +#define LLONG_MAX __LONG_LONG_MAX__ +#define ULLONG_MAX (LLONG_MAX * 2ULL + 1) +#define INT_MAX __INT_MAX__ + +int arr[6 * 5]; + +void +set (int loopidx, int idx) +{ +#pragma omp atomic + arr[loopidx * 5 + idx]++; +} + +#define check(var, val, loopidx, idx) \ + if (var == (val)) set (loopidx, idx); else +#define test(loopidx, count) \ + for (idx = 0; idx < 5; idx++) \ + if (arr[loopidx * 5 + idx] != idx < count) \ + abort (); \ + else \ + arr[loopidx * 5 + idx] = 0 + +int +test1 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(dynamic,1) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (i = -LLONG_MAX + 30000; i >= -LLONG_MAX + 10000; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (j = 20; j <= LLONG_MAX - 70; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (j = LLONG_MAX - 20000ULL; j <= LLONG_MAX + 10000ULL; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(dynamic,1) nowait + for (i = -3LL * INT_MAX - 20000LL; i <= INT_MAX + 10000LL; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test2 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(guided,1) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (i = -LLONG_MAX + 30000; i >= -LLONG_MAX + 10000; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (j = 20; j <= LLONG_MAX - 70; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (j = LLONG_MAX - 20000ULL; j <= LLONG_MAX + 10000ULL; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(guided,1) nowait + for (i = -3LL * INT_MAX - 20000LL; i <= INT_MAX + 10000LL; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test3 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(static) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(static) nowait + for (i = -LLONG_MAX + 30000; i >= -LLONG_MAX + 10000; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(static) nowait + for (j = 20; j <= LLONG_MAX - 70; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(static) nowait + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(static) nowait + for (j = LLONG_MAX - 20000ULL; j <= LLONG_MAX + 10000ULL; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(static) nowait + for (i = -3LL * INT_MAX - 20000LL; i <= INT_MAX + 10000LL; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test4 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(static,1) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (i = -LLONG_MAX + 30000; i >= -LLONG_MAX + 10000; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (j = 20; j <= LLONG_MAX - 70; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (j = LLONG_MAX - 20000ULL; j <= LLONG_MAX + 10000ULL; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(static,1) nowait + for (i = -3LL * INT_MAX - 20000LL; i <= INT_MAX + 10000LL; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +test5 (void) +{ + int e = 0, idx; + +#pragma omp parallel reduction(+:e) + { + long long i; + unsigned long long j; + #pragma omp for schedule(runtime) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + { + check (i, LLONG_MAX - 30001, 0, 0) + check (i, LLONG_MAX - 20001, 0, 1) + check (i, LLONG_MAX - 10001, 0, 2) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (i = -LLONG_MAX + 30000; i >= -LLONG_MAX + 10000; i -= 10000) + { + check (i, -LLONG_MAX + 30000, 1, 0) + check (i, -LLONG_MAX + 20000, 1, 1) + check (i, -LLONG_MAX + 10000, 1, 2) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (j = 20; j <= LLONG_MAX - 70; j += LLONG_MAX + 50ULL) + { + check (j, 20, 2, 0) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + { + check (j, ULLONG_MAX - 3, 3, 0) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (j = LLONG_MAX - 20000ULL; j <= LLONG_MAX + 10000ULL; j += 10000ULL) + { + check (j, LLONG_MAX - 20000ULL, 4, 0) + check (j, LLONG_MAX - 10000ULL, 4, 1) + check (j, LLONG_MAX, 4, 2) + check (j, LLONG_MAX + 10000ULL, 4, 3) + e = 1; + } + #pragma omp for schedule(runtime) nowait + for (i = -3LL * INT_MAX - 20000LL; i <= INT_MAX + 10000LL; i += INT_MAX + 200LL) + { + check (i, -3LL * INT_MAX - 20000LL, 5, 0) + check (i, -2LL * INT_MAX - 20000LL + 200LL, 5, 1) + check (i, -INT_MAX - 20000LL + 400LL, 5, 2) + check (i, -20000LL + 600LL, 5, 3) + check (i, INT_MAX - 20000LL + 800LL, 5, 4) + e = 1; + } + } + if (e) + abort (); + test (0, 3); + test (1, 3); + test (2, 1); + test (3, 1); + test (4, 4); + test (5, 5); + return 0; +} + +int +main (void) +{ + if (2 * sizeof (int) != sizeof (long long)) + return 0; + test1 (); + test2 (); + test3 (); + test4 (); + omp_set_schedule (omp_sched_static, 0); + test5 (); + omp_set_schedule (omp_sched_static, 3); + test5 (); + omp_set_schedule (omp_sched_dynamic, 5); + test5 (); + omp_set_schedule (omp_sched_guided, 2); + test5 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-7.c b/libgomp/testsuite/libgomp.c/loop-7.c new file mode 100644 index 000000000..fc97f4a29 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-7.c @@ -0,0 +1,105 @@ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (void); + +#define LLONG_MAX __LONG_LONG_MAX__ +#define ULLONG_MAX (LLONG_MAX * 2ULL + 1) +#define INT_MAX __INT_MAX__ + +int v; + +int +test1 (void) +{ + int e = 0, cnt = 0; + long long i; + unsigned long long j; + char buf[6], *p; + + #pragma omp for schedule(dynamic,1) collapse(2) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + for (j = 20; j <= LLONG_MAX - 70; j += LLONG_MAX + 50ULL) + if ((i != LLONG_MAX - 30001 + && i != LLONG_MAX - 20001 + && i != LLONG_MAX - 10001) + || j != 20) + e = 1; + else + cnt++; + if (e || cnt != 3) + abort (); + else + cnt = 0; + + #pragma omp for schedule(guided,1) collapse(2) nowait + for (i = -LLONG_MAX + 30000; i >= -LLONG_MAX + 10000; i -= 10000) + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + if ((i != -LLONG_MAX + 30000 + && i != -LLONG_MAX + 20000 + && i != -LLONG_MAX + 10000) + || j != ULLONG_MAX - 3) + e = 1; + else + cnt++; + if (e || cnt != 3) + abort (); + else + cnt = 0; + + #pragma omp for schedule(static,1) collapse(2) nowait + for (i = LLONG_MAX - 30001; i <= LLONG_MAX - 10001; i += 10000) + for (j = 20; j <= LLONG_MAX - 70 + v; j += LLONG_MAX + 50ULL) + if ((i != LLONG_MAX - 30001 + && i != LLONG_MAX - 20001 + && i != LLONG_MAX - 10001) + || j != 20) + e = 1; + else + cnt++; + if (e || cnt != 3) + abort (); + else + cnt = 0; + + #pragma omp for schedule(static) collapse(2) nowait + for (i = -LLONG_MAX + 30000 + v; i >= -LLONG_MAX + 10000; i -= 10000) + for (j = ULLONG_MAX - 3; j >= LLONG_MAX + 70ULL; j -= LLONG_MAX + 50ULL) + if ((i != -LLONG_MAX + 30000 + && i != -LLONG_MAX + 20000 + && i != -LLONG_MAX + 10000) + || j != ULLONG_MAX - 3) + e = 1; + else + cnt++; + if (e || cnt != 3) + abort (); + else + cnt = 0; + + #pragma omp for schedule(runtime) collapse(2) nowait + for (i = 10; i < 30; i++) + for (p = buf; p <= buf + 4; p += 2) + if (i < 10 || i >= 30 || (p != buf && p != buf + 2 && p != buf + 4)) + e = 1; + else + cnt++; + if (e || cnt != 60) + abort (); + else + cnt = 0; + + return 0; +} + +int +main (void) +{ + if (2 * sizeof (int) != sizeof (long long)) + return 0; + asm volatile ("" : "+r" (v)); + omp_set_schedule (omp_sched_dynamic, 1); + test1 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-8.c b/libgomp/testsuite/libgomp.c/loop-8.c new file mode 100644 index 000000000..25db25c3b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-8.c @@ -0,0 +1,27 @@ +extern void abort (void); + +int buf[256]; + +void __attribute__((noinline)) +foo (void) +{ + int i; + #pragma omp for schedule (auto) + for (i = 0; i < 256; i++) + buf[i] += i; +} + +int +main (void) +{ + int i; + #pragma omp parallel for schedule (auto) + for (i = 0; i < 256; i++) + buf[i] = i; + #pragma omp parallel num_threads (4) + foo (); + for (i = 0; i < 256; i++) + if (buf[i] != 2 * i) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-9.c b/libgomp/testsuite/libgomp.c/loop-9.c new file mode 100644 index 000000000..1f789e12e --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-9.c @@ -0,0 +1,18 @@ +extern void abort (void); + +char buf[8] = "01234567"; +char buf2[8] = "23456789"; + +int +main (void) +{ + char *p, *q; + int sum = 0; + #pragma omp parallel for collapse (2) reduction (+:sum) lastprivate (p, q) + for (p = buf; p < &buf[8]; p++) + for (q = &buf2[0]; q <= buf2 + 7; q++) + sum += (*p - '0') + (*q - '0'); + if (p != &buf[8] || q != buf2 + 8 || sum != 576) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nested-1.c b/libgomp/testsuite/libgomp.c/nested-1.c new file mode 100644 index 000000000..d3cfb0100 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nested-1.c @@ -0,0 +1,30 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = -1, j = -1; + + omp_set_nested (1); + omp_set_dynamic (0); +#pragma omp parallel num_threads (4) + { +#pragma omp single + { + i = omp_get_thread_num () + omp_get_num_threads () * 256; +#pragma omp parallel num_threads (2) + { +#pragma omp single + { + j = omp_get_thread_num () + omp_get_num_threads () * 256; + } + } + } + } + if (i < 4 * 256 || i >= 4 * 256 + 4) + abort (); + if (j < 2 * 256 || j >= 2 * 256 + 2) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nested-2.c b/libgomp/testsuite/libgomp.c/nested-2.c new file mode 100644 index 000000000..f52b074ff --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nested-2.c @@ -0,0 +1,30 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = -1, j = -1; + + omp_set_nested (0); + omp_set_dynamic (0); +#pragma omp parallel num_threads (4) + { +#pragma omp single + { + i = omp_get_thread_num () + omp_get_num_threads () * 256; +#pragma omp parallel num_threads (2) + { +#pragma omp single + { + j = omp_get_thread_num () + omp_get_num_threads () * 256; + } + } + } + } + if (i < 4 * 256 || i >= 4 * 256 + 4) + abort (); + if (j != 256 + 0) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nested-3.c b/libgomp/testsuite/libgomp.c/nested-3.c new file mode 100644 index 000000000..618600633 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nested-3.c @@ -0,0 +1,89 @@ +#include <omp.h> +#include <stdlib.h> +#include <string.h> + +int +main (void) +{ + int e[3]; + + memset (e, '\0', sizeof (e)); + omp_set_nested (1); + omp_set_dynamic (0); + if (omp_in_parallel () + || omp_get_level () != 0 + || omp_get_ancestor_thread_num (0) != 0 + || omp_get_ancestor_thread_num (-1) != -1 + || omp_get_ancestor_thread_num (1) != -1 + || omp_get_team_size (0) != 1 + || omp_get_team_size (-1) != -1 + || omp_get_team_size (1) != -1 + || omp_get_active_level () != 0) + abort (); +#pragma omp parallel num_threads (4) + { + int tn1 = omp_get_thread_num (); + if (omp_in_parallel () != 1 + || omp_get_num_threads () != 4 + || tn1 >= 4 || tn1 < 0 + || omp_get_level () != 1 + || omp_get_ancestor_thread_num (0) != 0 + || omp_get_ancestor_thread_num (1) != tn1 + || omp_get_ancestor_thread_num (-1) != -1 + || omp_get_ancestor_thread_num (2) != -1 + || omp_get_team_size (0) != 1 + || omp_get_team_size (1) != omp_get_num_threads () + || omp_get_team_size (-1) != -1 + || omp_get_team_size (2) != -1 + || omp_get_active_level () != 1) + #pragma omp atomic + e[0] += 1; + #pragma omp parallel if (0) num_threads(5) firstprivate(tn1) + { + int tn2 = omp_get_thread_num (); + if (omp_in_parallel () != 1 + || omp_get_num_threads () != 1 + || tn2 != 0 + || omp_get_level () != 2 + || omp_get_ancestor_thread_num (0) != 0 + || omp_get_ancestor_thread_num (1) != tn1 + || omp_get_ancestor_thread_num (2) != tn2 + || omp_get_ancestor_thread_num (-1) != -1 + || omp_get_ancestor_thread_num (3) != -1 + || omp_get_team_size (0) != 1 + || omp_get_team_size (1) != 4 + || omp_get_team_size (2) != 1 + || omp_get_team_size (-1) != -1 + || omp_get_team_size (3) != -1 + || omp_get_active_level () != 1) + #pragma omp atomic + e[1] += 1; + #pragma omp parallel num_threads(2) firstprivate(tn1, tn2) + { + int tn3 = omp_get_thread_num (); + if (omp_in_parallel () != 1 + || omp_get_num_threads () != 2 + || tn3 > 1 || tn3 < 0 + || omp_get_level () != 3 + || omp_get_ancestor_thread_num (0) != 0 + || omp_get_ancestor_thread_num (1) != tn1 + || omp_get_ancestor_thread_num (2) != tn2 + || omp_get_ancestor_thread_num (3) != tn3 + || omp_get_ancestor_thread_num (-1) != -1 + || omp_get_ancestor_thread_num (4) != -1 + || omp_get_team_size (0) != 1 + || omp_get_team_size (1) != 4 + || omp_get_team_size (2) != 1 + || omp_get_team_size (3) != 2 + || omp_get_team_size (-1) != -1 + || omp_get_team_size (4) != -1 + || omp_get_active_level () != 2) + #pragma omp atomic + e[2] += 1; + } + } + } + if (e[0] || e[1] || e[2]) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-1.c b/libgomp/testsuite/libgomp.c/nestedfn-1.c new file mode 100644 index 000000000..26c0d237c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-1.c @@ -0,0 +1,49 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int a = 1, b = 2, c = 3; + void + foo (void) + { + int l = 0; +#pragma omp parallel shared (a) private (b) firstprivate (c) \ + num_threads (2) reduction (||:l) + { + if (a != 1 || c != 3) l = 1; +#pragma omp barrier + if (omp_get_thread_num () == 0) + { + a = 4; + b = 5; + c = 6; + } +#pragma omp barrier + if (omp_get_thread_num () == 1) + { + if (a != 4 || c != 3) l = 1; + a = 7; + b = 8; + c = 9; + } + else if (omp_get_num_threads () == 1) + a = 7; +#pragma omp barrier + if (omp_get_thread_num () == 0) + if (a != 7 || b != 5 || c != 6) l = 1; +#pragma omp barrier + if (omp_get_thread_num () == 1) + if (a != 7 || b != 8 || c != 9) l = 1; + } + if (l) + abort (); + } + foo (); + if (a != 7) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-2.c b/libgomp/testsuite/libgomp.c/nestedfn-2.c new file mode 100644 index 000000000..fdbbe0f73 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-2.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ + +extern void abort (void); + +int +main (void) +{ + int i; + void + foo (void) + { +#pragma omp master + i += 8; + } + i = 4; + foo (); + if (i != 12) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-3.c b/libgomp/testsuite/libgomp.c/nestedfn-3.c new file mode 100644 index 000000000..8f8847f97 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-3.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (void); + +int +main (void) +{ + int i = 5, l = 0; + int foo (void) { return i == 6; } + int bar (void) { return i - 3; } + + omp_set_dynamic (0); + +#pragma omp parallel if (foo ()) num_threads (bar ()) reduction (|:l) + if (omp_get_num_threads () != 1) + l = 1; + + i++; + +#pragma omp parallel if (foo ()) num_threads (bar ()) reduction (|:l) + if (omp_get_num_threads () != 3) + l = 1; + + i++; + +#pragma omp master + if (bar () != 4) + abort (); + +#pragma omp single + { + if (foo ()) + abort (); + i--; + if (! foo ()) + abort (); + } + + if (l) + abort (); + + i = 8; +#pragma omp atomic + l += bar (); + + if (l != 5) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-4.c b/libgomp/testsuite/libgomp.c/nestedfn-4.c new file mode 100644 index 000000000..dbe1062bd --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-4.c @@ -0,0 +1,65 @@ +/* PR middle-end/25261 */ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (void); + +int +main (void) +{ + int i = 5, j, l = 0; + int foo (void) + { + return i == 6; + } + int bar (void) + { + return i - 3; + } + + omp_set_dynamic (0); + +#pragma omp parallel if (foo ()) num_threads (2) + if (omp_get_num_threads () != 1) +#pragma omp atomic + l++; + +#pragma omp parallel for schedule (static, bar ()) num_threads (2) \ + reduction (|:l) + for (j = 0; j < 4; j++) + if (omp_get_thread_num () != (j >= 2)) +#pragma omp atomic + l++; + + i++; + +#pragma omp parallel if (foo ()) num_threads (2) + if (omp_get_num_threads () != 2) +#pragma omp atomic + l++; + +#pragma omp parallel for schedule (static, bar ()) num_threads (2) \ + reduction (|:l) + for (j = 0; j < 6; j++) + if (omp_get_thread_num () != (j >= 3)) +#pragma omp atomic + l++; + +#pragma omp parallel num_threads (4) reduction (|:l) + if (!foo () || bar () != 3) +#pragma omp atomic + l++; + + i++; + +#pragma omp parallel num_threads (4) reduction (|:l) + if (foo () || bar () != 4) +#pragma omp atomic + l++; + + if (l) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-5.c b/libgomp/testsuite/libgomp.c/nestedfn-5.c new file mode 100644 index 000000000..6072b1fe3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-5.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +void +foo (int *j) +{ + int i = 5; + int bar (void) { return i + 1; } +#pragma omp sections + { + #pragma omp section + { + if (bar () != 6) + #pragma omp atomic + ++*j; + } + #pragma omp section + { + if (bar () != 6) + #pragma omp atomic + ++*j; + } + } +} + +int +main (void) +{ + int j = 0; +#pragma omp parallel num_threads (2) + foo (&j); + if (j) + abort (); + return 0; +} + diff --git a/libgomp/testsuite/libgomp.c/nestedfn-6.c b/libgomp/testsuite/libgomp.c/nestedfn-6.c new file mode 100644 index 000000000..c0ace6b3f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-6.c @@ -0,0 +1,21 @@ +extern void abort (void); + +int j; + +int +main (void) +{ + int i; + void nested (void) { i = 0; } +#pragma omp parallel for lastprivate (i) + for (i = 0; i < 50; i += 3) + ; + if (i != 51) + abort (); +#pragma omp parallel for lastprivate (j) + for (j = -50; j < 70; j += 7) + ; + if (j != 76) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nqueens-1.c b/libgomp/testsuite/libgomp.c/nqueens-1.c new file mode 100644 index 000000000..1fdc67b29 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nqueens-1.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fopenmp" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdio.h> +#include <string.h> + +int cnt; +#pragma omp threadprivate (cnt) + +void +nqueens (char *a, int n, int pos) +{ + /* b[i] = j means the queen in i-th row is in column j. */ + char b[pos + 1]; + int i, j; + memcpy (b, a, pos); + for (i = 0; i < n; i++) + { + for (j = 0; j < pos; j++) + if (b[j] == i || b[j] == i + pos - j || i == b[j] + pos - j) + break; + if (j < pos) + continue; + if (pos == n - 1) + /* Found a solution. Could output it here. */ + ++cnt; + else + { + b[pos] = i; + #pragma omp task + nqueens (b, n, pos + 1); + } + } +} + +int +main (int argc, char **argv) +{ + int n = 8; + if (argc >= 2) + n = strtoul (argv[1], NULL, 0); + if (n < 1 || n > 127) + { + fprintf (stderr, "invalid count %d\n", n); + return 1; + } + cnt = 0; + double stime = omp_get_wtime (); + nqueens ("", n, 0); + printf ("serial N %d solutions # %d time %f\n", n, cnt, omp_get_wtime () - stime); + #pragma omp parallel + cnt = 0; + stime = omp_get_wtime (); + int tempcnt = 0; + #pragma omp parallel reduction (+:tempcnt) + { + #pragma omp single + nqueens ("", n, 0); + tempcnt = cnt; + } + cnt = tempcnt; + printf ("parallel N %d solutions # %d time %f\n", n, cnt, omp_get_wtime () - stime); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-loop01.c b/libgomp/testsuite/libgomp.c/omp-loop01.c new file mode 100644 index 000000000..0e83c9583 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-loop01.c @@ -0,0 +1,96 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <omp.h> + +#define MAX 1000 + +void main1() +{ + int i, N1, N2, step; + int a[MAX], b[MAX]; + + N1 = rand () % 13; + N2 = rand () % (MAX - 51) + 50; + step = rand () % 7 + 1; + + printf ("N1 = %d\nN2 = %d\nstep = %d\n", N1, N2, step); + + for (i = N1; i <= N2; i += step) + a[i] = 42+ i; + + /* COUNTING UP (<). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N1; i < N2; i += step) + b[i] = a[i]; + } + + /* COUNTING UP (<). Check that all the cells were filled in properly. */ + for (i = N1; i < N2; i += step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i < %d; i += %d) [OK]\n", N1, N2, step); + + /* COUNTING UP (<=). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N1; i <= N2; i += step) + b[i] = a[i]; + } + + /* COUNTING UP (<=). Check that all the cells were filled in properly. */ + for (i = N1; i <= N2; i += step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i <= %d; i += %d) [OK]\n", N1, N2, step); + + /* COUNTING DOWN (>). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N2; i > N1; i -= step) + b[i] = a[i]; + } + + /* COUNTING DOWN (>). Check that all the cells were filled in properly. */ + for (i = N2; i > N1; i -= step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i > %d; i -= %d) [OK]\n", N2, N1, step); + + /* COUNTING DOWN (>=). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N2; i >= N1; i -= step) + b[i] = a[i]; + } + + /* COUNTING DOWN (>=). Check that all the cells were filled in properly. */ + for (i = N2; i >= N1; i -= step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i >= %d; i -= %d) [OK]\n", N2, N1, step); +} + +int +main () +{ + int i; + + srand (0); + for (i = 0; i < 10; ++i) + main1(); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-loop02.c b/libgomp/testsuite/libgomp.c/omp-loop02.c new file mode 100644 index 000000000..04aaea2e3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-loop02.c @@ -0,0 +1,32 @@ +#include <omp.h> + +/* Orphaned work sharing. */ + +extern void abort (void); + +#define N 10 + +void parloop (int *a) +{ + int i; + +#pragma omp for + for (i = 0; i < N; i++) + a[i] = i + 3; +} + +main() +{ + int i, a[N]; + +#pragma omp parallel shared(a) + { + parloop (a); + } + + for (i = 0; i < N; i++) + if (a[i] != i + 3) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-loop03.c b/libgomp/testsuite/libgomp.c/omp-loop03.c new file mode 100644 index 000000000..7bb9a1943 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-loop03.c @@ -0,0 +1,26 @@ +extern void abort (void); +int a; + +void +foo () +{ + int i; + a = 30; +#pragma omp barrier +#pragma omp for lastprivate (a) + for (i = 0; i < 1024; i++) + { + a = i; + } + if (a != 1023) + abort (); +} + +int +main (void) +{ +#pragma omp parallel num_threads (64) + foo (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-nested-1.c b/libgomp/testsuite/libgomp.c/omp-nested-1.c new file mode 100644 index 000000000..655ef26fa --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-nested-1.c @@ -0,0 +1,28 @@ +// { dg-do run } + +extern void abort(void); +#define N 1000 + +int foo() +{ + int i = 0, j; + + #pragma omp parallel for num_threads(2) shared (i) + for (j = 0; j < N; ++j) + { + #pragma omp parallel num_threads(1) shared (i) + { + #pragma omp atomic + i++; + } + } + + return i; +} + +int main() +{ + if (foo() != N) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-parallel-for.c b/libgomp/testsuite/libgomp.c/omp-parallel-for.c new file mode 100644 index 000000000..c6631a0a7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-parallel-for.c @@ -0,0 +1,20 @@ +extern void abort (void); + +main() +{ + int i, a; + + a = 30; + +#pragma omp parallel for firstprivate (a) lastprivate (a) \ + num_threads (2) schedule(static) + for (i = 0; i < 10; i++) + a = a + i; + + /* The thread that owns the last iteration will have computed + 30 + 5 + 6 + 7 + 8 + 9 = 65. */ + if (a != 65) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-parallel-if.c b/libgomp/testsuite/libgomp.c/omp-parallel-if.c new file mode 100644 index 000000000..5e378359a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-parallel-if.c @@ -0,0 +1,40 @@ +#include <omp.h> + +extern void abort (void); + +int +foo (void) +{ + return 10; +} + +main () +{ + int A = 0; + + #pragma omp parallel if (foo () > 10) shared (A) + { + A = omp_get_num_threads (); + } + + if (A != 1) + abort (); + + #pragma omp parallel if (foo () == 10) num_threads (3) shared (A) + { + A = omp_get_num_threads (); + } + + if (A != 3) + abort (); + + #pragma omp parallel if (foo () == 10) num_threads (foo ()) shared (A) + { + A = omp_get_num_threads (); + } + + if (A != 10) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-single-1.c b/libgomp/testsuite/libgomp.c/omp-single-1.c new file mode 100644 index 000000000..a44ca54ac --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-single-1.c @@ -0,0 +1,19 @@ +extern void abort (void); + +main() +{ + int i = 0; + + #pragma omp parallel shared (i) + { + #pragma omp single + { + i++; + } + } + + if (i != 1) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-single-2.c b/libgomp/testsuite/libgomp.c/omp-single-2.c new file mode 100644 index 000000000..687855973 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-single-2.c @@ -0,0 +1,38 @@ +#include <omp.h> + +extern void abort (void); + +struct X +{ + int a; + char b; + int c; +}; + +main() +{ + int i = 0; + struct X x; + int bad = 0; + + #pragma omp parallel private (i, x) shared (bad) + { + i = 5; + + #pragma omp single copyprivate (i, x) + { + i++; + x.a = 23; + x.b = 42; + x.c = 26; + } + + if (i != 6 || x.a != 23 || x.b != 42 || x.c != 26) + bad = 1; + } + + if (bad) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-single-3.c b/libgomp/testsuite/libgomp.c/omp-single-3.c new file mode 100644 index 000000000..5a0653244 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-single-3.c @@ -0,0 +1,21 @@ +extern void abort (void); + +void +single (int a, int b) +{ + #pragma omp single copyprivate(a) copyprivate(b) + { + a = b = 5; + } + + if (a != b) + abort (); +} + +int main() +{ + #pragma omp parallel + single (1, 2); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_hello.c b/libgomp/testsuite/libgomp.c/omp_hello.c new file mode 100644 index 000000000..8d58cd43b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_hello.c @@ -0,0 +1,39 @@ +/****************************************************************************** +* FILE: omp_hello.c +* DESCRIPTION: +* OpenMP Example - Hello World - C/C++ Version +* In this simple example, the master thread forks a parallel region. +* All threads in the team obtain their unique thread number and print it. +* The master thread only prints the total number of threads. Two OpenMP +* library routines are used to obtain the number of threads and each +* thread's number. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) { + +int nthreads, tid; + +/* Fork a team of threads giving them their own copies of variables */ +#pragma omp parallel private(nthreads, tid) + { + + /* Obtain thread number */ + tid = omp_get_thread_num(); + printf("Hello World from thread = %d\n", tid); + + /* Only master thread does this */ + if (tid == 0) + { + nthreads = omp_get_num_threads(); + printf("Number of threads = %d\n", nthreads); + } + + } /* All threads join master thread and disband */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_matvec.c b/libgomp/testsuite/libgomp.c/omp_matvec.c new file mode 100644 index 000000000..12b8c6896 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_matvec.c @@ -0,0 +1,72 @@ +/****************************************************************************** +* OpenMP Example - Matrix-vector multiplication - C/C++ Version +* FILE: omp_matvec.c +* DESCRIPTION: +* This example multiplies all row i elements of matrix A with vector +* element b(i) and stores the summed products in vector c(i). A total is +* maintained for the entire matrix. Performed by using the OpenMP loop +* work-sharing construct. The update of the shared global total is +* serialized by using the OpenMP critical directive. +* SOURCE: Blaise Barney 5/99 +* LAST REVISED: +******************************************************************************/ + +#include <omp.h> +#include <stdio.h> +#define SIZE 10 + + +main () +{ + +float A[SIZE][SIZE], b[SIZE], c[SIZE], total; +int i, j, tid; + +/* Initializations */ +total = 0.0; +for (i=0; i < SIZE; i++) + { + for (j=0; j < SIZE; j++) + A[i][j] = (j+1) * 1.0; + b[i] = 1.0 * (i+1); + c[i] = 0.0; + } +printf("\nStarting values of matrix A and vector b:\n"); +for (i=0; i < SIZE; i++) + { + printf(" A[%d]= ",i); + for (j=0; j < SIZE; j++) + printf("%.1f ",A[i][j]); + printf(" b[%d]= %.1f\n",i,b[i]); + } +printf("\nResults by thread/row:\n"); + +/* Create a team of threads and scope variables */ +#pragma omp parallel shared(A,b,c,total) private(tid,i) + { + tid = omp_get_thread_num(); + +/* Loop work-sharing construct - distribute rows of matrix */ +#pragma omp for private(j) + for (i=0; i < SIZE; i++) + { + for (j=0; j < SIZE; j++) + c[i] += (A[i][j] * b[i]); + + /* Update and display of running total must be serialized */ + #pragma omp critical + { + total = total + c[i]; + printf(" thread %d did row %d\t c[%d]=%.2f\t",tid,i,i,c[i]); + printf("Running total= %.2f\n",total); + } + + } /* end of parallel i loop */ + + } /* end of parallel construct */ + +printf("\nMatrix-vector total - sum of all c[] = %.2f\n\n",total); + + return 0; +} + diff --git a/libgomp/testsuite/libgomp.c/omp_orphan.c b/libgomp/testsuite/libgomp.c/omp_orphan.c new file mode 100644 index 000000000..cbf7abf37 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_orphan.c @@ -0,0 +1,47 @@ +/****************************************************************************** +* FILE: omp_orphan.c +* DESCRIPTION: +* OpenMP Example - Parallel region with an orphaned directive - C/C++ Version +* This example demonstrates a dot product being performed by an orphaned +* loop reduction construct. Scoping of the reduction variable is critical. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#define VECLEN 100 + +float a[VECLEN], b[VECLEN], sum; + +float dotprod () +{ +int i,tid; + +tid = omp_get_thread_num(); +#pragma omp for reduction(+:sum) + for (i=0; i < VECLEN; i++) + { + sum = sum + (a[i]*b[i]); + printf(" tid= %d i=%d\n",tid,i); + } + +return(sum); +} + + +int main (int argc, char *argv[]) +{ +int i; + +for (i=0; i < VECLEN; i++) + a[i] = b[i] = 1.0 * i; +sum = 0.0; + +#pragma omp parallel + sum = dotprod(); + +printf("Sum = %f\n",sum); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_reduction.c b/libgomp/testsuite/libgomp.c/omp_reduction.c new file mode 100644 index 000000000..5c9c41ec7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_reduction.c @@ -0,0 +1,35 @@ +/****************************************************************************** +* FILE: omp_reduction.c +* DESCRIPTION: +* OpenMP Example - Combined Parallel Loop Reduction - C/C++ Version +* This example demonstrates a sum reduction within a combined parallel loop +* construct. Notice that default data element scoping is assumed - there +* are no clauses specifying shared or private variables. OpenMP will +* automatically make loop index variables private within team threads, and +* global variables shared. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) { + +int i, n; +float a[100], b[100], sum; + +/* Some initializations */ +n = 100; +for (i=0; i < n; i++) + a[i] = b[i] = i * 1.0; +sum = 0.0; + +#pragma omp parallel for reduction(+:sum) + for (i=0; i < n; i++) + sum = sum + (a[i] * b[i]); + +printf(" Sum = %f\n",sum); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare1.c b/libgomp/testsuite/libgomp.c/omp_workshare1.c new file mode 100644 index 000000000..e33bef316 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare1.c @@ -0,0 +1,47 @@ +/****************************************************************************** +* FILE: omp_workshare1.c +* DESCRIPTION: +* OpenMP Example - Loop Work-sharing - C/C++ Version +* In this example, the iterations of a loop are scheduled dynamically +* across the team of threads. A thread will perform CHUNK iterations +* at a time before being scheduled for the next CHUNK of work. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#define CHUNKSIZE 10 +#define N 100 + +int main (int argc, char *argv[]) { + +int nthreads, tid, i, chunk; +float a[N], b[N], c[N]; + +/* Some initializations */ +for (i=0; i < N; i++) + a[i] = b[i] = i * 1.0; +chunk = CHUNKSIZE; + +#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,tid) + { + tid = omp_get_thread_num(); + if (tid == 0) + { + nthreads = omp_get_num_threads(); + printf("Number of threads = %d\n", nthreads); + } + printf("Thread %d starting...\n",tid); + + #pragma omp for schedule(dynamic,chunk) + for (i=0; i<N; i++) + { + c[i] = a[i] + b[i]; + printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); + } + + } /* end of parallel section */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare2.c b/libgomp/testsuite/libgomp.c/omp_workshare2.c new file mode 100644 index 000000000..32c93dbde --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare2.c @@ -0,0 +1,64 @@ +/****************************************************************************** +* FILE: omp_workshare2.c +* DESCRIPTION: +* OpenMP Example - Sections Work-sharing - C/C++ Version +* In this example, the OpenMP SECTION directive is used to assign +* different array operations to threads that execute a SECTION. Each +* thread receives its own copy of the result array to work with. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#define N 50 + +int main (int argc, char *argv[]) { + +int i, nthreads, tid; +float a[N], b[N], c[N]; + +/* Some initializations */ +for (i=0; i<N; i++) + a[i] = b[i] = i * 1.0; + +#pragma omp parallel shared(a,b,nthreads) private(c,i,tid) + { + tid = omp_get_thread_num(); + if (tid == 0) + { + nthreads = omp_get_num_threads(); + printf("Number of threads = %d\n", nthreads); + } + printf("Thread %d starting...\n",tid); + + #pragma omp sections nowait + { + #pragma omp section + { + printf("Thread %d doing section 1\n",tid); + for (i=0; i<N; i++) + { + c[i] = a[i] + b[i]; + printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); + } + } + + #pragma omp section + { + printf("Thread %d doing section 2\n",tid); + for (i=0; i<N; i++) + { + c[i] = a[i] * b[i]; + printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); + } + } + + } /* end of sections */ + + printf("Thread %d done.\n",tid); + + } /* end of parallel section */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare3.c b/libgomp/testsuite/libgomp.c/omp_workshare3.c new file mode 100644 index 000000000..913f1f731 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare3.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ + +/****************************************************************************** +* OpenMP Example - Combined Parallel Loop Work-sharing - C/C++ Version +* FILE: omp_workshare3.c +* DESCRIPTION: +* This example attempts to show use of the parallel for construct. However +* it will generate errors at compile time. Try to determine what is causing +* the error. See omp_workshare4.c for a corrected version. +* SOURCE: Blaise Barney 5/99 +* LAST REVISED: 03/03/2002 +******************************************************************************/ + +#include <omp.h> +#include <stdio.h> +#define N 50 +#define CHUNKSIZE 5 + +main () { + +int i, chunk, tid; +float a[N], b[N], c[N]; + +/* Some initializations */ +for (i=0; i < N; i++) + a[i] = b[i] = i * 1.0; +chunk = CHUNKSIZE; + +#pragma omp parallel for \ + shared(a,b,c,chunk) \ + private(i,tid) \ + schedule(static,chunk) + { /* { dg-error "expected" } */ + tid = omp_get_thread_num(); + for (i=0; i < N; i++) + { + c[i] = a[i] + b[i]; + printf("tid= %d i= %d c[i]= %f\n", tid, i, c[i]); + } + } /* end of parallel for construct */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare4.c b/libgomp/testsuite/libgomp.c/omp_workshare4.c new file mode 100644 index 000000000..67605e38b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare4.c @@ -0,0 +1,48 @@ +/****************************************************************************** +* OpenMP Example - Combined Parallel Loop Work-sharing - C/C++ Version +* FILE: omp_workshare4.c +* DESCRIPTION: +* This is a corrected version of the omp_workshare3.c example. Corrections +* include removing all statements between the parallel for construct and +* the actual for loop, and introducing logic to preserve the ability to +* query a thread's id and print it from inside the for loop. +* SOURCE: Blaise Barney 5/99 +* LAST REVISED: 03/03/2002 +******************************************************************************/ + +#include <omp.h> +#include <stdio.h> +#define N 50 +#define CHUNKSIZE 5 + +main () { + +int i, chunk, tid; +float a[N], b[N], c[N]; +char first_time; + +/* Some initializations */ +for (i=0; i < N; i++) + a[i] = b[i] = i * 1.0; +chunk = CHUNKSIZE; +first_time = 'y'; + +#pragma omp parallel for \ + shared(a,b,c,chunk) \ + private(i,tid) \ + schedule(static,chunk) \ + firstprivate(first_time) + + for (i=0; i < N; i++) + { + if (first_time == 'y') + { + tid = omp_get_thread_num(); + first_time = 'n'; + } + c[i] = a[i] + b[i]; + printf("tid= %d i= %d c[i]= %f\n", tid, i, c[i]); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/ordered-1.c b/libgomp/testsuite/libgomp.c/ordered-1.c new file mode 100644 index 000000000..c6143fac2 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/ordered-1.c @@ -0,0 +1,115 @@ +/* Test that all loop iterations are touched. This doesn't verify + scheduling order, merely coverage. */ +/* Note that we never call GOMP_ordered_start in here. AFAICS, this is + valid; the only requirement is "not more than once per iteration". */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 1000 +static int S, E, INCR, CHUNK, NTHR; +static int data[N]; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int i, j; + + for (i = 0; i < S; ++i) + assert (data[i] == -1); + + for (j = 0; i < E; ++i, j = (j + 1) % INCR) + if (j == 0) + assert (data[i] != -1); + else + assert (data[i] == -1); + + for (; i < N; ++i) + assert (data[i] == -1); +} + +static void set_data (long i, int val) +{ + int old; + assert (i >= 0 && i < N); + old = __sync_lock_test_and_set (data+i, val); + assert (old == -1); +} + + +#define TMPL_1(sched) \ +static void f_##sched##_1 (void *dummy) \ +{ \ + int iam = omp_get_thread_num (); \ + long s0, e0, i; \ + if (GOMP_loop_ordered_##sched##_start (S, E, INCR, CHUNK, &s0, &e0)) \ + do \ + { \ + for (i = s0; i < e0; i += INCR) \ + set_data (i, iam); \ + } \ + while (GOMP_loop_ordered_##sched##_next (&s0, &e0)); \ + GOMP_loop_end (); \ +} \ +static void t_##sched##_1 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ + f_##sched##_1 (NULL); \ + GOMP_parallel_end (); \ + test_data (); \ +} + +TMPL_1(static) +TMPL_1(dynamic) +TMPL_1(guided) + +static void test (void) +{ + t_static_1 (); + t_dynamic_1 (); + t_guided_1 (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + S = 0, E = N, INCR = 1, CHUNK = 4; + test (); + + S = 0, E = N, INCR = 2, CHUNK = 4; + test (); + + S = 1, E = N-1, INCR = 1, CHUNK = 5; + test (); + + S = 1, E = N-1, INCR = 2, CHUNK = 5; + test (); + + S = 2, E = 4, INCR = 1, CHUNK = 1; + test (); + + S = 0, E = N, INCR = 1, CHUNK = 0; + t_static_1 (); + + S = 1, E = N-1, INCR = 1, CHUNK = 0; + t_static_1 (); + + NTHR = 10; + S = 1, E = 9, INCR = 1, CHUNK = 0; + t_static_1 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/ordered-2.c b/libgomp/testsuite/libgomp.c/ordered-2.c new file mode 100644 index 000000000..91564371a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/ordered-2.c @@ -0,0 +1,82 @@ +/* Trivial test of ordered. */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 100 +static int next; +static int CHUNK, NTHR; + +static void clean_data (void) +{ + next = 0; +} + +static void set_data (long i) +{ + int n = __sync_fetch_and_add (&next, 1); + assert (n == i); +} + + +#define TMPL_1(sched) \ +static void f_##sched##_1 (void *dummy) \ +{ \ + long s0, e0, i; \ + if (GOMP_loop_ordered_##sched##_start (0, N, 1, CHUNK, &s0, &e0)) \ + do \ + { \ + for (i = s0; i < e0; ++i) \ + { \ + GOMP_ordered_start (); \ + set_data (i); \ + GOMP_ordered_end (); \ + } \ + } \ + while (GOMP_loop_ordered_##sched##_next (&s0, &e0)); \ + GOMP_loop_end (); \ +} \ +static void t_##sched##_1 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ + f_##sched##_1 (NULL); \ + GOMP_parallel_end (); \ +} + +TMPL_1(static) +TMPL_1(dynamic) +TMPL_1(guided) + +static void test (void) +{ + t_static_1 (); + t_dynamic_1 (); + t_guided_1 (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + CHUNK = 1; + test (); + + CHUNK = 5; + test (); + + CHUNK = 7; + test (); + + CHUNK = 0; + t_static_1 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/ordered-3.c b/libgomp/testsuite/libgomp.c/ordered-3.c new file mode 100644 index 000000000..2a2f21970 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/ordered-3.c @@ -0,0 +1,82 @@ +#include <stdlib.h> + +int cnt; + +void +check (int x) +{ + if (cnt++ != x) + abort (); +} + +int +main (void) +{ + int j; + + cnt = 0; +#pragma omp parallel for ordered schedule (static, 1) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (static, 1) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (runtime) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (runtime) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (dynamic) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (dynamic) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (guided) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (guided) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/parallel-1.c b/libgomp/testsuite/libgomp.c/parallel-1.c new file mode 100644 index 000000000..031f5bf88 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/parallel-1.c @@ -0,0 +1,48 @@ +/* Trivial test of thread startup. */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +static int nthr; +static int saw[4]; + +static void function(void *dummy) +{ + int iam = omp_get_thread_num (); + + if (iam == 0) + nthr = omp_get_num_threads (); + + saw[iam] = 1; +} + +int main() +{ + omp_set_dynamic (0); + + GOMP_parallel_start (function, NULL, 2); + function (NULL); + GOMP_parallel_end (); + + assert (nthr == 2); + assert (saw[0] != 0); + assert (saw[1] != 0); + assert (saw[2] == 0); + + memset (saw, 0, sizeof (saw)); + + GOMP_parallel_start (function, NULL, 3); + function (NULL); + GOMP_parallel_end (); + + assert (nthr == 3); + assert (saw[0] != 0); + assert (saw[1] != 0); + assert (saw[2] != 0); + assert (saw[3] == 0); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr24455-1.c b/libgomp/testsuite/libgomp.c/pr24455-1.c new file mode 100644 index 000000000..c39068f80 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr24455-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target tls } */ +extern int i; +#pragma omp threadprivate (i) + +int i; diff --git a/libgomp/testsuite/libgomp.c/pr24455.c b/libgomp/testsuite/libgomp.c/pr24455.c new file mode 100644 index 000000000..8af449e7b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr24455.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-additional-sources pr24455-1.c } */ +/* { dg-require-effective-target tls_runtime } */ + +extern void abort (void); + +extern int i; +#pragma omp threadprivate(i) + +int main() +{ + i = 0; + +#pragma omp parallel default(none) num_threads(10) + { + i++; +#pragma omp barrier + if (i != 1) + abort (); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr26171.c b/libgomp/testsuite/libgomp.c/pr26171.c new file mode 100644 index 000000000..eacc9a71d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr26171.c @@ -0,0 +1,14 @@ +/* PR c/26171 */ +/* { dg-do run } */ +/* { dg-options "-fopenmp" } */ +/* { dg-require-effective-target tls_runtime } */ + +int thrv = 0; +#pragma omp threadprivate (thrv) + +int +main () +{ + thrv = 1; + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr26943-1.c b/libgomp/testsuite/libgomp.c/pr26943-1.c new file mode 100644 index 000000000..86c43f04b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr26943-1.c @@ -0,0 +1,24 @@ +/* PR c++/26943 */ +/* { dg-do run } */ + +extern void abort (void); +extern void omp_set_dynamic (int); +int n = 6; + +int +main (void) +{ + int i, x = 0; + omp_set_dynamic (0); +#pragma omp parallel for num_threads (16) firstprivate (n) lastprivate (n) \ + schedule (static, 1) reduction (+: x) + for (i = 0; i < 16; i++) + { + if (n != 6) + ++x; + n = i; + } + if (x || n != 15) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr26943-2.c b/libgomp/testsuite/libgomp.c/pr26943-2.c new file mode 100644 index 000000000..c052e8112 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr26943-2.c @@ -0,0 +1,47 @@ +/* PR c++/26943 */ +/* { dg-do run } */ + +extern int omp_set_dynamic (int); +extern void abort (void); + +int a = 8, b = 12, c = 16, d = 20, j = 0; +char e[10] = "a", f[10] = "b", g[10] = "c", h[10] = "d"; + +int +main (void) +{ + int i; + omp_set_dynamic (0); +#pragma omp parallel for shared (a, e) firstprivate (b, f) \ + lastprivate (c, g) private (d, h) \ + schedule (static, 1) num_threads (4) \ + reduction (+:j) + for (i = 0; i < 4; i++) + { + if (a != 8 || b != 12 || e[0] != 'a' || f[0] != 'b') + j++; +#pragma omp barrier /* { dg-warning "may not be closely nested" } */ +#pragma omp atomic + a += i; + b += i; + c = i; + d = i; +#pragma omp atomic + e[0] += i; + f[0] += i; + g[0] = 'g' + i; + h[0] = 'h' + i; +#pragma omp barrier /* { dg-warning "may not be closely nested" } */ + if (a != 8 + 6 || b != 12 + i || c != i || d != i) + j += 8; + if (e[0] != 'a' + 6 || f[0] != 'b' + i || g[0] != 'g' + i) + j += 64; + if (h[0] != 'h' + i) + j += 512; + } + if (j || a != 8 + 6 || b != 12 || c != 3 || d != 20) + abort (); + if (e[0] != 'a' + 6 || f[0] != 'b' || g[0] != 'g' + 3 || h[0] != 'd') + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr26943-3.c b/libgomp/testsuite/libgomp.c/pr26943-3.c new file mode 100644 index 000000000..dc3d5010d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr26943-3.c @@ -0,0 +1,56 @@ +/* PR c++/26943 */ +/* { dg-do run } */ + +extern int omp_set_dynamic (int); +extern int omp_get_thread_num (void); +extern void abort (void); + +int a = 8, b = 12, c = 16, d = 20, j = 0, l = 0; +char e[10] = "a", f[10] = "b", g[10] = "c", h[10] = "d"; +volatile int k; + +int +main (void) +{ + int i; + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel num_threads (2) reduction (+:l) + if (k == omp_get_thread_num ()) + { +#pragma omp parallel for shared (a, e) firstprivate (b, f) \ + lastprivate (c, g) private (d, h) \ + schedule (static, 1) num_threads (4) \ + reduction (+:j) + for (i = 0; i < 4; i++) + { + if (a != 8 || b != 12 || e[0] != 'a' || f[0] != 'b') + j++; +#pragma omp barrier /* { dg-warning "may not be closely nested" } */ +#pragma omp atomic + a += i; + b += i; + c = i; + d = i; +#pragma omp atomic + e[0] += i; + f[0] += i; + g[0] = 'g' + i; + h[0] = 'h' + i; +#pragma omp barrier /* { dg-warning "may not be closely nested" } */ + if (a != 8 + 6 || b != 12 + i || c != i || d != i) + j += 8; + if (e[0] != 'a' + 6 || f[0] != 'b' + i || g[0] != 'g' + i) + j += 64; + if (h[0] != 'h' + i) + j += 512; + } + if (j || a != 8 + 6 || b != 12 || c != 3 || d != 20) + ++l; + if (e[0] != 'a' + 6 || f[0] != 'b' || g[0] != 'g' + 3 || h[0] != 'd') + l += 8; + } + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr26943-4.c b/libgomp/testsuite/libgomp.c/pr26943-4.c new file mode 100644 index 000000000..0f1d4197a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr26943-4.c @@ -0,0 +1,61 @@ +/* PR c++/26943 */ +/* { dg-do run } */ + +extern int omp_set_dynamic (int); +extern int omp_get_thread_num (void); +extern void abort (void); + +int a = 8, b = 12, c = 16, d = 20, j = 0, l = 0; +char e[10] = "a", f[10] = "b", g[10] = "c", h[10] = "d"; +volatile int k; + +int +main (void) +{ + int i; + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel num_threads (2) reduction (+:l) \ + firstprivate (a, b, c, d, e, f, g, h, j) + if (k == omp_get_thread_num ()) + { +#pragma omp parallel for shared (a, e) firstprivate (b, f) \ + lastprivate (c, g) private (d, h) \ + schedule (static, 1) num_threads (4) \ + reduction (+:j) + for (i = 0; i < 4; i++) + { + if (a != 8 || b != 12 || e[0] != 'a' || f[0] != 'b') + j++; +#pragma omp barrier /* { dg-warning "may not be closely nested" } */ +#pragma omp atomic + a += i; + b += i; + c = i; + d = i; +#pragma omp atomic + e[0] += i; + f[0] += i; + g[0] = 'g' + i; + h[0] = 'h' + i; +#pragma omp barrier /* { dg-warning "may not be closely nested" } */ + if (a != 8 + 6 || b != 12 + i || c != i || d != i) + j += 8; + if (e[0] != 'a' + 6 || f[0] != 'b' + i || g[0] != 'g' + i) + j += 64; + if (h[0] != 'h' + i) + j += 512; + } + if (j || a != 8 + 6 || b != 12 || c != 3 || d != 20) + ++l; + if (e[0] != 'a' + 6 || f[0] != 'b' || g[0] != 'g' + 3 || h[0] != 'd') + l += 8; + } + if (l) + abort (); + if (a != 8 || b != 12 || c != 16 || d != 20) + abort (); + if (e[0] != 'a' || f[0] != 'b' || g[0] != 'c' || h[0] != 'd') + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr29947-1.c b/libgomp/testsuite/libgomp.c/pr29947-1.c new file mode 100644 index 000000000..509c63229 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr29947-1.c @@ -0,0 +1,328 @@ +/* PR libgomp/29947 */ + +/* { dg-do run } */ + +extern void abort (void); + +int cnt; + +void +test1 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (dynamic) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test2 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (dynamic) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test3 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (guided) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test4 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (guided) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test5 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (dynamic) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test6 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (dynamic) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test7 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (guided) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test8 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (guided) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test9 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (dynamic) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test10 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (dynamic) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test11 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (guided) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test12 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (guided) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test13 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (dynamic) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test14 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (dynamic) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test15 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (guided) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test16 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (guided) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +int +__attribute__((noinline)) +test (long j1, long k1, long j2, long k2) +{ + test1 (j1, k1, j2, k2); + test2 (j1, k1, j2, k2); + test3 (j1, k1, j2, k2); + test4 (j1, k1, j2, k2); + test5 (j1, k1, j2, k2); + test6 (j1, k1, j2, k2); + test7 (j1, k1, j2, k2); + test8 (j1, k1, j2, k2); + test9 (j1, k1, j2, k2); + test10 (j1, k1, j2, k2); + test11 (j1, k1, j2, k2); + test12 (j1, k1, j2, k2); + test13 (j1, k1, j2, k2); + test14 (j1, k1, j2, k2); + test15 (j1, k1, j2, k2); + test16 (j1, k1, j2, k2); + return cnt; +} + +int +main (void) +{ + test (1, 5, 1, 5); + test (5, 5, 5, 5); + test (5, 4, 5, 4); + test (5, 1, 5, 1); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr29947-2.c b/libgomp/testsuite/libgomp.c/pr29947-2.c new file mode 100644 index 000000000..097498311 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr29947-2.c @@ -0,0 +1,328 @@ +/* PR libgomp/29947 */ + +/* { dg-do run } */ + +extern void abort (void); + +int cnt; + +void +test1 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test2 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test3 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static, 1) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test4 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static, 1) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test5 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test6 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test7 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static, 1) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test8 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel reduction (+:e,c) + { +#pragma omp for schedule (static, 1) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } +#pragma omp atomic + ++cnt; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test9 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test10 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test11 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static, 1) + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test12 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static, 1) + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test13 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test14 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test15 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static, 1) ordered + for (i = j1; i <= k1; ++i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +void +test16 (long j1, long k1, long j2, long k2) +{ + long i, e = 0, c = 0; +#pragma omp parallel for reduction (+:e,c) schedule (static, 1) ordered + for (i = k1; i >= j1; --i) + { + if (i < j2 || i > k2) + ++e; +#pragma omp ordered + ++c; + } + if (e || (c != j2 > k2 ? 0 : k2 - j2 + 1)) + abort (); +} + +int +__attribute__((noinline)) +test (long j1, long k1, long j2, long k2) +{ + test1 (j1, k1, j2, k2); + test2 (j1, k1, j2, k2); + test3 (j1, k1, j2, k2); + test4 (j1, k1, j2, k2); + test5 (j1, k1, j2, k2); + test6 (j1, k1, j2, k2); + test7 (j1, k1, j2, k2); + test8 (j1, k1, j2, k2); + test9 (j1, k1, j2, k2); + test10 (j1, k1, j2, k2); + test11 (j1, k1, j2, k2); + test12 (j1, k1, j2, k2); + test13 (j1, k1, j2, k2); + test14 (j1, k1, j2, k2); + test15 (j1, k1, j2, k2); + test16 (j1, k1, j2, k2); + return cnt; +} + +int +main (void) +{ + test (1, 5, 1, 5); + test (5, 5, 5, 5); + test (5, 4, 5, 4); + test (5, 1, 5, 1); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr30494.c b/libgomp/testsuite/libgomp.c/pr30494.c new file mode 100644 index 000000000..ec6828e44 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr30494.c @@ -0,0 +1,64 @@ +/* PR middle-end/30494 */ +/* { dg-do run } */ + +#include <omp.h> + +int errors; + +int +check (int m, int i, int *v, int *w) +{ + int j; + int n = omp_get_thread_num (); + for (j = 0; j < m; j++) + if (v[j] != j + n) + #pragma omp atomic + errors += 1; + for (j = 0; j < m * 3 + i; j++) + if (w[j] != j + 10 + n) + #pragma omp atomic + errors += 1; +} + +int +foo (int n, int m) +{ + int i; +#pragma omp for + for (i = 0; i < 6; i++) + { + int v[n], w[n * 3 + i], j; + for (j = 0; j < n; j++) + v[j] = j + omp_get_thread_num (); + for (j = 0; j < n * 3 + i; j++) + w[j] = j + 10 + omp_get_thread_num (); + check (m, i, v, w); + } + return 0; +} + +int +bar (int n, int m) +{ + int i; +#pragma omp parallel for num_threads (4) + for (i = 0; i < 6; i++) + { + int v[n], w[n * 3 + i], j; + for (j = 0; j < n; j++) + v[j] = j + omp_get_thread_num (); + for (j = 0; j < n * 3 + i; j++) + w[j] = j + 10 + omp_get_thread_num (); + check (m, i, v, w); + } + return 0; +} + +int +main (void) +{ +#pragma omp parallel num_threads (3) + foo (128, 128); + bar (256, 256); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr32362-1.c b/libgomp/testsuite/libgomp.c/pr32362-1.c new file mode 100644 index 000000000..3c62d4bdb --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr32362-1.c @@ -0,0 +1,32 @@ +/* PR middle-end/32362 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include <omp.h> +#include <stdlib.h> + +int +main () +{ + int n[4] = { -1, -1, -1, -1 }; + static int a = 2, b = 4; + omp_set_num_threads (4); + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel private(b) + { + b = omp_get_thread_num (); +#pragma omp parallel firstprivate(a) + { + a = (omp_get_thread_num () + a) + 1; + if (b == omp_get_thread_num ()) + n[omp_get_thread_num ()] = a + (b << 4); + } + } + if (n[0] != 3) + abort (); + if (n[3] != -1 + && (n[1] != 0x14 || n[2] != 0x25 || n[3] != 0x36)) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr32362-2.c b/libgomp/testsuite/libgomp.c/pr32362-2.c new file mode 100644 index 000000000..43f36e0e9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr32362-2.c @@ -0,0 +1,33 @@ +/* PR middle-end/32362 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include <omp.h> +#include <stdlib.h> + +int a = 2, b = 4; + +int +main () +{ + int n[4] = { -1, -1, -1, -1 }; + omp_set_num_threads (4); + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel private(b) + { + b = omp_get_thread_num (); +#pragma omp parallel firstprivate(a) + { + a = (omp_get_thread_num () + a) + 1; + if (b == omp_get_thread_num ()) + n[omp_get_thread_num ()] = a + (b << 4); + } + } + if (n[0] != 3) + abort (); + if (n[3] != -1 + && (n[1] != 0x14 || n[2] != 0x25 || n[3] != 0x36)) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr32362-3.c b/libgomp/testsuite/libgomp.c/pr32362-3.c new file mode 100644 index 000000000..09a88f52a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr32362-3.c @@ -0,0 +1,34 @@ +/* PR middle-end/32362 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include <omp.h> +#include <stdlib.h> + +int a = 2; + +int +main () +{ + int n[4] = { -1, -1, -1, -1 }; + int b = 4; + omp_set_num_threads (4); + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel private(b) + { + b = omp_get_thread_num (); +#pragma omp parallel firstprivate(a) + { + a = (omp_get_thread_num () + a) + 1; + if (b == omp_get_thread_num ()) + n[omp_get_thread_num ()] = a + (b << 4); + } + } + if (n[0] != 3) + abort (); + if (n[3] != -1 + && (n[1] != 0x14 || n[2] != 0x25 || n[3] != 0x36)) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr32468.c b/libgomp/testsuite/libgomp.c/pr32468.c new file mode 100644 index 000000000..f20f660bf --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr32468.c @@ -0,0 +1,26 @@ +/* PR libgomp/32468 */ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int res[2] = { -1, -1 }; + omp_set_dynamic (0); + omp_set_num_threads (4); +#pragma omp parallel + { + #pragma omp sections + { + #pragma omp section + res[0] = omp_get_num_threads () != 4; + #pragma omp section + res[1] = omp_get_num_threads () != 4; + } + } + if (res[0] != 0 || res[1] != 0) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr33880.c b/libgomp/testsuite/libgomp.c/pr33880.c new file mode 100644 index 000000000..5d719cd63 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr33880.c @@ -0,0 +1,123 @@ +/* PR middle-end/33880 */ +/* { dg-do run } */ + +extern void abort (void); + +void +test1 (void) +{ + int i = 0, j = 0; + void bar (void) + { + i++; + j++; + } + bar (); + #pragma omp parallel for num_threads(4) + for (i = 0; i < 100; i++) + #pragma omp atomic + j += 1; + if (j != 101) + abort (); + #pragma omp parallel for lastprivate(i) num_threads(2) + for (i = 0; i < 100; i++) + #pragma omp atomic + j += 1; + if (i != 100) + abort (); + i = 3; + bar (); + if (j != 202) + abort (); + if (i != 4) + abort (); +} + +void +test2 (void) +{ + int i = -1, j = 99, k, l = 9, m = 0; + void bar (void) + { + i++; + j++; + l++; + m++; + } + bar (); + #pragma omp parallel for num_threads(4) + for (k = i; k < j; k += l) + #pragma omp atomic + m += 1; + bar (); + if (i != 1 || j != 101 || l != 11 || m != 12) + abort (); +} + +void +test3 (void) +{ + int i, j, k, l, m; + void bar (void) + { + #pragma omp parallel for num_threads(4) + for (i = j; i < k; i += l) + #pragma omp atomic + m += 1; + } + void baz (void) + { + #pragma omp parallel for num_threads(2) lastprivate(i) + for (i = j; i < k * 2; i += l / 2) + #pragma omp atomic + m += 1; + } + i = 7; + j = 0; + k = 100; + l = 2; + m = 0; + bar (); + if (j != 0 || k != 100 || l != 2 || m != 50) + abort (); + baz (); + if (i != 200 || j != 0 || k != 100 || l != 2 || m != 250) + abort (); +} + +void +test4 (void) +{ + int i, j, k, l, m = 0; + int foo (void) + { + return j; + } + int bar (void) + { + return k; + } + int baz (void) + { + return l; + } + j = 0; + k = 1000; + l = 2; + #pragma omp parallel for num_threads(8) lastprivate(i) + for (i = foo (); i < bar (); i += baz ()) + #pragma omp atomic + m += 1; + if (i != 1000 || m != 500 || j != 0 || k != 1000 || l != 2) + abort (); +} + +int +main (void) +{ + test1 (); + test2 (); + test3 (); + test4 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr34513.c b/libgomp/testsuite/libgomp.c/pr34513.c new file mode 100644 index 000000000..76c7ac1f3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr34513.c @@ -0,0 +1,33 @@ +/* PR c++/34513 */ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (); + +static int errors = 0; +static int thrs = 4; + +int +main () +{ + omp_set_dynamic (0); + + #pragma omp parallel num_threads (thrs) + { + static int shrd = 0; + + #pragma omp atomic + shrd += 1; + + #pragma omp barrier + + if (shrd != thrs) + #pragma omp atomic + errors += 1; + } + + if (errors) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr35130.c b/libgomp/testsuite/libgomp.c/pr35130.c new file mode 100644 index 000000000..12962d807 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr35130.c @@ -0,0 +1,131 @@ +/* PR middle-end/35130 */ + +extern void abort (void); + +void +f1 (void) +{ + int a[4], k; + void nested (int x) + { + a[x] = 42; + } + + for (k = 0; k < 4; k++) + a[k] = 0; +#pragma omp parallel for + for (k = 0; k < 4; k++) + nested (k); + + if (a[0] != 42 || a[1] != 42 || a[2] != 42 || a[3] != 42) + abort (); +} + +void +f2 (void) +{ + int a[4], k; + void nested (void) + { + int l; + void nested2 (int x) + { + a[x] = 42; + } +#pragma omp parallel for + for (l = 0; l < 4; l++) + nested2 (l); + } + + for (k = 0; k < 4; k++) + a[k] = 0; + + nested (); + + if (a[0] != 42 || a[1] != 42 || a[2] != 42 || a[3] != 42) + abort (); +} + +void +f3 (void) +{ + int a[4], b[4], c[4], k; + void nested (int x) + { + a[x] = b[x] = c[x] = 42; + } + + for (k = 0; k < 4; k++) + a[k] = b[k] = c[k] = 0; + nested (0); + +#pragma omp parallel + { + #pragma omp single + { + a[1] = 43; + b[1] = 43; + } + #pragma omp parallel + { + #pragma omp single + { + b[2] = 44; + c[2] = 44; + } + } + } + + if (a[0] != 42 || a[1] != 43 || a[2] != 0 || a[3] != 0) + abort (); + if (b[0] != 42 || b[1] != 43 || b[2] != 44 || b[3] != 0) + abort (); + if (c[0] != 42 || c[1] != 0 || c[2] != 44 || c[3] != 0) + abort (); +} + +void +f4 (void) +{ + int a[4], b[4], c[4], k; + void nested () + { + #pragma omp parallel + { + #pragma omp single + { + a[1] = 43; + b[1] = 43; + } + #pragma omp parallel + { + #pragma omp single + { + b[2] = 44; + c[2] = 44; + } + } + } + } + + for (k = 0; k < 4; k++) + a[k] = b[k] = c[k] = k == 0 ? 42 : 0; + nested (); + + if (a[0] != 42 || a[1] != 43 || a[2] != 0 || a[3] != 0) + abort (); + if (b[0] != 42 || b[1] != 43 || b[2] != 44 || b[3] != 0) + abort (); + if (c[0] != 42 || c[1] != 0 || c[2] != 44 || c[3] != 0) + abort (); +} + +int +main (void) +{ + f1 (); + f2 (); + f3 (); + f4 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr35196.c b/libgomp/testsuite/libgomp.c/pr35196.c new file mode 100644 index 000000000..e92d97629 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr35196.c @@ -0,0 +1,43 @@ +/* PR middle-end/35196 */ +/* { dg-do run } */ + +extern void abort (void); +extern void omp_set_dynamic (int); + +int +main (void) +{ + int i, j; + omp_set_dynamic (0); +#pragma omp parallel for lastprivate (i, j) num_threads (8) schedule (static) + for (i = 0; i < 5; i++) + j = i; + if (i != 5 || j != 4) + abort (); +#pragma omp parallel for lastprivate (i, j) num_threads (8) schedule (static, 2) + for (i = 0; i < 5; i++) + j = i; + if (i != 5 || j != 4) + abort (); +#pragma omp parallel for lastprivate (i, j) num_threads (8) schedule (dynamic) + for (i = 0; i < 5; i++) + j = i; + if (i != 5 || j != 4) + abort (); +#pragma omp parallel for lastprivate (i, j) num_threads (8) schedule (static) + for (i = -12; i < 21; i += 3) + j = i; + if (i != 21 || j != 18) + abort (); +#pragma omp parallel for lastprivate (i, j) num_threads (8) schedule (static, 2) + for (i = -12; i < 21; i += 3) + j = i; + if (i != 21 || j != 18) + abort (); +#pragma omp parallel for lastprivate (i, j) num_threads (8) schedule (dynamic, 3) + for (i = -12; i < 21; i += 3) + j = i; + if (i != 21 || j != 18) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr35549.c b/libgomp/testsuite/libgomp.c/pr35549.c new file mode 100644 index 000000000..269a0c262 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr35549.c @@ -0,0 +1,30 @@ +/* PR middle-end/35549 */ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 6, n = 0; + omp_set_dynamic (0); + omp_set_nested (1); + #pragma omp parallel shared (i) num_threads (3) + { + if (omp_get_num_threads () != 3) + #pragma omp atomic + n += 1; + #pragma omp parallel shared (i) num_threads (4) + { + if (omp_get_num_threads () != 4) + #pragma omp atomic + n += 1; + #pragma omp critical + i += 1; + } + } + if (n == 0 && i != 6 + 3 * 4) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr35625.c b/libgomp/testsuite/libgomp.c/pr35625.c new file mode 100644 index 000000000..f2978f911 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr35625.c @@ -0,0 +1,18 @@ +/* PR libgomp/35625 */ +/* { dg-do run } */ +/* { dg-options "-std=c99" } */ + +int +main (void) +{ +#pragma omp parallel + { + #pragma omp for schedule (guided, 10) + for (int i = 0; i < 1826; i += 10) + ; + #pragma omp for schedule (guided, 10) + for (int i = 0; i > -1826; i -= 10) + ; + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr36802-1.c b/libgomp/testsuite/libgomp.c/pr36802-1.c new file mode 100644 index 000000000..4ed5e1276 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr36802-1.c @@ -0,0 +1,34 @@ +/* PR middle-end/36802 */ + +extern void abort (void); + +int +foo (int k) +{ + int i = 0; +#pragma omp parallel + #pragma omp single + { + if (!k) + { + int j; + for (j = 0; j < 10; j++) + #pragma omp task + if (j == 4) + i++; + } + else + i++; + } + return i; +} + +int +main (void) +{ + if (foo (0) != 1) + abort (); + if (foo (1) != 1) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr36802-2.c b/libgomp/testsuite/libgomp.c/pr36802-2.c new file mode 100644 index 000000000..06e792f0f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr36802-2.c @@ -0,0 +1,46 @@ +/* PR middle-end/36802 */ + +extern void abort (void); + +int q; + +int +foo (int k) +{ + int i = 6, n = 0; + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel shared (i) num_threads (3) + { + int l; + + if (omp_get_num_threads () != 3) + #pragma omp atomic + n += 1; + else + #pragma omp for + for (l = 0; l < 3; l++) + if (k) + #pragma omp atomic + q += i; + else + #pragma omp parallel shared (i) num_threads (4) + { + if (omp_get_num_threads () != 4) + #pragma omp atomic + n += 1; + #pragma omp critical + i += 1; + } + } + if (n == 0 && i != 6 + 3 * 4) + abort (); + return 0; +} + +int +main (void) +{ + foo (0); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr36802-3.c b/libgomp/testsuite/libgomp.c/pr36802-3.c new file mode 100644 index 000000000..f11baa09f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr36802-3.c @@ -0,0 +1,46 @@ +/* PR middle-end/36802 */ + +extern void abort (void); + +int q; + +int +foo (int k) +{ + int i = 6, n = 0; + omp_set_dynamic (0); + omp_set_nested (1); +#pragma omp parallel shared (i) num_threads (3) + { + int l; + + if (omp_get_num_threads () != 3) + #pragma omp atomic + n += 1; + else + #pragma omp for + for (l = 0; l < 3; l++) + if (!k) + #pragma omp parallel shared (i) num_threads (4) + { + if (omp_get_num_threads () != 4) + #pragma omp atomic + n += 1; + #pragma omp critical + i += 1; + } + else + #pragma omp atomic + q += i; + } + if (n == 0 && i != 6 + 3 * 4) + abort (); + return 0; +} + +int +main (void) +{ + foo (0); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr38650.c b/libgomp/testsuite/libgomp.c/pr38650.c new file mode 100644 index 000000000..7066239b0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr38650.c @@ -0,0 +1,49 @@ +/* PR c++/38650 */ +/* { dg-do run } */ + +#include <stdlib.h> + +int e; + +int +main () +{ + volatile int i, j = 10; + e = 0; +#pragma omp parallel for reduction(+:e) + for (i = 0; i < j; i += 1) + e++; + if (e != 10) + abort (); + e = 0; +#pragma omp parallel for reduction(+:e) + for (i = 0; i < j; ++i) + e++; + if (e != 10) + abort (); + e = 0; +#pragma omp parallel for reduction(+:e) + for (i = 0; i < j; i++) + e++; + if (e != 10) + abort (); + e = 0; +#pragma omp parallel for reduction(+:e) + for (i = 0; i < 10; i += 1) + e++; + if (e != 10) + abort (); + e = 0; +#pragma omp parallel for reduction(+:e) + for (i = 0; i < 10; ++i) + e++; + if (e != 10) + abort (); + e = 0; +#pragma omp parallel for reduction(+:e) + for (i = 0; i < 10; i++) + e++; + if (e != 10) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr39154.c b/libgomp/testsuite/libgomp.c/pr39154.c new file mode 100644 index 000000000..5a4c89e13 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr39154.c @@ -0,0 +1,105 @@ +/* PR middle-end/39154 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=gnu99" } */ + +extern void abort (void); + +int n = 20; + +int +main (void) +{ + int a[n], b[n][n]; + +#pragma omp parallel for + for (int i = 0; i < n; i++) + { + a[i] = i + 1; +#pragma omp parallel for + for (int j = 0; j < n; j++) + b[i][j] = a[i]; + } + + for (int i = 0; i < n; i++) + { + for (int j = 0; j < n; j++) + if (b[i][j] != i + 1) + abort (); + if (a[i] != i + 1) + abort (); + } + +#pragma omp parallel for shared (n, a, b) + for (int i = 0; i < n; i++) + { + a[i] = i + 3; +#pragma omp parallel for + for (int j = 0; j < n; j++) + b[i][j] = a[i]; + } + + for (int i = 0; i < n; i++) + { + for (int j = 0; j < n; j++) + if (b[i][j] != i + 3) + abort (); + if (a[i] != i + 3) + abort (); + } + +#pragma omp parallel for + for (int i = 0; i < n; i++) + { + a[i] = i + 5; +#pragma omp parallel for shared (n, a, b) + for (int j = 0; j < n; j++) + b[i][j] = a[i]; + } + + for (int i = 0; i < n; i++) + { + for (int j = 0; j < n; j++) + if (b[i][j] != i + 5) + abort (); + if (a[i] != i + 5) + abort (); + } + +#pragma omp parallel for shared (n, a, b) + for (int i = 0; i < n; i++) + { + a[i] = i + 7; +#pragma omp parallel for shared (n, a, b) + for (int j = 0; j < n; j++) + b[i][j] = a[i]; + } + + for (int i = 0; i < n; i++) + { + for (int j = 0; j < n; j++) + if (b[i][j] != i + 7) + abort (); + if (a[i] != i + 7) + abort (); + } + +#pragma omp parallel for private (a, b) + for (int i = 0; i < n; i++) + { + a[i] = i + 1; +#pragma omp parallel for + for (int j = 0; j < n; j++) + b[i][j] = a[i]; + } + +#pragma omp parallel for private (a, b) + for (int i = 0; i < n; i++) + { + a[i] = i + 1; +#pragma omp parallel for private (b) + for (int j = 0; j < n; j++) + b[i][j] = a[i]; + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr39591-1.c b/libgomp/testsuite/libgomp.c/pr39591-1.c new file mode 100644 index 000000000..dfd8d9e8a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr39591-1.c @@ -0,0 +1,33 @@ +/* PR other/39591 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +int err; + +int +main (void) +{ +#pragma omp parallel + { + int array[40]; + int i; + for (i = 0; i < sizeof array / sizeof array[0]; i++) + array[i] = 0x55555555; + +#pragma omp for schedule(dynamic) + for (i = 0; i < 50; i++) +#pragma omp task shared(array) + { + int j; + for (j = 0; j < sizeof array / sizeof array[0]; j++) + if (array[j] != 0x55555555) +#pragma omp atomic + err++; + } + } + if (err) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr39591-2.c b/libgomp/testsuite/libgomp.c/pr39591-2.c new file mode 100644 index 000000000..b5f8f9cc7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr39591-2.c @@ -0,0 +1,39 @@ +/* PR other/39591 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +int err; + +void __attribute__((noinline)) +foo (int *array) +{ +#pragma omp task + { + int j; + for (j = 0; j < sizeof array / sizeof array[0]; j++) + if (array[j] != 0x55555555) +#pragma omp atomic + err++; + } +} + +int +main (void) +{ +#pragma omp parallel + { + int array[40]; + int i; + for (i = 0; i < sizeof array / sizeof array[0]; i++) + array[i] = 0x55555555; + +#pragma omp for schedule (dynamic) + for (i = 0; i < 50; i++) + foo (array); + } + if (err) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr39591-3.c b/libgomp/testsuite/libgomp.c/pr39591-3.c new file mode 100644 index 000000000..a9aeea7c8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr39591-3.c @@ -0,0 +1,40 @@ +/* PR other/39591 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +int err, a[40]; + +void __attribute__((noinline)) +foo (int *array) +{ +#pragma omp task + { + int j; + for (j = 0; j < sizeof array / sizeof array[0]; j++) + if (array[j] != 0x55555555) +#pragma omp atomic + err++; + } +} + +int +main (void) +{ + int k; + for (k = 0; k < sizeof a / sizeof a[0]; k++) + a[k] = 0x55555555; + +#pragma omp parallel + { + int i; + +#pragma omp for schedule (dynamic) + for (i = 0; i < 50; i++) + foo (a); + } + if (err) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr42029.c b/libgomp/testsuite/libgomp.c/pr42029.c new file mode 100644 index 000000000..ea7ac2c09 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr42029.c @@ -0,0 +1,19 @@ +/* PR middle-end/42029 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int i; + _Complex int c = 0; + +#pragma omp parallel for private(i) reduction(+:c) + for (i = 0; i < 8; ++i) + c += 1; + + if (c != 8) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr42942.c b/libgomp/testsuite/libgomp.c/pr42942.c new file mode 100644 index 000000000..5d5785245 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr42942.c @@ -0,0 +1,61 @@ +/* PR libgomp/42942 */ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int e = 0; + omp_set_dynamic (0); + omp_set_nested (1); + omp_set_max_active_levels (1); + if (omp_get_max_active_levels () != 1) + abort (); +#pragma omp parallel num_threads(2) reduction(|:e) + if (!omp_in_parallel () + || omp_get_num_threads () != 2) + e = 1; + else +#pragma omp parallel num_threads(2) reduction(|:e) + if (!omp_in_parallel () + || omp_get_num_threads () != 1) + e = 1; + if (e) + abort (); + omp_set_max_active_levels (0); + if (omp_get_max_active_levels () != 0) + abort (); +#pragma omp parallel num_threads(2) reduction(|:e) + if (omp_in_parallel () + || omp_get_num_threads () != 1) + e = 1; + else +#pragma omp parallel num_threads(2) reduction(|:e) + if (omp_in_parallel () + || omp_get_num_threads () != 1) + e = 1; + if (e) + abort (); + omp_set_max_active_levels (2); + if (omp_get_max_active_levels () != 2) + abort (); +#pragma omp parallel num_threads(2) reduction(|:e) + if (!omp_in_parallel () + || omp_get_num_threads () != 2) + e = 1; + else +#pragma omp parallel num_threads(2) reduction(|:e) + if (!omp_in_parallel () + || omp_get_num_threads () != 2) + e = 1; + else +#pragma omp parallel num_threads(2) reduction(|:e) + if (!omp_in_parallel () + || omp_get_num_threads () != 1) + e = 1; + if (e) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr43893.c b/libgomp/testsuite/libgomp.c/pr43893.c new file mode 100644 index 000000000..b85e9242b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr43893.c @@ -0,0 +1,61 @@ +/* PR c/43893 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int c; + unsigned int i; + int j; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 0; i < 1; i++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 0; i <= 0; i++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = - __INT_MAX__ - 1; j < - __INT_MAX__; j++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = - __INT_MAX__ - 1; j <= - __INT_MAX__ - 1; j++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 2U * __INT_MAX__ + 1; i > 2U * __INT_MAX__; i--) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 2U * __INT_MAX__ + 1; i >= 2U * __INT_MAX__ + 1; i--) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = __INT_MAX__; j > __INT_MAX__ - 1; j--) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = __INT_MAX__; j >= __INT_MAX__; j--) + c++; + if (c != 1) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr46886.c b/libgomp/testsuite/libgomp.c/pr46886.c new file mode 100644 index 000000000..fbdc4e130 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr46886.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O -ftree-parallelize-loops=4 -fno-tree-ch -fno-tree-dominator-opts" } */ + +void abort(void); + +int d[1024], e[1024]; + +int foo (void) +{ + int s = 0; + int i; + for (i = 0; i < 1024; i++) + s += d[i] - e[i]; + return s; +} + +int main () +{ + int i; + for (i = 0; i < 1024; i++) + { + d[i] = i * 2; + e[i] = i; + } + if (foo () != 1023 * 1024 / 2) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr48591.c b/libgomp/testsuite/libgomp.c/pr48591.c new file mode 100644 index 000000000..18dfd7f47 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr48591.c @@ -0,0 +1,22 @@ +/* PR middle-end/48591 */ +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* } } */ +/* { dg-options "-fopenmp" } */ + +extern void abort (void); + +int +main () +{ + __float128 f = 0.0; + int i; + #pragma omp parallel for reduction(+:f) + for (i = 0; i < 128; i++) + f += 0.5Q; + if (f != 64.0Q) + abort (); + #pragma omp atomic + f += 8.5Q; + if (f != 72.5Q) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr49897-1.c b/libgomp/testsuite/libgomp.c/pr49897-1.c new file mode 100644 index 000000000..d21a26252 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr49897-1.c @@ -0,0 +1,31 @@ +/* PR middle-end/49897 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int i, j, x = 0, y, sum = 0; +#pragma omp parallel reduction(+:sum) + { + #pragma omp for firstprivate(x) lastprivate(x, y) + for (i = 0; i < 10; i++) + { + x = i; + y = 0; + #pragma omp parallel reduction(+:sum) + { + #pragma omp for firstprivate(y) lastprivate(y) + for (j = 0; j < 10; j++) + { + y = j; + sum += y; + } + } + } + } + if (x != 9 || y != 9 || sum != 450) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr49897-2.c b/libgomp/testsuite/libgomp.c/pr49897-2.c new file mode 100644 index 000000000..c9ea5eced --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr49897-2.c @@ -0,0 +1,25 @@ +/* PR middle-end/49897 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int i, j, x = 0, y, sum = 0; +#pragma omp parallel for reduction(+:sum) firstprivate(x) lastprivate(x, y) + for (i = 0; i < 10; i++) + { + x = i; + y = 0; + #pragma omp parallel for reduction(+:sum) firstprivate(y) lastprivate(y) + for (j = 0; j < 10; j++) + { + y = j; + sum += y; + } + } + if (x != 9 || y != 9 || sum != 450) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr49898-1.c b/libgomp/testsuite/libgomp.c/pr49898-1.c new file mode 100644 index 000000000..175426d40 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr49898-1.c @@ -0,0 +1,26 @@ +/* PR middle-end/49898 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int i, j, sum = 0; +#pragma omp parallel + { + #pragma omp for reduction(+:sum) + for (i = 0; i < 10; i++) + { + #pragma omp parallel + { + #pragma omp for reduction(+:sum) + for (j = 0; j < 10; j++) + sum += j; + } + } + } + if (sum != 450) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr49898-2.c b/libgomp/testsuite/libgomp.c/pr49898-2.c new file mode 100644 index 000000000..03ba0f8ff --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr49898-2.c @@ -0,0 +1,18 @@ +/* PR middle-end/49898 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int i, j, sum = 0; +#pragma omp parallel for reduction(+:sum) + for (i = 0; i < 10; i++) + #pragma omp parallel for reduction(+:sum) + for (j = 0; j < 10; j++) + sum += j; + if (sum != 450) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr52547.c b/libgomp/testsuite/libgomp.c/pr52547.c new file mode 100644 index 000000000..f746e2ec4 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr52547.c @@ -0,0 +1,36 @@ +/* PR middle-end/52547 */ +/* { dg-do run } */ + +extern void abort (void); + +__attribute__((noinline, noclone)) int +baz (int *x, int (*fn) (int *)) +{ + return fn (x); +} + +__attribute__((noinline, noclone)) int +foo (int x, int *y) +{ + int i, e = 0; +#pragma omp parallel for reduction(|:e) + for (i = 0; i < x; ++i) + { + __label__ lab; + int bar (int *z) { return z - y; } + if (baz (&y[i], bar) != i) + e |= 1; + } + return e; +} + +int +main () +{ + int a[100], i; + for (i = 0; i < 100; i++) + a[i] = i; + if (foo (100, a)) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/private-1.c b/libgomp/testsuite/libgomp.c/private-1.c new file mode 100644 index 000000000..1d3659b25 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/private-1.c @@ -0,0 +1,54 @@ +extern void abort (void); + +int a = 18; + +void +f1 (int i, int j, int k) +{ + int l = 6, m = 7, n = 8; +#pragma omp parallel private(j, m) shared(k, n) firstprivate(i, l) \ + num_threads(1) + { + j = 6; + m = 5; + if (++a != 19 || ++i != 9 || j != 6 || ++l != 7 || m != 5 || ++n != 9) + #pragma omp atomic + k++; + } + if (a != 19 || i != 8 || j != 26 || k != 0 || l != 6 || m != 7 || n != 9) + abort (); +} + +int v1 = 1, v2 = 2, v5 = 5; +int err; + +void +f2 (void) +{ + int v3 = 3; +#pragma omp sections private (v1) firstprivate (v2) + { + #pragma omp section + { + int v4 = 4; + v1 = 7; + #pragma omp parallel num_threads(1) firstprivate(v1, v2, v3, v4) + { + if (++v1 != 8 || ++v2 != 3 || ++v3 != 4 || ++v4 != 5 || ++v5 != 6) + err = 1; + } + if (v1 != 7 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 6) + abort (); + if (err) + abort (); + } + } +} + +int +main (void) +{ + f1 (8, 26, 0); + f2 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-1.c b/libgomp/testsuite/libgomp.c/reduction-1.c new file mode 100644 index 000000000..665163af0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-1.c @@ -0,0 +1,36 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = ~0; + double d = 1.0; +#pragma omp parallel num_threads(4) reduction(+:i) reduction(*:d) reduction(&:k) + { + if (i != 0 || d != 1.0 || k != ~0) +#pragma omp atomic + j |= 1; + + if (omp_get_num_threads () != 4) +#pragma omp atomic + j |= 2; + + i = omp_get_thread_num (); + d = i + 1; + k = ~(1 << (2 * i)); + } + + if (j & 1) + abort (); + if ((j & 2) == 0) + { + if (i != (0 + 1 + 2 + 3)) + abort (); + if (d != (1.0 * 2.0 * 3.0 * 4.0)) + abort (); + if (k != (~0 ^ 0x55)) + abort (); + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-2.c b/libgomp/testsuite/libgomp.c/reduction-2.c new file mode 100644 index 000000000..52b3faff7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-2.c @@ -0,0 +1,50 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = ~0, l; + double d = 1.0; +#pragma omp parallel num_threads(4) + { +#pragma omp single + { + i = 16; + k ^= (1 << 16); + d += 32.0; + } + +#pragma omp for reduction(+:i) reduction(*:d) reduction(&:k) + for (l = 0; l < 4; l++) + { + if (omp_get_num_threads () == 4 && (i != 0 || d != 1.0 || k != ~0)) +#pragma omp atomic + j |= 1; + + if (l == omp_get_thread_num ()) + { + i = omp_get_thread_num (); + d = i + 1; + k = ~(1 << (2 * i)); + } + } + + if (omp_get_num_threads () == 4) + { + if (i != (16 + 0 + 1 + 2 + 3)) +#pragma omp atomic + j |= 2; + if (d != (33.0 * 1.0 * 2.0 * 3.0 * 4.0)) +#pragma omp atomic + j |= 4; + if (k != (~0 ^ 0x55 ^ (1 << 16))) +#pragma omp atomic + j |= 8; + } + } + + if (j) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-3.c b/libgomp/testsuite/libgomp.c/reduction-3.c new file mode 100644 index 000000000..4f8f2fc12 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-3.c @@ -0,0 +1,51 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = ~0, l; + double d = 1.0; +#pragma omp parallel num_threads(4) + { +#pragma omp single + { + i = 16; + k ^= (1 << 16); + d += 32.0; + } + +#pragma omp for reduction(+:i) reduction(*:d) reduction(&:k) nowait + for (l = 0; l < 4; l++) + { + if (omp_get_num_threads () == 4 && (i != 0 || d != 1.0 || k != ~0)) +#pragma omp atomic + j |= 1; + + if (l == omp_get_thread_num ()) + { + i = omp_get_thread_num (); + d = i + 1; + k = ~(1 << (2 * i)); + } + } + + if (omp_get_num_threads () == 4) + { +#pragma omp barrier + if (i != (16 + 0 + 1 + 2 + 3)) +#pragma omp atomic + j |= 2; + if (d != (33.0 * 1.0 * 2.0 * 3.0 * 4.0)) +#pragma omp atomic + j |= 4; + if (k != (~0 ^ 0x55 ^ (1 << 16))) +#pragma omp atomic + j |= 8; + } + } + + if (j) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-4.c b/libgomp/testsuite/libgomp.c/reduction-4.c new file mode 100644 index 000000000..23e9d6d5b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-4.c @@ -0,0 +1,36 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = 0, l = 0; +#pragma omp parallel num_threads(4) reduction(-:i) reduction(|:k) \ + reduction(^:l) + { + if (i != 0 || k != 0 || l != 0) +#pragma omp atomic + j |= 1; + + if (omp_get_num_threads () != 4) +#pragma omp atomic + j |= 2; + + i = omp_get_thread_num (); + k = 1 << (2 * i); + l = 0xea << (3 * i); + } + + if (j & 1) + abort (); + if ((j & 2) == 0) + { + if (i != (0 + 1 + 2 + 3)) + abort (); + if (k != 0x55) + abort (); + if (l != 0x1e93a) + abort (); + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-5.c b/libgomp/testsuite/libgomp.c/reduction-5.c new file mode 100644 index 000000000..de87d9f6d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-5.c @@ -0,0 +1,78 @@ +/* PR middle-end/36506 */ + +extern void abort (void); + +int +main (void) +{ + int sum = 0, prod = 1; +#pragma omp parallel + #pragma omp sections reduction (+:sum) + { + #pragma omp section + sum += 2; + #pragma omp section + sum += 2; + #pragma omp section + sum += 2; + } + if (sum != 6) + abort (); + sum = 0; +#pragma omp parallel sections reduction (+:sum) + { + #pragma omp section + sum += 2; + #pragma omp section + sum += 2; + #pragma omp section + sum += 2; + } + if (sum != 6) + abort (); + sum = 0; +#pragma omp parallel + #pragma omp sections reduction (+:sum) reduction (*:prod) + { + #pragma omp section + { + sum += 2; + prod *= 2; + } + #pragma omp section + { + sum += 2; + prod *= 2; + } + #pragma omp section + { + sum += 2; + prod *= 2; + } + } + if (sum != 6 || prod != 8) + abort (); + sum = 0; + prod = 1; +#pragma omp parallel sections reduction (+:sum) reduction (*:prod) + { + #pragma omp section + { + sum += 2; + prod *= 2; + } + #pragma omp section + { + sum += 2; + prod *= 2; + } + #pragma omp section + { + sum += 2; + prod *= 2; + } + } + if (sum != 6 || prod != 8) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/sections-1.c b/libgomp/testsuite/libgomp.c/sections-1.c new file mode 100644 index 000000000..3a6584cb7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/sections-1.c @@ -0,0 +1,85 @@ +/* Test that all sections are touched. */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 100 +static int data[N]; +static int NTHR; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int i; + + for (i = 0; i < N; ++i) + assert (data[i] != -1); +} + +static void set_data (unsigned i, int val) +{ + int old; + assert (i >= 1 && i <= N); + old = __sync_lock_test_and_set (data+i-1, val); + assert (old == -1); +} + + +static void f_1 (void *dummy) +{ + int iam = omp_get_thread_num (); + unsigned long s; + + for (s = GOMP_sections_start (N); s ; s = GOMP_sections_next ()) + set_data (s, iam); + GOMP_sections_end (); +} + +static void test_1 (void) +{ + clean_data (); + GOMP_parallel_start (f_1, NULL, NTHR); + f_1 (NULL); + GOMP_parallel_end (); + test_data (); +} + +static void f_2 (void *dummy) +{ + int iam = omp_get_thread_num (); + unsigned s; + + while ((s = GOMP_sections_next ())) + set_data (s, iam); + GOMP_sections_end_nowait (); +} + +static void test_2 (void) +{ + clean_data (); + GOMP_parallel_sections_start (f_2, NULL, NTHR, N); + f_2 (NULL); + GOMP_parallel_end (); + test_data (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + test_1 (); + test_2 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/shared-1.c b/libgomp/testsuite/libgomp.c/shared-1.c new file mode 100644 index 000000000..f7d4fb2d6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/shared-1.c @@ -0,0 +1,58 @@ +extern void abort (void); + +struct Y +{ + int l[5][10]; +}; + +struct X +{ + struct Y y; + float b[10]; +}; + +void +parallel (int a, int b) +{ + int i, j; + struct X A[10][5]; + a = b = 3; + + for (i = 0; i < 10; i++) + for (j = 0; j < 5; j++) + A[i][j].y.l[3][3] = -10; + + #pragma omp parallel shared (a, b, A) num_threads (5) + { + int i, j; + + #pragma omp atomic + a += omp_get_num_threads (); + + #pragma omp atomic + b += omp_get_num_threads (); + + #pragma omp for private (j) + for (i = 0; i < 10; i++) + for (j = 0; j < 5; j++) + A[i][j].y.l[3][3] += 20; + + } + + for (i = 0; i < 10; i++) + for (j = 0; j < 5; j++) + if (A[i][j].y.l[3][3] != 10) + abort (); + + if (a != 28) + abort (); + + if (b != 28) + abort (); +} + +main() +{ + parallel (1, 2); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/shared-2.c b/libgomp/testsuite/libgomp.c/shared-2.c new file mode 100644 index 000000000..56c88ecc7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/shared-2.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <omp.h> + +extern void abort (void); + +void +parallel (int a, int b) +{ + int bad, LASTPRIV, LASTPRIV_SEC; + int i; + + a = b = 3; + + bad = 0; + + #pragma omp parallel firstprivate (a,b) shared (bad) num_threads (5) + { + if (a != 3 || b != 3) + bad = 1; + + #pragma omp for lastprivate (LASTPRIV) + for (i = 0; i < 10; i++) + LASTPRIV = i; + + #pragma omp sections lastprivate (LASTPRIV_SEC) + { + #pragma omp section + { LASTPRIV_SEC = 3; } + + #pragma omp section + { LASTPRIV_SEC = 42; } + } + + } + + if (LASTPRIV != 9) + abort (); + + if (LASTPRIV_SEC != 42) + abort (); + + if (bad) + abort (); +} + +int main() +{ + parallel (1, 2); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/shared-3.c b/libgomp/testsuite/libgomp.c/shared-3.c new file mode 100644 index 000000000..494a970ad --- /dev/null +++ b/libgomp/testsuite/libgomp.c/shared-3.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ + +void abort (void); + +int main() +{ + int x; + int *p; + + p = &x; + + #pragma omp parallel + { + if (p != &x) + abort (); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/single-1.c b/libgomp/testsuite/libgomp.c/single-1.c new file mode 100644 index 000000000..1ce89118d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/single-1.c @@ -0,0 +1,53 @@ +/* Trivial test of single. */ + +/* { dg-require-effective-target sync_int_long } */ + +#include <omp.h> +#include <sys/time.h> +#include <unistd.h> +#include <assert.h> +#include "libgomp_g.h" + + +static int test; + +static void f_nocopy (void *dummy) +{ + if (GOMP_single_start ()) + { + int iam = omp_get_thread_num (); + int old = __sync_lock_test_and_set (&test, iam); + assert (old == -1); + } +} + +static void f_copy (void *dummy) +{ + int *x = GOMP_single_copy_start (); + if (x == NULL) + { + int iam = omp_get_thread_num (); + int old = __sync_lock_test_and_set (&test, iam); + assert (old == -1); + GOMP_single_copy_end (&test); + } + else + assert (x == &test); +} + +int main() +{ + omp_set_dynamic (0); + + test = -1; + GOMP_parallel_start (f_nocopy, NULL, 3); + f_nocopy (NULL); + GOMP_parallel_end (); + + test = -1; + GOMP_parallel_start (f_copy, NULL, 3); + f_copy (NULL); + GOMP_parallel_end (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/single-2.c b/libgomp/testsuite/libgomp.c/single-2.c new file mode 100644 index 000000000..b510ce735 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/single-2.c @@ -0,0 +1,15 @@ +#include <stdlib.h> + +int +main (void) +{ + int i; + i = 4; +#pragma omp single copyprivate (i) + { + i = 6; + } + if (i != 6) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/sort-1.c b/libgomp/testsuite/libgomp.c/sort-1.c new file mode 100644 index 000000000..269d69da1 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/sort-1.c @@ -0,0 +1,379 @@ +/* Test and benchmark of a couple of parallel sorting algorithms. + Copyright (C) 2008 Free Software Foundation, Inc. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include <limits.h> +#include <omp.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int failures; + +#define THRESHOLD 100 + +static void +verify (const char *name, double stime, int *array, int count) +{ + int i; + double etime = omp_get_wtime (); + + printf ("%s: %g\n", name, etime - stime); + for (i = 1; i < count; i++) + if (array[i] < array[i - 1]) + { + printf ("%s: incorrectly sorted\n", name); + failures = 1; + } +} + +static void +insertsort (int *array, int s, int e) +{ + int i, j, val; + for (i = s + 1; i <= e; i++) + { + val = array[i]; + j = i; + while (j-- > s && val < array[j]) + array[j + 1] = array[j]; + array[j + 1] = val; + } +} + +struct int_pair +{ + int lo; + int hi; +}; + +struct int_pair_stack +{ + struct int_pair *top; +#define STACK_SIZE 4 * CHAR_BIT * sizeof (int) + struct int_pair arr[STACK_SIZE]; +}; + +static inline void +init_int_pair_stack (struct int_pair_stack *stack) +{ + stack->top = &stack->arr[0]; +} + +static inline void +push_int_pair_stack (struct int_pair_stack *stack, int lo, int hi) +{ + stack->top->lo = lo; + stack->top->hi = hi; + stack->top++; +} + +static inline void +pop_int_pair_stack (struct int_pair_stack *stack, int *lo, int *hi) +{ + stack->top--; + *lo = stack->top->lo; + *hi = stack->top->hi; +} + +static inline int +size_int_pair_stack (struct int_pair_stack *stack) +{ + return stack->top - &stack->arr[0]; +} + +static inline void +busy_wait (void) +{ +#if defined __i386__ || defined __x86_64__ + __asm volatile ("rep; nop" : : : "memory"); +#elif defined __ia64__ + __asm volatile ("hint @pause" : : : "memory"); +#elif defined __sparc__ && (defined __arch64__ || defined __sparc_v9__) + __asm volatile ("membar #LoadLoad" : : : "memory"); +#else + __asm volatile ("" : : : "memory"); +#endif +} + +static inline void +swap (int *array, int a, int b) +{ + int val = array[a]; + array[a] = array[b]; + array[b] = val; +} + +static inline int +choose_pivot (int *array, int lo, int hi) +{ + int mid = (lo + hi) / 2; + + if (array[mid] < array[lo]) + swap (array, lo, mid); + if (array[hi] < array[mid]) + { + swap (array, mid, hi); + if (array[mid] < array[lo]) + swap (array, lo, mid); + } + return array[mid]; +} + +static inline int +partition (int *array, int lo, int hi) +{ + int pivot = choose_pivot (array, lo, hi); + int left = lo; + int right = hi; + + for (;;) + { + while (array[++left] < pivot); + while (array[--right] > pivot); + if (left >= right) + break; + swap (array, left, right); + } + return left; +} + +static void +sort1 (int *array, int count) +{ + omp_lock_t lock; + struct int_pair_stack global_stack; + int busy = 1; + int num_threads; + + omp_init_lock (&lock); + init_int_pair_stack (&global_stack); + #pragma omp parallel firstprivate (array, count) + { + int lo = 0, hi = 0, mid, next_lo, next_hi; + bool idle = true; + struct int_pair_stack local_stack; + + init_int_pair_stack (&local_stack); + if (omp_get_thread_num () == 0) + { + num_threads = omp_get_num_threads (); + hi = count - 1; + idle = false; + } + + for (;;) + { + if (hi - lo < THRESHOLD) + { + insertsort (array, lo, hi); + lo = hi; + } + if (lo >= hi) + { + if (size_int_pair_stack (&local_stack) == 0) + { + again: + omp_set_lock (&lock); + if (size_int_pair_stack (&global_stack) == 0) + { + if (!idle) + busy--; + if (busy == 0) + { + omp_unset_lock (&lock); + break; + } + omp_unset_lock (&lock); + idle = true; + while (size_int_pair_stack (&global_stack) == 0 + && busy) + busy_wait (); + goto again; + } + if (idle) + busy++; + pop_int_pair_stack (&global_stack, &lo, &hi); + omp_unset_lock (&lock); + idle = false; + } + else + pop_int_pair_stack (&local_stack, &lo, &hi); + } + + mid = partition (array, lo, hi); + if (mid - lo < hi - mid) + { + next_lo = mid; + next_hi = hi; + hi = mid - 1; + } + else + { + next_lo = lo; + next_hi = mid - 1; + lo = mid; + } + + if (next_hi - next_lo < THRESHOLD) + insertsort (array, next_lo, next_hi); + else + { + if (size_int_pair_stack (&global_stack) < num_threads - 1) + { + int size; + + omp_set_lock (&lock); + size = size_int_pair_stack (&global_stack); + if (size < num_threads - 1 && size < STACK_SIZE) + push_int_pair_stack (&global_stack, next_lo, next_hi); + else + push_int_pair_stack (&local_stack, next_lo, next_hi); + omp_unset_lock (&lock); + } + else + push_int_pair_stack (&local_stack, next_lo, next_hi); + } + } + } + omp_destroy_lock (&lock); +} + +static void +sort2_1 (int *array, int lo, int hi, int num_threads, int *busy) +{ + int mid; + + if (hi - lo < THRESHOLD) + { + insertsort (array, lo, hi); + return; + } + + mid = partition (array, lo, hi); + + if (*busy >= num_threads) + { + sort2_1 (array, lo, mid - 1, num_threads, busy); + sort2_1 (array, mid, hi, num_threads, busy); + return; + } + + #pragma omp atomic + *busy += 1; + + #pragma omp parallel num_threads (2) \ + firstprivate (array, lo, hi, mid, num_threads, busy) + { + if (omp_get_thread_num () == 0) + sort2_1 (array, lo, mid - 1, num_threads, busy); + else + { + sort2_1 (array, mid, hi, num_threads, busy); + #pragma omp atomic + *busy -= 1; + } + } +} + +static void +sort2 (int *array, int count) +{ + int num_threads; + int busy = 1; + + #pragma omp parallel + #pragma omp single nowait + num_threads = omp_get_num_threads (); + + sort2_1 (array, 0, count - 1, num_threads, &busy); +} + +#if _OPENMP >= 200805 +static void +sort3_1 (int *array, int lo, int hi) +{ + int mid; + + if (hi - lo < THRESHOLD) + { + insertsort (array, lo, hi); + return; + } + + mid = partition (array, lo, hi); + #pragma omp task + sort3_1 (array, lo, mid - 1); + sort3_1 (array, mid, hi); +} + +static void +sort3 (int *array, int count) +{ + #pragma omp parallel + #pragma omp single + sort3_1 (array, 0, count - 1); +} +#endif + +int +main (int argc, char **argv) +{ + int i, count = 1000000; + double stime; + int *unsorted, *sorted, num_threads; + if (argc >= 2) + count = strtoul (argv[1], NULL, 0); + + unsorted = malloc (count * sizeof (int)); + sorted = malloc (count * sizeof (int)); + if (unsorted == NULL || sorted == NULL) + { + puts ("allocation failure"); + exit (1); + } + + srand (0xdeadbeef); + for (i = 0; i < count; i++) + unsorted[i] = rand (); + + omp_set_nested (1); + omp_set_dynamic (0); + #pragma omp parallel + #pragma omp single nowait + num_threads = omp_get_num_threads (); + printf ("Threads: %d\n", num_threads); + + memcpy (sorted, unsorted, count * sizeof (int)); + stime = omp_get_wtime (); + sort1 (sorted, count); + verify ("sort1", stime, sorted, count); + + memcpy (sorted, unsorted, count * sizeof (int)); + stime = omp_get_wtime (); + sort2 (sorted, count); + verify ("sort2", stime, sorted, count); + +#if _OPENMP >= 200805 + memcpy (sorted, unsorted, count * sizeof (int)); + stime = omp_get_wtime (); + sort3 (sorted, count); + verify ("sort3", stime, sorted, count); +#endif + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/task-1.c b/libgomp/testsuite/libgomp.c/task-1.c new file mode 100644 index 000000000..66f58a29b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/task-1.c @@ -0,0 +1,84 @@ +extern void abort (void); + +int a = 18; + +void +f1 (int i, int j, int k) +{ + int l = 6, m = 7, n = 8; +#pragma omp task private(j, m) shared(k, n) + { + j = 6; + m = 5; + if (++a != 19 || ++i != 9 || j != 6 || ++l != 7 || m != 5 || ++n != 9) + #pragma omp atomic + k++; + } +#pragma omp taskwait + if (a != 19 || i != 8 || j != 26 || k != 0 || l != 6 || m != 7 || n != 9) + abort (); +} + +int v1 = 1, v2 = 2, v5 = 5; +int err; + +void +f2 (void) +{ + int v3 = 3; +#pragma omp sections private (v1) firstprivate (v2) + { + #pragma omp section + { + int v4 = 4; + v1 = 7; + #pragma omp task + { + if (++v1 != 8 || ++v2 != 3 || ++v3 != 4 || ++v4 != 5 || ++v5 != 6) + err = 1; + } + #pragma omp taskwait + if (v1 != 7 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 6) + abort (); + if (err) + abort (); + } + } +} + +void +f3 (int i, int j, int k) +{ + int l = 6, m = 7, n = 8; +#pragma omp task private(j, m) shared(k, n) untied + { + j = 6; + m = 5; + if (++a != 19 || ++i != 9 || j != 6 || ++l != 7 || m != 5 || ++n != 9) + #pragma omp atomic + k++; + } +#pragma omp taskwait + if (a != 19 || i != 8 || j != 26 || k != 0 || l != 6 || m != 7 || n != 9) + abort (); +} + +int +main (void) +{ + f1 (8, 26, 0); + f2 (); + a = 18; + f3 (8, 26, 0); + a = 18; +#pragma omp parallel num_threads(4) + { + #pragma omp master + { + f1 (8, 26, 0); + a = 18; + f3 (8, 26, 0); + } + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/task-2.c b/libgomp/testsuite/libgomp.c/task-2.c new file mode 100644 index 000000000..ed6a09c35 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/task-2.c @@ -0,0 +1,53 @@ +extern void abort (void); + +int +f1 (void) +{ + int a = 6, e = 0; + int nested (int x) + { + return x + a; + } + #pragma omp task + { + int n = nested (5); + if (n != 11) + #pragma omp atomic + e += 1; + } + #pragma omp taskwait + return e; +} + +int +f2 (void) +{ + int a = 6, e = 0; + int nested (int x) + { + return x + a; + } + a = nested (4); + #pragma omp task + { + if (a != 10) + #pragma omp atomic + e += 1; + } + #pragma omp taskwait + return e; +} + +int +main (void) +{ + int e = 0; + #pragma omp parallel num_threads(4) reduction(+:e) + { + e += f1 (); + e += f2 (); + } + if (e) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/task-3.c b/libgomp/testsuite/libgomp.c/task-3.c new file mode 100644 index 000000000..5657346bd --- /dev/null +++ b/libgomp/testsuite/libgomp.c/task-3.c @@ -0,0 +1,70 @@ +/* { dg-do run } */ + +#include <omp.h> +extern void abort (); + +int l = 5; + +int +foo (int i) +{ + int j = 7; + const int k = 8; + #pragma omp task firstprivate (i) shared (j, l) + { + #pragma omp critical + { + j += i; + l += k; + } + } + i++; + #pragma omp task firstprivate (i) shared (j, l) + { + #pragma omp critical + { + j += i; + l += k; + } + } + i++; + #pragma omp task firstprivate (i) shared (j, l) + { + #pragma omp critical + { + j += i; + l += k; + } + } + i++; + #pragma omp task firstprivate (i) shared (j, l) + { + #pragma omp critical + { + j += i; + l += k; + } + } + i++; + #pragma omp taskwait + return (i != 8 * omp_get_thread_num () + 4 + || j != 4 * i - 3 + || k != 8); +} + +int +main (void) +{ + int r = 0; + #pragma omp parallel num_threads (4) reduction(+:r) + if (omp_get_num_threads () != 4) + { + #pragma omp master + l = 133; + } + else if (foo (8 * omp_get_thread_num ())) + r++; + if (r || l != 133) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/task-4.c b/libgomp/testsuite/libgomp.c/task-4.c new file mode 100644 index 000000000..184359300 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/task-4.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> +#include <string.h> + +int e; + +void __attribute__((noinline)) +baz (int i, int *p, int j, int *q) +{ + if (p[0] != 1 || p[i] != 3 || q[0] != 2 || q[j] != 4) + #pragma omp atomic + e++; +} + +void __attribute__((noinline)) +foo (int i, int j) +{ + int p[i + 1]; + int q[j + 1]; + memset (p, 0, sizeof (p)); + memset (q, 0, sizeof (q)); + p[0] = 1; + p[i] = 3; + q[0] = 2; + q[j] = 4; + #pragma omp task firstprivate (p, q) + baz (i, p, j, q); +} + +int +main (void) +{ + #pragma omp parallel num_threads (4) + foo (5 + omp_get_thread_num (), 7 + omp_get_thread_num ()); + if (e) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/vla-1.c b/libgomp/testsuite/libgomp.c/vla-1.c new file mode 100644 index 000000000..bdacdbbe8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/vla-1.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> +#include <string.h> + +int +main (int argc, char **argv[]) +{ + int n = argc < 5 ? 12 : 31, i, m, l; + char a[n + 3]; + unsigned short b[n / 2 - 1]; + int c[n * 2 + 1]; + + for (i = 0; i < n + 3; i++) + a[i] = i; + for (i = 0; i < n / 2 - 1; i++) + b[i] = (i << 8) | i; + for (i = 0; i < n * 2 + 1; i++) + c[i] = (i << 24) | i; + l = 0; + m = n; +#pragma omp parallel default (shared) num_threads (4) \ + firstprivate (a, m) private (b, i) reduction (+:l) + { + for (i = 0; i < m + 3; i++) + if (a[i] != i) + l++; + for (i = 0; i < m * 2 + 1; i++) + if (c[i] != ((i << 24) | i)) + l++; +#pragma omp barrier + memset (a, omp_get_thread_num (), m + 3); + for (i = 0; i < m / 2 - 1; i++) + b[i] = a[0] + 7; +#pragma omp master + { + for (i = 0; i < m * 2 + 1; i++) + c[i] = a[0] + 16; + } +#pragma omp barrier + if (a[0] != omp_get_thread_num ()) + l++; + for (i = 1; i < m + 3; i++) + if (a[i] != a[0]) + l++; + for (i = 0; i < m / 2 - 1; i++) + if (b[i] != a[0] + 7) + l++; + for (i = 0; i < m * 2 + 1; i++) + if (c[i] != 16) + l++; + } + if (l) + abort (); + for (i = 0; i < n * 2 + 1; i++) + if (c[i] != 16) + l++; + return 0; +} |