Skip to content

[SYCL] [FPGA] Add mutual diagnostic of max_concurrency attribute in conjunction of disable_loop_pipelining attribute #3512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 13, 2021
6 changes: 3 additions & 3 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -2869,7 +2869,7 @@ This attribute applies to a loop or a function. It indicates that the
loop/function should allow no more than N threads or iterations to execute it
simultaneously. N must be a non negative integer. '0' indicates the
max_concurrency case to be unbounded. Cannot be applied multiple times to the
same loop.
same loop or function in conjunction with disable_loop_pipelining.

.. code-block:: c++

Expand Down Expand Up @@ -2942,10 +2942,10 @@ max_concurrency, initiation_interval, or ivdep.

void foo() {
int var = 0;
[[intel::disable_loop_pipelining] for (int i = 0; i < 10; ++i) var++;
[[intel::disable_loop_pipelining]] for (int i = 0; i < 10; ++i) var++;
}

[[intel::disable_loop_pipelining] void foo1() { }
[[intel::disable_loop_pipelining]] void foo1() { }

}];
}
Expand Down
29 changes: 17 additions & 12 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3313,6 +3313,11 @@ static void handleSYCLIntelFPGADisableLoopPipeliningAttr(Sema &S, Decl *D,
if (checkAttrMutualExclusion<SYCLIntelFPGAInitiationIntervalAttr>(S, D, A))
return;

// [[intel::disable_loop_pipelining] and [[intel::max_concurrency()]]
// attributes are incompatible.
if (checkAttrMutualExclusion<SYCLIntelFPGAMaxConcurrencyAttr>(S, D, A))
return;

D->addAttr(::new (S.Context)
SYCLIntelFPGADisableLoopPipeliningAttr(S.Context, A));
}
Expand Down Expand Up @@ -6367,12 +6372,12 @@ SYCLIntelFPGAMaxConcurrencyAttr *Sema::MergeSYCLIntelFPGAMaxConcurrencyAttr(
}
return nullptr;
}
// FIXME
// max_concurrency and disable_component_pipelining attributes can't be
// applied to the same function. Upcoming patch needs to have this code
// added to it:
// if (checkAttrMutualExclusion<IntelDisableComponentPipeline>(S, D, AL))
// return;

// [[intel::max_concurrency()]] and [[intel::disable_loop_pipelining]
// attributes are incompatible.
if (checkAttrMutualExclusion<SYCLIntelFPGADisableLoopPipeliningAttr>(*this, D,
A))
return nullptr;

return ::new (Context)
SYCLIntelFPGAMaxConcurrencyAttr(Context, A, A.getNThreadsExpr());
Expand Down Expand Up @@ -6406,18 +6411,18 @@ void Sema::AddSYCLIntelFPGAMaxConcurrencyAttr(Decl *D,
}
}

// [[intel::disable_loop_pipelining] and [[intel::max_concurrency()]]
// attributes are incompatible.
if (checkAttrMutualExclusion<SYCLIntelFPGADisableLoopPipeliningAttr>(*this, D,
CI))
return;

D->addAttr(::new (Context) SYCLIntelFPGAMaxConcurrencyAttr(Context, CI, E));
}

static void handleSYCLIntelFPGAMaxConcurrencyAttr(Sema &S, Decl *D,
const ParsedAttr &A) {
S.CheckDeprecatedSYCLAttributeSpelling(A);
// FIXME
// max_concurrency and disable_component_pipelining attributes can't be
// applied to the same function. Upcoming patch needs to have this code
// added to it:
// if (checkAttrMutualExclusion<IntelDisableComponentPipeline>(S, D, AL))
// return;

Expr *E = A.getArgAsExpr(0);
S.AddSYCLIntelFPGAMaxConcurrencyAttr(D, A, E);
Expand Down
7 changes: 3 additions & 4 deletions clang/test/CodeGenSYCL/disable_loop_pipelining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ int main() {
return 0;
}

// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel1"() #0 !kernel_arg_buffer_location ![[NUM4:[0-9]+]] !disable_loop_pipelining ![[NUM5:[0-9]+]]
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel2"() #0 !kernel_arg_buffer_location ![[NUM4]]
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel3"() #0 !kernel_arg_buffer_location ![[NUM4]] !disable_loop_pipelining ![[NUM5]]
// CHECK: ![[NUM4]] = !{}
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel1"() #0 {{.*}} !disable_loop_pipelining ![[NUM5:[0-9]+]]
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel2"() #0 {{.*}}
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel3"() #0 {{.*}} !disable_loop_pipelining ![[NUM5]]
// CHECK: ![[NUM5]] = !{i32 1}
9 changes: 4 additions & 5 deletions clang/test/CodeGenSYCL/initiation_interval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ int main() {
return 0;
}

// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name1"() #0 !kernel_arg_buffer_location ![[NUM0:[0-9]+]] !initiation_interval ![[NUM1:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name2"() #0 !kernel_arg_buffer_location ![[NUM0]] !initiation_interval ![[NUM42:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name3"() #0 !kernel_arg_buffer_location ![[NUM0]] !initiation_interval ![[NUM2:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name4"() #0 !kernel_arg_buffer_location ![[NUM0]]
// CHECK: ![[NUM0]] = !{}
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name1"() #0 {{.*}} !initiation_interval ![[NUM1:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name2"() #0 {{.*}} !initiation_interval ![[NUM42:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name3"() #0 {{.*}} !initiation_interval ![[NUM2:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name4"() #0 {{.*}}
// CHECK: ![[NUM1]] = !{i32 1}
// CHECK: ![[NUM42]] = !{i32 42}
// CHECK: ![[NUM2]] = !{i32 2}
6 changes: 4 additions & 2 deletions clang/test/SemaSYCL/initiation_interval.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// RUN: %clang_cc1 -fsycl-is-device -verify %s

// Test that checks disable_loop_pipelining attribute support on Function.
// Test that checks initiation_interval attribute support on function.

// Tests for incorrect argument values for Intel FPGA initiation_interval function attribute.
[[intel::initiation_interval]] void one() {} // expected-error {{'initiation_interval' attribute takes one argument}}

[[intel::initiation_interval(5)]] int a; // expected-error{{'initiation_interval' attribute only applies to 'for', 'while', 'do' statements, and functions}}

[[intel::initiation_interval("foo")]] void func() {} // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'const char [4]'}}
Expand All @@ -27,7 +29,7 @@
[[intel::initiation_interval(1)]] void func6(); // expected-note {{previous attribute is here}}
[[intel::initiation_interval(3)]] void func6(); // expected-warning {{attribute 'initiation_interval' is already applied with different arguments}}

// Tests for Intel FPGA loop fusion function attributes compatibility
// Tests for Intel FPGA initiation_interval and disable_loop_pipelining function attributes compatibility.
// expected-error@+2 {{'initiation_interval' and 'disable_loop_pipelining' attributes are not compatible}}
// expected-note@+1 {{conflicting attribute is here}}
[[intel::disable_loop_pipelining]] [[intel::initiation_interval(2)]] void func7();
Expand Down
14 changes: 14 additions & 0 deletions clang/test/SemaSYCL/max-concurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ class Functor1 {

[[intel::max_concurrency]] void foo() {} // expected-error {{'max_concurrency' attribute takes one argument}}

// Tests for Intel FPGA max_concurrency and disable_loop_pipelining function attributes compatibility.
// expected-error@+2 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}}
// expected-note@+1 {{conflicting attribute is here}}
[[intel::disable_loop_pipelining]] [[intel::max_concurrency(2)]] void check();

// expected-error@+2 {{'disable_loop_pipelining' and 'max_concurrency' attributes are not compatible}}
// expected-note@+1 {{conflicting attribute is here}}
[[intel::max_concurrency(4)]] [[intel::disable_loop_pipelining]] void check1();

// expected-error@+2 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}}
// expected-note@+2 {{conflicting attribute is here}}
[[intel::max_concurrency(4)]] void check2();
[[intel::disable_loop_pipelining]] void check2();

class Functor2 {
public:
void operator()() const {
Expand Down