|
| 1 | +// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2017 -Wno-sycl-2017-compat -verify -pedantic %s |
| 2 | + |
| 3 | +// The test checks functionality of [[intel::reqd_sub_group_size()]] attribute on SYCL kernel. |
| 4 | + |
| 5 | +#include "sycl.hpp" |
| 6 | + |
| 7 | +using namespace cl::sycl; |
| 8 | +queue q; |
| 9 | + |
| 10 | +[[intel::reqd_sub_group_size(4)]] void foo() {} // expected-note {{conflicting attribute is here}} |
| 11 | +// expected-note@-1 {{conflicting attribute is here}} |
| 12 | +[[intel::reqd_sub_group_size(32)]] void baz() {} // expected-note {{conflicting attribute is here}} |
| 13 | + |
| 14 | +class Functor8 { // expected-error {{conflicting attributes applied to a SYCL kernel}} |
| 15 | +public: |
| 16 | + [[intel::reqd_sub_group_size(8)]] void operator()() const { // expected-note {{conflicting attribute is here}} |
| 17 | + foo(); |
| 18 | + } |
| 19 | +}; |
| 20 | + |
| 21 | +int main() { |
| 22 | + q.submit([&](handler &h) { |
| 23 | + Functor8 f8; |
| 24 | + h.single_task<class kernel_name1>(f8); |
| 25 | + |
| 26 | + h.single_task<class kernel_name2>([]() { // expected-error {{conflicting attributes applied to a SYCL kernel}} |
| 27 | + foo(); |
| 28 | + baz(); |
| 29 | + }); |
| 30 | + }); |
| 31 | + return 0; |
| 32 | +} |
| 33 | +[[intel::reqd_sub_group_size(16)]] SYCL_EXTERNAL void B(); |
| 34 | +[[intel::reqd_sub_group_size(16)]] void A() { |
| 35 | +} |
| 36 | + |
| 37 | +[[intel::reqd_sub_group_size(16)]] SYCL_EXTERNAL void B() { |
| 38 | + A(); |
| 39 | +} |
| 40 | +// expected-note@+1 {{conflicting attribute is here}} |
| 41 | +[[intel::reqd_sub_group_size(2)]] void sg_size2() {} |
| 42 | + |
| 43 | +// expected-note@+2 {{conflicting attribute is here}} |
| 44 | +// expected-error@+1 {{conflicting attributes applied to a SYCL kernel}} |
| 45 | +[[intel::reqd_sub_group_size(4)]] __attribute__((sycl_device)) void sg_size4() { |
| 46 | + sg_size2(); |
| 47 | +} |
| 48 | + |
| 49 | +// Test that checks support and functionality of reqd_sub_group_size attribute support on function. |
| 50 | + |
| 51 | +// Tests for incorrect argument values for Intel reqd_sub_group_size attribute. |
| 52 | +[[intel::reqd_sub_group_size]] void one() {} // expected-error {{'reqd_sub_group_size' attribute takes one argument}} |
| 53 | +[[intel::reqd_sub_group_size(5)]] int a; // expected-error{{'reqd_sub_group_size' attribute only applies to functions}} |
| 54 | +[[intel::reqd_sub_group_size("foo")]] void func() {} // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} |
| 55 | +[[intel::reqd_sub_group_size(-1)]] void func1() {} // expected-error{{'reqd_sub_group_size' attribute requires a positive integral compile time constant expression}} |
| 56 | +[[intel::reqd_sub_group_size(0, 1)]] void arg() {} // expected-error{{'reqd_sub_group_size' attribute takes one argument}} |
| 57 | + |
| 58 | +// Diagnostic is emitted because the arguments mismatch. |
| 59 | +[[intel::reqd_sub_group_size(12)]] void quux(); // expected-note {{previous attribute is here}} |
| 60 | +[[intel::reqd_sub_group_size(100)]] void quux(); // expected-warning {{attribute 'reqd_sub_group_size' is already applied with different arguments}} expected-note {{previous attribute is here}} |
| 61 | +[[sycl::reqd_sub_group_size(200)]] void quux(); // expected-warning {{attribute 'reqd_sub_group_size' is already applied with different arguments}} |
| 62 | + |
| 63 | +// Make sure there's at least one argument passed. |
| 64 | +[[sycl::reqd_sub_group_size]] void quibble(); // expected-error {{'reqd_sub_group_size' attribute takes one argument}} |
| 65 | + |
| 66 | +// No diagnostic is emitted because the arguments match. |
| 67 | +[[intel::reqd_sub_group_size(12)]] void same(); |
| 68 | +[[intel::reqd_sub_group_size(12)]] void same() {} // OK |
| 69 | + |
| 70 | +// No diagnostic because the attributes are synonyms with identical behavior. |
| 71 | +[[sycl::reqd_sub_group_size(12)]] void same(); // OK |
| 72 | + |
| 73 | +// Test that checks wrong function template instantiation and ensures that the type |
| 74 | +// is checked properly when instantiating from the template definition. |
| 75 | +template <typename Ty> |
| 76 | +// expected-error@+3{{'reqd_sub_group_size' attribute requires a positive integral compile time constant expression}} |
| 77 | +// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'S'}} |
| 78 | +// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'float'}} |
| 79 | +[[intel::reqd_sub_group_size(Ty{})]] void func() {} |
| 80 | + |
| 81 | +struct S {}; |
| 82 | +void test() { |
| 83 | + // expected-note@+1{{in instantiation of function template specialization 'func<S>' requested here}} |
| 84 | + func<S>(); |
| 85 | + // expected-note@+1{{in instantiation of function template specialization 'func<float>' requested here}} |
| 86 | + func<float>(); |
| 87 | + // expected-note@+1{{in instantiation of function template specialization 'func<int>' requested here}} |
| 88 | + func<int>(); |
| 89 | +} |
| 90 | + |
| 91 | +// Test that checks expression is not a constant expression. |
| 92 | +// expected-note@+1{{declared here}} |
| 93 | +int foo1(); |
| 94 | +// expected-error@+2{{expression is not an integral constant expression}} |
| 95 | +// expected-note@+1{{non-constexpr function 'foo1' cannot be used in a constant expression}} |
| 96 | +[[intel::reqd_sub_group_size(foo1() + 12)]] void func1(); |
| 97 | + |
| 98 | +// Test that checks expression is a constant expression. |
| 99 | +constexpr int bar1() { return 0; } |
| 100 | +[[intel::reqd_sub_group_size(bar1() + 12)]] void func2(); // OK |
| 101 | + |
| 102 | +// Test that checks template parameter support on member function of class template. |
| 103 | +template <int SIZE> |
| 104 | +class KernelFunctor { |
| 105 | +public: |
| 106 | + // expected-error@+1{{'reqd_sub_group_size' attribute requires a positive integral compile time constant expression}} |
| 107 | + [[intel::reqd_sub_group_size(SIZE)]] void operator()() {} |
| 108 | +}; |
| 109 | + |
| 110 | +int check() { |
| 111 | + // expected-note@+1{{in instantiation of template class 'KernelFunctor<-1>' requested here}} |
| 112 | + KernelFunctor<-1>(); |
| 113 | + return 0; |
| 114 | +} |
| 115 | + |
| 116 | +// Test that checks template parameter support on function. |
| 117 | +template <int N> |
| 118 | +// expected-error@+1{{'reqd_sub_group_size' attribute requires a positive integral compile time constant expression}} |
| 119 | +[[intel::reqd_sub_group_size(N)]] void func3() {} |
| 120 | + |
| 121 | +template <int N> |
| 122 | +[[intel::reqd_sub_group_size(4)]] void func4(); // expected-note {{previous attribute is here}} |
| 123 | + |
| 124 | +template <int N> |
| 125 | +[[intel::reqd_sub_group_size(N)]] void func4() {} // expected-warning {{attribute 'reqd_sub_group_size' is already applied with different arguments}} |
| 126 | + |
| 127 | +int check1() { |
| 128 | + // no error expected |
| 129 | + func3<12>(); |
| 130 | + // expected-note@+1{{in instantiation of function template specialization 'func3<-1>' requested here}} |
| 131 | + func3<-1>(); |
| 132 | + func4<6>(); // expected-note {{in instantiation of function template specialization 'func4<6>' requested here}} |
| 133 | + return 0; |
| 134 | +} |
0 commit comments