OpenMP: New C/C++ testcases for imperfectly nested loops.
gcc/testsuite/ChangeLog * c-c++-common/gomp/imperfect-attributes.c: New. * c-c++-common/gomp/imperfect-badloops.c: New. * c-c++-common/gomp/imperfect-blocks.c: New. * c-c++-common/gomp/imperfect-extension.c: New. * c-c++-common/gomp/imperfect-gotos.c: New. * c-c++-common/gomp/imperfect-invalid-scope.c: New. * c-c++-common/gomp/imperfect-labels.c: New. * c-c++-common/gomp/imperfect-legacy-syntax.c: New. * c-c++-common/gomp/imperfect-pragmas.c: New. * c-c++-common/gomp/imperfect1.c: New. * c-c++-common/gomp/imperfect2.c: New. * c-c++-common/gomp/imperfect3.c: New. * c-c++-common/gomp/imperfect4.c: New. * c-c++-common/gomp/imperfect5.c: New. libgomp/ChangeLog * testsuite/libgomp.c-c++-common/imperfect1.c: New. * testsuite/libgomp.c-c++-common/imperfect2.c: New. * testsuite/libgomp.c-c++-common/imperfect3.c: New. * testsuite/libgomp.c-c++-common/imperfect4.c: New. * testsuite/libgomp.c-c++-common/imperfect5.c: New. * testsuite/libgomp.c-c++-common/imperfect6.c: New. * testsuite/libgomp.c-c++-common/target-imperfect1.c: New. * testsuite/libgomp.c-c++-common/target-imperfect2.c: New. * testsuite/libgomp.c-c++-common/target-imperfect3.c: New. * testsuite/libgomp.c-c++-common/target-imperfect4.c: New.
This commit is contained in:
parent
53891f18f3
commit
410df0843d
24 changed files with 2018 additions and 0 deletions
81
gcc/testsuite/c-c++-common/gomp/imperfect-attributes.c
Normal file
81
gcc/testsuite/c-c++-common/gomp/imperfect-attributes.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* { dg-do compile { target { c || c++11 } } } */
|
||||
|
||||
/* Check that a nested FOR loop with standard c/c++ attributes on it
|
||||
is treated as intervening code, since it doesn't match the grammar
|
||||
for canonical loop nest form. */
|
||||
|
||||
extern void do_something (void);
|
||||
|
||||
void imperfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
[[]] for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
/* { dg-error "inner loops must be perfectly nested" "" { target *-*-*} .-1 } */
|
||||
{
|
||||
[[]] for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Similar, but put the attributes on a block wrapping the nested loop
|
||||
instead. */
|
||||
|
||||
void imperfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
[[]]
|
||||
{
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void perfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
/* { dg-error "inner loops must be perfectly nested" "" { target *-*-*} .-1 } */
|
||||
{
|
||||
[[]]
|
||||
{
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure attributes are accepted in the innermost loop body, which has
|
||||
no intervening code restrictions. */
|
||||
|
||||
void imperfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
[[]] do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
[[]] do_something ();
|
||||
}
|
||||
}
|
50
gcc/testsuite/c-c++-common/gomp/imperfect-badloops.c
Normal file
50
gcc/testsuite/c-c++-common/gomp/imperfect-badloops.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This test case is expected to fail due to errors. */
|
||||
|
||||
int f1 (int depth, int iter);
|
||||
int f2 (int depth, int iter);
|
||||
void do_something (void);
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
if (a1 < a2)
|
||||
{
|
||||
int z = 0;
|
||||
while (z < i) /* { dg-error "loop not permitted in intervening code " } */
|
||||
{
|
||||
do_something ();
|
||||
z++;
|
||||
}
|
||||
do /* { dg-error "loop not permitted in intervening code " } */
|
||||
{
|
||||
do_something ();
|
||||
z--;
|
||||
} while (z >= 0);
|
||||
}
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
if (a1 < a3)
|
||||
{
|
||||
int z;
|
||||
for (z = 0; z < i; z++) /* { dg-error "loop not permitted in intervening code " } */
|
||||
{
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
75
gcc/testsuite/c-c++-common/gomp/imperfect-blocks.c
Normal file
75
gcc/testsuite/c-c++-common/gomp/imperfect-blocks.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Check that compound statements in intervening code are correctly
|
||||
handled. */
|
||||
|
||||
extern void do_something (void);
|
||||
|
||||
void imperfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
{}
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
{}
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void imperfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
void perfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
void imperfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
{ do_something (); }
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
{ do_something (); }
|
||||
}
|
||||
}
|
||||
|
||||
void perfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
{ do_something (); }
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
{ do_something (); }
|
||||
}
|
||||
}
|
||||
|
55
gcc/testsuite/c-c++-common/gomp/imperfect-extension.c
Normal file
55
gcc/testsuite/c-c++-common/gomp/imperfect-extension.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Check that __extension__ introduces intervening code. */
|
||||
|
||||
extern void do_something (void);
|
||||
|
||||
void imperfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
__extension__ ({
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void perfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
/* { dg-error "inner loops must be perfectly nested" "" { target *-*-*} .-1 } */
|
||||
{
|
||||
__extension__ ({
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that we don't barf on __extension__ in the inner loop body. */
|
||||
void imperfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
__extension__ ({
|
||||
do_something ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void perfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
__extension__ ({
|
||||
do_something ();
|
||||
});
|
||||
}
|
||||
}
|
174
gcc/testsuite/c-c++-common/gomp/imperfect-gotos.c
Normal file
174
gcc/testsuite/c-c++-common/gomp/imperfect-gotos.c
Normal file
|
@ -0,0 +1,174 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This file contains tests that are expected to fail. */
|
||||
|
||||
|
||||
/* These jumps are all OK since they are to/from the same structured block. */
|
||||
|
||||
void f1a (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
goto a; a:;
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
goto c; c:;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Jump around loop body to/from different structured blocks of intervening
|
||||
code. */
|
||||
void f2a (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
goto a; a:;
|
||||
if (i > 16) goto b; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
goto c; c:;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Jump into loop body from intervening code. */
|
||||
void f3a (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
goto a; a:;
|
||||
if (i > 16) goto c; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
c:
|
||||
;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Jump out of loop body to intervening code. */
|
||||
void f4a (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
goto a; a:;
|
||||
for (int j = 0; j < 64; ++j)
|
||||
if (i > 16) goto c; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
c:
|
||||
;
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* The next group of tests use the GNU extension for local labels. Expected
|
||||
behavior is the same as the above group. */
|
||||
|
||||
/* These jumps are all OK since they are to/from the same structured block. */
|
||||
|
||||
void f1b (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
__label__ a, b, c;
|
||||
goto a; a:;
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
goto c; c:;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Jump around loop body to/from different structured blocks of intervening
|
||||
code. */
|
||||
void f2b (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
__label__ a, b, c;
|
||||
goto a; a:;
|
||||
if (i > 16) goto b; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
goto c; c:;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Jump into loop body from intervening code. */
|
||||
void f3b (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
__label__ a, b, c;
|
||||
goto a; a:;
|
||||
if (i > 16) goto c; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
c:
|
||||
;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Jump out of loop body to intervening code. */
|
||||
void f4b (void)
|
||||
{
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
__label__ a, b, c;
|
||||
goto a; a:;
|
||||
for (int j = 0; j < 64; ++j)
|
||||
if (i > 16) goto c; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
c:
|
||||
;
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that the even the valid jumps are rejected when intervening code
|
||||
is not allowed at all. */
|
||||
|
||||
void f1c (void)
|
||||
{
|
||||
#pragma omp for ordered(2)
|
||||
for (int i = 0; i < 64; ++i) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
goto a; a:;
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
goto c; c:;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
||||
void f1d (void)
|
||||
{
|
||||
#pragma omp for ordered(2)
|
||||
for (int i = 0; i < 64; ++i) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
__label__ a, b, c;
|
||||
goto a; a:;
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
goto c; c:;
|
||||
}
|
||||
goto b; b:;
|
||||
}
|
||||
}
|
||||
|
77
gcc/testsuite/c-c++-common/gomp/imperfect-invalid-scope.c
Normal file
77
gcc/testsuite/c-c++-common/gomp/imperfect-invalid-scope.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Check that various cases of invalid references to variables bound
|
||||
in an intervening code scope are diagnosed and do not ICE. This test
|
||||
is expected to produce errors. */
|
||||
|
||||
extern void foo (int, int);
|
||||
|
||||
void f1 (void)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int v = (i + 4) * 2;
|
||||
for (int j = v; j < 64; j++) /* { dg-error "initializer is bound in intervening code" } */
|
||||
foo (i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void f2 (void)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int v = (i + 4) * 2;
|
||||
for (int j = 0; j < v; j++) /* { dg-error "end test is bound in intervening code" } */
|
||||
foo (i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void f3 (void)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int v = (i + 4) * 2;
|
||||
for (int j = 0; j < 64; j = j + v) /* { dg-error "increment expression is bound in intervening code" } */
|
||||
foo (i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void f4 (void)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int v = 8;
|
||||
for (int j = v; j < 64; j++) /* { dg-error "initializer is bound in intervening code" } */
|
||||
foo (i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void f5 (void)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < 64; j++) /* { dg-error "loop variable is bound in intervening code" } */
|
||||
foo (i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void f6 (void)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int j;
|
||||
{
|
||||
int v = 8;
|
||||
for (j = v; j < 64; j++) /* { dg-error "loop variable is bound in intervening code" } */
|
||||
/* { dg-error "initializer is bound in intervening code" "" { target *-*-* } .-1 } */
|
||||
foo (i, j);
|
||||
}
|
||||
}
|
||||
}
|
85
gcc/testsuite/c-c++-common/gomp/imperfect-labels.c
Normal file
85
gcc/testsuite/c-c++-common/gomp/imperfect-labels.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Check that a nested FOR loop with a label on it is treated as
|
||||
intervening code, since it doesn't match the grammar for canonical
|
||||
loop nest form. */
|
||||
|
||||
extern void do_something (void);
|
||||
|
||||
void imperfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
foo:
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
/* { dg-error "inner loops must be perfectly nested" "" { target *-*-*} .-1 } */
|
||||
{
|
||||
foo:
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Similar, but put the label on a block wrapping the nested loop instead. */
|
||||
|
||||
void imperfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
foo:
|
||||
{
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void perfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
/* { dg-error "inner loops must be perfectly nested" "" { target *-*-*} .-1 } */
|
||||
{
|
||||
foo:
|
||||
{
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check that labels are allowed in the innermost loop body. */
|
||||
|
||||
void imperfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
foo:
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
foo:
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
44
gcc/testsuite/c-c++-common/gomp/imperfect-legacy-syntax.c
Normal file
44
gcc/testsuite/c-c++-common/gomp/imperfect-legacy-syntax.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Braces may enclose a nested FOR even when intervening code is not
|
||||
permitted. Before GCC implemented OpenMP 5.1 canonical loop syntax
|
||||
and support for intervening code, it used to ignore empty statements
|
||||
instead of treating them as intervening code; as an extension, those
|
||||
are still accepted without complaint even in constructs where intervening
|
||||
code is not supposed to be valid. */
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for ordered(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void s2 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for ordered(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
;
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
;
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
}
|
||||
;
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
85
gcc/testsuite/c-c++-common/gomp/imperfect-pragmas.c
Normal file
85
gcc/testsuite/c-c++-common/gomp/imperfect-pragmas.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Check that non-statement pragmas are accepted in a canonical loop nest
|
||||
even when perfect nesting is required. */
|
||||
|
||||
extern void do_something (void);
|
||||
|
||||
void imperfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
void perfect1 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
for (int j = 0; j < y; j++)
|
||||
do_something ();
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* "GCC unroll" is a statement pragma that consumes the following loop as
|
||||
a substatement. Thus, the inner loop should be treated as intervening
|
||||
code rather than part of the loop nest. */
|
||||
|
||||
void imperfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
#pragma GCC unroll 4
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect2 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++) /* { dg-error "not enough nested loops" } */
|
||||
/* { dg-error "inner loops must be perfectly nested" "" { target *-*-*} .-1 } */
|
||||
{
|
||||
#pragma GCC unroll 4
|
||||
for (int j = 0; j < y; j++) /* { dg-error "loop not permitted in intervening code" } */
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check that statement pragmas are accepted in the innermost loop body. */
|
||||
|
||||
void imperfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for collapse (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
#pragma GCC unroll 4
|
||||
for (int k = 0; k < 4; k++)
|
||||
do_something ();
|
||||
}
|
||||
}
|
||||
|
||||
void perfect3 (int x, int y)
|
||||
{
|
||||
#pragma omp for ordered (2)
|
||||
for (int i = 0; i < x; i++)
|
||||
for (int j = 0; j < y; j++)
|
||||
{
|
||||
#pragma GCC unroll 4
|
||||
for (int k = 0; k < 4; k++)
|
||||
do_something ();
|
||||
}
|
||||
}
|
38
gcc/testsuite/c-c++-common/gomp/imperfect1.c
Normal file
38
gcc/testsuite/c-c++-common/gomp/imperfect1.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This test case is expected to fail due to errors. */
|
||||
|
||||
int f1 (int depth, int iter);
|
||||
int f2 (int depth, int iter);
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
#pragma omp barrier /* { dg-error "intervening code must not contain OpenMP directives" } */
|
||||
f1 (1, j);
|
||||
if (i == 2)
|
||||
continue; /* { dg-error "invalid exit" } */
|
||||
else
|
||||
break; /* { dg-error "invalid exit" } */
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
for (k = 0; k < a3; k++) /* { dg-error "loop not permitted in intervening code " } */
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
34
gcc/testsuite/c-c++-common/gomp/imperfect2.c
Normal file
34
gcc/testsuite/c-c++-common/gomp/imperfect2.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This test case is expected to fail due to errors. */
|
||||
|
||||
/* These functions that are part of the OpenMP runtime API would ordinarily
|
||||
be declared in omp.h, but we don't have that here. */
|
||||
extern int omp_get_num_threads(void);
|
||||
extern int omp_get_max_threads(void);
|
||||
|
||||
int f1 (int depth, int iter);
|
||||
int f2 (int depth, int iter);
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
for (j = 0; j < omp_get_num_threads (); j++) /* This is OK */
|
||||
{
|
||||
f1 (1, omp_get_num_threads ()); /* { dg-error "not permitted in intervening code" } */
|
||||
for (k = omp_get_num_threads (); k < a3; k++) /* This is OK */
|
||||
{
|
||||
f1 (2, omp_get_num_threads ());
|
||||
f2 (2, omp_get_max_threads ());
|
||||
}
|
||||
f2 (1, omp_get_max_threads ()); /* { dg-error "not permitted in intervening code" } */
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
52
gcc/testsuite/c-c++-common/gomp/imperfect3.c
Normal file
52
gcc/testsuite/c-c++-common/gomp/imperfect3.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This test case is expected to fail due to errors. */
|
||||
|
||||
/* Test that the imperfectly-nested loops with the ordered clause gives
|
||||
an error, and that there is only one error (and not one on every
|
||||
intervening statement). */
|
||||
|
||||
int f1 (int depth, int iter);
|
||||
int f2 (int depth, int iter);
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
/* This loop without intervening code ought to be OK. */
|
||||
#pragma omp for ordered(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
#pragma omp ordered doacross(source:omp_cur_iteration)
|
||||
#pragma omp ordered doacross(sink: i - 2, j + 2, k - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now add intervening code. */
|
||||
#pragma omp for ordered(3)
|
||||
for (i = 0; i < a1; i++) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
f1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
f1 (1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
#pragma omp ordered doacross(source:omp_cur_iteration)
|
||||
#pragma omp ordered doacross(sink: i - 2, j + 2, k - 1)
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
33
gcc/testsuite/c-c++-common/gomp/imperfect4.c
Normal file
33
gcc/testsuite/c-c++-common/gomp/imperfect4.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This test case is expected to fail due to errors. */
|
||||
|
||||
int f1 (int depth, int iter);
|
||||
int f2 (int depth, int iter);
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(4)
|
||||
for (i = 0; i < a1; i++) /* { dg-error "not enough nested loops" } */
|
||||
{
|
||||
f1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
f1 (1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
/* According to the grammar, this is intervening code; we
|
||||
don't know that we are also missing a nested for loop
|
||||
until we have parsed this whole compound expression. */
|
||||
#pragma omp barrier /* { dg-error "intervening code must not contain OpenMP directives" } */
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
95
gcc/testsuite/c-c++-common/gomp/imperfect5.c
Normal file
95
gcc/testsuite/c-c++-common/gomp/imperfect5.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* This test case is expected to fail due to errors. */
|
||||
|
||||
#define N 30
|
||||
#define M 3
|
||||
|
||||
int a[N][M], b[N][M], c[N][M];
|
||||
|
||||
extern void dostuff (int, int);
|
||||
|
||||
/* good1 and good2 should compile without error. */
|
||||
void
|
||||
good1 (void)
|
||||
{
|
||||
int x, shift;
|
||||
|
||||
x = 0;
|
||||
#pragma omp parallel for simd collapse(2) reduction(inscan,+: x) private(shift)
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
for (int j = 0; j < M; j++)
|
||||
{
|
||||
x += a[i][j];
|
||||
x += b[i][j];
|
||||
#pragma omp scan inclusive(x)
|
||||
shift = i + 29*j;
|
||||
c[i][j] = x + shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
good2 (void)
|
||||
{
|
||||
int x, shift;
|
||||
x = 0;
|
||||
|
||||
#pragma omp parallel for simd collapse(2) reduction(inscan,+: x) private(shift)
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
for (int j = 0; j < M; j++)
|
||||
{
|
||||
shift = i + 29*j;
|
||||
c[i][j] = x + shift;
|
||||
#pragma omp scan exclusive(x)
|
||||
x += a[i][j];
|
||||
x += b[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adding intervening code should trigger an error. */
|
||||
|
||||
void
|
||||
bad1 (void)
|
||||
{
|
||||
int x, shift;
|
||||
|
||||
x = 0;
|
||||
#pragma omp parallel for simd collapse(2) reduction(inscan,+: x) private(shift)
|
||||
for (int i = 0; i < N; i++) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
dostuff (i, 0);
|
||||
for (int j = 0; j < M; j++)
|
||||
{
|
||||
x += a[i][j];
|
||||
x += b[i][j];
|
||||
#pragma omp scan inclusive(x)
|
||||
shift = i + 29*j;
|
||||
c[i][j] = x + shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bad2 (void)
|
||||
{
|
||||
int x, shift;
|
||||
x = 0;
|
||||
|
||||
#pragma omp parallel for simd collapse(2) reduction(inscan,+: x) private(shift)
|
||||
for (int i = 0; i < N; i++) /* { dg-error "inner loops must be perfectly nested" } */
|
||||
{
|
||||
for (int j = 0; j < M; j++)
|
||||
{
|
||||
shift = i + 29*j;
|
||||
c[i][j] = x + shift;
|
||||
#pragma omp scan exclusive(x)
|
||||
x += a[i][j];
|
||||
x += b[i][j];
|
||||
}
|
||||
dostuff (i, 1);
|
||||
}
|
||||
}
|
76
libgomp/testsuite/libgomp.c-c++-common/imperfect1.c
Normal file
76
libgomp/testsuite/libgomp.c-c++-common/imperfect1.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
f1 (1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
114
libgomp/testsuite/libgomp.c-c++-common/imperfect2.c
Normal file
114
libgomp/testsuite/libgomp.c-c++-common/imperfect2.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
{
|
||||
g1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
f1 (1, j);
|
||||
{
|
||||
g1 (1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
{
|
||||
g1 (2, k);
|
||||
g2 (2, k);
|
||||
}
|
||||
f2 (2, k);
|
||||
}
|
||||
g2 (1, j);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
g2 (0, i);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
119
libgomp/testsuite/libgomp.c-c++-common/imperfect3.c
Normal file
119
libgomp/testsuite/libgomp.c-c++-common/imperfect3.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect2.c, but includes bindings in the blocks. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
int local0 = 0;
|
||||
f1 (local0, i);
|
||||
{
|
||||
g1 (local0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
int local1 = 1;
|
||||
f1 (local1, j);
|
||||
{
|
||||
g1 (local1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
int local2 = 2;
|
||||
f1 (local2, k);
|
||||
{
|
||||
g1 (local2, k);
|
||||
g2 (local2, k);
|
||||
}
|
||||
f2 (local2, k);
|
||||
}
|
||||
g2 (local1, j);
|
||||
}
|
||||
f2 (local1, j);
|
||||
}
|
||||
g2 (local0, i);
|
||||
}
|
||||
f2 (local0, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
117
libgomp/testsuite/libgomp.c-c++-common/imperfect4.c
Normal file
117
libgomp/testsuite/libgomp.c-c++-common/imperfect4.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect2.c, but includes blocks that are themselves intervening
|
||||
code. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
{ f1 (0, i); }
|
||||
{
|
||||
g1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
{ f1 (1, j); }
|
||||
{
|
||||
{ g1 (1, j); }
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
{
|
||||
g1 (2, k);
|
||||
g2 (2, k);
|
||||
}
|
||||
f2 (2, k);
|
||||
}
|
||||
{ g2 (1, j); }
|
||||
}
|
||||
{ f2 (1, j); }
|
||||
}
|
||||
{ g2 (0, i); }
|
||||
}
|
||||
{ f2 (0, i); }
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
49
libgomp/testsuite/libgomp.c-c++-common/imperfect5.c
Normal file
49
libgomp/testsuite/libgomp.c-c++-common/imperfect5.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
static int inner_loop_count = 0;
|
||||
static int intervening_code_count = 0;
|
||||
|
||||
void
|
||||
g (int x, int y)
|
||||
{
|
||||
inner_loop_count++;
|
||||
}
|
||||
|
||||
int
|
||||
foo (int imax, int jmax)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
#pragma omp for collapse(2)
|
||||
for (int i = 0; i < imax; ++i)
|
||||
{
|
||||
/* All the intervening code at the same level must be executed
|
||||
the same number of times. */
|
||||
++intervening_code_count;
|
||||
for (int j = 0; j < jmax; ++j)
|
||||
{
|
||||
g (i, j);
|
||||
}
|
||||
/* This is the outer j, not the one from the inner collapsed loop. */
|
||||
++j;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int j = foo (5, 3);
|
||||
if (j != intervening_code_count)
|
||||
abort ();
|
||||
if (inner_loop_count != 5 * 3)
|
||||
abort ();
|
||||
if (intervening_code_count < 5 || intervening_code_count > 5 * 3)
|
||||
abort ();
|
||||
}
|
115
libgomp/testsuite/libgomp.c-c++-common/imperfect6.c
Normal file
115
libgomp/testsuite/libgomp.c-c++-common/imperfect6.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect4.c, but bind the iteration variables in the loops. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
|
||||
#pragma omp for collapse(3)
|
||||
for (int i = 0; i < a1; i++)
|
||||
{
|
||||
{ f1 (0, i); }
|
||||
{
|
||||
g1 (0, i);
|
||||
for (int j = 0; j < a2; j++)
|
||||
{
|
||||
{ f1 (1, j); }
|
||||
{
|
||||
{ g1 (1, j); }
|
||||
for (int k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
{
|
||||
g1 (2, k);
|
||||
g2 (2, k);
|
||||
}
|
||||
f2 (2, k);
|
||||
}
|
||||
{ g2 (1, j); }
|
||||
}
|
||||
{ f2 (1, j); }
|
||||
}
|
||||
{ g2 (0, i); }
|
||||
}
|
||||
{ f2 (0, i); }
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
81
libgomp/testsuite/libgomp.c-c++-common/target-imperfect1.c
Normal file
81
libgomp/testsuite/libgomp.c-c++-common/target-imperfect1.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect1.c, but enables offloading. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
#pragma omp declare target enter (f1count, f2count)
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp target parallel for collapse(3) map(always, tofrom:f1count, f2count)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
f1 (1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
f2 (2, k);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
122
libgomp/testsuite/libgomp.c-c++-common/target-imperfect2.c
Normal file
122
libgomp/testsuite/libgomp.c-c++-common/target-imperfect2.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect2.c, but enables offloading. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
#pragma omp declare target enter (f1count, f2count)
|
||||
#pragma omp declare target enter (g1count, g2count)
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp target parallel for collapse(3) map(always, tofrom:f1count, f2count, g1count, g2count)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
f1 (0, i);
|
||||
{
|
||||
g1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
f1 (1, j);
|
||||
{
|
||||
g1 (1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
{
|
||||
g1 (2, k);
|
||||
g2 (2, k);
|
||||
}
|
||||
f2 (2, k);
|
||||
}
|
||||
g2 (1, j);
|
||||
}
|
||||
f2 (1, j);
|
||||
}
|
||||
g2 (0, i);
|
||||
}
|
||||
f2 (0, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
125
libgomp/testsuite/libgomp.c-c++-common/target-imperfect3.c
Normal file
125
libgomp/testsuite/libgomp.c-c++-common/target-imperfect3.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect3.c, but enables offloading. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
#pragma omp declare target enter (f1count, f2count)
|
||||
#pragma omp declare target enter (g1count, g2count)
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp target parallel for collapse(3) map(always, tofrom:f1count, f2count, g1count, g2count)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
int local0 = 0;
|
||||
f1 (local0, i);
|
||||
{
|
||||
g1 (local0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
int local1 = 1;
|
||||
f1 (local1, j);
|
||||
{
|
||||
g1 (local1, j);
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
int local2 = 2;
|
||||
f1 (local2, k);
|
||||
{
|
||||
g1 (local2, k);
|
||||
g2 (local2, k);
|
||||
}
|
||||
f2 (local2, k);
|
||||
}
|
||||
g2 (local1, j);
|
||||
}
|
||||
f2 (local1, j);
|
||||
}
|
||||
g2 (local0, i);
|
||||
}
|
||||
f2 (local0, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
122
libgomp/testsuite/libgomp.c-c++-common/target-imperfect4.c
Normal file
122
libgomp/testsuite/libgomp.c-c++-common/target-imperfect4.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
/* Like imperfect4.c, but enables offloading. */
|
||||
|
||||
static int f1count[3], f2count[3];
|
||||
static int g1count[3], g2count[3];
|
||||
#pragma omp declare target enter (f1count, f2count)
|
||||
#pragma omp declare target enter (g1count, g2count)
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern void abort (void);
|
||||
#else
|
||||
extern "C" void abort (void);
|
||||
#endif
|
||||
|
||||
int f1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int f2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
f2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g1 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
g1count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
int g2 (int depth, int iter)
|
||||
{
|
||||
#pragma omp atomic
|
||||
g2count[depth]++;
|
||||
return iter;
|
||||
}
|
||||
|
||||
void s1 (int a1, int a2, int a3)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
#pragma omp target parallel for collapse(3) map(always, tofrom:f1count, f2count, g1count, g2count)
|
||||
for (i = 0; i < a1; i++)
|
||||
{
|
||||
{ f1 (0, i); }
|
||||
{
|
||||
g1 (0, i);
|
||||
for (j = 0; j < a2; j++)
|
||||
{
|
||||
{ f1 (1, j); }
|
||||
{
|
||||
{ g1 (1, j); }
|
||||
for (k = 0; k < a3; k++)
|
||||
{
|
||||
f1 (2, k);
|
||||
{
|
||||
g1 (2, k);
|
||||
g2 (2, k);
|
||||
}
|
||||
f2 (2, k);
|
||||
}
|
||||
{ g2 (1, j); }
|
||||
}
|
||||
{ f2 (1, j); }
|
||||
}
|
||||
{ g2 (0, i); }
|
||||
}
|
||||
{ f2 (0, i); }
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
f1count[0] = 0;
|
||||
f1count[1] = 0;
|
||||
f1count[2] = 0;
|
||||
f2count[0] = 0;
|
||||
f2count[1] = 0;
|
||||
f2count[2] = 0;
|
||||
|
||||
g1count[0] = 0;
|
||||
g1count[1] = 0;
|
||||
g1count[2] = 0;
|
||||
g2count[0] = 0;
|
||||
g2count[1] = 0;
|
||||
g2count[2] = 0;
|
||||
|
||||
s1 (3, 4, 5);
|
||||
|
||||
/* All intervening code at the same depth must be executed the same
|
||||
number of times. */
|
||||
if (f1count[0] != f2count[0]) abort ();
|
||||
if (f1count[1] != f2count[1]) abort ();
|
||||
if (f1count[2] != f2count[2]) abort ();
|
||||
if (g1count[0] != f1count[0]) abort ();
|
||||
if (g2count[0] != f1count[0]) abort ();
|
||||
if (g1count[1] != f1count[1]) abort ();
|
||||
if (g2count[1] != f1count[1]) abort ();
|
||||
if (g1count[2] != f1count[2]) abort ();
|
||||
if (g2count[2] != f1count[2]) abort ();
|
||||
|
||||
/* Intervening code must be executed at least as many times as the loop
|
||||
that encloses it. */
|
||||
if (f1count[0] < 3) abort ();
|
||||
if (f1count[1] < 3 * 4) abort ();
|
||||
|
||||
/* Intervening code must not be executed more times than the number
|
||||
of logical iterations. */
|
||||
if (f1count[0] > 3 * 4 * 5) abort ();
|
||||
if (f1count[1] > 3 * 4 * 5) abort ();
|
||||
|
||||
/* Check that the innermost loop body is executed exactly the number
|
||||
of logical iterations expected. */
|
||||
if (f1count[2] != 3 * 4 * 5) abort ();
|
||||
}
|
Loading…
Add table
Reference in a new issue