| // 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); |
| } |