blob: 2c9cc57d351056c7bbd8ff58df531803963f9cdb [file] [edit]
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++17 -fopenmp -fsyntax-only -Wuninitialized -verify %s
// A collapsed intra-tile loop starts from the floor counter of an outer loop
// in the same nest, so that floor must itself be one of the collapsed loops.
// Inside another loop transformation it is assigned in an enclosing loop's
// body and the nest would read a stale value, which is diagnosed rather than
// silently miscomputed.
extern void body(int);
void collapse_through_single_tile() {
#pragma omp for collapse(2)
#pragma omp tile sizes(4)
for (int i = 0; i < 6; ++i)
body(i);
}
void collapse_through_tile_2d() {
#pragma omp for collapse(4)
#pragma omp tile sizes(2, 3)
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 7; ++j)
body(i + j);
}
void collapse_outer_of_stacked_tiles() {
// Only the outer tile's floor and intra-tile loops are collapsed, and that
// floor is a collapsed counter, so this is fine.
#pragma omp for collapse(2)
#pragma omp tile sizes(2)
#pragma omp tile sizes(4)
for (int i = 0; i < 6; ++i)
body(i);
}
void collapse_into_stacked_tiles() {
// The third loop is the inner tile's intra-tile loop, whose floor is computed
// inside the outer intra-tile loop's body.
#pragma omp for collapse(3)
#pragma omp tile sizes(2)
#pragma omp tile sizes(4)
// expected-error@+1 {{cannot collapse the intra-tile loop of a '#pragma omp tile' that is nested inside another loop-transforming directive; OpenMP permits this construct, but it is not yet supported}}
for (int i = 0; i < 6; ++i)
body(i);
}
void collapse_simd_over_tile() {
// Rejected by the pre-existing restriction on nesting inside a 'simd' region.
#pragma omp simd collapse(2)
// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region except for ordered simd, simd, scan, or atomic directive}}
#pragma omp tile sizes(4)
for (int i = 0; i < 6; ++i)
body(i);
}
void collapse_outer_of_stacked_tiles_2d() {
// Outer tile sizes(2, 3) needs two loops, so it reaches the inner
// intra-tile loop. Same limitation as tile_of_tile_two_sizes.
#pragma omp for collapse(4)
#pragma omp tile sizes(2, 3)
#pragma omp tile sizes(4)
// expected-error@+1 {{cannot apply a loop transformation to the intra-tile loop of a '#pragma omp tile' that is nested inside another loop-transforming directive; OpenMP permits this construct, but it is not yet supported}}
for (int i = 0; i < 6; ++i)
body(i);
}
void tile_of_tile_two_sizes() {
// Outer tile sizes(3, 5) needs two loops, so it reaches the inner
// intra-tile loop. That nest would run the wrong iterations.
#pragma omp tile sizes(3, 5)
#pragma omp tile sizes(2)
// expected-error@+1 {{cannot apply a loop transformation to the intra-tile loop of a '#pragma omp tile' that is nested inside another loop-transforming directive; OpenMP permits this construct, but it is not yet supported}}
for (int i = 0; i < 6; ++i)
body(i);
}