Skip to content

Commit 558b3ba

Browse files
authored
[SYCL][FPGA] Allow safelen = 0 with ivdep attribute (#6336)
This patch allows safelen = 0 with ivdep attribute and emits suppressible warning when safelen of 0 or 1 is used Current behaviour: ivdep with safelen of 1 is allowed with no warning. Safelen of 0 causes an error. Desired behaviour: safelen of 1 and 0 should both be allowed but will have no effect on the loop. Both should emit a warning. The warning should be suppressible with a -Wno flag. Justification: The safelen parameter of an ivdep will sometimes be set based on a template argument. It makes this type of code much cleaner if the setting of 0 is permitted. The warning for both the 0 and 1 case is helpful for users who might misunderstand the meaning of the safelen parameter and set a value of 1 (or possibly 0) thinking it will have some effect. The warning should be suppressible for those developers using the templated coding pattern described above who understand and accept that a safelen of 0 will have no effect. Signed-off-by: Soumi Manna soumi.manna@intel.com
1 parent db5f72a commit 558b3ba

File tree

7 files changed

+78
-6
lines changed

7 files changed

+78
-6
lines changed

clang/include/clang/Basic/AttrDocs.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3161,6 +3161,9 @@ is unspecified and is therefore considered infinite.
31613161
In case of ivdep being applied both w/o an array variable and for a particular
31623162
array, the array variables that were not designated a separate ivdep will receive
31633163
the no-array ivdep's safelen, with the correspondent treatment by the backend.
3164+
The ``[[intel::ivdep]]`` attribute applies a safelen value of 0 or 1 that has
3165+
no effect on the loop and emits a suppressible warning when safelen value of 0
3166+
or 1 is used.
31643167

31653168
.. code-block:: c++
31663169

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,9 +737,10 @@ def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
737737
def NSConsumedMismatch : DiagGroup<"nsconsumed-mismatch">;
738738
def NSReturnsMismatch : DiagGroup<"nsreturns-mismatch">;
739739

740+
def SyclIvdepAttribute : DiagGroup<"ivdep-compat">;
740741
def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
741742
def UnknownAttributes : DiagGroup<"unknown-attributes">;
742-
def IgnoredAttributes : DiagGroup<"ignored-attributes">;
743+
def IgnoredAttributes : DiagGroup<"ignored-attributes", [SyclIvdepAttribute]>;
743744
def AcceptedAttributes : DiagGroup<"accepted-attributes">;
744745
def Attributes : DiagGroup<"attributes", [UnknownAttributes,
745746
IgnoredAttributes,

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11794,6 +11794,9 @@ def err_ivdep_declrefexpr_arg : Error<
1179411794
def warn_ivdep_redundant : Warning <"ignoring redundant Intel FPGA loop "
1179511795
"attribute 'ivdep': safelen %select{INF|%1}0 >= safelen %select{INF|%3}2">,
1179611796
InGroup<IgnoredAttributes>;
11797+
def warn_ivdep_attribute_argument : Warning<
11798+
"'ivdep' attribute with value %0 has no effect; attribute ignored">,
11799+
InGroup<SyclIvdepAttribute>;
1179711800
def warn_attribute_spelling_deprecated : Warning<
1179811801
"attribute %0 is deprecated">,
1179911802
InGroup<DeprecatedAttributes>;

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,11 @@ Sema::BuildSYCLIntelFPGAPipelineAttr(const AttributeCommonInfo &A, Expr *E) {
248248

249249
static bool checkSYCLIntelFPGAIVDepSafeLen(Sema &S, llvm::APSInt &Value,
250250
Expr *E) {
251-
if (!Value.isStrictlyPositive())
251+
// This attribute requires a non-negative value.
252+
if (!Value.isNonNegative())
252253
return S.Diag(E->getExprLoc(),
253254
diag::err_attribute_requires_positive_integer)
254-
<< "'ivdep'" << /* positive */ 0;
255+
<< "'ivdep'" << /*non-negative*/ 1;
255256
return false;
256257
}
257258

@@ -276,6 +277,12 @@ static IVDepExprResult HandleFPGAIVDepAttrExpr(Sema &S, Expr *E,
276277
if (checkSYCLIntelFPGAIVDepSafeLen(S, *ArgVal, E))
277278
return IVDepExprResult::Invalid;
278279
SafelenValue = ArgVal->getZExtValue();
280+
// ivdep attribute allows both safelen = 0 and safelen = 1 with a warning.
281+
if (SafelenValue == 0 || SafelenValue == 1) {
282+
S.Diag(E->getExprLoc(), diag::warn_ivdep_attribute_argument)
283+
<< SafelenValue;
284+
return IVDepExprResult::Invalid;
285+
}
279286
return IVDepExprResult::SafeLen;
280287
}
281288

clang/test/CodeGenSYCL/intel-fpga-ivdep-global.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,34 @@ void ivdep_conflicting_safelen() {
7575
}
7676
}
7777

78+
// Global ivdep w/ safelen value 1 is specified - do not annotate GEP
79+
//
80+
// CHECK: define {{.*}}spir_func void @_Z{{[0-9]+}}ivdep_safelen_onev()
81+
void ivdep_safelen_one() {
82+
// CHECK: %[[ARRAY_A:[0-9a-z]+]] = alloca [10 x i32]
83+
int a[10];
84+
[[intel::ivdep(1)]] for (int i = 0; i != 10; ++i) {
85+
// CHECK: %{{[0-9a-z]+}} = getelementptr inbounds [10 x i32], ptr addrspace(4) %[[ARRAY_A]].ascast, i64 0, i64 %{{[0-9a-z]+}}
86+
// CHECK-NOT: !llvm.index.group
87+
a[i] = 0;
88+
// CHECK: br label %for.cond, !llvm.loop ![[MD_NO_LOOP_SAFELEN1:[0-9]+]]
89+
}
90+
}
91+
92+
// Global ivdep w/ safelen value 0 is specified - do not annotate GEP
93+
//
94+
// CHECK: define {{.*}}spir_func void @_Z{{[0-9]+}}ivdep_safelen_zerov()
95+
void ivdep_safelen_zero() {
96+
// CHECK: %[[ARRAY_A:[0-9a-z]+]] = alloca [10 x i32]
97+
int a[10];
98+
[[intel::ivdep(0)]] for (int i = 0; i != 10; ++i) {
99+
// CHECK: %{{[0-9a-z]+}} = getelementptr inbounds [10 x i32], ptr addrspace(4) %[[ARRAY_A]].ascast, i64 0, i64 %{{[0-9a-z]+}}
100+
// CHECK-NOT: !llvm.index.group
101+
a[i] = 0;
102+
// CHECK: br label %for.cond, !llvm.loop ![[MD_NO_LOOP_SAFELEN2:[0-9]+]]
103+
}
104+
}
105+
78106
template <typename name, typename Func>
79107
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
80108
kernelFunc();
@@ -86,6 +114,8 @@ int main() {
86114
ivdep_no_param_multiple_geps();
87115
ivdep_safelen();
88116
ivdep_conflicting_safelen();
117+
ivdep_safelen_one();
118+
ivdep_safelen_zero();
89119
});
90120
return 0;
91121
}
@@ -122,3 +152,11 @@ int main() {
122152
// CHECK-DAG: ![[IDX_GROUP_B_CONFL_SAFELEN]] = distinct !{}
123153
// CHECK-DAG: ![[MD_LOOP_CONFL_SAFELEN]] = distinct !{![[MD_LOOP_CONFL_SAFELEN]], ![[#]], ![[IVDEP_CONFL_SAFELEN:[0-9]+]], ![[IVDEP_LEGACY_SAFELEN_5]]}
124154
// CHECK-DAG: ![[IVDEP_CONFL_SAFELEN]] = !{!"llvm.loop.parallel_access_indices", ![[IDX_GROUP_A_CONFL_SAFELEN]], ![[IDX_GROUP_B_CONFL_SAFELEN]], i32 5}
155+
156+
/// Global ivdep w/ safelen value of 1 has no effect. Attribute is ignored and no IR is generated with safelen value of 1.
157+
// CHECK-DAG: ![[MD_NO_LOOP_SAFELEN1]] = distinct !{![[MD_NO_LOOP_SAFELEN1]], ![[#]]}
158+
// CHECK-NOT: !{!"llvm.loop.ivdep.safelen", i32 1}
159+
160+
/// Global ivdep w/ safelen value of 0 has no effect. Attribute is ignored and no IR is generated with safelen value of 0.
161+
// CHECK-DAG: ![[MD_NO_LOOP_SAFELEN2]] = distinct !{![[MD_NO_LOOP_SAFELEN2]], ![[#]]}
162+
// CHECK-NOT: !{!"llvm.loop.ivdep.enable"}

clang/test/SemaSYCL/intel-fpga-loops.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void goo() {
139139
// no diagnostics are expected
140140
[[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i)
141141
a[i] = 0;
142-
// expected-error@+1 {{'ivdep' attribute requires a positive integral compile time constant expression}}
142+
// expected-warning@+1 {{'ivdep' attribute with value 0 has no effect; attribute ignored}}
143143
[[intel::ivdep(0)]] for (int i = 0; i != 10; ++i)
144144
a[i] = 0;
145145
// expected-error@+1 {{'initiation_interval' attribute requires a positive integral compile time constant expression}}
@@ -418,10 +418,11 @@ void ivdep_dependent() {
418418
[[intel::ivdep(5)]] for (int i = 0; i != 10; ++i)
419419
a[i] = 0;
420420

421+
// expected-warning@+1 {{'ivdep' attribute with value 1 has no effect; attribute ignored}}
421422
[[intel::ivdep(C)]]
422-
// expected-error@-1 {{'ivdep' attribute requires a positive integral compile time constant expression}}
423+
// expected-error@-1 {{'ivdep' attribute requires a non-negative integral compile time constant expression}}
423424
for (int i = 0; i != 10; ++i)
424-
a[i] = 0;
425+
a[i] = 0;
425426

426427
// expected-warning@+3 {{ignoring redundant Intel FPGA loop attribute 'ivdep': safelen 4 >= safelen 2}}
427428
// expected-note@+1 {{previous attribute is here}}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -Wno-ivdep-compat -verify %s
2+
// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -Wno-ignored-attributes -verify %s
3+
4+
// expected-no-diagnostics
5+
6+
// Test that the warning gets suppressed with a -Wno flag when the
7+
// [[intel::ivdep]] attribute applies a safelen value of 0 or 1 to the loop.
8+
9+
void test_zero() {
10+
int a[10];
11+
[[intel::ivdep(0)]] for (int i = 0; i != 10; ++i)
12+
a[i] = 0;
13+
}
14+
15+
void test_one() {
16+
int b[10];
17+
[[intel::ivdep(1)]] for (int i = 0; i != 10; ++i)
18+
b[i] = 0;
19+
}

0 commit comments

Comments
 (0)