| // RUN: %clang_cc1 %s -fopenacc -verify |
| |
| constexpr int three() { return 3; } |
| constexpr int one() { return 1; } |
| constexpr int neg() { return -1; } |
| constexpr int zero() { return 0; } |
| |
| struct NotConstexpr { |
| constexpr NotConstexpr(){}; |
| |
| operator int(){ return 1; } |
| }; |
| struct ConvertsNegative { |
| constexpr ConvertsNegative(){}; |
| |
| constexpr operator int(){ return -1; } |
| }; |
| struct ConvertsOne{ |
| constexpr ConvertsOne(){}; |
| |
| constexpr operator int(){ return 1; } |
| }; |
| |
| struct ConvertsThree{ |
| constexpr ConvertsThree(){}; |
| |
| constexpr operator int(){ return 3; } |
| }; |
| |
| template<typename T, int Val> |
| void negative_zero_constexpr_templ() { |
| // expected-error@+1 2{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} |
| #pragma acc serial loop tile(*, T{}) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} |
| #pragma acc parallel loop tile(Val, *) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} |
| #pragma acc kernels loop tile(zero(), *) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| } |
| |
| void negative_zero_constexpr() { |
| negative_zero_constexpr_templ<int, 1>(); // expected-note{{in instantiation of function template specialization}} |
| negative_zero_constexpr_templ<int, -1>(); // expected-note{{in instantiation of function template specialization}} |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} |
| #pragma acc serial loop tile(0, *) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} |
| #pragma acc parallel loop tile(1, 0) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} |
| #pragma acc kernels loop tile(1, -1) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} |
| #pragma acc parallel loop tile(-1, 0) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} |
| #pragma acc serial loop tile(zero(), 0) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} |
| #pragma acc kernels loop tile(1, neg()) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be an asterisk or a constant expression}} |
| #pragma acc parallel loop tile(NotConstexpr{}) |
| for(int i = 0; i < 5; ++i); |
| |
| // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} |
| #pragma acc serial loop tile(1, ConvertsNegative{}) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| #pragma acc kernels loop tile(*, ConvertsOne{}) |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| } |
| |
| template<unsigned One> |
| void only_for_loops_templ() { |
| // expected-note@+1{{'parallel loop' construct is here}} |
| #pragma acc parallel loop tile(One) |
| // expected-error@+1{{OpenACC 'parallel loop' construct can only be applied to a 'for' loop}} |
| while(true); |
| |
| // expected-note@+1{{'serial loop' construct is here}} |
| #pragma acc serial loop tile(One) |
| // expected-error@+1{{OpenACC 'serial loop' construct can only be applied to a 'for' loop}} |
| do {} while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc kernels loop tile(One, 2) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| // expected-error@+1{{while loop cannot appear in intervening code of a 'kernels loop' with a 'tile' clause}} |
| while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc serial loop tile(One, 2) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| // expected-error@+1{{do loop cannot appear in intervening code of a 'serial loop' with a 'tile' clause}} |
| do{}while(true); |
| } |
| |
| |
| void only_for_loops() { |
| // expected-note@+1{{'parallel loop' construct is here}} |
| #pragma acc parallel loop tile(1) |
| // expected-error@+1{{OpenACC 'parallel loop' construct can only be applied to a 'for' loop}} |
| while(true); |
| |
| // expected-note@+1{{'serial loop' construct is here}} |
| #pragma acc serial loop tile(1) |
| // expected-error@+1{{OpenACC 'serial loop' construct can only be applied to a 'for' loop}} |
| do {} while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc kernels loop tile(1, 2) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| // expected-error@+1{{while loop cannot appear in intervening code of a 'kernels loop' with a 'tile' clause}} |
| while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc parallel loop tile(1, 2) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| // expected-error@+1{{do loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| do{}while(true); |
| } |
| |
| template<unsigned Val> |
| void depth_too_high_templ() { |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc kernels loop tile (Val, *, Val) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc parallel loop tile (Val, *, Val) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j) |
| // expected-error@+1{{while loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc serial loop tile (Val, *, Val) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j) |
| // expected-error@+1{{do loop cannot appear in intervening code of a 'serial loop' with a 'tile' clause}} |
| do{}while(true); |
| |
| int Arr[Val+5]; |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc kernels loop tile (Val, *, Val) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(auto x : Arr) |
| // expected-error@+1{{while loop cannot appear in intervening code of a 'kernels loop' with a 'tile' clause}} |
| while(true) |
| for(int j = 0; j < 5; ++j); |
| |
| #pragma acc parallel loop tile (Val, *, Val) |
| for(int i = 0; i < 5; ++i) |
| for(auto x : Arr) |
| for(int j = 0; j < 5; ++j) |
| while(true); |
| } |
| |
| void depth_too_high() { |
| depth_too_high_templ<3>(); |
| |
| int Arr[5]; |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc serial loop tile (1, *, 3) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc parallel loop tile (1, *, 3) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j) |
| // expected-error@+1{{while loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc parallel loop tile (1, *, 3) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j) |
| // expected-error@+1{{do loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| do{}while(true); |
| |
| // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} |
| #pragma acc parallel loop tile (1, *, 3) // expected-note 2{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) |
| for(int j = 0; j < 5; ++j) |
| // expected-error@+1{{while loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| while(true) |
| for(int j = 0; j < 5; ++j); |
| |
| #pragma acc parallel loop tile (1, *, 3) |
| for(int i = 0; i < 5; ++i) |
| for(auto x : Arr) |
| for(int j = 0; j < 5; ++j) |
| while(true); |
| } |
| |
| template<unsigned Val> |
| void not_single_loop_templ() { |
| |
| int Arr[Val]; |
| |
| #pragma acc parallel loop tile (Val, *, 3) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| for (auto x : Arr) |
| for(int k = 0; k < 5; ++k); |
| // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'parallel loop' construct with a 'tile' clause}} |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k); |
| } |
| } |
| |
| void not_single_loop() { |
| not_single_loop_templ<3>(); // no diagnostic, was diagnosed in phase 1. |
| |
| int Arr[5]; |
| |
| #pragma acc parallel loop tile (1, *, 3)// expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| for (auto x : Arr) |
| for(int k = 0; k < 5; ++k); |
| // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'parallel loop' construct with a 'tile' clause}} |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k); |
| } |
| } |
| |
| template<unsigned Val> |
| void no_other_directives_templ() { |
| |
| int Arr[Val]; |
| |
| #pragma acc parallel loop tile (Val, *, 3) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| for (auto x : Arr) { |
| // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| #pragma acc serial |
| ; |
| for(int j = 0; j < 5; ++j); |
| } |
| } |
| |
| // OK, in innermost |
| #pragma acc parallel loop tile (Val, *, 3) |
| for(int i = 0; i < 5; ++i) { |
| for(int j = 0; j < 5; ++j) { |
| for (auto x : Arr) { |
| #pragma acc serial |
| ; |
| } |
| } |
| } |
| } |
| |
| void no_other_directives() { |
| no_other_directives_templ<3>(); |
| int Arr[5]; |
| |
| #pragma acc parallel loop tile (1, *, 3) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| for (auto x : Arr) { |
| // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} |
| #pragma acc serial |
| ; |
| for(int j = 0; j < 5; ++j); |
| } |
| } |
| |
| // OK, in innermost |
| #pragma acc parallel loop tile (3, *, 3) |
| for(int i = 0; i < 5; ++i) { |
| for(int j = 0; j < 5; ++j) { |
| for (auto x : Arr) { |
| #pragma acc serial |
| ; |
| } |
| } |
| } |
| } |
| |
| void call(); |
| template<unsigned Val> |
| void intervening_templ() { |
| #pragma acc parallel loop tile(1, Val, *) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} |
| call(); |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k); |
| } |
| |
| #pragma acc parallel loop tile(1, Val, *) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} |
| unsigned I; |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k); |
| } |
| |
| #pragma acc parallel loop tile(1, Val, *) |
| // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} |
| // expected-note@-2{{'parallel loop' construct is here}} |
| for(int i = 0;;++i) { |
| // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} |
| // expected-note@-5{{'parallel loop' construct is here}} |
| for(int j = 0;;++j) |
| // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} |
| // expected-note@-8{{'parallel loop' construct is here}} |
| for(int k = 0;;++k) |
| call(); |
| } |
| } |
| |
| void intervening() { |
| intervening_templ<3>(); |
| |
| #pragma acc parallel loop tile(1, 2, *) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} |
| call(); |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k); |
| } |
| |
| #pragma acc parallel loop tile(1, 2, *) // expected-note{{active 'tile' clause defined here}} |
| for(int i = 0; i < 5; ++i) { |
| //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} |
| unsigned I; |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k); |
| } |
| |
| #pragma acc parallel loop tile(1, 2, *) |
| for(int i = 0; i < 5; ++i) { |
| for(int j = 0; j < 5; ++j) |
| for(int k = 0; k < 5; ++k) |
| call(); |
| } |
| |
| #pragma acc parallel loop tile(1, 2, *) |
| // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} |
| // expected-note@-2{{'parallel loop' construct is here}} |
| for(int i = 0;;++i) { |
| // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} |
| // expected-note@-5{{'parallel loop' construct is here}} |
| for(int j = 0;;++j) |
| // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} |
| // expected-note@-8{{'parallel loop' construct is here}} |
| for(int k = 0;;++k) |
| for(;;) |
| call(); |
| } |
| } |
| |
| void collapse_tile_depth() { |
| // expected-error@+4{{'collapse' clause specifies a loop count greater than the number of available loops}} |
| // expected-note@+3{{active 'collapse' clause defined here}} |
| // expected-error@+2{{'tile' clause specifies a loop count greater than the number of available loops}} |
| // expected-note@+1{{active 'tile' clause defined here}} |
| #pragma acc parallel loop tile(1, 2, 3) collapse (3) |
| for(int i = 0; i < 5;++i) { |
| for(int j = 0; j < 5; ++j); |
| } |
| } |